Aller au contenu

Vue imprimable multi-pages de cette section. .

Retour à la version par défaut.

HAProxy 3.4.4 Documentation

Version complète en anglais des manuels HAProxy 3.4 : Introduction, Configuration et Administration

HAProxy est un proxy inverse gratuit, rapide et fiable pour la haute disponibilité, l’équilibrage de charge TCP et HTTP, ainsi que la gestion du trafic applicatif. Ce composant contient le texte intégral anglais des trois manuels principaux d’HAProxy 3.4, réorganisés sous forme d’une séquence lisible Markdown plate destinée à OINK.

Choisissez un manuel

  • Guide de démarrage — 9 sujets sur les concepts de répartition de charge, l’architecture HAProxy, les fonctionnalités, la dimensionnement, les versions et l’écosystème.
  • Manuel de configuration — 12 chapitres couvrant les proxies, les ACLs, les exemples, la journalisation, les filtres et chaque famille d’options.
  • Guide de gestion — 13 chapitres sur le démarrage, les rechargements, les ressources, la journalisation, les statistiques, la CLI d’exécution, le débogage et la sécurité.

Couverture édition

ManuelSource amontOrganisation locale
Guide de démarrage1 695 lignes9 pages de sujet plat
Manuel de configuration33 148 lignes12 pages de chapitre plat
Guide de gestion5 285 lignes13 pages de chapitre plat

Les 34 pages de lecture sont directement situées sous la racine du composant HAProxy. Trois espaces réservés séparateurs non liés divisent les manuels dans la barre latérale sans ajouter de niveaux de répertoire ni d’arrêts de pagination.

Les sources complètes épinglées et leurs sommes de contrôle SHA-256 sont conservées sous sources/haproxy/. La notice de licence amont et le texte GPLv2 sont publiés avec les manuels. Une édition complémentaire relue en chinois simplifié est disponible pour chaque page.

1 - Fundamentaux de la répartition de charge

Équilibre de charge de paquets, réseau, serveur, L4 et L7

Ce document présente HAProxy à l’intention de tous ceux qui ne le connaissent pas, ainsi que de ceux qui souhaitent le redécouvrir après avoir utilisé des versions antérieures. Son objectif principal est de fournir à l’utilisateur toutes les informations nécessaires pour décider si HAProxy correspond ou non à ses besoins. Les utilisateurs avancés pourront y trouver certaines solutions à des idées qu’ils avaient eues, simplement parce qu’ils ignoraient une fonctionnalité récente. Des indications de dimensionnement sont également fournies, le cycle de vie du produit est expliqué, ainsi que des comparaisons avec des produits partiellement similaires.

Ce document ne fournit aucune aide ou indication de configuration, mais explique où trouver les documents pertinents. Le guide est présenté sous la forme d’une séquence plane de pages thématiques dans la barre latérale HAProxy.

La répartition de charge consiste à regrouper plusieurs composants afin d’obtenir une capacité de traitement totale supérieure à celle de chaque composant individuellement, sans intervention de l’utilisateur final et de manière évolutif. Cela permet d’exécuter simultanément un plus grand nombre d’opérations pendant le temps nécessaire à un composant pour exécuter une seule opération. Une opération unique reste toutefois traitée par un seul composant à la fois et n’est pas plus rapide qu’en l’absence de répartition de charge. Elle nécessite toujours au moins autant d’opérations que de composants disponibles, ainsi qu’un mécanisme de répartition de charge efficace pour tirer parti de tous les composants et bénéficier pleinement de la répartition de charge. Un bon exemple en est le nombre de voies sur une autoroute, qui permet à autant de véhicules de passer pendant le même intervalle de temps sans augmenter leur vitesse individuelle.

Exemples de répartition de charge :

  • Planification des processus dans les systèmes à plusieurs processeurs
  • Répartition de charge sur les liens (par exemple, EtherChannel, Bonding)
  • Répartition de charge par adresse IP (par exemple, ECMP, round-robin DNS)
  • Répartition de charge sur les serveurs (via des répartiteurs de charge)

Le mécanisme ou composant qui effectue l’opération de répartition de charge est appelé un répartiteur de charge. Dans les environnements web, ces composants sont désignés comme un « répartiteur de charge réseau », et plus couramment un « répartiteur de charge », étant donné que cette activité constitue de loin le cas le plus connu de répartition de charge.

Un répartiteur de charge peut agir :

  • au niveau du lien : il s’agit de la répartition de charge au niveau du lien, qui consiste à choisir le lien réseau par lequel envoyer un paquet ;

  • au niveau du réseau : cela s’appelle la répartition de charge réseau, et consiste à choisir le chemin suivi par une série de paquets ;

  • au niveau du serveur : il s’agit de la répartition de charge au niveau du serveur, qui consiste à déterminer quel serveur traitera une connexion ou une requête.

Deux technologies distinctes existent et répondent à des besoins différents, bien qu’elles se chevauchent parfois. Dans chaque cas, il est essentiel de garder à l’esprit que la répartition de charge consiste à détourner le trafic de son flux naturel, et qu’un minimum de précaution est toujours nécessaire pour maintenir le niveau requis de cohérence entre toutes les décisions de routage.

La première agit au niveau des paquets et les traite plus ou moins individuellement. La relation entre paquets d’entrée et de sortie est de 1 à 1 ; un analyseur réseau classique peut donc suivre le trafic de part et d’autre du répartiteur. Cette technologie peut être très peu coûteuse et extrêmement rapide. Elle est généralement implémentée dans le matériel (ASIC), ce qui permet d’atteindre le débit de ligne, par exemple avec des commutateurs ECMP. Habituellement sans état, elle peut aussi conserver un état en tenant compte de la session du paquet ; on parle alors de layer4-LB ou L4. Elle peut prendre en charge le DSR (retour direct du serveur sans repasser par le répartiteur) lorsque les paquets ne sont pas modifiés, mais n’offre presque aucune connaissance du contenu. Cette technologie convient particulièrement à la répartition de charge réseau, bien qu’elle serve parfois à une répartition serveur très simple à haut débit.

Le deuxième agit sur le contenu des sessions. Il nécessite que les flux d’entrée soient reconstitués et traités dans leur intégralité. Le contenu peut être modifié, et le flux de sortie est segmenté en nouveaux paquets. C’est pourquoi cette opération est généralement réalisée par des proxies, qui sont souvent appelés répartiteurs de charge au niveau 7 ou L7. Cela implique qu’il existe deux connexions distinctes de chaque côté, et qu’aucune relation n’existe entre les tailles ou les nombres de paquets d’entrée et de sortie. Les clients et les serveurs ne sont pas tenus d’utiliser le même protocole (par exemple IPv4 contre IPv6, clair contre SSL). Les opérations sont toujours étatiques, et le trafic de retour doit passer par le répartiteur de charge. Ce traitement supplémentaire comporte un coût, si bien qu’il n’est pas toujours possible d’atteindre un débit en ligne, notamment avec des paquets de petite taille. En revanche, il offre de nombreuses possibilités et est généralement réalisé par logiciel pur, même lorsqu’il est intégré à des appareils matériels. Cette technologie convient particulièrement bien à la répartition de charge des serveurs.

Les répartiteurs de charge basés sur les paquets sont généralement déployés en mode cut-through, ce qui signifie qu’ils sont installés sur le chemin normal du trafic et le redirigent selon la configuration. Le trafic de retour n’est pas nécessairement acheminé via le répartiteur de charge. Des modifications peuvent être apportées à l’adresse réseau de destination afin de diriger le trafic vers la destination appropriée. Dans ce cas, il est obligatoire que le trafic de retour passe par le répartiteur de charge. Si les routes ne permettent pas cette configuration, le répartiteur de charge peut également remplacer l’adresse source des paquets par la sienne afin de forcer le trafic de retour à passer par lui.

Les répartiteurs de charge basés sur un proxy sont déployés comme un serveur disposant de leurs propres adresses IP et ports, sans nécessiter de modification de l’architecture. Parfois, cela exige d’apporter certaines adaptations aux applications afin que les clients soient correctement redirigés vers l’adresse IP du répartiteur de charge et non directement vers celle du serveur. Certains répartiteurs de charge peuvent devoir ajuster certaines réponses des serveurs pour permettre cette redirection (par exemple, le champ d’en-tête HTTP Location utilisé dans les redirections HTTP). Certains répartiteurs de charge basés sur un proxy peuvent intercepter le trafic destiné à une adresse qu’ils ne possèdent pas, et masquer l’adresse du client lors de la connexion au serveur. Cela leur permet d’être déployés comme un routeur ou un pare-feu classique, en mode pass-through très similaire à celui des répartiteurs de charge basés sur les paquets. Cette caractéristique est particulièrement appréciée pour les produits qui combinent à la fois le mode paquet et le mode proxy. Dans ce cas, le DSR reste évidemment impossible, et le trafic de retour doit toujours être acheminé de retour vers le répartiteur de charge.

Une approche à plusieurs niveaux très évolutive consisterait à mettre en place un routeur frontal qui reçoit le trafic provenant de plusieurs liens répartis en charge, et qui utilise ECMP pour distribuer ce trafic à une première couche de plusieurs répartiteurs de charge basés sur les paquets et état ( L4 ). Ces répartiteurs de charge L4 transmettent ensuite le trafic à un nombre encore plus important de répartiteurs basés sur des proxies ( L7 ), qui doivent analyser le contenu pour déterminer quel serveur recevra finalement le trafic.

Le nombre de composants et de chemins possibles pour le trafic augmente le risque de défaillance ; dans des environnements très volumineux, il est même normal de voir en permanence quelques composants défaillants en cours de réparation ou de remplacement. La répartition de charge effectuée sans prise de conscience de l’état global de la pile dégrade significativement la disponibilité. Pour cette raison, tout répartiteur de charge raisonnable vérifiera que les composants auxquels il entend acheminer le trafic sont toujours actifs et accessibles, et il cesse de distribuer du trafic aux composants défaillants. Cela peut être réalisé à l’aide de diverses méthodes.

Le cas le plus courant consiste à envoyer périodiquement des sondes afin de vérifier que le composant reste opérationnel. Ces sondes sont appelées « contrôles d’état ». Elles doivent être représentatives du type de panne à détecter. Par exemple, un contrôle basé sur ping ne détectera pas qu’un serveur web a cessé de fonctionner et ne répond plus sur un port, tandis qu’une connexion au port permet de vérifier cela, et une requête plus avancée peut même valider que le serveur fonctionne toujours et que la base de données dont il dépend reste accessible. Les contrôles d’état comportent souvent quelques tentatives afin de compenser les erreurs de mesure occasionnelles. L’intervalle entre les contrôles doit être suffisamment court pour garantir que le composant défaillant n’est pas utilisé trop longtemps après la survenue d’une erreur.

D’autres méthodes échantillonnent le trafic de production envoyé à une destination pour vérifier son traitement et écarter les composants qui renvoient des réponses inappropriées. Cela sacrifie toutefois une partie du trafic de production, ce qui n’est pas toujours acceptable. Combiner ces deux mécanismes offre le meilleur de chaque approche : ils servent ensemble à détecter une panne, tandis que les contrôles d’état seuls en détectent la fin. Une dernière méthode repose sur un rapport centralisé : un agent de supervision met périodiquement à jour tous les répartiteurs avec l’état des composants. Chacun dispose ainsi d’une vue globale de l’infrastructure, parfois moins précise ou moins réactive. Cette approche convient surtout aux environnements comportant de nombreux répartiteurs et serveurs.

Les répartiteurs de charge au niveau 7 font également face à un autre défi connu sous le nom de persistance ou « sticky session ». Le principe consiste à orienter généralement plusieurs requêtes ou connexions successives provenant d’une même origine (par exemple, un utilisateur final) vers la même cible. L’exemple le plus connu est le panier d’achat sur un site marchand en ligne. Si chaque clic entraîne une nouvelle connexion, l’utilisateur doit toujours être acheminé vers le serveur qui détient son panier. La prise en compte du contenu facilite la détection d’éléments dans la requête afin d’identifier le serveur à qui la requête doit être acheminée, mais cela ne suffit pas toujours. Par exemple, si l’adresse source est utilisée comme clé pour sélectionner un serveur, on peut décider d’utiliser un algorithme basé sur un hachage, selon lequel une adresse IP donnée sera toujours acheminée vers le même serveur, en fonction d’une division de l’adresse par le nombre de serveurs disponibles. Mais si un serveur tombe en panne, le résultat change et tous les utilisateurs sont soudainement redirigés vers un autre serveur, ce qui fait perdre leur panier. La solution à ce problème consiste à mémoriser la cible choisie, de sorte que chaque fois qu’un même visiteur est détecté, il soit dirigé vers le même serveur, indépendamment du nombre de serveurs disponibles. Cette information peut être stockée en mémoire du répartiteur de charge, auquel cas elle doit éventuellement être répliquée sur d’autres répartiteurs de charge s’il n’est pas seul, ou stockée en mémoire du client à l’aide de diverses méthodes, à condition que le client soit capable de présenter cette information à chaque requête (insertion de cookie, redirection vers un sous-domaine, etc.). Ce mécanisme présente l’avantage supplémentaire de ne pas dépendre d’informations instables ou inégalement réparties (comme l’adresse IP source). C’est en réalité la raison la plus forte d’adopter un répartiteur de charge au niveau 7 plutôt qu’au niveau 4.

Afin d’extraire des informations telles qu’un cookie, un champ d’en-tête d’hôte, une URL ou tout autre élément, un répartiteur de charge peut devoir déchiffrer le trafic SSL/TLS, voire le réchiffrer lorsqu’il le transmet au serveur. Cette opération coûteuse explique pourquoi, dans certaines infrastructures à fort trafic, il peut y avoir un grand nombre de répartiteurs de charge.

Puisqu’un répartiteur de charge au niveau 7 peut effectuer un certain nombre d’opérations complexes sur le trafic (décrypter, analyser, modifier, comparer les cookies, décider quel serveur contacter, etc.), il peut effectivement causer des problèmes et est très fréquemment accusé à tort d’être à l’origine de nombreux dysfonctionnements qu’il n’a fait que révéler. Il arrive souvent que l’on découvre que les serveurs sont instables et passent périodiquement de l’état actif à l’état inactif, ou que, pour les serveurs web, ils renvoient des pages contenant des liens codés en dur qui obligent les clients à se connecter directement à un serveur spécifique sans passer par le répartiteur de charge, ou encore qu’ils mettent une éternité à répondre sous forte charge, provoquant des délais d’expiration. C’est pourquoi la journalisation constitue un aspect extrêmement important de la répartition de charge au niveau 7. Dès qu’un problème est signalé, il est essentiel de déterminer si le répartiteur de charge a pris une décision erronée et, le cas échéant, pourquoi, afin qu’il ne se reproduise plus.

2 - Qu'est-ce qu'HAProxy et comment il fonctionne

Rôle, limites, architecture orientée événements et modèle de traitement des requêtes de HAProxy

La graphie « HAProxy » désigne le produit, tandis que « haproxy » désigne le programme exécutable, le paquet logiciel ou un processus. Ces graphies sont toutefois couramment utilisées dans chaque contexte et se prononcent H-A-Proxy. À l’origine, « haproxy » signifiait « high availability proxy » et le nom s’écrivait en deux mots distincts ; aujourd’hui, il ne signifie plus rien d’autre que « HAProxy ».

3.1. Ce qu’est et ce qu’il n’est pas HAProxy

HAProxy est :

  • un proxy TCP : il peut accepter une connexion TCP sur un socket d’écoute, se connecter à un serveur et associer ces sockets afin que le trafic circule dans chaque direction. Les sockets IPv4, IPv6 et même UNIX sont pris en charge de part et d’autre, ce qui permet de traduire facilement les adresses entre différentes familles.

  • un proxy inverse HTTP (appelé « passerelle » en terminologie HTTP) : il se présente comme un serveur, reçoit les requêtes HTTP sur des connexions établies via une socket TCP d’écoute, puis transmet les requêtes provenant de ces connexions vers des serveurs en utilisant des connexions distinctes. Il peut utiliser n’importe quelle combinaison de HTTP/1.x ou HTTP/2 sur chaque côté et détecte même automatiquement le protocole utilisé sur chaque côté lorsque ALPN est utilisé sur TLS.

  • un terminateur, initiateur ou déchargeur SSL : SSL/TLS peut être utilisé sur la connexion provenant du client, sur celle allant vers le serveur, ou simultanément sur ces connexions. De nombreux paramètres peuvent être appliqués par nom (SNI) et mis à jour à l’exécution sans redémarrage. Ces configurations passent extrêmement bien à l’échelle ; des déploiements comportant des dizaines ou des centaines de milliers de certificats ont été signalés.

  • un normalisateur TCP : puisque le système d’exploitation termine les connexions localement, il n’existe aucune relation entre les extrémités. Le trafic anormal, tel que des paquets invalides, des combinaisons de drapeaux, des annonces de fenêtre, des numéros de séquence ou des connexions incomplètes (SYN flood), n’est donc pas transmis à l’autre extrémité. Cela protège les piles TCP fragiles contre les attaques de protocole et permet d’optimiser les paramètres de connexion côté client sans modifier ceux de la pile TCP des serveurs.

  • un normalisateur HTTP : lorsqu’il est configuré pour traiter le trafic HTTP, seules les requêtes complètes et valides sont transmises. Cela protège contre de nombreux attaques basées sur le protocole. En outre, les écarts au protocole pour lesquels une tolérance est prévue dans la spécification sont corrigés afin qu’ils n’entraînent pas de problème sur les serveurs (par exemple, les en-têtes sur plusieurs lignes).

  • outil de correction HTTP : il peut modifier, corriger, ajouter, supprimer ou réécrire l’URL ou n’importe quel en-tête de requête ou de réponse. Cela permet de résoudre les problèmes d’interopérabilité dans des environnements complexes.

  • un commutateur basé sur le contenu : il peut prendre en compte n’importe quel élément de la requête pour déterminer le serveur vers lequel acheminer la requête ou la connexion. Il devient ainsi possible de gérer plusieurs protocoles sur un même port (par exemple, HTTP, HTTPS, SSH).

  • un répartiteur de charge : il peut répartir les connexions TCP et les requêtes HTTP. En mode TCP, les décisions de répartition sont prises pour toute la connexion. En mode HTTP, les décisions sont prises par requête.

  • un régulateur de trafic : il peut appliquer une limitation de débit à divers emplacements, protéger les serveurs contre la surcharge, ajuster les priorités du trafic en fonction du contenu, et transmettre même ces informations aux couches inférieures et aux composants du réseau externe en marquant les paquets.

  • une protection contre les attaques DDoS et l’abus de service : elle peut conserver un grand nombre de statistiques par adresse IP, URL, cookie, etc., détecter lorsqu’un abus a lieu, puis prendre des mesures (ralentir les auteurs d’abus, les bloquer, les rediriger vers des contenus obsolètes, etc.).

  • un point d’observation pour le dépannage réseau : en raison de la précision des informations rapportées dans les journaux, il est souvent utilisé pour restreindre le champ des problèmes liés au réseau.

  • un déchargeur de compression HTTP : il peut compresser les réponses qui n’ont pas été compressées par le serveur, réduisant ainsi le temps de chargement des pages pour les clients ayant une connectivité médiocre ou utilisant des réseaux mobiles à forte latence.

  • un proxy de mise en mémoire tampon : il peut mettre en mémoire tampon des réponses en RAM afin que les requêtes ultérieures pour le même objet évitent le coût d’une nouvelle transmission réseau depuis le serveur, tant que l’objet reste présent et valide. Il ne stockera toutefois pas les objets dans un stockage persistant. Veuillez noter que cette fonction de mise en mémoire tampon est conçue pour être entièrement autonome et se concentre exclusivement sur la conservation des ressources précieuses de HAProxy, et non sur la préservation des ressources du serveur. Les mécanismes de mise en mémoire tampon visant à optimiser les serveurs nécessitent bien plus de réglages et de flexibilité. Si vous avez besoin d’une telle mise en mémoire tampon avancée, veuillez utiliser Varnish Cache, qui s’intègre parfaitement à HAProxy, notamment lorsque le chiffrement SSL/TLS est requis sur l’une ou l’autre des extrémités.

  • un passerelle FastCGI : FastCGI peut être considéré comme une représentation différente du protocole HTTP, et HAProxy peut donc équilibrer la charge directement sur une ferme composée de tout ensemble combiné de serveurs d’applications FastCGI, sans nécessiter de placer un niveau supplémentaire de passerelle entre eux. Cela permet de réaliser des économies de ressources et de réduire les coûts de maintenance.

HAProxy n’est pas :

  • un proxy HTTP explicite, c’est-à-dire le proxy utilisé par les navigateurs pour accéder à Internet. Il existe de nombreux logiciels open source dédiés à cette tâche, tels que Squid. Toutefois, HAProxy peut être installé devant un tel proxy afin de fournir une répartition de charge et une haute disponibilité.

  • un nettoyeur de données : il ne modifie ni le corps des requêtes ni celui des réponses.

  • un serveur web statique : au démarrage, il s’isole dans une prison chroot et abandonne ses privilèges, de sorte qu’il ne réalise aucune opération d’accès au système de fichiers une fois lancé. En conséquence, il ne peut pas être utilisé comme serveur web statique (les serveurs dynamiques sont pris en charge via FastCGI toutefois). Il existe de nombreux logiciels open source excellents à cet effet, tels qu’Apache ou NGINX, et HAProxy peut facilement être installé devant eux pour assurer la répartition de charge, la haute disponibilité et l’accélération.

  • un répartiteur de charge basé sur les paquets : il ne traite ni les paquets IP ni les datagrammes UDP, n’effectue pas de NAT, ni encore moins de DSR. Ces tâches relèvent des couches inférieures. Certains composants basés noyau, comme IPVS (Linux Virtual Server), s’en occupent déjà très bien et s’associent parfaitement à HAProxy.

3.2. Comment fonctionne HAProxy

HAProxy est un moteur événementiel, non bloquant, combinant une couche I/O très rapide à un planificateur multithreadé basé sur la priorité. Conçu avec pour objectif principal le transfert de données, son architecture est optimisée pour acheminer les données aussi rapidement que possible, avec un nombre minimal d’opérations. Il se concentre sur l’optimisation de l’efficacité du cache CPU en maintenant les connexions sur le même processeur aussi longtemps que possible. En conséquence, il met en œuvre un modèle en couches offrant des mécanismes de bypass à chaque niveau, garantissant que les données n’atteignent pas les niveaux supérieurs sauf si nécessaire. La majeure partie du traitement est effectuée dans le noyau, et HAProxy fait tout son possible pour aider le noyau à accomplir son travail aussi rapidement que possible, en fournissant certains indices ou en évitant certaines opérations lorsqu’il estime qu’elles pourraient être regroupées ultérieurement. En conséquence, les chiffres typiques montrent que 15 % du temps de traitement sont consacrés à HAProxy contre 85 % dans le noyau en mode TCP ou HTTP fermé, et environ 30 % pour HAProxy contre 70 % pour le noyau en mode HTTP keep-alive.

Un seul processus peut exécuter de nombreux instances de proxy ; des configurations comprenant jusqu’à 300 000 proxies distincts dans un seul processus ont été signalées comme fonctionnant correctement. Une configuration à un seul cœur, un seul processeur est largement suffisante pour plus de 99 % des utilisateurs, et les utilisateurs de conteneurs et de machines virtuelles sont donc encouragés à utiliser les images les plus petites possibles afin de réduire les coûts opérationnels et de simplifier le dépannage. Toutefois, la machine sur laquelle HAProxy s’exécute ne doit jamais échanger, et son CPU ne doit jamais être artificiellement limité (allocation sous-entière de CPU dans les hyperviseurs) ni partagé avec des processus intensifs en calcul, ce qui entraînerait une latence de basculement de contexte très élevée.

Le thread permet d’utiliser toute la capacité de traitement disponible en utilisant un thread par cœur processeur. Cela est principalement utile pour le chiffrement SSL ou lorsque des débits de transfert de données supérieurs à 40 Gbps sont requis. Dans ces cas, il est essentiel d’éviter les communications entre plusieurs processeurs physiques, qui peuvent entraîner des goulets d’étranglement importants dans la pile réseau et dans HAProxy lui-même. Bien que cela puisse sembler contre-intuitif pour certains, la première action à entreprendre lorsqu’on rencontre des problèmes de performance est souvent de réduire le nombre de cœurs sur lesquels HAProxy s’exécute.

HAProxy nécessite uniquement l’exécutable haproxy et un fichier de configuration pour s’exécuter. Pour la journalisation, il est fortement recommandé de disposer d’un démon syslog correctement configuré ainsi que de rotations de journaux en place. Les journaux peuvent également être envoyés vers stdout/stderr, ce qui peut être utile dans les conteneurs. Les fichiers de configuration sont analysés avant le démarrage, puis HAProxy tente de lier tous les sockets d’écoute, et refuse de démarrer en cas d’échec. À partir de ce point, il ne peut plus échouer. Cela signifie qu’il n’y a pas d’échec en temps d’exécution, et que s’il accepte de démarrer, il fonctionnera jusqu’à son arrêt.

Une fois HAProxy lancé, il effectue exactement 3 opérations :

  • traite les connexions entrantes ;

  • vérifier périodiquement l’état des serveurs (appelé contrôle d’état);

  • échanger des informations avec d’autres nœuds HAProxy.

Le traitement des connexions entrantes est sans doute la tâche la plus complexe, car elle dépend de nombreuses possibilités de configuration, mais elle peut être résumée en 9 étapes ci-dessous :

  • accepter les connexions entrantes provenant des sockets d’écoute appartenant à une entité de configuration connue sous le nom de « frontal », qui référence une ou plusieurs adresses d’écoute ;

  • appliquer les règles spécifiques au frontal à ces connexions, ce qui peut entraîner leur blocage, la modification de certains en-têtes ou leur interception afin d’exécuter certains applets internes, tels que la page de statistiques ou l’interface CLI ;

  • transmettre ces connexions entrantes à une autre entité de configuration représentant une ferme de serveurs appelée « backend », qui contient la liste des serveurs et la stratégie de répartition de charge pour cette ferme ;

  • appliquer les règles spécifiques au backend à ces connexions ;

  • détermine quel serveur doit recevoir la connexion selon la stratégie de répartition de charge ;

  • appliquer les règles spécifiques au backend au traitement des données de la réponse ;

  • appliquer les règles spécifiques au frontal au traitement des données de réponse ;

  • émet un journal pour rapporter ce qui s’est passé en détail ;

  • en HTTP, bouclez vers la deuxième étape pour attendre une nouvelle requête, sinon fermez la connexion.

Les frontaux et les backends sont parfois considérés comme des demi-proxies, car ils ne traitent qu’un seul côté d’une connexion bout-en-bout ; le frontal ne s’intéresse qu’aux clients, tandis que le backend ne s’intéresse qu’aux serveurs. HAProxy prend également en charge les proxies complets, qui sont exactement la union d’un frontal et d’un backend. Lorsqu’une traitement HTTP est requis, la configuration est généralement divisée en frontaux et backends, car cela ouvre de nombreuses possibilités, puisqu’un frontal quelconque peut transférer une connexion à un backend quelconque. Avec des proxies ne gérant que le protocole TCP, l’utilisation de frontaux et de backends apporte rarement d’avantage, et la configuration peut être plus lisible avec des proxies complets.

3 - Fonctionnalités de base

Proxys, TLS, surveillance, haute disponibilité, équilibrage, persistance, journaux et statistiques

Cette section énumère un certain nombre de fonctionnalités implémentées par HAProxy, certaines étant généralement attendues d’un répartiteur de charge moderne, et d’autres constituant un avantage direct de l’architecture d’HAProxy. Les fonctionnalités avancées seront détaillées dans la section suivante.

3.3.1. Fonctionnalités de base : Proxys

Le proxy consiste à transférer des données entre un client et un serveur via deux connexions indépendantes. Les fonctionnalités de base suivantes sont prises en charge par HAProxy en matière de proxy et de gestion des connexions :

  • Fournir au serveur une connexion propre afin de les protéger contre toute défaillance ou attaque côté client ;

  • Écouter plusieurs adresses IP et/ou ports, y compris des plages de ports ;

  • Acceptation transparente : intercepter le trafic ciblant une adresse IP arbitraire, même n’appartenant pas au système local ;

  • Le port serveur n’a pas besoin d’être lié au port d’écoute, et peut même être décalé par un offset fixe (utile avec les plages) ;

  • Connexion transparente : masquer l’adresse IP du client (ou toute autre adresse) si nécessaire lors de la connexion au serveur ;

  • Fournir une adresse IP de retour fiable aux serveurs dans les équilibreurs de charge multi-sites ;

  • Réduire la charge du serveur grâce à l’utilisation de tampons et éventuellement de connexions à durée de vie courte, afin de diminuer le nombre de connexions simultanées et la consommation mémoire ;

  • Optimiser les piles TCP (par exemple SACK), le contrôle de congestion et réduire les impacts du RTT ;

  • Prendre en charge différentes familles de protocoles de part et d’autre (par exemple IPv4, IPv6 ou Unix) ;

  • Application du délai d’expiration : HAProxy prend en charge plusieurs niveaux de délais d’expiration selon l’étape de la connexion, afin qu’un client ou serveur défaillant, ou un attaquant, ne puisse pas monopoliser les ressources trop longtemps ;

  • Validation du protocole : le HTTP, le SSL ou le chargement utile est inspecté et les éléments de protocole non valides sont rejetés, sauf instruction contraire pour les accepter malgré tout ;

  • Application de la politique : garantir que seules les requêtes autorisées sont acheminées ;

  • Les connexions entrantes et sortantes peuvent être limitées à certains espaces de noms réseau (Linux uniquement), ce qui facilite la mise en œuvre d’un répartiteur de charge multi-locataires et cross-conteneur ;

  • Le protocole PROXY expose l’adresse IP du client au serveur, même pour le trafic non HTTP. Il s’agit d’une extension HAProxy adoptée par plusieurs produits tiers, au moins ceux-ci au moment de la rédaction :

    • client : HAProxy, stud, stunnel, exaproxy, ELB, squid
    • server : HAProxy, stud, postfix, exim, NGINX, squid, node.js, varnish

3.3.2. Fonctionnalités de base : SSL

La pile SSL d’HAProxy est reconnue comme l’une des plus riches en fonctionnalités selon les ingénieurs de Google (http://istlsfastyet.com/ ). Les fonctionnalités les plus couramment utilisées, qui en font une solution très complète, sont :

  • Hébergement multi-hôtes basé sur SNI, sans limite sur le nombre de sites, avec un accent sur les performances. Au moins une déployment est connue pour gérer 50 000 domaines avec leurs certificats respectifs ;

  • la prise en charge des certificats wildcard réduit la nécessité de nombreux certificats ;

  • authentification client basée sur un certificat, avec des politiques configurables en cas de non-présentation d’un certificat valide. Cela permet de présenter une ferme serveur différente afin de régénérer le certificat client, par exemple ;

  • L’authentification du backend garantit que le serveur backend est bien le véritable serveur et non un intermédiaire malveillant ;

  • L’authentification avec le serveur backend permet au serveur backend de savoir qu’il s’agit réellement du nœud HAProxy attendu qui se connecte à celui-ci ;

  • Les extensions TLS NPN et ALPN permettent de transférer de manière fiable les connexions SPDY/HTTP2 et de les transmettre en clair aux serveurs backend ;

  • Le stapling OCSP réduit davantage le temps de chargement de la première page en livrant inline une réponse OCSP lorsque le client demande un statut de certificat ;

  • La taille dynamique des enregistrements offre à la fois des performances élevées et une latence faible, et réduit fortement le temps de chargement des pages en permettant au navigateur de commencer à télécharger de nouveaux objets pendant que les paquets sont encore en transit ;

  • accès permanent à toutes les informations pertinentes au niveau SSL/TLS pour la journalisation, le contrôle d’accès, le reporting, etc. Ces éléments peuvent être intégrés dans un en-tête HTTP ou même comme extension du protocole PROXY, afin que le serveur déchargé dispose de toutes les informations qu’il aurait eu s’il avait lui-même effectué la terminaison SSL.

  • Détecter, journaliser et bloquer certains attaques connues, même sur des bibliothèques SSL vulnérables, telles que l’attaque Heartbleed affectant certaines versions d’OpenSSL.

  • prise en charge de la reprise de session sans état (extension TLS Ticket RFC 5077). Les tickets TLS peuvent être mis à jour depuis la ligne de commande, ce qui permet d’implémenter une confidentialité parfaite en les renouvelant fréquemment.

3.3.3. Fonctionnalités de base : Surveillance

HAProxy accorde une grande importance à la disponibilité. En conséquence, il surveille l’état des serveurs et signale son propre état aux autres composants du réseau :

  • L’état des serveurs est surveillé en continu à l’aide de paramètres propres à chaque serveur. Cela garantit que le chemin vers le serveur est opérationnel pour le trafic régulier ;

  • Les contrôles d’état prennent en charge deux seuils d’hystérésis pour les transitions vers haut et bas, afin de protéger contre les fluctuations d’état ;

  • Les vérifications peuvent être envoyées à une adresse, un port ou un protocole différents : cela facilite le contrôle d’un service unique considéré comme représentatif de plusieurs autres, par exemple le port HTTPS pour un serveur HTTP+HTTPS.

  • Les serveurs peuvent suivre d’autres serveurs et tomber en même temps : cela garantit que les serveurs hébergeant plusieurs services échouent de manière atomique, et qu’aucun client ne sera dirigé vers un serveur partiellement défaillant ;

  • Les agents peuvent être déployés sur le serveur pour surveiller la charge et l’état : un serveur peut être intéressé par le rapport de sa charge, de son état opérationnel et de son état administratif, indépendamment de ce que les contrôles d’état peuvent détecter. En exécutant un agent simple sur le serveur, il est possible de prendre en compte la vision du serveur concernant son propre état, en complément des contrôles d’état qui valident l’intégralité du chemin ;

  • Plusieurs méthodes de vérification sont disponibles : connexion TCP, requête HTTP, message SMTP, message SSL, LDAP, SQL, Redis, scripts envoi/réception, avec ou sans SSL ;

  • Le changement d’état est notifié dans les journaux et la page de statistiques avec la raison de la défaillance (par exemple, la réponse HTTP reçue au moment où la défaillance a été détectée). Un courrier électronique peut également être envoyé à une adresse configurable en cas de tel changement ;

  • L’état du serveur est également rapporté sur l’interface de statistiques et peut être utilisé pour prendre des décisions de routage, afin d’envoyer le trafic vers des fermes différentes selon leurs tailles et/ou leur état de santé (par exemple, perte d’une liaison inter-DC) ;

  • HAProxy peut utiliser les requêtes de contrôle d’état pour transmettre des informations aux serveurs, telles que leurs noms, leur poids, le nombre d’autres serveurs dans la ferme, etc., afin que les serveurs puissent ajuster leur réponse et leurs décisions en fonction de ces données (par exemple, différer les sauvegardes pour préserver plus de ressources CPU) ;

  • Les serveurs peuvent utiliser des contrôles d’état pour signaler un état plus détaillé que simple actif/inactif (par exemple : je souhaite m’arrêter, veuillez cesser d’envoyer de nouveaux visiteurs) ;

  • HAProxy peut rapporter son état à des composants externes, tels que des routeurs ou d’autres équilibreurs de charge, permettant ainsi de mettre en œuvre des infrastructures multi-chemins et multi-niveaux très complètes.

3.3.4. Fonctionnalités de base : Haute disponibilité

Tout comme tout répartiteur de charge sérieux, HAProxy accorde une grande importance à la disponibilité afin d’assurer la meilleure continuité de service globale :

  • Seules les serveurs valides sont utilisés ; les autres sont automatiquement exclus des fermes de répartition de charge ; dans certaines conditions, il est toutefois possible de forcer leur utilisation ;

  • Prise en charge d’un arrêt progressif afin de pouvoir retirer des serveurs d’une ferme sans affecter les connexions en cours ;

  • Les serveurs de sauvegarde sont automatiquement utilisés lorsque les serveurs actifs sont hors ligne et les remplacent afin de préserver les sessions lorsque cela est possible. Cela permet également de créer plusieurs chemins pour atteindre le même serveur (par exemple, plusieurs interfaces) ;

  • Capacité à renvoyer un statut global d’échec pour une ferme lorsque trop de serveurs sont hors ligne. Cela, combiné aux capacités de surveillance, permet à un composant amont de choisir un autre nœud de répartition de charge pour un service donné ;

  • Un design sans état permet de faciliter la mise en cluster : par conception, HAProxy fait tout son possible pour garantir la continuité du service sans avoir à stocker d’informations pouvant être perdues en cas de panne. Cela assure une reprise opérationnelle aussi fluide que possible ;

  • Intègre parfaitement le démon standard de basculement VRRP keepalived : HAProxy informe facilement keepalived de son état et gère très bien les adresses IP virtuelles flottantes. Remarque : n’utilisez les protocoles de redondance IP (VRRP/CARP) que sur des solutions basées sur un cluster (Heartbeat, …) car ce sont les seuls à offrir un basculement rapide, transparent et fiable.

3.3.5. Fonctionnalités de base : répartition de charge

HAProxy propose un ensemble assez complet de fonctionnalités de répartition de charge, dont la plupart ne sont malheureusement pas disponibles dans un certain nombre d’autres produits de répartition de charge :

  • au moins 10 algorithmes de répartition de charge sont pris en charge, dont certains s’appliquent aux données d’entrée pour offrir une liste infinie de possibilités. Les plus courants sont : round-robin (pour les connexions courtes, sélectionne chaque serveur tour à tour), leastconn (pour les connexions longues, sélectionne le serveur ayant le moins de connexions actives et le moins récemment utilisé), source (pour les fermes SSL ou les fermes de serveurs terminaux, le serveur dépend directement de l’adresse source du client), URI (pour les caches HTTP, le serveur dépend directement de l’URI HTTP), hdr (le serveur dépend directement du contenu d’un champ d’en-tête HTTP spécifique), first (pour les machines virtuelles à durée de vie courte, toutes les connexions sont regroupées sur le sous-ensemble le plus petit possible de serveurs afin que les serveurs inutilisés puissent être mis hors tension).

  • tous les algorithmes ci-dessus prennent en charge les pondérations par serveur, ce qui permet d’intégrer des générations de serveurs différentes dans une ferme, ou de diriger une petite fraction du trafic vers des serveurs spécifiques (mode de débogage, exécution de la prochaine version du logiciel, etc.) ;

  • les poids dynamiques sont pris en charge pour les algorithmes round-robin, leastconn et hachage cohérent ; cela permet de modifier les poids des serveurs en temps réel depuis la ligne de commande ou même par un agent en cours d’exécution sur le serveur ;

  • le démarrage progressif est pris en charge chaque fois qu’une pondération dynamique est prise en charge ; cela permet à un serveur de prendre progressivement le trafic. Cette fonctionnalité est essentielle pour les serveurs d’applications fragiles qui doivent compiler des classes en cours d’exécution, ainsi que pour les caches froids qui doivent être remplis avant de fonctionner à plein régime ;

  • Le hachage peut s’appliquer à divers éléments tels qu’une adresse source cliente, des composants d’URL, un élément de chaîne de requête, des valeurs de champ d’en-tête, un paramètre POST ou un cookie RDP ;

  • le hachage cohérent protège les fermes de serveurs contre une redistribution massive lors de l’ajout ou de la suppression de serveurs dans une ferme. Cela est particulièrement important dans les grandes fermes de mise en mémoire tampon et permet d’utiliser le démarrage progressif pour remplir les mémoires tampon froides ;

  • un certain nombre de métriques internes, telles que le nombre de connexions par serveur, par backend, ou le nombre de slots de connexion disponibles dans un backend, permet de mettre en œuvre des stratégies de répartition de charge très avancées.

3.3.6. Fonctionnalités de base : Persistance

La répartition de charge applicative serait inutile sans la persistance de session. HAProxy propose un ensemble assez complet de possibilités pour maintenir un visiteur sur le même serveur, même en cas d’événements variés tels que l’ajout ou la suppression de serveurs, les cycles de mise hors ligne/mise en ligne, et certaines méthodes sont conçues pour résister à la distance entre plusieurs nœuds de répartition de charge, car elles n’exigent aucune réplication :

  • les informations de persistance peuvent être individuellement correspondantes et apprises à partir de différentes sources, si nécessaire. Par exemple, un cookie JSESSIONID peut être correspondant à la fois dans un cookie et dans l’URL. Jusqu’à 8 sources parallèles peuvent être apprises simultanément, chacune pouvant pointer vers une table de persistance différente ;

  • Les informations de persistance peuvent provenir de tout élément visible dans une requête ou une réponse, y compris l’adresse source, le décalage et la longueur du chargement TCP, les éléments de chaîne de requête HTTP, les valeurs de champs d’en-tête, les cookies, etc.

  • les tables de persistance sont répliquées entre tous les nœuds de manière multi-maître ;

  • éléments couramment utilisés, tels que l’ID SSL ou les cookies RDP (pour les fermes TSE), sont directement accessibles pour faciliter leur manipulation ;

  • toutes les règles de maintien peuvent être conditionnées dynamiquement par des listes de contrôle d’accès ;

  • il est possible de décider de ne pas rester attaché à certains serveurs, tels que des serveurs de sauvegarde, afin que, lorsque le serveur nominal revient en ligne, il reprend automatiquement la charge. Cela est souvent utilisé dans les environnements multi-chemins ;

  • en HTTP, il est souvent préférable de ne rien apprendre et de manipuler à la place un cookie dédié à la persistance. Pour cela, il est possible de détecter, modifier, insérer ou préfixer un tel cookie afin que le client mémorise quel serveur lui a été attribué ;

  • le serveur peut décider de modifier ou de supprimer le cookie de persistance à la déconnexion, afin que les visiteurs quittant la session soient automatiquement déliés du serveur ;

  • en utilisant des règles basées sur les ACL, il est également possible d’ignorer ou d’imposer sélectivement la persistance de session, indépendamment de l’état du serveur ; combiné à des contrôles d’état avancés, cela permet aux administrateurs de vérifier que le serveur qu’ils installent est opérationnel avant de le rendre accessible à l’ensemble du monde ;

  • un mécanisme innovant permettant de définir un délai maximal d’inactivité et une durée pour les cookies assure que la persistance peut être arrêtée de manière fluide sur les appareils qui ne sont jamais fermés (smartphones, téléviseurs, appareils domestiques) sans avoir à les stocker sur un support persistant ;

  • plusieurs entrées de serveur peuvent partager les mêmes clés de persistance afin de ne pas perdre la persistance dans les environnements à chemins multiples lorsque l’un des chemins tombe en panne ;

  • soft-stop garantit que seuls les utilisateurs possédant des informations de persistance continueront à accéder au serveur qui leur a été attribué, mais aucun nouvel utilisateur n’y sera dirigé.

3.3.7. Fonctionnalités de base : Journalisation

La journalisation est une fonctionnalité extrêmement importante pour un répartiteur de charge, tout d’abord parce qu’un répartiteur de charge est souvent injustement accusé de provoquer les problèmes qu’il révèle, et ensuite parce qu’il est placé à un point critique dans une infrastructure où toute activité normale ou anormale doit être analysée et corrélée avec les autres composants.

HAProxy fournit des journaux très détaillés, avec une précision au millième de seconde et l’heure exacte d’acceptation de la connexion, pouvant être recherchée dans les journaux des pare-feu (par exemple pour la corrélation NAT). Par défaut, les journaux TCP et HTTP sont assez détaillés et contiennent tout ce qui est nécessaire au dépannage, tel que l’adresse IP source et le port, le frontal, le backend, le serveur, les temporisateurs (durée de réception de la requête, durée d’attente en file, temps de mise en place de la connexion, temps d’envoi des en-têtes de réponse, temps de transfert de données), l’état global du processus, le nombre de connexions, l’état de la file d’attente, le nombre de tentatives, les actions de persistance détaillées et les raisons de déconnexion, ainsi que les captures d’en-têtes avec une encodage de sortie sécurisé. Il est alors possible d’étendre ou de remplacer ce format afin d’inclure toute donnée échantillonnée, variable ou capture, aboutissant à des informations très détaillées. Par exemple, il est possible de journaliser le nombre de requêtes cumulées ou le nombre d’URL différentes visitées par un client.

Le niveau de journalisation peut être ajusté par requête à l’aide des ACL standards, ce qui permet d’automatiquement masquer certaines traces considérées comme de la pollution, tout en générant des avertissements lorsque se produit un comportement anormal pour une petite partie du trafic (par exemple, un trop grand nombre d’URLs ou d’erreurs HTTP provenant d’une même adresse source). Les journaux administratifs sont également émis avec leurs propres niveaux afin d’informer sur la perte ou la récupération d’un serveur, par exemple.

Chaque frontal et chaque backend peut utiliser plusieurs sorties de journalisation indépendantes, ce qui facilite la multi-locataire. Les journaux sont préférablement envoyés en UDP, éventuellement encodés au format JSON, et tronqués après une longueur de ligne configurable afin de garantir leur livraison. Il est également possible de les envoyer vers stdout/stderr ou tout descripteur de fichier, ainsi que vers un tampon circulaire auquel un client peut se abonner pour les récupérer.

3.3.8. Fonctionnalités de base : Statistiques

HAProxy fournit une interface web de rapport statistique avec authentification, niveaux de sécurité et portées. Il est ainsi possible de fournir à chaque client hébergé une page personnalisée affichant uniquement ses propres instances. Cette page peut être située dans une partie cachée de l’URL du site web régulier, sans nécessiter l’ouverture d’un nouveau port. Elle peut également indiquer la disponibilité d’autres nœuds HAProxy, afin de repérer facilement, d’un coup d’œil, si tout fonctionne comme prévu. La vue est synthétique, avec un accès à de nombreuses informations détaillées (comme les causes d’erreur, la dernière connexion ou la durée de la dernière modification, etc.), qui sont également disponibles sous forme de tableau CSV pouvant être importé par d’autres outils pour tracer des graphiques. La page peut se rafraîchir automatiquement, afin d’être utilisée comme page de surveillance sur un grand écran. En mode administration, la page permet également de modifier l’état des serveurs pour faciliter les opérations de maintenance.

Un exportateur Prometheus est également fourni afin que les statistiques puissent être consommées dans un format différent selon le déploiement.

4 - Fonctionnalités standard

Extraction d’échantillons, mappages, listes ACL, commutation de contenu, table de persistance, réécriture et protection des serveurs

Dans cette section, sont énumérées certaines fonctionnalités très couramment utilisées avec HAProxy mais qui ne sont pas nécessairement disponibles sur d’autres répartiteurs de charge.

3.4.1. Fonctionnalités standard : Échantillonnage et conversion d’informations

HAProxy prend en charge l’extraction d’échantillons à l’aide d’une large gamme de « fonctions d’extraction d’échantillon ». Le principe consiste à extraire des éléments d’information appelés échantillons, destinés à une utilisation immédiate. Cela est utilisé pour la persistance de session, la création de conditions, la génération d’informations dans les journaux ou l’enrichissement des en-têtes HTTP.

Les échantillons peuvent être récupérés à partir de diverses sources :

  • constants : entiers, chaînes, adresses IP, blocs binaires ;

  • le processus : date, variables d’environnement, état du serveur/ frontal/ backend/ processus, comptes/débits en octets/connexions, longueur de file d’attente, générateur aléatoire, …

  • variables : variables par session, par requête, par réponse ;

  • la connexion cliente : adresses source et destination, ports, ainsi que toutes les statistiques associées compteurs ;

  • la session client SSL : protocole, version, algorithme, chiffre, taille de clé, identifiant de session, tous les champs du certificat client et serveur, numéro de série du certificat, SNI, ALPN, NPN, prise en charge par le client de certaines extensions ;

  • contenu des tampons de requête et de réponse : charge utile arbitraire à l’offset/longueur, longueur des données, RDP cookie, décodage du type SSL hello, décodage du SNI TLS;

  • HTTP (requête et réponse) : méthode, URI, chemin, arguments de chaîne de requête, code d’état, en-têtes, valeurs d’en-tête positionnelles, cookies, captures, authentification, éléments du corps ;

Un échantillon peut ensuite passer par un certain nombre d’opérateurs appelés « convertisseurs » afin d’effectuer une transformation. Un convertisseur consomme un échantillon et en produit un nouveau, éventuellement de type complètement différent. Par exemple, un convertisseur peut être utilisé pour ne retourner que la longueur entière de la chaîne d’entrée, ou pour convertir une chaîne en majuscules. Un nombre arbitraire de convertisseurs peut être appliqué en série à un échantillon avant son utilisation finale. Parmi tous les convertisseurs d’échantillons disponibles, les suivants sont les plus couramment utilisés :

  • opérateurs arithmétiques et logiques : ils permettent d’effectuer des calculs avancés sur les données d’entrée, tels que le calcul de rapports, de pourcentages ou simplement la conversion d’une unité à une autre ;

  • Les masques d’adresse IP sont utiles lorsque certaines adresses doivent être regroupées par réseaux plus grands ;

  • représentation des données : décodage URL, base64, hexadécimal, chaînes JSON, hachage ;

  • conversion de chaîne : extraire des sous-chaînes à des positions fixes, de longueur fixe, extraire des champs spécifiques autour de délimiteurs donnés, extraire des mots précis, modifier la casse, appliquer une substitution basée sur une expression régulière ;

  • conversion de date : convertir au format de date HTTP, convertir entre heure locale et UTC, et ajouter ou supprimer un décalage ;

  • rechercher une entrée dans une table de persistance afin de consulter des statistiques ou un serveur affecté ;

  • conversion clé-valeur basée sur une carte à partir d’un fichier (utilisée principalement pour la géolocalisation).

3.4.2. Fonctionnalités standard : Maps

Les cartes sont un type puissant de convertisseur consistant à charger un fichier à deux colonnes en mémoire au démarrage, puis à rechercher chaque échantillon d’entrée dans la première colonne et à renvoyer le motif correspondant de la deuxième colonne s’il est trouvé, ou une valeur par défaut sinon. Comme la sortie est également un échantillon, elle peut à son tour subir d’autres transformations, y compris d’autres recherches dans des cartes. Les cartes sont principalement utilisées pour traduire l’adresse IP du client en numéro de AS ou code pays, car elles prennent en charge la correspondance la plus longue pour les adresses réseau, mais elles peuvent être utilisées à divers autres fins.

Une partie de leur efficacité provient de leur capacité à être mises à jour en temps réel, soit depuis la ligne de commande, soit à l’aide de certaines actions via d’autres exemples, ce qui leur permet de stocker et de récupérer des informations entre des accès successifs. Une autre force réside dans l’indexation basée sur un arbre binaire, qui les rend extrêmement rapides, même lorsqu’elles contiennent des centaines de milliers d’entrées, rendant la géolocalisation très peu coûteuse et facile à mettre en œuvre.

3.4.3. Fonctionnalités standard : ACL et conditions

La plupart des opérations dans HAProxy peuvent être rendues conditionnelles. Les conditions sont construites en combinant plusieurs ACL à l’aide d’opérateurs logiques (ET, OU, NON). Chaque ACL est une série de tests fondés sur les éléments suivants :

  • une méthode d’extraction d’échantillon pour récupérer l’élément à tester ;

  • une série facultative de convertisseurs permettant de transformer l’élément ;

  • une liste de modèles à comparer ;

  • une méthode correspondante pour indiquer comment comparer les modèles avec l’échantillon

Par exemple, l’échantillon peut être extrait de l’en-tête HTTP « Host », puis converti en minuscules, avant d’être comparé à plusieurs modèles regex à l’aide de la méthode de correspondance regex.

Techniquement, les ACL sont basées sur le même noyau que les cartes ; elles partagent exactement la même structure interne, les mêmes méthodes de correspondance de motifs et les mêmes performances. La seule différence réelle réside dans le fait qu’au lieu de renvoyer un échantillon, elles ne renvoient que « trouvé » ou « non trouvé ». En matière d’utilisation, les motifs ACL peuvent être déclarés en ligne dans le fichier de configuration et n’ont pas besoin de fichier dédié. Les ACL peuvent être nommées afin de faciliter leur utilisation ou d’améliorer la lisibilité des configurations. Une ACL nommée peut être déclarée plusieurs fois, et elle évaluera toutes les définitions successivement jusqu’à ce qu’une correspondance soit trouvée.

Environ 13 méthodes différentes de correspondance de modèles sont proposées, dont le masque d’adresse IP, les plages d’entiers, les sous-chaînes et les expressions régulières. Elles fonctionnent comme des fonctions, et tout comme dans n’importe quel langage de programmation, seules les parties nécessaires sont évaluées. Ainsi, lorsqu’une condition impliquant un OU est déjà vraie, les suivantes ne sont pas évaluées, et de même, lorsque une condition impliquant un ET est déjà fausse, le reste de la condition n’est pas évalué.

Il n’existe aucune limite pratique au nombre d’ACL déclarées, et un certain nombre d’ACL couramment utilisées sont fournies. Toutefois, l’expérience a montré que les configurations utilisant de nombreuses ACL nommées sont souvent difficiles à dépanner, et qu’il peut parfois être plus simple d’utiliser des ACL anonymes en inline, car cela réduit le nombre de références en dehors de la portée analysée.

3.4.4. Fonctionnalités standard : Commutation de contenu

HAProxy implémente un mécanisme connu sous le nom de commutation basée sur le contenu. Le principe consiste à ce qu’une connexion ou une requête arrive sur un frontal, puis que les informations transportées par cette requête ou cette connexion soient traitées ; à ce stade, il est possible d’écrire des conditions basées sur des ACLs utilisant ces informations pour déterminer quel backend traitera la requête. Ainsi, le trafic est acheminé vers un backend ou un autre en fonction du contenu de la requête. L’exemple le plus courant consiste à utiliser l’en-tête Host et/ou des éléments du chemin (sous-répertoires ou extensions de nom de fichier) pour décider si une requête HTTP cible un objet statique ou l’application, puis à acheminer le trafic des objets statiques vers un backend composé de serveurs rapides et légers, et tout le reste du trafic vers un serveur d’application plus complexe, constituant ainsi une solution de hébergement virtuel à granularité fine. Cela est particulièrement pratique pour faire coexister plusieurs technologies dans le cadre d’une solution plus globale.

Un autre cas d’utilisation du commutateur de contenu consiste à utiliser des algorithmes de répartition de charge différents selon divers critères. Un cache peut utiliser un hachage d’URI tandis qu’une application peut utiliser une répartition en roue libre.

Enfin, il permet à plusieurs clients d’utiliser une petite part d’une ressource commune en imposant des limites de connexion par backend (donc par client).

Les règles de commutation de contenu se montrent très performantes, bien que leur efficacité puisse dépendre du nombre et de la complexité des ACL en usage. Il est toutefois possible d’écrire des règles de commutation de contenu dynamiques où une valeur d’échantillonnage se transforme directement en nom de backend, sans faire appel aux ACL. De telles configurations ont été rapportées comme fonctionnant correctement, même avec au moins 300 000 backends en production.

3.4.5. Fonctionnalités standard : tables de persistance

Les tables de persistance sont couramment utilisées pour stocker des informations de persistance, c’est-à-dire pour conserver une référence au serveur vers lequel un visiteur donné a été dirigé. La clé est alors l’identifiant associé au visiteur (son adresse source, l’ID SSL de la connexion, un cookie HTTP ou RDP, le numéro de client extrait de l’URL ou du contenu, …) et la valeur stockée est ensuite l’identifiant du serveur.

Les tables de persistance peuvent utiliser trois types d’échantillons différents pour leurs clés : des entiers, des chaînes de caractères et des adresses. Une seule table de persistance peut être référencée dans un proxy, et elle est désignée partout par le nom du proxy. Jusqu’à 8 clés peuvent être suivies en parallèle. L’identifiant du serveur est fixé pendant le traitement d’une requête ou d’une réponse, une fois que la clé et le serveur sont connus.

Le contenu de la table de persistance peut être répliqué en mode actif-actif avec d’autres nœuds HAProxy appelés « peers », ainsi qu’avec le nouveau processus lors d’une opération de rechargement, afin que tous les nœuds de répartition de charge partagent les mêmes informations et prennent les mêmes décisions de routage lorsque les requêtes clients sont réparties sur plusieurs nœuds.

Étant donné que les tables de stickiness sont indexées sur les éléments permettant d’identifier un client, elles sont souvent utilisées pour stocker des informations supplémentaires, telles que des statistiques par client. Ces statistiques supplémentaires consomment de l’espace supplémentaire et doivent être déclarées explicitement. Les types de statistiques pouvant être stockées incluent la bande passante entrante et sortante, le nombre de connexions simultanées, le débit et le nombre de connexions sur une période donnée, la quantité et la fréquence des erreurs, certains balises et compteurs spécifiques, etc. Afin de permettre le stockage de ces informations sans être contraint de rester lié à un serveur donné, une fonctionnalité spéciale « suivi » est mise en œuvre, permettant de suivre jusqu’à 3 clés simultanées provenant de tables différentes en même temps, indépendamment des règles de stickiness. Chaque statistique stockée peut être recherchée, affichée ou effacée depuis l’interface CLI et enrichit les capacités de dépannage en temps réel.

Bien que ce mécanisme puisse être utilisé pour surclasser un visiteur retour ou ajuster la qualité du service fourni en fonction du comportement (bon ou mauvais), il est principalement employé pour lutter contre l’abus de service et, plus généralement, les attaques DDoS, car il permet de mettre en œuvre des modèles complexes pour détecter certains comportements malveillants à une vitesse de traitement élevée.

3.4.6. Fonctionnalités standard : chaînes formatées

HAProxy doit manipuler de nombreuses chaînes de caractères, par exemple dans les journaux, les redirections, l’ajout d’en-têtes, etc. Afin de garantir la plus grande flexibilité, la notion de chaînes formatées a été introduite, initialement pour les journaux, ce qui explique pourquoi elle est toujours appelée « log-format ». Ces chaînes contiennent des caractères d’échappement permettant d’insérer diverses données dynamiques, y compris des variables et des expressions d’extraction d’échantillon, ainsi que de modifier le codage pendant la conversion du résultat en chaîne (par exemple, en ajoutant des guillemets). Cela permet de construire efficacement le contenu d’en-têtes, de générer des données de réponse ou même des modèles de réponse, ou encore de personnaliser les lignes de journal. En outre, pour simplifier la construction des chaînes les plus courantes, environ 50 balises spéciales sont fournies comme raccourcis pour des informations fréquemment utilisées dans les journaux.

3.4.7. Fonctionnalités standard : réécriture et redirection HTTP

Installer un répartiteur de charge devant une application conçue sans tenir compte de cette configuration peut s’avérer une tâche difficile sans les outils appropriés. L’une des opérations les plus fréquemment demandées dans ce cas consiste à ajuster les en-têtes des requêtes et des réponses afin que le répartiteur de charge semble être le serveur d’origine et corriger les informations codées en dur. Cela implique de modifier le chemin des requêtes (ce qui est fortement déconseillé), de modifier le champ d’en-tête Host, de modifier le champ d’en-tête de réponse Location pour les redirections, de modifier les attributs de chemin et de domaine pour les cookies, et ainsi de suite. Il arrive également qu’un certain nombre de serveurs soient excessivement verbeux et tendent à révéler trop d’informations dans les réponses, ce qui les rend plus vulnérables aux attaques ciblées. Bien que, théoriquement, ce ne soit pas le rôle d’un répartiteur de charge de nettoyer ces informations, en pratique, il se trouve au meilleur emplacement dans l’infrastructure pour garantir que tout soit correctement nettoyé.

De même, le répartiteur de charge peut parfois devoir intercepter certaines requêtes et répondre par une redirection vers une nouvelle URL cible. Bien que certaines personnes confondent souvent les redirections et la réécriture, il s’agit de deux concepts totalement différents : la réécriture fait voir des choses différentes au client et au serveur (et entraîne un désaccord sur l’emplacement de la page visitée), tandis que les redirections demandent au client de visiter la nouvelle URL afin qu’il voie le même emplacement que le serveur.

Pour ce faire, HAProxy prend en charge diverses possibilités de réécriture et de redirection, parmi lesquelles :

  • réécriture d’URL et d’en-têtes basée sur des expressions régulières dans les requêtes et les réponses. Les expressions régulières sont l’outil le plus couramment utilisé pour modifier les valeurs d’en-tête, car elles sont faciles à manipuler et bien comprises ;

  • Les en-têtes peuvent également être ajoutés, supprimés ou remplacés selon des chaînes formatées, afin de transmettre des informations (par exemple, l’algorithme et le chiffre TLS côté client) ;

  • Les redirections HTTP peuvent utiliser n’importe quel code 3xx vers une URI relative, absolue ou entièrement dynamique (chaîne formatée) ;

  • Les redirections HTTP prennent également en charge certaines options supplémentaires, telles que la définition ou la suppression d’un cookie spécifique, le rejet de la chaîne de requête, l’ajout d’une barre oblique si elle est manquante, etc. ;

  • un directive “return” puissante permet de personnaliser chaque partie d’une réponse, comme le statut, les en-têtes ou le corps, en utilisant des contenus dynamiques ou même des fichiers modèles.

  • toutes les opérations prennent en charge des conditions basées sur les listes de contrôle d’accès ;

3.4.8. Fonctionnalités standard : protection des serveurs

HAProxy met tout en œuvre pour maximiser la disponibilité du service, et à cet effet, il déploie de grands efforts pour protéger les serveurs contre la surcharge et les attaques. Le premier et le plus important point est que seules les requêtes complètes et valides sont acheminées vers les serveurs. La raison première est que HAProxy doit identifier les éléments du protocole nécessaires pour rester synchronisé avec le flux d’octets, et la deuxième raison est qu’aussi longtemps que la requête n’est pas complète, il n’existe aucun moyen de savoir si certains éléments pourraient modifier son sémantique. Le bénéfice direct de cette approche est que les serveurs ne sont pas exposés à des requêtes invalides ou incomplètes. Cela constitue une protection très efficace contre les attaques slowloris, qui ont presque aucun impact sur HAProxy.

Un autre point important est que HAProxy dispose de tampons pour stocker les requêtes et les réponses, et qu’en n’envoyant une requête au serveur que lorsqu’elle est complète, et en lisant entièrement la réponse très rapidement depuis le réseau local, la connexion côté serveur est utilisée pendant une durée très brève, ce qui préserve au maximum les ressources du serveur.

Une extension directe de cette fonctionnalité est que HAProxy peut limiter artificiellement le nombre de connexions simultanées ou de requêtes en attente vers un serveur, garantissant ainsi que le serveur ne sera jamais surchargé, même en cas de pointe de trafic où il fonctionnerait continuellement à 100 % de sa capacité. Toutes les requêtes excédentaires seront simplement mises en file d’attente pour être traitées lorsque une place se libère. En fin de compte, cette économie importante de ressources garantit souvent des temps de réponse du serveur bien meilleurs, ce qui se traduit par une performance réelle supérieure à celle obtenue en surchargeant le serveur. Les requêtes en attente peuvent être réacheminées vers d’autres serveurs, ou même annulées en file d’attente si le client se déconnecte, ce qui protège également les serveurs contre l’effet « rechargement », où chaque clic sur « recharger » d’un visiteur sur une page à chargement lent déclenche généralement une nouvelle requête et maintient le serveur dans un état surchargé.

Le mécanisme de démarrage progressif protège également les serveurs redémarrés contre des niveaux élevés de trafic pendant qu’ils finalisent encore leur démarrage ou qu’ils compilent certaines classes.

En ce qui concerne la protection au niveau du protocole, il est possible de relâcher l’analyseur HTTP afin d’accepter des requêtes ou réponses non conformes mais inoffensives, voire de les corriger. Cela permet d’accéder à des applications défectueuses pendant qu’une correction est en cours de développement. Parallèlement, les messages problématiques sont entièrement capturés avec un rapport détaillé qui aide les développeurs à identifier la cause dans l’application. Les violations de protocole les plus dangereuses sont correctement détectées, traitées et corrigées. Par exemple, les requêtes ou réponses malformées comportant deux en-têtes Content-Length sont soit corrigées si leurs valeurs sont identiques, soit rejetées si elles diffèrent, car cela devient un problème de sécurité. L’inspection de protocole n’est pas limitée à HTTP, elle est également disponible pour d’autres protocoles tels que TLS ou RDP.

Lorsqu’une violation de protocole ou une attaque est détectée, diverses options sont disponibles pour répondre à l’utilisateur, telles que le renvoi de la réponse HTTP 400 standard « mauvaise requête », la fermeture de la connexion par un réinitialisation TCP, ou la simulation d’une erreur après un délai prolongé (« tarpit ») afin de troubler l’attaquant. Toutes ces mesures contribuent à protéger les serveurs en décourageant le client fautif de poursuivre une attaque devenue très coûteuse à maintenir.

HAProxy propose également des options plus avancées pour protéger contre les fuites de données accidentelles et les chevauchements de session. Non seulement il peut journaliser les réponses du serveur suspectes, mais il peut également journaliser et, optionnellement, bloquer une réponse pouvant compromettre la confidentialité d’un visiteur donné. Un exemple en est un cookie pouvant être mis en mémoire tampon apparaissant dans une réponse pouvant être mise en mémoire tampon, ce qui pourrait entraîner la livraison de ce cookie à un autre visiteur par un cache intermédiaire, provoquant ainsi un partage de session accidentel.

5 - Fonctionnalités avancées

Gestion en cours d’exécution, capacités du système d’exploitation, script Lua et traçage en temps réel

3.5.1. Fonctionnalités avancées : Gestion

HAProxy est conçu pour rester extrêmement stable et sécurisé à gérer dans un environnement de production classique. Il est fourni sous forme d’un seul fichier exécutable ne nécessitant aucun processus d’installation. Plusieurs versions peuvent coexister facilement, ce qui permet (et est recommandé) de mettre à jour les instances progressivement, par ordre de priorité, plutôt que de les migrer toutes en même temps. Les fichiers de configuration sont facilement versionnés. La vérification de configuration se fait hors ligne, sans nécessiter de redémarrer un service susceptible de échouer. Pendant la vérification de configuration, un certain nombre d’erreurs avancées peuvent être détectées (par exemple, une règle masquant une autre, ou une persistance qui ne fonctionnera pas), et des avertissements détaillés ainsi que des suggestions de configuration sont proposés pour les corriger. La compatibilité des fichiers de configuration avec les versions antérieures s’étend très loin dans le temps : la version 1.5 supporte encore entièrement les configurations écrites pour les versions 1.1, il y a 13 ans, et la version 1.6 n’a abandonné le support que pour des mots-clés presque inutilisés et obsolètes, pouvant être remplacés autrement. Le mécanisme de mise à jour de la configuration et du logiciel est fluide et non disruptif, car il permet à des processus anciens et nouveaux de coexister sur le système, chacun gérant ses propres connexions. L’état du système, les options de compilation et la compatibilité des bibliothèques sont rapportés au démarrage.

Certaines fonctionnalités avancées permettent à un administrateur d’application d’arrêter un serveur de manière fluide, de détecter lorsqu’il n’y a plus d’activité dessus, puis de le retirer du service, de l’arrêter, de le mettre à jour, et de s’assurer qu’il ne reçoit aucune requête pendant la mise à jour, puis de le tester à nouveau via le chemin normal sans le rendre accessible au public, et tout cela sans modifier HAProxy. Cela garantit que même des opérations de production complexes peuvent être effectuées pendant les heures d’ouverture, avec l’ensemble des ressources techniques disponibles.

Le processus tente de préserver au maximum les ressources, utilise des pools de mémoire pour réduire le temps d’allocation et limiter la fragmentation mémoire, libère les tampons de charge utile dès que leurs contenus ont été envoyés, et prend en charge l’application de limites mémoire strictes, au-delà desquelles les connexions doivent attendre qu’un tampon devienne disponible au lieu d’allouer davantage de mémoire. Ce système permet de garantir l’utilisation mémoire dans certains environnements stricts.

Une interface en ligne de commande (CLI) est disponible sous forme de socket UNIX ou TCP, afin d’effectuer diverses opérations et de récupérer des informations utiles au dépannage. Toutes les actions effectuées sur cette socket ne nécessitent pas de modification de configuration, aussi est-elle principalement utilisée pour des changements temporaires. Grâce à cette interface, il est possible de modifier l’adresse, le poids et l’état d’un serveur, de consulter les statistiques et de réinitialiser les compteurs, de sauvegarder et vider les tables de persistance, éventuellement de manière sélective selon des critères clés, de sauvegarder et interrompre les connexions côté client ou côté serveur, de sauvegarder les erreurs capturées avec une analyse détaillée de la cause exacte et de l’emplacement de l’erreur, de sauvegarder, ajouter ou supprimer des entrées dans les listes ACL et les cartes, de mettre à jour les secrets TLS partagés, d’appliquer des limites de connexion et de débit en temps réel sur des frontaux arbitraires (utile dans les environnements d’hébergement partagé), et de désactiver un frontend spécifique afin de libérer un port d’écoute (utile lorsque les opérations diurnes sont interdites et qu’une correction s’impose tout de même). Il est permis de mettre à jour les certificats et leur configuration en temps réel, ainsi que d’activer et de consulter les traces de chaque étape du traitement du trafic.

Dans les environnements où SNMP est obligatoire, il existe au moins deux agents. L’un est fourni avec les sources HAProxy et repose sur le module Perl Net-SNMP. L’autre accompagne les paquets commerciaux et ne requiert pas Perl. Ils offrent une couverture globalement équivalente.

Il est souvent recommandé d’installer les quatre utilitaires suivants sur la machine où HAProxy est déployé :

  • socat (afin de se connecter à l’interface CLI, bien que certaines variantes de netcat puissent également le faire dans une certaine mesure) ;

  • halog depuis la dernière version d’HAProxy : il s’agit d’un outil d’analyse de journaux, qui analyse très rapidement les journaux TCP et HTTP natifs (de 1 à 2 Go par seconde) et extrait des informations et statistiques utiles, telles que le nombre de requêtes par URL, par adresse source, les URLs triées par temps de réponse ou taux d’erreur, les codes de terminaison, etc. Il a été conçu pour être déployé sur les serveurs de production afin d’aider au dépannage des problèmes en temps réel, il doit donc être présent et prêt à être utilisé ;

  • tcpdump : il est fortement recommandé d’utiliser tcpdump pour capturer les traces réseau nécessaires au dépannage d’un problème apparu dans les journaux. Il arrive un moment où l’analyse effectuée par l’application et celle effectuée par HAProxy divergent, et les traces réseau sont la seule manière de déterminer qui a raison et qui a tort. Il est également fréquent de détecter des bugs dans les piles réseau ou les hyperviseurs grâce à tcpdump.

  • strace : il est le complément de tcpdump. Il indique ce que HAProxy voit réellement et permet de distinguer les problèmes liés au système d’exploitation de ceux liés à HAProxy. strace est souvent demandé lorsqu’un bug dans HAProxy est suspecté ;

3.5.2. Fonctionnalités avancées : Capacités spécifiques au système

Selon le système d’exploitation sur lequel HAProxy est déployé, certaines fonctionnalités supplémentaires peuvent être disponibles ou nécessaires. Bien qu’il soit pris en charge sur plusieurs plates-formes, HAProxy est principalement développé sous Linux, ce qui explique pourquoi certaines fonctionnalités ne sont disponibles que sur cette plate-forme.

Les fonctionnalités de liaison transparente et de connexion, le support de la liaison des connexions à une interface réseau spécifique, ainsi que la possibilité de lier plusieurs processus au même adresse IP et ports ne sont disponibles que sur les systèmes Linux et BSD, bien que seul Linux effectue une répartition de charge côté noyau des requêtes entrantes entre les processus disponibles.

Sur Linux, plusieurs fonctionnalités et optimisations supplémentaires sont disponibles, notamment le support des espaces de noms réseau (également appelés « conteneurs »), permettant à HAProxy d’agir comme passerelle entre tous les conteneurs, la possibilité de définir la taille maximale de segment (MSS), les marques Netfilter et le champ IP TOS sur la connexion côté client, le support du TCP FastOpen côté écoute, les délais d’expiration utilisateur TCP pour permettre au noyau de tuer rapidement les connexions lorsque le client disparaît avant l’expiration configurée, le découpage TCP pour permettre au noyau de transférer les données entre les deux extrémités d’une connexion, évitant ainsi plusieurs copies en mémoire, la possibilité d’activer l’option bind « defer-accept » afin de ne recevoir une notification d’une connexion entrante qu’une fois que des données sont disponibles dans les tampons du noyau, ainsi que la possibilité d’envoyer la requête avec l’ACK confirmant la connexion (parfois appelé « piggy-back »), activée par l’option « tcp-smart-connect ». Sur Linux, HAProxy prend également grand soin à manipuler les accusés de réception différés TCP afin de réduire au maximum le nombre de paquets sur le réseau.

Certains systèmes disposent d’une horloge peu fiable, qui saute indéfiniment dans le passé et dans le futur. Cela se produisait autrefois sur certains systèmes NUMA où plusieurs processeurs ne voyaient pas exactement la même heure, et cela devient désormais plus fréquent dans les environnements virtualisés, où l’horloge virtuelle n’a aucune relation avec l’horloge réelle, entraînant des sauts temporels importants (des sauts de jusqu’à 30 secondes ont été observés). Cela pose de nombreux problèmes en ce qui concerne l’application des délais d’expiration en général. En raison de cette imperfection de ces systèmes, HAProxy maintient sa propre horloge monotone, basée sur l’horloge système mais où le dérive est mesuré et compensé. Cela garantit que, même avec une horloge système très défaillante, les temporisateurs restent raisonnablement précis et que les délais d’expiration continuent de fonctionner. Notez que ce problème affecte tous les logiciels s’exécutant sur de tels systèmes et n’est pas spécifique à HAProxy. Les effets courants sont des délais d’expiration erronés ou des blocages d’applications. Par conséquent, si ce comportement est détecté sur un système, il doit être corrigé, quelle que soit la protection offerte par HAProxy.

Sous Linux, un nouveau processus de démarrage peut communiquer avec l’ancien afin de réutiliser ses descripteurs de fichiers d’écoute, de sorte que les sockets d’écoute ne soient jamais interrompus pendant le remplacement du processus.

3.5.3. Fonctionnalités avancées : Scripting

HAProxy peut être compilé avec prise en charge du langage embarqué Lua, ce qui ouvre un large éventail de possibilités liées à la manipulation complexe des requêtes ou des réponses, aux décisions de routage, au traitement des statistiques, etc. En utilisant Lua, il est même possible d’établir des connexions parallèles avec d’autres serveurs afin d’échanger des informations. Ainsi, il devient possible (bien que complexe) de développer un système d’authentification, par exemple. Pour en savoir plus sur l’utilisation de Lua, reportez-vous à la documentation disponible dans le fichier “doc/lua-api/index.rst”.

3.5.4. Fonctionnalités avancées : Suivi

À tout moment, un administrateur peut se connecter via l’interface CLI et activer le traçage dans divers sous-systèmes internes. Des niveaux de détail variés sont fournis par défaut, de sorte qu’en pratique, on puisse récupérer entre une ligne par requête et 500 lignes par requête. Des filtres ainsi qu’un mécanisme automatique d’activation/désactivation/pause de la capture sont disponibles, permettant ainsi réellement d’attendre un événement spécifique et de l’observer en détail. Cela est extrêmement pratique pour diagnostiquer des violations de protocole provenant de serveurs ou de clients défaillants, ou des attaques par déni de service.

6 - Taille et performance

Principes de planification de capacité, ordres de grandeur des performances et règles pratiques de bon sens

Les valeurs typiques d’utilisation du processeur montrent que 15 % du temps de traitement sont consacrés à HAProxy contre 85 % au noyau en mode TCP ou HTTP fermé, et environ 30 % pour HAProxy contre 70 % pour le noyau en mode HTTP keep-alive. Cela signifie que le système d’exploitation et son réglage ont une influence forte sur les performances globales.

Les usages varient beaucoup d’un utilisateur à l’autre : certains se concentrent sur le débit, d’autres sur le taux de requêtes, d’autres sur la concurrence des connexions, d’autres encore sur les performances SSL. Cette section vise à fournir quelques éléments pour faciliter cette tâche.

Il est important de garder à l’esprit que chaque opération comporte un coût, de sorte que chaque opération individuelle ajoute son surcoût aux autres, ce qui peut être négligeable dans certains cas, mais peut aussi dominer dans d’autres.

Lors du traitement des requêtes émanant d’une connexion, on peut dire que :

  • le transfert des données coûte moins cher que l’analyse des en-têtes de requête ou de réponse ;

  • analyser les en-têtes de requête ou de réponse coûte moins cher que d’établir puis de fermer une connexion vers un serveur ;

  • établir ou fermer une connexion coûte moins qu’une opération de reprise TLS ;

  • une opération de reprise TLS coûte moins cher qu’une négociation TLS complète avec calcul de clé ;

  • une connexion inactif consomme moins de CPU qu’une connexion dont les tampons contiennent des données ;

  • un contexte TLS consomme encore plus de mémoire qu’une connexion avec des données ;

En pratique, il est donc moins coûteux de traiter les octets de charge utile que les octets d’en-tête, ce qui rend plus facile l’atteinte d’un débit réseau élevé avec des objets volumineux (peu de requêtes par unité de volume) qu’avec des objets de petite taille (nombreuses requêtes par unité de volume). C’est pourquoi le débit maximal est toujours mesuré avec des objets volumineux, tandis que le débit de requêtes ou le débit de connexions est mesuré avec des objets de petite taille.

Certaines opérations échelonnent bien sur plusieurs processus répartis sur plusieurs processeurs, tandis que d’autres ne s’échelonnent pas aussi efficacement. La bande passante réseau ne s’échelonne pas très loin, car le processeur n’est rarement pas le goulot d’étranglement pour de grands objets, le goulot étant principalement la bande passante réseau et les bus de données pour atteindre les interfaces réseau. Le débit de connexion ne s’échelonne pas bien sur plusieurs processeurs en raison de quelques verrous dans le système lors de la gestion du tableau des ports locaux. Le débit de requêtes sur des connexions persistantes s’échelonne très bien, car il implique peu de mémoire ni de bande passante réseau et ne nécessite pas d’accéder à des structures verrouillées. Le calcul de la clé TLS s’échelonne très bien, car il est entièrement limité par le processeur. La reprise TLS s’échelonne modérément bien, mais atteint ses limites vers 4 processus, où la surcharge liée à l’accès au tableau partagé compense les gains faibles attendus d’une puissance accrue.

Les performances qu’on peut attendre d’un système très bien optimisé se situent dans la plage suivante. Il est important de les considérer comme des ordres de grandeur, et de s’attendre à des variations importantes dans n’importe quelle direction, en fonction du processeur, des paramètres IRQ, du type de mémoire, du type d’interface réseau, de l’optimisation du système d’exploitation, etc.

Les chiffres suivants ont été obtenus sur un processeur Core i7 fonctionnant à 3,7 GHz, équipé de deux ports réseau 10 Gbps, sous un noyau Linux 3,10, HAProxy 1,6 et OpenSSL 1,0,2. HAProxy était exécuté en tant que processus unique sur un cœur CPU dédié, et deux cœurs supplémentaires étaient dédiés aux interruptions réseau :

  • 20 Gbps de bande passante réseau maximale en clair pour les objets de 256 ko ou plus, 10 Gbps pour les objets de 41 ko ou plus ;

  • 4,6 Gbps de trafic TLS utilisant le chiffrement AES256-GCM avec des objets volumineux ;

  • 83000 connexions TCP par seconde depuis le client vers le serveur ;

  • 82000 connexions HTTP par seconde du client vers le serveur ;

  • 97000 requêtes HTTP par seconde en mode server-close (keep-alive avec le client, fermeture avec le serveur);

  • 243000 requêtes HTTP par seconde en mode keep-alive end-to-end ;

  • 300000 connexions TCP filtrées par seconde (anti-DDoS)

  • 160000 requêtes HTTPS par seconde en mode keep-alive sur des connexions TLS persistantes ;

  • 13100 requêtes HTTPS par seconde en utilisant des connexions TLS réinitialisées ;

  • 1300 connexions HTTPS par seconde utilisant des connexions TLS renégociées avec RSA2048 ;

  • 20000 connexions simultanées saturées par Go de RAM, incluant la mémoire nécessaire aux tampons système ; il est possible d’obtenir de meilleurs résultats avec un réglage soigné, mais ce résultat est facile à atteindre.

  • environ 8000 connexions TLS simultanées (côté client uniquement) par Go de mémoire vive, incluant la mémoire nécessaire aux tampons système ;

  • environ 5000 connexions TLS de bout en bout simultanées, côté client et côté serveur, par Go de RAM, y compris la mémoire requise pour les tampons système ;

Une benchmark plus récente, mettant en œuvre HAProxy 2.4 activé en multithread sur un processeur ARM Graviton2 à 64 cœurs dans AWS, a atteint 2 millions de requêtes HTTPS par seconde avec un temps de réponse inférieur à un milliseconde, ainsi qu’un débit de 100 Gbps :

https://www.haproxy.com/blog/haproxy-forwards-over-2-million-http-requests-per-second-on-a-single-aws-arm-instance/

Ainsi, une bonne règle empirique à garder à l’esprit est que le débit des requêtes est divisé par 10 entre le maintien de la connexion TLS et la reprise TLS, ainsi qu’entre la reprise TLS et la renegotiation TLS, tandis qu’il n’est divisé que par 3 entre le maintien de la connexion HTTP et la fermeture HTTP. Une autre bonne règle empirique consiste à se souvenir qu’un cœur à fréquence élevée disposant d’instructions AES peut traiter environ 20 Gbps de AES-GCM par cœur.

Une autre règle pratique consiste à considérer qu’un même serveur peut permettre à HAProxy de saturer :

  • environ 5 à 10 serveurs statiques ou proxies de mise en cache ;

  • environ 100 proxies anti-virus ;

  • et environ 100 à 1000 serveurs d’applications, selon la technologie utilisée.

7 - Versions, Paquets et Mises à jour

Branches stables, sources de version, identification des versions, maintenance et mises à jour

HAProxy est un projet open source soumis à la licence GPLv2, ce qui signifie que toute personne est autorisée à le redistribuer à condition de fournir l’accès au code source sur demande, notamment si des modifications ont été apportées.

HAProxy évolue via une branche de développement principale appelée « master » ou « mainline », à partir de laquelle de nouvelles branches sont créées une fois que le code est jugé stable. De nombreux sites web exécutent des branches de développement en production de manière volontaire, soit pour participer au projet, soit parce qu’ils ont besoin d’une fonctionnalité de pointe, et leurs retours sont précieux pour corriger les bogues et évaluer la qualité et la stabilité globales de la version en développement.

Les nouvelles branches créées lorsque le code est suffisamment stable constituent une version stable et sont généralement maintenues pendant plusieurs années, de sorte qu’il n’y a pas d’urgence à migrer vers une branche plus récente, même si vous n’êtes pas sur la dernière. Une fois qu’une branche stable est publiée, elle ne reçoit que des correctifs de bogues, et très rarement des mises à jour mineures lorsque cela facilite la vie des utilisateurs. Tous les correctifs intégrés à une branche stable proviennent nécessairement de la branche master. Cela garantit qu’aucun correctif ne sera perdu après une mise à jour. Pour cette raison, si vous corrigez un bogue, veuillez appliquer votre correctif à la branche master, et non à la branche stable. Vous pourriez même découvrir qu’il était déjà corrigé. Ce processus garantit également que les régressions dans une branche stable sont extrêmement rares, si bien qu’il n’y a jamais d’excuse pour ne pas mettre à jour vers la dernière version de votre branche actuelle.

Les branches sont numérotées avec deux chiffres séparés par un point, par exemple “1.6”. Depuis la version 1.9, les branches dont le deuxième chiffre est impair sont principalement consacrées à des mises à jour techniques sensibles et s’adressent davantage aux utilisateurs avancés, car elles sont susceptibles de provoquer plus de bogues que les autres. Elles sont maintenues pendant environ un an seulement et ne doivent pas être déployées là où un retour arrière d’urgence n’est pas possible. Une version complète inclut une ou deux sous-versions indiquant le niveau de correction. Par exemple, la version 1.5.14 est la 14e version corrigée de la branche 1.5 après la publication de la version 1.5.0. Elle contient 126 corrections pour des bogues individuels, 24 mises à jour de la documentation et 75 autres correctifs importés, dont la plupart étaient nécessaires pour corriger les 126 bogues mentionnés ci-dessus. Une fonctionnalité existante ne peut jamais être modifiée ni supprimée dans une branche stable, afin de garantir que les mises à jour au sein de la même branche seront toujours sans risque.

HAProxy est disponible depuis plusieurs sources, selon des rythmes de publication différents :

  • Le site web officiel de la communauté : http://www.haproxy.org/ : ce site fournit les sources de la dernière version de développement, de toutes les versions stables, ainsi que des instantanés nocturnes pour chaque branche. Le cycle de publication n’est pas rapide, plusieurs mois séparent les versions stables ou les instantanés de développement. Des versions très anciennes sont toujours prises en charge. Tout est fourni uniquement sous forme de sources, il faut donc reconstruire et/ou repackager tout ce qui provient de ce site.

  • GitHub : https://github.com/haproxy/haproxy/ : ce miroir est réservé à la branche de développement uniquement, il permet l’intégration avec le suivi des problèmes, les outils d’intégration continue et de couverture du code. Il est exclusivement destiné aux contributeurs ;

  • Certains systèmes d’exploitation, tels que les distributions Linux et les ports BSD. Ces systèmes fournissent généralement des versions maintenues à long terme, qui ne contiennent pas toujours tous les correctifs des versions officielles, mais qui incluent au moins les correctifs critiques. Il s’agit souvent d’une bonne option pour la plupart des utilisateurs qui ne recherchent pas de configurations avancées et souhaitent simplement simplifier les mises à jour ;

  • Versions commerciales à partir de http://www.haproxy.com/ : il s’agit de paquets professionnels pris en charge, construits pour divers systèmes d’exploitation ou fournis sous forme d’appareils, basés sur les dernières versions stables et incluant un certain nombre de fonctionnalités portées en arrière depuis la prochaine version, pour lesquelles la demande est forte. C’est l’option idéale pour les utilisateurs souhaitant bénéficier des dernières fonctionnalités avec la fiabilité d’une branche stable, un temps de réponse le plus rapide possible pour corriger les bogues, ou simplement des contrats de support sur un produit open source ;

Afin de vous assurer que la version que vous utilisez est la plus récente dans votre branche, procédez comme suit :

  • vérifiez quel exécutable HAProxy vous exécutez : certains systèmes le livrent par défaut et les administrateurs installent leurs versions ailleurs sur le système, il est donc important de vérifier dans les scripts de démarrage quel exécutable est utilisé ;

  • détermine la source de votre version de HAProxy. Pour cela, il suffit généralement de taper « HAProxy -v ». Une version de développement apparaît alors sous cette forme, avec le mot « dev » après le numéro de branche :

HAProxy version 2.4-dev18-a5357c-137 2021/05/09 - https://haproxy.org/
Une version stable s'affiche comme suit, tout comme les versions stables non modifiées

versions fournies par les éditeurs de systèmes d’exploitation :

HAProxy version 1.5.14 2015/07/02
Et une capture nocturne d'une version stable apparaît comme suit, avec une séquence hexadécimale après la version, ainsi qu'une date de la capture.

à la place de la date de la version :

HAProxy version 1.5.14-e4766ba 2015/07/29
Tout autre format peut indiquer un paquet spécifique au système, doté de son propre jeu de correctifs. Par exemple, les versions HAProxy Enterprise apparaîtront avec le

au format (<branch>-<latest commit>-<revision>):

HAProxy version 1.5.0-994126-357 2015/07/02
Veuillez noter qu’historiquement, les versions antérieures à 2.4 affichaient le nom du processus avec un trait d’union entre « HA » et « Proxy », y compris celles qui ont été ajustées pour afficher le format correct uniquement, il est donc préférable de l’ignorer ou d’utiliser une correspondance souple dans les scripts. En outre, les versions modernes ajoutent une URL pointant vers la page d’accueil du projet.

Enfin, les versions 2.1 et ultérieures incluront une ligne « Statut » indiquant si la version est sûre pour la production ou non, et le cas échéant, jusqu’à quand, ainsi qu’un lien vers la liste des bogues connus affectant cette version.
  • pour les paquets spécifiques au système, vous devez consulter le dépôt de paquets de votre fournisseur ou mettre à jour votre système afin de vous assurer que celui-ci est toujours pris en charge et que des correctifs sont toujours fournis pour votre branche. Pour les versions communautaires provenant de HAProxy.org, rendez-vous simplement sur le site, vérifiez l’état de votre branche et comparez la dernière version avec la vôtre afin de savoir si vous êtes à jour. Si ce n’est pas le cas, vous pouvez procéder à une mise à niveau. Si votre branche n’est plus maintenue, vous êtes certainement très en retard et devrez envisager une mise à niveau vers une branche plus récente (lisez attentivement le README lors de cette opération).

HAProxy doit être mis à jour conformément à la source d’où il provient. En général, cela suit la méthode utilisée par le fournisseur du système pour mettre à jour un paquet. Si HAProxy a été obtenu à partir des sources, veuillez lire le fichier README du répertoire des sources après extraction des sources et suivez les instructions propres à votre système d’exploitation.

8 - Produits complémentaires et alternatives

Comment HAProxy s’inscrit parmi Apache, NGINX, Varnish, LVS, Envoy et d’autres répartiteurs de charge

HAProxy s’intègre assez bien avec certains produits listés ci-dessous, ce qui justifie leur mention ici, même s’ils ne sont pas directement liés à HAProxy.

4.1. Serveur HTTP Apache

Apache est le serveur HTTP de facto. Il s’agit d’un projet très complet et modulaire, capable de servir des fichiers ainsi que du contenu dynamique. Il peut agir de front-end pour certains serveurs d’applications. Il peut même acheminer des requêtes et mettre en mémoire tampon les réponses. Dans tous ces cas d’utilisation, un répartiteur de charge frontal est généralement nécessaire. Apache peut fonctionner dans divers modes, certains étant plus lourds que d’autres. Certains modules nécessitent encore le modèle pré-forké plus lourd, ce qui empêche Apache de bien évoluer avec un grand nombre de connexions. Dans ce cas, HAProxy peut apporter une aide considérable en imposant des limites de connexion par serveur à une valeur sûre, ce qui accélère significativement le serveur et préserve ses ressources, qui seront mieux utilisées par l’application.

Apache peut extraire l’adresse du client à partir de l’en-tête X-Forwarded-For en utilisant l’extension “mod_rpaf”. HAProxy alimente automatiquement cet en-tête lorsque l’option forwardfor est spécifiée dans sa configuration. HAProxy peut également offrir une protection efficace à Apache lorsqu’il est exposé à internet, lui permettant de mieux résister à un large éventail de types d’attaques de type DoS.

4.2. NGINX

NGINX est le second serveur HTTP de facto. Comme Apache, il couvre un large éventail de fonctionnalités. Conçu selon un modèle similaire à HAProxy, il gère sans difficulté des dizaines de milliers de connexions simultanées. Lorsqu’il sert de passerelle vers des applications, par exemple avec PHP FPM, limiter les connexions en frontal peut réduire la charge de l’application PHP. HAProxy est alors utile tant comme répartiteur de charge classique que comme régulateur de trafic pour désengorger PHP. Comme ces produits consomment très peu de CPU grâce à leur architecture événementielle, il est souvent facile d’installer HAProxy et NGINX sur le même système. NGINX implémente le protocole PROXY de HAProxy ; HAProxy peut donc lui transmettre les informations de connexion du client afin que l’application dispose de tout le contexte utile. Des benchmarks ont aussi montré que, pour servir de gros fichiers statiques, un hachage cohérent dans HAProxy devant NGINX peut améliorer le taux de succès du cache du système d’exploitation, qui est essentiellement multiplié par le nombre de nœuds serveurs.

4.3. Varnish

Varnish est un proxy inversé intelligent à mémoire cache, probablement le mieux décrit comme un accélérateur d’applications web. Varnish n’implémente pas SSL/TLS et souhaite consacrer l’intégralité de ses cycles processeur à ce qu’il fait le mieux. Varnish implémente également le protocole PROXY d’HAProxy, de sorte qu’HAProxy peut être déployé très facilement devant Varnish en tant qu’offloader SSL ainsi qu’en tant que répartiteur de charge, tout en transmettant à Varnish toutes les informations pertinentes relatives au client. Varnish prend naturellement en charge la décompression depuis le cache lorsque le serveur fournit un objet compressé, mais ne compresse pas lui-même. HAProxy peut alors être utilisé pour compresser les données sortantes lorsque les serveurs backend ne mettent pas en œuvre la compression, bien que ce ne soit généralement pas une bonne idée de compresser sur le répartiteur de charge, sauf si le trafic est faible.

Lors de la mise en place de fermes de mise en cache étendues sur plusieurs nœuds, HAProxy peut utiliser le hachage URL cohérent pour répartir intelligemment la charge sur les nœuds de mise en cache et éviter la duplication de cache, ce qui permet d’obtenir une taille totale de cache égale à la somme de celles de tous les nœuds de mise en cache. En outre, la mise en cache de petits objets simples pendant une courte durée sur HAProxy peut parfois permettre d’éviter des allers-retours réseau et de réduire la charge CPU sur les nœuds HAProxy et Varnish. Cela n’est possible que si aucune opération n’est effectuée sur ces objets sur Varnish (ce cas est souvent désigné sous le terme de « cache favicon », permettant parfois d’éviter une proportion importante de requêtes inutiles en aval). Toutefois, ne pas activer la mise en cache sur HAProxy pendant une durée prolongée (plusieurs secondes) devant toute autre cache, car cela compliquerait considérablement le dépannage sans apporter de gains réellement significatifs.

4.4. Alternatives

Le répartiteur de charge Linux Virtual Server (LVS ou IPVS) est un répartiteur de charge au niveau 4 intégré au noyau Linux. Il fonctionne au niveau des paquets et gère TCP et UDP. Dans la plupart des cas, il s’agit davantage d’un complément que d’une alternative, car il ne possède aucune connaissance au niveau 7.

Pound est un autre répartiteur de charge bien connu. Il est beaucoup plus simple et offre nettement moins de fonctionnalités que HAProxy, mais Pound comme HAProxy peuvent convenir à de nombreuses configurations élémentaires. Son auteur a toujours privilégié l’auditabilité du code et souhaite conserver un ensemble restreint de fonctionnalités. Son architecture à base de threads passe moins bien à l’échelle avec un grand nombre de connexions, mais le produit reste solide.

Pen est un répartiteur de charge relativement léger. Il prend en charge le SSL, maintient la persistance grâce à une table de taille fixe contenant les adresses IP de ses clients. Il prend en charge un mode orienté paquets, permettant de supporter le retour direct du serveur et le UDP dans une certaine mesure. Il est destiné à des charges faibles (la table de persistance ne comporte que 2048 entrées).

NGINX peut effectuer une répartition de charge à certains égards, bien qu’il ne s’agisse clairement pas de sa fonction principale. Le trafic de production sert à détecter les défaillances de serveur, les algorithmes de répartition de charge sont plus limités, et la persistance est très limitée. Toutefois, cela peut avoir un sens dans certains scénarios de déploiement simples où NGINX est déjà présent. Le point positif est qu’étant donné son intégration très fluide avec HAProxy, il n’y a rien de mal à ajouter HAProxy ultérieurement lorsque les limites de NGINX ont été atteintes.

Varnish effectue également une répartition de charge sur ses serveurs backend et prend en charge des contrôles d’état réels. Il ne met toutefois pas en œuvre de persistance de session, de sorte qu’à l’instar de NGINX, cela peut suffire pour démarrer, à condition que la persistance ne soit pas requise. De même, puisque HAProxy et Varnish s’intègrent si bien, il est aisé d’ajouter Varnish ultérieurement dans la chaîne afin de compléter l’ensemble des fonctionnalités.

9 - Documentation et communauté

Le jeu manuel de serveurs amont, les emplacements sources, les canaux de support, les contacts et la licence

1. Documentation disponible

La documentation complète de HAProxy est contenue dans les documents suivants. Veuillez vous assurer de consulter la documentation pertinente afin d’économiser du temps et d’obtenir la réponse la plus précise à vos besoins. Veuillez également vous abstenir d’envoyer des questions à la liste de diffusion dont les réponses sont déjà disponibles dans ces documents.

  • intro.txt (ce document) : il présente les bases de la répartition de charge, HAProxy en tant que produit, ses fonctionnalités, ses limites, certains pièges à éviter, certaines limitations propres aux systèmes d’exploitation, comment l’obtenir, son évolution, comment s’assurer d’exécuter une version avec tous les correctifs connus, comment le mettre à jour, ainsi que des compléments et des alternatives.

  • management.txt : il explique comment démarrer HAProxy, comment le gérer en temps réel, comment le gérer sur plusieurs nœuds, et comment procéder à des mises à jour sans interruption.

  • configuration.txt : le manuel de référence détaille tous les mots-clés de configuration et leurs options. Il est utilisé lorsqu’une modification de configuration est nécessaire.

  • coding-style.txt : destiné aux développeurs souhaitant proposer du code au projet. Il décrit le style à adopter pour le code. Il n’est pas très strict et l’ensemble du code ne le respecte pas entièrement, mais les contributions s’en écartant trop seront rejetées.

  • proxy-protocol.txt : il s’agit de la spécification de facto du protocole PROXY, implémentée par HAProxy et un certain nombre de produits tiers.

  • security.txt : comment signaler un problème de sécurité, et ce qui constitue ou ne constitue pas une vulnérabilité.

  • README : comment compiler HAProxy à partir des sources

5. Contacts

Si vous souhaitez contacter les développeurs ou un membre de la communauté à propos de quoi que ce soit, la meilleure façon de procéder est généralement d’envoyer votre message à la liste de diffusion à l’adresse haproxy@formilux.org . Veuillez noter que cette liste est publique ainsi que ses archives, vous devez donc éviter de divulguer des informations sensibles. Des milliers d’utilisateurs, de tous niveaux d’expérience, y sont présents, et les questions les plus complexes trouvent généralement une réponse optimale relativement rapidement. Les suggestions sont également les bienvenues. Pour les utilisateurs ayant des difficultés avec le courrier électronique, une plateforme Discourse est disponible à l’adresse http://discourse.haproxy.org/ . Toutefois, veuillez garder à l’esprit qu’un nombre réduit de personnes lisent les questions posées là-bas, et que la plupart sont traitées par une équipe extrêmement réduite. Dans tous les cas, veuillez être patient et respectueux envers ceux qui consacrent leur temps libre à aider les autres.

Si vous pensez avoir découvert un bogue mais n’en êtes pas certain, il est préférable de le signaler sur la liste de diffusion. Si vous êtes convaincu d’avoir trouvé un bogue, que votre version est à jour dans sa branche, et que vous disposez déjà d’un compte GitHub, vous pouvez directement vous rendre sur https://github.com/haproxy/haproxy/ et soumettre un problème en incluant toutes les informations disponibles. Encore une fois, cela est public, veillez donc à ne pas publier d’informations que vous pourriez regretter plus tard. Étant donné que le suivi des problèmes s’affiche sous la forme d’un fil très long, évitez de coller des extraits très longs (plusieurs centaines de lignes ou plus) et joignez-les à la place.

Si vous pensez avoir découvert un problème de sécurité, veuillez vous référer au fichier doc/security.txt. Il explique ce qui constitue ou ne constitue pas une vulnérabilité dans HAProxy, ainsi que la procédure à suivre pour signaler une vulnérabilité réelle de manière confidentielle. La plupart des problèmes suspectés s’avèrent être des bogues ordinaires, mieux signalés comme décrit ci-dessus.

Configuration locale complète manuelle

Édition provenance

10 - 1. Petit rappel sur HTTP

Transactions HTTP, requêtes, réponses, en-têtes et terminologie du protocole

Ce document traite du langage de configuration tel qu’il est implémenté dans la version indiquée ci-dessus. Il ne fournit aucune indication, exemple ou conseil. Pour ce type de documentation, veuillez vous référer au Manuel de référence ou au Manuel d’architecture. Les chapitres numérotés sont ordonnés dans la barre latérale plate de HAProxy pour une navigation directe.

Lorsque HAProxy fonctionne en mode HTTP, la requête et la réponse sont entièrement analysées et indexées, ce qui permet de définir des critères de correspondance sur presque tout élément présent dans leur contenu.

Toutefois, il est essentiel de comprendre comment les requêtes et réponses HTTP sont structurées, ainsi que la manière dont HAProxy les décompose. Il sera alors plus facile d’écrire des règles correctes et de déboguer les configurations existantes.

Tout d’abord, HTTP est standardisé par une série de RFC que HAProxy suit aussi strictement que possible :

  • RFC 9110 : Sémantique HTTP (explique le sens des éléments du protocole)
  • RFC 9111 : Mise en mémoire tampon HTTP (explique les règles à suivre pour un cache HTTP)
  • RFC 9112 : HTTP/1.1 (représentation, règles d’interopérabilité, sécurité)
  • RFC 9113 : HTTP/2 (représentation, règles d’interopérabilité, sécurité)
  • RFC 9114 : HTTP/3 (représentation, règles d’interopérabilité, sécurité)

En complément de ces éléments, les RFC 8999 à 9002 définissent la couche transport QUIC utilisée par le protocole HTTP/3.

1.1. Le modèle de transaction HTTP

Le protocole HTTP est fondé sur des transactions. Cela signifie qu’une requête entraîne une et une seule réponse. À l’origine, avec la version 1.0 du protocole, il y avait une seule requête par connexion : une connexion TCP est établie depuis le client vers le serveur, le client envoie une requête sur la connexion, le serveur répond, puis la connexion est fermée. Une nouvelle requête nécessite donc une nouvelle connexion :

[CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ...

En ce mode, souvent appelé le mode « fermeture HTTP », le nombre d’établissements de connexion correspond au nombre de transactions HTTP. Comme la connexion est fermée par le serveur après la réponse, le client n’a pas besoin de connaître la longueur du contenu ; il considère la réponse comme complète lorsque la connexion se termine. Cela signifie également qu’en cas de troncature de certaines réponses due à des erreurs réseau, le client pourrait à tort considérer qu’une réponse était complète, ce qui pouvait entraîner parfois l’affichage d’images tronquées à l’écran.

En raison de la nature transactionnelle du protocole, il a été possible d’optimiser celui-ci afin d’éviter la fermeture de la connexion entre deux transactions successives. Toutefois, en ce mode, il est obligatoire que le serveur indique la longueur du contenu pour chaque réponse, afin que le client ne reste pas en attente indéfiniment. Pour cela, une en-tête spéciale est utilisée : « Content-length ». Ce mode est appelé le mode « keep-alive », et est apparu avec HTTP/1.1 (certains agents HTTP/1.0 le supportent), et les connexions réutilisées entre requêtes sont appelées des « connexions persistantes » :

[CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...

Ses avantages sont une latence réduite entre les transactions, une charge de traitement moindre côté serveur, et la capacité à détecter une réponse tronquée. Il est généralement plus rapide que le mode close, mais pas toujours, car certains clients limitent souvent leur nombre de connexions simultanées à une valeur plus faible, ce qui compense moins une connectivité réseau médiocre. En outre, certains serveurs doivent maintenir la connexion ouverte longtemps en attendant une éventuelle nouvelle requête et peuvent subir une utilisation mémoire élevée en raison du grand nombre de connexions, et fermer trop rapidement peut interrompre certaines requêtes arrivées au moment où la connexion était fermée.

En ce mode, la taille de la réponse doit être connue à l’avance, ce qui n’est pas toujours possible avec des contenus générés dynamiquement ou compressés. Pour cette raison, un autre mode a été mis en œuvre, le « mode chunké », dans lequel, au lieu d’annoncer la taille totale d’un coup, l’expéditeur indique uniquement la taille du prochain « morceau » de réponse déjà présent dans un tampon, et peut terminer à tout moment avec un morceau de taille nulle. En ce mode, l’en-tête Content-Length n’est pas utilisé.

Une autre amélioration des communications est le mode de pipeline. Il utilise toujours keep-alive, mais le client n’attend pas la première réponse pour envoyer la deuxième requête. Cela est utile pour récupérer un grand nombre d’images composant une page :

[CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ...

Cela peut évidemment offrir un bénéfice considérable en performance, car la latence réseau est éliminée entre les requêtes successives. De nombreux agents HTTP ne prennent pas correctement en charge le pipelining, car il n’existe aucun moyen d’associer une réponse à la requête correspondante en HTTP. Pour cette raison, il est obligatoire que le serveur réponde dans le même ordre exact que celui des requêtes reçues. En pratique, après plusieurs tentatives de divers clients pour le mettre en œuvre, il a été complètement abandonné en raison de son manque de fiabilité sur certains serveurs. Toutefois, il est obligatoire que les serveurs le prennent en charge.

L’amélioration suivante est le mode multiplexé, tel qu’il est implémenté dans HTTP/2 et HTTP/3. Plusieurs transactions, c’est-à-dire des paires requête-réponse, sont transmises en parallèle sur une seule connexion et progressent chacune à leur propre rythme. Les protocoles multiplexés ont introduit la notion de « flux » pour représenter ces communications parallèles. Chaque flux reçoit généralement un identifiant unique pour la connexion, utilisé par chaque extrémité pour acheminer les données. Les clients ouvrent couramment de nombreux flux, jusqu’à 100 ou davantage, sur la même connexion et laissent le serveur répondre dans l’ordre de disponibilité. Le multiplexage réduit fortement les allers-retours et accélère le chargement des pages sur les réseaux à forte latence. Sur les sites riches en images, celles-ci semblent alors se charger en parallèle.

Ces protocoles ont également amélioré leur efficacité en adoptant des mécanismes de compression des en-têtes afin de réduire le nombre d’octets transmis sur le réseau. Par conséquent, sans outils appropriés, ils ne sont pas réellement manipulables à la main ni lisibles à l’œil nu, contrairement à HTTP/1. Pour cette raison, divers exemples de messages HTTP continuent d’être représentés dans la littérature (y compris dans ce document) à l’aide de la syntaxe HTTP/1, même pour les versions plus récentes du protocole.

HTTP/2 présente certaines limitations liées à sa conception, telles que les pertes de paquets qui affectent simultanément toutes les flux, et si un client met trop de temps à récupérer un objet (par exemple, s’il doit le stocker sur le disque), cela peut ralentir sa récupération et rendre impossible l’accès aux données en attente derrière celui-ci durant cette période. Ce phénomène est appelé « blocage en tête de file » ou « HoL blocking », ou parfois simplement « HoL ».

HTTP/3 est implémenté sur QUIC, lui-même implémenté sur UDP. QUIC résout le blocage en tête de file au niveau du transport grâce à des flux gérés indépendamment. En effet, en cas de perte de paquets, un flux impacté n’affecte pas les autres flux, qui peuvent tous être accessibles en parallèle. QUIC offre également un support du déplacement de connexion, mais HAProxy ne le prend pas en charge actuellement.

Par défaut, HAProxy utilise le mode keep-alive pour les connexions persistantes : il traite chaque requête et chaque réponse, puis laisse la connexion inactive de part et d’autre entre la fin d’une réponse et le début de la requête suivante. Lorsqu’un client établit une connexion HTTP/2, HAProxy traite les requêtes en parallèle puis laisse la connexion inactive en attendant de nouvelles requêtes, comme pour une connexion HTTP keep-alive.

HAProxy prend en charge essentiellement trois modes de connexion :

  • keep-alive : toutes les requêtes et réponses sont traitées, et les connexions côté client ainsi que celles côté serveur sont maintenues ouvertes pour de nouvelles requêtes. Ceci est le comportement par défaut et convient aux web modernes et aux protocoles modernes (HTTP/2 et HTTP/3).

  • server close : la connexion côté serveur est fermée après la réponse.

  • close : la connexion est activement fermée de part et d’autre après la fin de la réponse.

En complément, par défaut, la connexion orientée serveur est réutilisable par toute requête provenant de n’importe quel client, conformément à la spécification du protocole HTTP, de sorte que toute information relative à un client spécifique doit être transmise avec chaque requête, le cas échéant (par exemple, l’adresse source du client, etc.). Lorsqu’HTTP/2 est utilisé avec un serveur, HAProxy affecte par défaut cette connexion au même client afin d’éviter le risque de blocage en tête de file entre clients.

1.2. Terminologie

À l’intérieur d’HAProxy, la terminologie a évolué au fil du temps pour suivre les évolutions du protocole HTTP et de ses usages. À l’origine, aucune différence significative n’existait entre une connexion, une session, un flux ou une transaction, mais ces termes se sont précisés au fil du temps afin de correspondre étroitement à ce qui existe dans les versions modernes du protocole HTTP, bien que certains termes persistent dans la configuration ou l’interface en ligne de commande afin de préserver la compatibilité historique.

Voici quelques définitions applicables à la version actuelle de HAProxy :

  • connection : une connexion est un canal de communication unidirectionnel unique entre un agent distant (client ou serveur) et HAProxy, au niveau le plus bas possible. En général, elle correspond à une socket TCP établie entre une paire d’adresses IP et de ports. Du côté client, les connexions sont les premières entités instanciées lorsqu’un client se connecte à HAProxy, et les règles s’appliquant au niveau de la connexion sont les premières à s’appliquer.

  • session : une session ajoute des informations contextuelles associées à une connexion. Cela inclut des informations spécifiques au niveau du transport (par exemple, les clés TLS, etc.) ou des variables. Ce terme est utilisé depuis longtemps dans HAProxy pour désigner les communications HTTP/1.0 bout à bout entre deux extrémités, et il reste visible dans le nom de certaines commandes CLI ou statistiques, même s’il désigne désormais des flux, mais les messages d’aide et les descriptions cherchent à éviter toute ambiguïté. Il reste pertinent dans le cadre de la terminologie au niveau réseau (par exemple, les sessions TCP au sein du système d’exploitation ou les sessions TCP à travers un pare-feu), ou pour les applications utilisateur non HTTP (par exemple, une session telnet ou une session SSH). Il ne doit pas être confondu avec les « sessions applicatives », qui servent à stocker un contexte utilisateur complet dans un cookie et nécessitent d’être envoyées au même serveur.

  • stream : un flux correspond exactement à une communication bidirectionnelle point à point au niveau de l’application, où des analyses et des transformations peuvent être appliquées. En HTTP, il contient une seule requête et sa réponse associée, et est instancié à l’arrivée de la requête, se terminant avec la fin de la livraison de la réponse. Dans ce contexte, il existe une relation 1:1 entre un tel flux et le flux d’un protocole multiplexé. En communication TCP, il existe un seul flux par connexion.

  • transaction : une transaction n’est qu’une paire constituée d’une requête et de la réponse associée. Ce terme était utilisé en conjonction avec les sessions avant les flux, mais aujourd’hui, une relation 1:1 existe entre une transaction et un flux. Cela est essentiellement visible dans la portée des variables « txn », qui est valable pendant toute la transaction, donc pendant tout le flux.

  • requête : elle désigne le trafic allant du client vers le serveur. Elle est principalement utilisée dans le cadre du protocole HTTP pour indiquer où les opérations sont effectuées. Ce terme existe également pour les opérations TCP afin d’indiquer où les données sont traitées. Les requêtes apparaissent souvent dans les compteurs comme unité de trafic ou d’activité. Elles n’impliquent pas toujours de réponse (par exemple en cas d’erreur), mais comme il n’existe pas de réponses spontanées sans requête, les requêtes restent un indicateur pertinent de l’activité globale. En TCP, le nombre de requêtes est égal au nombre de connexions.

  • réponse : désigne le trafic circulant du serveur vers le client, ou parfois du serveur HAProxy vers le client, lorsque HAProxy génère lui-même la réponse (par exemple, une redirection HTTP).

  • service : cela indique généralement un traitement interne dans HAProxy qui n’exige pas de serveur, comme la page de statistiques, le cache ou un code Lua destiné à implémenter une petite application. Un service lit généralement une requête, effectue certaines opérations et produit une réponse.

1.3. Requête HTTP

Tout d’abord, examinons cette requête HTTP :

Line     Contents
number
   1     GET /serv/login.php?lang=en&profile=2 HTTP/1.1
   2     Host: www.mydomain.com
   3     User-agent: my small browser
   4     Accept: image/jpeg, image/gif
   5     Accept: image/png

1.3.1. Ligne de requête

Ligne 1 est la « ligne de requête ». Elle est toujours composée de 3 champs :

  • méthode : GET
  • URI : /serv/login.php?lang=en&profile=2
  • balise de version : HTTP/1.1

Tous sont délimités par ce que la norme appelle LWS (espaces blancs linéaires), qui sont généralement des espaces, mais peuvent aussi être des tabulations ou des sauts de ligne ou retours chariot suivis d’espaces ou de tabulations. La méthode elle-même ne peut contenir aucun deux-points (’:’) et est limitée aux lettres alphabétiques. Ces différentes combinaisons rendent souhaitable que HAProxy effectue lui-même la séparation plutôt que de laisser l’utilisateur écrire une expression régulière complexe ou inexacte.

L’URI lui-même peut prendre plusieurs formes :

  • Une « URI relative » :
  /serv/login.php?lang=en&profile=2

It is a complete URL without the host part. This is generally what is
received by servers, reverse proxies and transparent proxies.
  • Un « URI absolu », également appelé « URL » :
  http://192.168.0.12:8080/serv/login.php?lang=en&profile=2

It is composed of a "scheme" (the protocol name followed by '://'), a host
name or address, optionally a colon (':') followed by a port number, then
a relative URI beginning at the first slash ('/') after the address part.
This is generally what proxies receive, but a server supporting HTTP/1.1
must accept this form too.
  • étoile (’*’) : cette forme n’est acceptée que dans le cadre de la méthode OPTIONS et n’est pas relaisable. Elle est utilisée pour interroger les fonctionnalités d’un saut suivant.

  • une combinaison adresse:port : 192.168.0.12:80. Cette option est utilisée avec la méthode CONNECT, qui permet d’établir des tunnels TCP à travers des proxies HTTP, généralement pour HTTPS, mais parfois aussi pour d’autres protocoles.

Dans une URI relative, deux sous-parties sont identifiées. La partie située avant le point d’interrogation est appelée le « chemin ». Elle correspond généralement au chemin relatif vers des objets statiques sur le serveur. La partie située après le point d’interrogation est appelée la « chaîne de requête ». Elle est principalement utilisée avec les requêtes GET envoyées à des scripts dynamiques et est très spécifique à la langue, au framework ou à l’application utilisés.

HTTP/2 et HTTP/3 ne transmettent pas d’information de version avec la requête, la version est donc supposée être la même que celle du protocole sous-jacent (par exemple, « HTTP/2 »). En outre, ces protocoles n’envoient pas de ligne de requête comme une seule entité, mais la divisent en champs individuels appelés « pseudo-en-têtes », dont le nom commence par deux-points, et qui sont réassemblés de manière pratique par HAProxy en une ligne de requête équivalente. Pour cette raison, les lignes de requête présentes dans les journaux peuvent légèrement différer entre HTTP/1.x et HTTP/2 ou HTTP/3.

1.3.2. Les en-têtes de requête

Les en-têtes commencent à la deuxième ligne. Ils sont composés d’un nom au début de la ligne, immédiatement suivi d’un deux-points (’:’). Traditionnellement, un LWS est ajouté après le deux-points, mais cela n’est pas obligatoire. Ensuite viennent les valeurs. Plusieurs en-têtes identiques peuvent être regroupés sur une seule ligne, les valeurs étant séparées par des virgules, à condition de respecter leur ordre. Cela est couramment observé dans le champ « Cookie: ». Un en-tête peut s’étendre sur plusieurs lignes si les lignes suivantes commencent par un LWS. Dans l’exemple de la section 1.3, les lignes 4 et 5 définissent au total trois valeurs pour l’en-tête « Accept: ». Enfin, tous les LWS situés au début ou à la fin d’un en-tête sont ignorés et ne font pas partie de la valeur, conformément à la spécification.

Contrairement à une idée reçue courante, les noms d’en-tête ne sont pas sensibles à la casse, ni leurs valeurs lorsqu’elles font référence à d’autres noms d’en-tête (comme l’en-tête « Connection: »). En HTTP/2 et HTTP/3, les noms d’en-tête sont toujours envoyés en minuscules, comme on peut le constater en mode débogage. Internalement, tous les noms d’en-tête sont normalisés en minuscules afin que HTTP/1.x, HTTP/2 et HTTP/3 utilisent exactement la même représentation, et ils sont transmis tel quel de l’autre côté. Cela explique pourquoi une requête HTTP/1.x saisie en casse camélisée est livrée en minuscules.

La fin des en-têtes est indiquée par la première ligne vide. On dit souvent qu’il s’agit d’un double saut de ligne, ce qui n’est pas exact, même si un double saut de ligne constitue une forme valide de ligne vide.

Heureusement, HAProxy gère toutes ces combinaisons complexes lors de l’indexation des en-têtes, de la vérification des valeurs et de leur comptage, si bien qu’il n’y a aucune raison de s’inquiéter quant à la manière dont ils peuvent être écrits, mais il est important de ne pas accuser une application de présenter un comportement défectueux si elle effectue des actions inhabituelles, mais valides.

Note importante :

As suggested by RFC7231, HAProxy normalizes headers by replacing line breaks
in the middle of headers by LWS in order to join multi-line headers. This
is necessary for proper analysis and helps less capable HTTP parsers to work
correctly and not to be fooled by such complex constructs.

1.4. Réponse HTTP

Une réponse HTTP ressemble beaucoup à une requête HTTP. Ces éléments sont appelés des messages HTTP. Considérons la réponse suivante :

Line     Contents
number
   1     HTTP/1.1 200 OK
   2     Content-length: 350
   3     Content-Type: text/html

En tant que cas particulier, HTTP prend en charge ce qu’on appelle des « réponses informatives » sous forme de codes d’état 1xx. Ces messages sont spéciaux car ils ne transmettent aucune partie de la réponse ; ils servent uniquement de message de signalisation, par exemple pour demander au client de poursuivre l’envoi de sa requête. Dans le cas d’une réponse 100, les informations demandées seront transportées par le message de réponse suivant qui n’est pas un code 100. Cela implique qu’une même requête peut recevoir plusieurs réponses, et que cela ne fonctionne que lorsque le maintien de la connexion est activé (les messages 1xx ont été introduits dans HTTP/1.1). HAProxy gère ces messages et est capable de les acheminer correctement tout en les ignorant, en ne traitant que la prochaine réponse non 100. En conséquence, ces messages ne sont ni journalisés ni transformés, sauf indication contraire explicite. Les réponses 101 indiquent qu’un changement de protocole a lieu sur la même connexion, et que HAProxy doit passer en mode tunnel, comme s’une requête CONNECT avait eu lieu. Dans ce cas, l’en-tête Upgrade contiendra des informations supplémentaires sur le type de protocole vers lequel la connexion effectue la bascule.

1.4.1. Ligne de réponse

Ligne 1 est la « ligne de réponse ». Elle est toujours composée de 3 champs :

  • une version d’étiquette : HTTP/1.1
  • un code de statut : 200
  • une raison : OK

Le code d’état est toujours composé de trois chiffres. Le premier chiffre indique un état général :

  • 1xx = message d’information à ignorer (par exemple 100, 101)
  • 2xx = OK, le contenu suit (par exemple 200, 206)
  • 3xx = OK, aucun contenu ne suit (par exemple 302, 304)
  • 4xx = erreur provoquée par le client (par exemple 401, 403, 404)
  • 5xx = erreur provoquée par le serveur (par exemple 500, 502, 503)

Les codes d’état supérieurs à 599 ne doivent pas être émis dans les communications, bien que certains agents puissent les produire dans les journaux pour signaler leurs états internes. Veuillez vous référer à RFC9110 pour la signification détaillée de tous ces codes. HTTP/2 et les versions ultérieures ne comportent pas d’étiquette de version et utilisent l’en-tête pseudo « :status » pour rapporter le code d’état.

Le champ « reason » est simplement une indication, mais n’est pas analysé par les clients. Tout peut y être trouvé, mais il est courant de respecter les messages établis. Il peut être composé d’un ou plusieurs mots, tels que « OK », « Found » ou « Authentication Required ». Ce champ n’existe pas en HTTP/2 et versions ultérieures, et n’est pas émis dans ces versions. Lorsqu’une réponse provenant d’HTTP/2 ou d’une version ultérieure est transmise à un client HTTP/1, HAProxy produira un champ raison courant correspondant au code de statut.

HAProxy peut émettre les codes d’état suivants par lui-même :

Code  When / reason
 200  access to stats page, and when replying to monitoring requests
 301  when performing a redirection, depending on the configured code
 302  when performing a redirection, depending on the configured code
 303  when performing a redirection, depending on the configured code
 307  when performing a redirection, depending on the configured code
 308  when performing a redirection, depending on the configured code
 400  for an invalid or too large request
 401  when an authentication is required to perform the action (when
      accessing the stats page)
 403  when a request is forbidden by a "http-request deny" rule
 404  when the requested resource could not be found
 408  when the request timeout strikes before the request is complete
 410  when the requested resource is no longer available and will not
      be available again
 413  when a HTTP/1.0 GET/HEAD/DELETE requests has a payload, also see
      the "h1-accept-payload-with-any-method" option
 500  when HAProxy encounters an unrecoverable internal error, such as a
      memory allocation failure, which should never happen
 501 when HAProxy is unable to satisfy a client request because of an
     unsupported feature
 502  when the server returns an empty, invalid or incomplete response, or
      when an "http-response deny" rule blocks the response.
 503  when no server was available to handle the request, or in response to
      monitoring requests which match the "monitor fail" condition
 504  when the response timeout strikes before the server responds

Les codes d’erreur 4xx et 5xx ci-dessus peuvent être personnalisés (voir “errorloc” dans section 4.2 ). D’autres codes d’état peuvent être émis intentionnellement par des actions spécifiques (voir les actions “deny”, “return” et “redirect” dans section 4.3 par exemple).

1.4.2. Les en-têtes de réponse

Les en-têtes de réponse fonctionnent exactement comme les en-têtes de requête ; HAProxy utilise donc la même fonction pour les analyser. Reportez-vous au paragraphe 1.3.2 pour plus de détails.

11 - 2. Configuration de HAProxy

Syntaxe des fichiers, guillemets, variables, conditions, formats horaires et de taille, adresses et exemples

2.1. Format du fichier de configuration

Le processus de configuration d’HAProxy repose sur 3 sources majeures de paramètres :

  • les arguments en ligne de commande, qui ont toujours la priorité
  • le(s) fichier(s) de configuration, dont le format est décrit ici
  • l’environnement du processus en cours d’exécution, en cas de référence explicite à certaines variables d’environnement

Le fichier de configuration suit un format hiérarchique assez simple qui obéit à quelques règles fondamentales :

1. a configuration file is an ordered sequence of statements

2. a statement is a single non-empty line before any unprotected "#" (hash)

3. a line is a series of tokens or "words" delimited by unprotected spaces or
   tab characters

4. the first word or sequence of words of a line is one of the keywords or
   keyword sequences listed in this document

5. all other words are all arguments of the first one, some being well-known
   keywords listed in this document, others being values, references to other
   parts of the configuration, or expressions

6. certain keywords delimit a section inside which only a subset of keywords
   are supported

7. a section ends at the end of a file or on a special keyword starting a new
   section

C’est tout ce qu’il faut savoir pour écrire un générateur de configuration simple mais fiable, mais cela ne suffit pas à analyser de manière fiable n’importe quelle configuration ni à déterminer comment traiter certains cas limites.

Tout d’abord, plusieurs conséquences découlent des règles ci-dessus. La règle 6 et la règle 7 impliquent que les mots-clés utilisés pour définir une nouvelle section sont valables partout et ne peuvent avoir une signification différente dans une section spécifique. Ces mots-clés sont toujours un seul mot (contrairement à une suite de mots), et la section qui suit traditionnellement porte le même nom. Par exemple, lorsqu’on parle de la « section global », cela désigne la section de configuration qui suit le mot-clé « global ». Cette convention est fréquemment utilisée dans les messages d’erreur afin d’aider à localiser les parties à corriger.

Plusieurs sections créent un objet interne ou un espace de configuration, qui doit être distingué des autres. Dans ce cas, elles incluent un mot supplémentaire définissant le nom de cette section particulière. Pour certaines d’entre elles, le nom de section est obligatoire. Par exemple, « frontend foo » crée une nouvelle section de type « frontend » nommée « foo ». En général, un nom est spécifique à sa section, et deux sections de types différents peuvent utiliser le même nom, mais cela n’est pas recommandé car cela complique la gestion de la configuration.

Une conséquence directe de la règle 7 est que, lorsqu’un nombre de fichiers est lu simultanément, chacun d’eux doit commencer par une nouvelle section, et la fin de chaque fichier marque la fin d’une section. Un fichier ne peut pas contenir de sous-sections ni terminer une section existante tout en en commençant une nouvelle.

Règle 1 indique que l’ordre a de l’importance. En effet, certains mots-clés créent des directives pouvant être répétées plusieurs fois afin de former des séquences ordonnées de règles à appliquer dans un ordre précis. Par exemple, « tcp-request » peut être utilisé pour alterner des règles « accept » et « reject » selon des critères variés. En conséquence, un processeur de fichier de configuration doit toujours conserver l’ordre d’une section lors de l’édition d’un fichier. L’ordre des sections ne compte généralement pas, sauf pour la section globale, qui doit être placée avant les autres sections, bien qu’elle puisse être répétée si nécessaire. En outre, certains identifiants automatiques peuvent être attribués automatiquement à certains objets créés (par exemple, des proxies), et en réorganisant les sections, leurs identifiants changeront. Ces identifiants apparaissent par exemple dans les statistiques. Ainsi, la configuration ci-dessous attribuera à « foo » un numéro d’identifiant inférieur à celui de son homologue « bar ». Cet ordre sera inversé si les deux sections sont échangées :

listen foo
    bind:80

listen bar
    bind:81

Un autre point important est que, conformément aux règles 2 et 3 ci-dessus, les lignes vides, espaces, tabulations et commentaires suivant le caractère non protégé “#” ne font pas partie de la configuration, car ils ne servent qu’à délimiter les éléments. Cela implique que les configurations suivantes sont strictement équivalentes :

    global#this is the global section
daemon#daemonize
    frontend         foo
mode             http   # or tcp

et :

global
    daemon

# this is the public web frontend
frontend foo
    mode http

La pratique courante consiste à aligner à gauche uniquement le mot-clé qui introduit une nouvelle section, et à insérer des espaces (c’est-à-dire préfixer un caractère de tabulation ou quelques espaces) pour les autres mots-clés afin qu’il soit immédiatement visible qu’ils appartiennent à la même section (comme dans l’exemple ci-dessus). Placer des commentaires avant une nouvelle section aide le lecteur à déterminer s’il s’agit de la section souhaitée. Laisser une ligne vide à la fin d’une section aide également visuellement à repérer sa fin lors de son édition.

Les tabulations sont très pratiques pour la mise en retrait, mais elles ne se copient pas bien. Si l’on utilise des espaces à la place, il est recommandé d’en éviter un trop grand nombre (de 2 à 4) afin que l’édition dans le champ ne devienne pas une contrainte avec les éditeurs limités ne prenant pas en charge l’indentation automatique.

Dans les premiers temps, il était courant de voir les arguments séparés à des positions de tabulation fixes, car la plupart des mots-clés ne prenaient pas plus de deux arguments. Avec les versions modernes, qui intègrent des expressions complexes, cette pratique n’est plus valable et n’est pas recommandée.

2.2. Citation et échappement

Dans les configurations modernes, certains arguments exigent l’utilisation de caractères qui étaient auparavant considérés comme des délimiteurs purs. Afin de rendre cela possible, HAProxy prend en charge l’échappement des caractères en préfixant le caractère à échapper d’une barre oblique inverse (’\’), la citation faible en entourant un morceau de texte de guillemets doubles ("") et la citation forte en entourant un morceau de texte de guillemets simples (’’).

Cela ressemble fortement à ce qui est fait dans plusieurs langages de programmation et est très proche de ce qu’on rencontre couramment dans le shell Bourne. Le principe est le suivant : pendant que le parseur de configuration découpe les lignes en mots, il prend également en compte les guillemets et les barres obliques inversées pour déterminer si un caractère est un séparateur ou la représentation brute de ce caractère dans le mot courant. Lorsque cela est fait, le caractère d’échappement est supprimé, les guillemets sont supprimés, et le mot restant est utilisé tel quel comme mot-clé ou argument, par exemple.

Si une barre oblique inverse est nécessaire dans un mot, elle doit soit être échappée en utilisant elle-même (c’est-à-dire une barre oblique inverse en double), soit être fortement citée.

La sortie des guillemets est obtenue en précédant un caractère spécial d’un backslash (\):

\    to mark a space and differentiate it from a delimiter
\#   to mark a hash and differentiate it from a comment
\\   to use a backslash
\'   to use a single quote and differentiate it from strong quoting
\"   to use a double quote and differentiate it from weak quoting

En outre, quelques caractères non imprimables peuvent être émis en utilisant leur représentation habituelle en langage C :

\n   to insert a line feed (LF, character \x0a or ASCII 10 decimal)
\r   to insert a carriage return (CR, character \x0d or ASCII 13 decimal)
\t   to insert a tab (character \x09 or ASCII 9 decimal)
\xNN to insert character having ASCII code hex NN (e.g \x0a for LF).

La citation faible est obtenue en entourant de guillemets doubles ("") le caractère ou la séquence de caractères à protéger. La citation faible empêche l’interprétation de :

     space or tab as a word separator
'    single quote as a strong quoting delimiter
#    hash as a comment start

La citation faible permet l’interprétation des variables d’environnement (qui ne sont pas évaluées en dehors des guillemets) en les précédant d’un signe dollar (’$’). Si un caractère dollar est nécessaire à l’intérieur de guillemets doubles, il doit être échappé à l’aide d’une barre oblique inverse.

Une citation forte est obtenue en entourant les caractères ou la séquence de caractères à protéger de guillemets simples (’’). À l’intérieur des guillemets simples, aucun caractère n’est interprété ; il s’agit de la méthode la plus efficace pour citer des expressions régulières.

En conséquence, voici la matrice indiquant comment les caractères spéciaux peuvent être saisis dans différents contextes (les caractères non imprimables sont remplacés par leur nom entre chevrons). Notez que certains caractères qui ne peuvent être représentés qu’avec une échappement n’ont aucune représentation possible entre guillemets simples, d’où leur absence dans ce cas :

  Character  |  Unquoted     |  Weakly quoted              |  Strongly quoted
  -----------+---------------+-----------------------------+-----------------
    <TAB>    |  \<TAB>, \x09 |  "<TAB>", "\<TAB>", "\x09"  |  '<TAB>'
  -----------+---------------+-----------------------------+-----------------
    <LF>     |  \n, \x0a     |  "\n", "\x0a"               |
  -----------+---------------+-----------------------------+-----------------
    <CR>     |  \r, \x0d     |  "\r", "\x0d"               |
  -----------+---------------+-----------------------------+-----------------
    <SPC>    |  \<SPC>, \x20 |  "<SPC>", "\<SPC>", "\x20"  |  '<SPC>'
  -----------+---------------+-----------------------------+-----------------
    "        |  \", \x22     |  "\"", "\x22"               |  '"'
  -----------+---------------+-----------------------------+-----------------
    #        |  \#, \x23     |  "#", "\#", "\x23"          |  '#'
  -----------+---------------+-----------------------------+-----------------
    $        |  $, \$, \x24  |  "\$", "\x24"               |  '$'
  -----------+---------------+-----------------------------+-----------------
    '        |  \', \x27     |  "'", "\'", "\x27"          |
  -----------+---------------+-----------------------------+-----------------
    \        |  \\, \x5c     |  "\\", "\x5c"               |  '\'
  -----------+---------------+-----------------------------+-----------------

Exemple :

# those are all strictly equivalent:
log-format %{+Q}o\ %t\ %s\ %{-Q}r
log-format "%{+Q}o %t %s %{-Q}r"
log-format '%{+Q}o %t %s %{-Q}r'
log-format "%{+Q}o %t"' %s %{-Q}r'
log-format "%{+Q}o %t"' %s'\ %{-Q}r

Il existe un cas particulier où une deuxième niveau de citation ou d’échappement peut être nécessaire. Certains mots-clés prennent des arguments entre parenthèses, parfois séparés par des virgules. Ces arguments sont généralement des entiers ou des mots prédéfinis, mais lorsqu’ils sont des chaînes arbitraires, il peut être nécessaire d’effectuer un niveau d’échappement supplémentaire afin de distinguer les caractères appartenant à l’argument de ceux utilisés pour délimiter les arguments eux-mêmes. Un cas assez courant est le convertisseur « regsub ». Il prend une expression régulière en argument, et si une parenthèse fermante est nécessaire à l’intérieur, celle-ci devra être elle-même citée.

L’analyseur d’arguments en mot-clé est identique à celui du niveau supérieur en ce qui concerne les guillemets, à ceci près que les séquences d’échappement \#, \$, et \xNN ne sont pas traitées. Mais ce qui n’est pas toujours évident, c’est que les délimiteurs utilisés à l’intérieur doivent d’abord être échappés ou mis entre guillemets afin qu’ils ne soient pas résolus au niveau supérieur.

Prenons cet exemple utilisant le convertisseur « regsub », qui prend trois arguments : une expression régulière, une chaîne de remplacement et un ensemble d’indicateurs :

# replace all occurrences of "foo" with "blah" in the path:
http-request set-path %[path,regsub(foo,blah,g)]

Ici, aucune citation particulière n’était nécessaire. Mais si nous voulons maintenant remplacer soit « foo » soit « bar » par « blah », nous devrons utiliser l’expression régulière « (foo|bar) ». Nous ne pouvons pas écrire :

http-request set-path %[path,regsub((foo|bar),blah,g)]

car nous souhaitons que la chaîne soit coupée de cette manière :

    http-request set-path %[path,regsub((foo|bar),blah,g)]
                                       |---------|----|-|
                                 arg1 _/         /    /
                                 arg2 __________/    /
                                 arg3 ______________/

mais en réalité ce qui est transmis est une chaîne entre les parenthèses d’ouverture et de fermeture, suivie de déchets :

    http-request set-path %[path,regsub((foo|bar),blah,g)]
                                       |--------|--------|
                        arg1=(foo|bar _/        /
                    trailing garbage  _________/

La solution évidente semble ici être de citer le parenthèse fermante, mais cela ne fonctionnera pas seul, car, comme mentionné ci-dessus, les guillemets sont traités par l’analyseur de niveau supérieur, qui les résout avant le traitement de ce mot :

http-request set-path %[path,regsub("(foo|bar)",blah,g)]
------------ -------- ----------------------------------
   word1       word2    word3=%[path,regsub((foo|bar),blah,g)]

Ainsi, nous n’avons apporté aucune modification au parseur d’arguments au second niveau, qui continue de voir une expression régulière tronquée comme seul argument, ainsi que des données aléatoires à la fin de la chaîne. En échappant les guillemets, ceux-ci seront transmis inchangés au second niveau :

    http-request set-path %[path,regsub(\"(foo|bar)\",blah,g)]
    ------------ -------- ------------------------------------
       word1       word2    word3=%[path,regsub("(foo|bar)",blah,g)]
                                                |---------||----|-|
                                arg1=(foo|bar) _/          /    /
                                    arg2=blah  ___________/    /
                                        arg3=g _______________/

Une autre approche consiste à utiliser des guillemets simples à l’extérieur de toute la chaîne et des guillemets doubles à l’intérieur (afin que les guillemets doubles ne soient pas supprimés à nouveau) :

    http-request set-path '%[path,regsub("(foo|bar)",blah,g)]'
    ------------ --------  ----------------------------------
       word1       word2    word3=%[path,regsub("(foo|bar)",blah,g)]
                                                |---------||----|-|
                                arg1=(foo|bar) _/          /    /
                                          arg2 ___________/    /
                                          arg3 _______________/

Mais dans ce cas, il est important de noter que les délimiteurs intégrés dans la chaîne de niveau supérieur restent des caractères purs et ne sont plus des délimiteurs. Cela signifie notamment que les espaces et tabulations autour des virgules font partie de la chaîne. L’exemple ci-dessous est erroné pour plusieurs raisons :

    http-request set-path '%[path, regsub("(foo|bar)", blah, g)]'
    ------------ --------  --------------------------------------
       word1       word2    word3=%[path, regsub("(foo|bar)", blah, g)]
                                        |--------|---------||-----|--|
                       converter=" regsub" _/        /         /   /
                                    arg1=(foo|bar) _/         /   /
                                     arg2=" blah" ___________/   /
                                        arg3=" g" ______________/

Le simple fait d’entourer les virgules d’espaces a fait que ces espaces faisaient partie du champ lui-même, d’où la conversion « regsub » (commençant par un espace), qui ne sera pas trouvée et déclenchera une erreur, mais de manière plus subtile, la chaîne de remplacement « blah » insérera un espace dans la sortie. Une bonne règle générale consiste à ne jamais insérer d’espaces inutiles à l’intérieur des expressions.

Lorsque l’on utilise des expressions régulières, il peut arriver que le caractère dollar (’$’) apparaisse dans l’expression ou qu’une barre oblique inverse (’\’) soit utilisée dans la chaîne de remplacement. Dans ce cas, celles-ci seront également traitées à l’intérieur des guillemets doubles, d’où la préférence pour les guillemets simples (ou l’échappement double). Exemple :

    http-request set-path '%[path,regsub("^/(here)(/|$)","my/\1",g)]'
    ------------ --------  -----------------------------------------
       word1       word2    word3=%[path,regsub("^/(here)(/|$)","my/\1",g)]
                                                |-------------| |-----||-|
                              arg1=(here)(/|$) _/               /      /
                                    arg2=my/\1 ________________/      /
                                          arg3 ______________________/

Souvenez-vous que les barres obliques inverses ne sont pas des caractères d’échappement entre guillemets simples, et que tout le mot ci-dessus est déjà protégé contre elles grâce aux guillemets simples. À l’inverse, si des guillemets doubles avaient été utilisés autour de l’expression entière, le caractère dollar et les barres obliques auraient été résolus au niveau supérieur, rompant ainsi le contenu de l’argument au second niveau.

Malheureusement, comme les guillemets simples ne peuvent pas être échappés à l’intérieur d’une citation forte, si vous devez inclure des guillemets simples dans votre argument, vous devrez les échapper ou les citer deux fois. Il existe plusieurs façons de procéder :

http-request set-var(txn.foo) str("\\'foo\\'")
http-request set-var(txn.foo) str(\"\'foo\'\")
http-request set-var(txn.foo) str(\\\'foo\\\')

En cas de doute, il est préférable de ne jamais utiliser de guillemets, puis d’ajouter des guillemets simples ou doubles autour des arguments nécessitant une virgule ou une parenthèse fermante, en envisageant d’échapper ces guillemets à l’aide d’un backslash si la chaîne contient un dollar ou un backslash. Encore une fois, cela ressemble fortement à ce qui est utilisé sous un shell Bourne lorsqu’on échappe deux fois une commande passée à « eval ». Pour les auteurs d’API, la meilleure approche consiste probablement à entourer chaque argument d’un guillemet échappé, quelle que soit sa teneur. Les utilisateurs constateront probablement que l’utilisation de guillemets simples autour de l’expression entière et de guillemets doubles autour de chaque argument rend les configurations plus lisibles.

2.3. Variables d’environnement

La configuration d’HAProxy prend en charge les variables d’environnement. Ces variables ne sont interprétées qu’à l’intérieur de guillemets doubles. Les variables sont étendues pendant l’analyse de la configuration. Les noms de variables doivent être précédés du signe dollar ("$") et éventuellement entourés d’accolades ("{}"), de manière similaire à ce qui est fait dans le shell Bourne. Les noms de variables peuvent contenir des caractères alphanumériques ou le caractère souligné ("_"), mais ne doivent pas commencer par un chiffre. Si la variable contient une liste de plusieurs valeurs séparées par des espaces, elle peut être étendue en arguments individuels en entourant la variable d’accolades et en ajoutant le suffixe ‘[*]’ avant la fermeture de l’accolade. Il est également possible de spécifier une valeur par défaut à utiliser lorsque la variable n’est pas définie, en ajoutant cette valeur après un trait de soulignement ‘-’ à côté du nom de la variable. Notez que la valeur par défaut ne remplace que les variables non définies, pas les variables vides.

Exemple :

bind "fd@${FD_APP1}"

log "${LOCAL_SYSLOG-127.0.0.1}:514" local0 notice  # send to local server

user "$HAPROXY_USER"

Certains variables sont définis par HAProxy, ils peuvent être utilisés dans le fichier de configuration. Ces variables sont listées dans le tableau ci-dessous et sont classées selon quatre catégories :

  • utilisable : la variable est accessible à partir de la configuration, soit pour être résolue telle quelle, soit utilisée dans des blocs conditionnels ou des prédicats afin d’activer ou de désactiver certains fragments de configuration, comme décrit dans section 2.4 « Blocs conditionnels ».

  • modifiable : la variable peut être redéfinie ou supprimée dans la configuration via les mots-clés “setenv”/“unsetenv”.

  • répertorié : la variable est répertoriée dans la sortie de la commande CLI “show env”, décrite dans la section 9.3 “Commandes sockets Unix” du guide de gestion.

Il existe également deux sous-catégories, « master » et « worker », marquées respectivement par « M » et « W » dans le tableau ci-dessous, illustrant les différences entre les deux processus lorsque HAProxy est lancé en mode master-worker.

  • master : la variable est définie et accessible depuis le processus principal. Elle apparaît donc dans la sortie de la commande CLI du processus principal « show env » et peut être utilisée dans des blocs conditionnels ou des directives afin d’activer certaines configurations spéciales pour le processus principal (voir les exemples dans la section 2.4 « Blocs conditionnels »).

  • worker : la variable est définie et accessible depuis le processus worker. Elle apparaît dans la commande “show env” de l’interface CLI du worker (ou de l’interface CLI principale avec “@1 show env”), et peut également conditionner certains paramètres du processus worker (voir les exemples dans la section 2.4 “Blocs conditionnels”).

En mode autonome (sans l’option “-W” ni le mot-clé “master-worker”), le processus se comporte comme un worker, à l’exception des variables “HAPROXY_MASTER_CLI” et “HAPROXY_MWORKER” qui ne sont pas définies.

Certains variables sont marqués comme non utilisables et non modifiables :

  • FICHIERS_DE_CONFIG_HAPROXY
  • TRAVAILLEUR_M_HAPROXY
  • CLI_HAPROXY
  • CLI_PRIMAIRE_HAPROXY
  • PAIR_LOCAL_HAPROXY

Leurs valeurs sont indéfinies pendant l’analyse de la configuration ; elles sont définies ultérieurement lors de l’initialisation. Il est donc recommandé de ne pas utiliser ces variables au sein de blocs conditionnels, ni de les référencer dans les mots-clés “setenv”/“resetenv”/“unsetenv” de la section globale.

Le tableau ci-dessous résume l’état de chaque variable pour les différents modes de fonctionnement :

  +---------------------------+---------+------------+-----------+
  |          variable         | usable  | modifiable |  listed   |
  |                           +---------+------------+-----------+
  |                           |  M | W  |   M  |  W  |  M  |  W  |
  +---------------------------+----+----+------+-----+-----+-----+
  | HAPROXY_STARTUP_VERSION   |  X | X  |      |     |  X  |  X  |
  | HAPROXY_BRANCH            |  X | X  |      |     |  X  |  X  |
  | HAPROXY_CFGFILES          |    |    |      |     |  X  |  X  |
  | HAPROXY_MWORKER           |    |    |      |     |  X  |  X  |
  | HAPROXY_CLI               |    |    |      |     |     |  X  |
  | HAPROXY_MASTER_CLI        |    |    |      |     |  X  |     |
  | HAPROXY_LOCALPEER         |    | X  |      |     |     |  X  |
  | HAPROXY_HTTP_LOG_FMT      |    | X  |      |  X  |     |     |
  | HAPROXY_HTTP_CLF_LOG_FMT  |    | X  |      |  X  |     |     |
  | HAPROXY_HTTPS_LOG_FMT     |    | X  |      |  X  |     |     |
  | HAPROXY_TCP_LOG_FMT       |    | X  |      |  X  |     |     |
  | HAPROXY_TCP_CLF_LOG_FMT   |    | X  |      |  X  |     |     |
  | HAPROXY_KEYLOG_FC_LOG_FMT |    | X  |      |  X  |     |     |
  | HAPROXY_KEYLOG_BC_LOG_FMT |    | X  |      |  X  |     |     |
  +---------------------------+----+----+------+-----+-----+-----+

Les variables en question sont les suivantes :

  • HAPROXY_LOCALPEER : défini au démarrage du processus et contient le nom de l’homologue local. (Voir “-L” dans le guide d’administration.)

  • HAPROXY_CFGFILES : liste des fichiers de configuration chargés par HAProxy, séparés par des points-virgules. Peut être utile dans le cas où vous avez spécifié un répertoire.

  • HAPROXY_HTTP_LOG_FMT : contient la valeur du format de journalisation HTTP par défaut tel qu défini dans la section 8.2.3 « Format de journalisation HTTP ». Il peut être utilisé pour remplacer le format de journalisation par défaut sans avoir à copier l’ensemble de la définition originale.

  • HAPROXY_HTTP_CLF_LOG_FMT : contient la valeur du format de journalisation HTTP CLF par défaut, tel qu défini dans la section 8.2.3 « Format de journalisation HTTP ». Il peut être utilisé pour remplacer le format de journalisation par défaut sans avoir à copier toute la définition originale.

Exemple :

# Add the rule that gave the final verdict to the log
log-format "${HAPROXY_TCP_LOG_FMT} lr=%[last_rule_file]:%[last_rule_line]"
  • HAPROXY_HTTPS_LOG_FMT : similaire à HAPROXY_HTTP_LOG_FMT mais pour le format des journaux HTTPS tel qu’il est défini dans section 8.2.4 “Format des journaux HTTPS”.

  • HAPROXY_TCP_LOG_FMT : similaire à HAPROXY_HTTP_LOG_FMT mais pour le format des journaux TCP tel qu défini dans la section 8.2.2 « Format des journaux TCP ».

  • HAPROXY_TCP_CLF_LOG_FMT : similaire à HAPROXY_HTTP_CLF_LOG_FMT mais pour le format de journalisation TCP CLF tel qu défini dans la section 8.2.2 « Format de journalisation TCP ».

  • HAPROXY_KEYLOG_FC_LOG_FMT : contient le format de journalisation des clés pour la connexion TLS du frontend (face client), avec les entrées de clés séparées par des sauts de ligne, ce qui peut entraîner une incompatibilité avec votre serveur syslog. “tune.ssl.keylog on” est obligatoire.

  • HAPROXY_KEYLOG_BC_LOG_FMT : similaire à HAPROXY_KEYLOG_FC_LOG_FMT mais destiné à la connexion TLS côté backend (vers le serveur). Les entrées clés sont séparées par des sauts de ligne, ce qui peut entraîner une incompatibilité avec votre serveur syslog. “tune.ssl.keylog on” est obligatoire.

  • HAPROXY_MWORKER : En mode master-worker, cette variable est définie à 1.

  • HAPROXY_CLI : adresses des écouteurs configurés pour le socket de statistiques de chaque processus, séparées par des points-virgules.

  • HAPROXY_MASTER_CLI : En mode master-worker, les adresses des écouteurs de l’interface CLI principale, séparées par des points-virgules.

  • HAPROXY_STARTUP_VERSION : contient la version utilisée au démarrage, en mode master-worker, il s’agit de la version utilisée pour démarrer le master, même après mise à jour du binaire et rechargement.

  • HAPROXY_BRANCH : contient la version de branche d’HAProxy (par exemple “2.8”). Il ne contient pas le numéro de version complet. Il peut être utile en cas de migration si les ressources (par exemple des cartes ou des certificats) sont situées dans un chemin contenant le numéro de branche.

En outre, certaines variables pseudo sont résolues internement et peuvent être utilisées comme des variables régulières. Les variables pseudo commencent toujours par un point (’.’), et ce sont les seules où l’utilisation du point est autorisée. La liste actuelle des variables pseudo est :

  • .FICHIER : le nom du fichier de configuration actuellement en cours d’analyse.

  • .LINE : le numéro de ligne du fichier de configuration actuellement analysé, commençant à un.

  • .SECTION : le nom de la section actuellement analysée, ou son type si la section n’a pas de nom (par exemple « global »), ou une chaîne vide avant la première section.

Ces variables sont résolues à l’emplacement où elles sont analysées. Par exemple, si une variable “.LINE” est utilisée dans une directive « log-format » située dans une section « defaults », son numéro de ligne sera résolu avant l’analyse et la compilation de la directive « log-format », de sorte que ce même numéro de ligne sera réutilisé par les proxies ultérieurs.

Ainsi, il est possible d’émettre des informations afin d’aider à localiser une règle dans des variables, des journaux, des états d’erreur, des contrôles d’état, des valeurs d’en-tête, voire d’utiliser des numéros de ligne pour nommer certains objets de configuration, comme des serveurs par exemple.

2.4. Blocs conditionnels

Il peut parfois être pratique de pouvoir activer ou désactiver conditionnellement certaines parties arbitraires de la configuration, par exemple pour activer/désactiver le SSL ou les chiffres, activer ou désactiver certains écouteurs en pré-production sans modifier la configuration, ou ajuster la syntaxe de la configuration pour prendre en charge deux versions distinctes d’HAProxy pendant une migration. HAProxy fournit un ensemble de directives imbriquables du type préprocesseur, permettant d’intégrer ou d’ignorer certains blocs de texte. Ces directives doivent être placées sur une ligne à part et agissent sur les lignes qui les suivent. Deux d’entre elles prennent une expression, les autres ne font que basculer vers un bloc alternatif ou terminer un niveau actuel. Les 4 directives suivantes sont définies pour former des blocs conditionnels :

  • .si <condition>
  • .sinon_si <condition>
  • .sinon
  • .fin_si

La directive “.if” introduit un nouveau niveau, “.elif” reste au même niveau, “.else” également, et “.endif” ferme un niveau. Chaque “.if” doit être terminée par une directive “.endif” correspondante. La directive “.elif” ne peut être placée qu’après “.if” ou “.elif”, et il n’y a pas de limite au nombre de “.elif” pouvant être enchaînés. Il ne peut y avoir qu’une seule “.else” par “.if” et elle doit toujours être placée après “.if” ou après le dernier “.elif” d’un bloc.

Les commentaires peuvent être placés sur la même ligne si nécessaire, après un ‘#’, ils seront ignorés. Les directives sont tokenisées comme les autres directives de configuration, et il est donc possible d’utiliser des variables d’environnement dans les conditions.

Les conditions peuvent également être évaluées au démarrage grâce au paramètre -cc. Voir « 3. Démarrage de HAProxy » dans la documentation de gestion.

Les conditions sont soit une chaîne vide (qui renvoie alors false), soit une expression composée de toute combinaison de :

  • l’entier zéro (‘0’), retourne toujours « false »
  • un entier non nul (par exemple ‘1’), retourne toujours « true ».
  • une prédicat suivie éventuellement de paramètre(s) entre parenthèses.
  • une condition placée entre une paire de parenthèses ‘(’ et ‘)’
  • un point d’exclamation (’!’) placé avant l’un quelconque des éléments ci-dessus non vides, qui inverse son état.
  • des expressions combinées par une opération ET logique (’&&’), évaluées de gauche à droite jusqu’à ce qu’une retourne « false »
  • des expressions combinées par une opération OU logique (’||’), évaluées de droite à gauche jusqu’à ce qu’une retourne « true »

Le même analyseur de lignes et parseur d’arguments est utilisé que pour le reste du langage de configuration. Les mots sont séparés autour de séries consécutives d’un ou plusieurs espaces ou tabulations non entre guillemets, puis réassemblés en utilisant un seul espace pour les séparer avant évaluation, afin de simplifier la tâche de l’utilisateur qui n’a pas à entourer toute la ligne de guillemets. Toutefois, cela signifie également que les espaces entourant les virgules ou les parenthèses font bien partie de la valeur, ce qui n’est pas toujours attendu. Par exemple, l’expression suivante :

.if defined( HAPROXY_MWORKER )

testera l’existence de la variable « HAPROXY_MWORKER » (avec des espaces), et celle-ci :

.if streq("$ENABLE_SSL",     1)

comparera la variable d’environnement “ENABLE_SSL” à la valeur « 1 » (avec un seul espace initial). La raison est que la ligne est d’abord divisée en mots de cette manière :

   .if streq("$ENABLE_SSL",     1)
  |---|--------------------|   |--|
    1           2               3

puis la citation faible est appliquée et la variable d’environnement “$ENABLE_SSL” est résolue (par exemple, supposons que ENABLE_SSL=0), avant que les mots ne soient finalement réassemblés en une chaîne unique en insérant un seul espace entre les mots :

   .if streq(0, 1)
  |---|-------|--|
    1     2     3

et uniquement alors est-il analysé comme une expression unique. L’espace inséré entre la virgule et « 1 » fait toujours partie de la valeur de l’argument, rendant cet argument « 1 » :

   .if streq(0, 1)
  |---|-----|-|--|
    \    \    \  \_ argument2: " 1"
     \    \    \___ argument1: "0"
      \    \_______ function: "streq"
       \___________ directive: ".if"

On constate ici que, même si ENABLE_SSL avait été égal à « 1 », il n’aurait pas correspondu à « 1 » car la chaîne aurait différé d’un espace.

Note : comme expliqué dans la section « 2.2. Citation et échappement », une bonne règle de base consiste à ne jamais insérer d’espaces inutiles à l’intérieur des expressions.

Notez que, comme dans d’autres langages, l’opérateur ET a une priorité supérieure à celle de l’opérateur OU, de sorte que « A && B || C && D » est évalué comme « (A && B) || (C && D) ».

La liste des prédicats actuellement pris en charge est la suivante :

  • awslc_api_atleast(<ver>): retourne true si le numéro actuel de l’API awslc est au moins aussi récent que <ver> sinon false. Exemple : awslc_api_atleast(35)

  • awslc_api_before(<ver>): renvoie true si le numéro actuel de l’API awslc est strictement inférieur à <ver> sinon false. Exemple : awslc_api_before(26)

  • defined(<name>) : renvoie true si une variable d’environnement <name> existe, quelle que soit sa valeur

  • feature(<name>) : renvoie true si la fonction <name> est indiquée comme présente dans la liste des fonctions signalées par “haproxy -vv” (ce qui signifie qu’un <name> apparaît après un ‘+’)

  • openssl_version_atleast(<ver>): retourne true si la version actuelle d’OpenSSL est au moins aussi récente que <ver>, sinon false. Des bibliothèques comme LibreSSL, AWS-LC et WolfSSL fournissent également une version pseudo-OpenSSL. Exemple :

ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1)
  • openssl_version_before(<ver>): renvoie true si la version OpenSSL actuelle est strictement antérieure à <ver>, sinon false. Des bibliothèques comme LibreSSL, AWS-LC et WolfSSL fournissent également une version pseudo-OpenSSL. Exemple : openssl_version_before(3.5.0)

  • ssllib_name_startswith(<name>) : renvoie true si le nom de la bibliothèque SSL avec laquelle HAProxy a été lié commence par <name>. Exemple : ssllib_name_startswith(wolfSSL)

  • streq(<str1>,<str2>) : renvoie true uniquement si les deux chaînes sont égales

  • strneq(<str1>,<str2>): renvoie true uniquement si les deux chaînes diffèrent

  • strstr(<str1>,<str2>): renvoie true uniquement si la deuxième chaîne est trouvée dans la première.

  • version_atleast(<ver>): renvoie true si la version actuelle de HAProxy est au moins aussi récente que <ver>, sinon false. La syntaxe des versions est la même que celle affichée par la commande “haproxy -v”, et les composantes manquantes sont supposées valoir zéro.

  • version_before(<ver>): renvoie true si la version actuelle de HAProxy est strictement antérieure à <ver> sinon false. La syntaxe des versions est identique à celle affichée par la commande “haproxy -v” et les composantes manquantes sont supposées valoir zéro.

  • enabled(<opt>) : retourne true si l’option <opt> est activée en cours d’exécution. Seul un sous-ensemble d’options est pris en charge :

POLL, EPOLL, KQUEUE, EVPORTS, SPLICE,
GETADDRINFO, REUSEPORT, FAST-FORWARD,
SERVER-SSL-VERIFY-NONE

Exemple :

# 1. HAPROXY_MWORKER variable is set automatically by HAProxy in master and
# in worker process environments (see HAProxy variables matrix from
# 2.3. Environment variables). Its presence enables an additional listener.

global
  master-worker

.if defined(HAPROXY_MWORKER) listen mwcli_px bind:1111 … .endif

# 2. HAPROXY_BRANCH is set automatically by HAProxy in master and in worker
# process environments (see HAProxy variables matrix from 2.3. Environment
# variables). We check HAPROXY_BRANCH value and conditionally enable
# mworker-max-reloads parameter.

global
  master-worker

.if streq("$HAPROXY_BRANCH",3.1) mworker-max-reloads 5 .endif

# 3. Some arbitrary environment variables are set by user in the global
# section. If HAProxy is started in master-worker mode, they are presented in
# master and in worker process environments. We check values of these
# variables and conditionally enable ports 80 and 443. Environment variables
# checks can be mixed with features and version checks.

global
  setenv WITH_SSL yes
  unsetenv SSL_ONLY

.if strneq("$SSL_ONLY",yes) bind:80 .endif

.if streq("$WITH_SSL",yes) .if feature(OPENSSL) bind:443 ssl crt … .endif .endif

.if feature(OPENSSL) && (streq("$WITH_SSL",yes) || streq("$SSL_ONLY",yes)) bind:443 ssl crt … .endif

.if version_atleast(2.4-dev19) profiling.memory on .endif

.if !feature(OPENSSL) .alert “SSL support is mandatory” .endif

Quatre autres directives sont fournies pour signaler certains états :

  • .diag “message” : émettre ce message uniquement en mode diagnostic (-dD)
  • .notice “message” : émettre ce message au niveau NOTICE
  • .warning “message” : émettre ce message au niveau WARNING
  • .alert “message” : émettre ce message au niveau ALERT

Les messages émis au niveau WARNING peuvent empêcher le démarrage du processus si l’option « zero-warning » est activée. Les messages émis au niveau ALERT provoquent toujours une erreur fatale. Ces messages peuvent être utilisés pour détecter certaines conditions inappropriées et fournir des conseils à l’utilisateur.

Exemple :

.if "${A}"
  .if "${B}"
     .notice "A=1, B=1"
  .elif "${C}"
     .notice "A=1, B=0, C=1"
  .elif "${D}"
     .warning "A=1, B=0, C=0, D=1"
  .else
     .alert "A=1, B=0, C=0, D=0"
  .endif
.else
     .notice "A=0"
.endif

.diag "WTA/2021-05-07: replace 'redirect' with 'return' after switch to 2.4"
      http-request redirect location /goaway if ABUSE

2.5. Format d’horodatage

Certains paramètres comportent des valeurs représentant une durée, telles que les délais d’expiration. Ces valeurs sont généralement exprimées en millisecondes (sauf indication contraire explicite), mais peuvent être exprimées dans toute autre unité en ajoutant l’unité à la valeur numérique. Il est important de le prendre en compte, car cela ne sera pas rappelé pour chaque mot-clé. Les unités prises en charge sont :

  • us : microsecondes. 1us = 1/1000000s
  • ms : millisecondes. 1ms = 1/1000s. Il s’agit de l’unité par défaut.
  • s : secondes. 1s = 1000ms
  • m : minutes. 1m = 60s = 60000ms
  • h : heures. 1h = 60m = 3600s = 3600000ms
  • d : jours. 1d = 24h = 1440m = 86400s = 86400000ms

2.6. Format de taille

Certains paramètres impliquent des valeurs représentant une taille, telles que les limites de débit. Ces valeurs sont généralement exprimées en octets (sauf indication contraire explicite), mais peuvent être exprimées dans n’importe quelle autre unité en ajoutant l’unité à la valeur numérique. Il est important de le prendre en compte, car cela ne sera pas rappelé pour chaque mot-clé. Les unités prises en charge sont insensibles à la casse :

  • k : kilo-octets. 1 kilo-octet = 1024 octets
  • m : méga-octets. 1 méga-octet = 1048576 octets
  • g : giga-octets. 1 giga-octet = 1073741824 octets

Les formats de temps et de taille exigent des entiers ; la notation décimale n’est pas autorisée.

2.7. Format de nom pour les cartes et les listes ACL

Il est possible d’utiliser une liste de modèles pour les cartes ou les ACL. Une liste de modèles est identifiée par son nom et peut être utilisée à différents endroits dans la configuration. Les listes de modèles sont divisées en trois catégories selon le format du nom :

  • Listes de motifs basées sur des fichiers réguliers : c’est le cas par défaut. Le nom du fichier, absolu ou relatif, est utilisé comme nom. Le fichier doit exister, sinon une erreur est déclenchée. Toutefois, il peut être vide. Le préfixe « file@ » peut également être spécifié, mais il ne fait pas partie du nom identifiant la liste. Un nom de fichier, avec ou sans préfixe, référence la même liste de motifs.

  • Listes de motifs basées sur des fichiers facultatifs : le nom de fichier doit être précédé du préfixe “opt@”. L’existence du fichier est facultative. Si le fichier existe, son contenu est chargé, mais aucune erreur n’est signalée s’il est absent. Le préfixe ne fait pas partie du nom identifiant la liste. Cela signifie qu’un fichier facultatif et un fichier régulier portant le même nom référencent la même liste de motifs.

  • Listes de motifs basées sur des fichiers virtuels : le nom n’est qu’un identifiant. Il ne fait pas référence à aucun fichier. Le préfixe « virt@ » doit être utilisé. Il fait partie du nom. Il ne peut donc pas être combiné avec d’autres types de listes.

Les fichiers virtuels sont utiles lorsque les modèles sont entièrement gérés de manière dynamique, sans modèles présents au démarrage ni lors d’un rechargement. Les fichiers facultatifs peuvent être utilisés dans les mêmes conditions. Toutefois, les modèles peuvent être sauvegardés dans le fichier, par le biais d’un script externe basé, par exemple, sur la commande CLI « show map ». Ainsi, il devient possible de conserver les modèles lors d’un rechargement.

Note : Même si cela est peu probable, cela signifie qu’aucun fichier régulier commençant par « file@ », « opt@ » ou « virt@ » ne peut être chargé, sauf en ajoutant explicitement « ./ » devant le nom de fichier (par exemple « file@./virt@map »).

2.8. Variables

Dans la configuration HAProxy, les variables peuvent être utilisées dans les fonctions d’extraction d’échantillon, les convertisseurs, les chaînes de format de journalisation ou les actions TCP/HTTP. Des variables propres au processus peuvent être définies, accessibles globalement pendant toute la durée de vie du processus. D’autres ont une durée de vie plus courte. Les variables sont similaires à celles utilisées dans les scripts shell. Il s’agit d’un nom symbolique pour une zone de mémoire. La taille des variables n’est pas limitée et est allouée dynamiquement. Elles doivent donc être utilisées avec précaution, notamment en cas d’utilisation intensive. Toutefois, il est possible de limiter la quantité maximale de mémoire utilisée par les variables en configurant les paramètres globaux “tune.vars”.

Les variables doivent être désignées en utilisant le format “<scope>.<name>”. Le <scope> est un mot unique indiquant la durée de vie de la variable. La partie <name>, à l’intérieur d’une portée, ne peut contenir que des caractères ‘a-z’, ‘A-Z’, ‘0-9’ et ‘_’. Elle est unique dans cette portée, mais le même nom utilisé dans des portées différentes peut faire référence à des variables différentes. Les portées prises en charge sont :

  • proc : pour les variables connues pendant toute la durée de vie du processus et accessibles globalement. Les variables « proc » peuvent être manipulées depuis la ligne de commande à l’aide des commandes « get var » et « set var ». Elles peuvent également être définies depuis les sections « global » à l’aide des directives « set-var » et « set-var-fmt ».

  • sess : pour les variables connues pendant toute la durée de vie d’une session. Les variables « sess » sont privées à une session, non visibles depuis l’extérieur et non partagées avec d’autres sessions.

  • txn : pour les variables connues pendant toute la durée de vie d’une transaction. Les variables « txn » sont privées à un flux, non visibles depuis l’extérieur et non partagées avec d’autres flux.

  • req : pour les variables connues pendant le traitement d’une requête sur un flux spécifique. Les variables « req » sont visibles depuis la création du flux jusqu’à la première tentative de connexion au serveur. Elles sont privées à un flux, non visibles depuis l’extérieur et non partagées avec d’autres flux. Il n’y a aucune superposition entre les variables « req » et « res ».

  • res : pour les variables connues pendant le traitement de la réponse pour un flux spécifique. Les variables « res » sont visibles à partir de la première tentative de connexion au serveur jusqu’à la destruction du flux. Elles sont privées à un flux, non visibles depuis l’extérieur et non partagées avec d’autres flux. Il n’y a aucune superposition entre les variables « req » et « res ».

  • check : pour les variables connues pendant l’exécution d’une vérification de santé. Les variables « check » sont privées à une vérification de santé, non visibles depuis l’extérieur de celle-ci et non partagées avec d’autres vérifications de santé. Elles peuvent être définies à l’aide des directives dédiées « tcp-check » ou « http-check ».

En fonction du contexte, des portées supplémentaires faisant référence au parent d’un flux actuel peuvent être utilisées :

  • psess : identique à « sess » mais utilise la session du flux parent, le cas échéant.

  • ptxn : identique à « txn » mais utilise la transaction du flux parent, le cas échéant.

  • preq : identique à “req” mais utilise le flux parent, le cas échéant. Les variables “preq” ne sont accessibles que pendant le traitement de la requête du flux parent.

  • pres : identique à « res » mais utilise le flux parent, le cas échéant. Les variables « pres » ne sont accessibles que pendant le traitement de la réponse du flux parent.

Les portées faisant référence au flux parent sont utilisables dès la définition de ce dernier. Dans la plupart des cas, aucun flux parent n’existe. Toutefois, s’il est applicable, cela sera explicitement précisé. Pour l’instant, il est uniquement possible de récupérer la valeur des variables définies dans une portée du flux parent. Il n’est pas possible de définir ni d’annuler de telles variables. En général, un flux enfant effectue un traitement pour le parent à un moment précis et empêche celui-ci de progresser jusqu’à la fin de l’opération qu’il effectue. Cela signifie que le parent peut être arrêté au milieu du traitement d’une requête ou d’une réponse, par exemple. En conséquence, certaines portées ne seront pas disponibles depuis le flux enfant. Par exemple, si une requête fait l’objet d’une analyse effectuée par un flux enfant, ce dernier ne trouvera aucune variable dans la portée « pres » car le parent n’est pas en train de traiter une réponse, et donc ne possède aucune variable dans sa portée « res ».

Le contenu d’une variable est le résultat d’une expression d’extraction d’échantillon et hérite du type de sortie de cette expression. Il est important de le prendre en compte lors de l’utilisation de la variable, car son type doit être compatible avec son usage. Par exemple, une variable contenant une chaîne utilisée dans le convertisseur « add() » doit être convertible en entier valide pour réussir. Cela est particulièrement vrai lorsque les variables sont comparées à des valeurs statiques. La méthode de correspondance appropriée doit être utilisée.

2.9. Formats d’adresses

Plusieurs instructions telles que « bind », « server », « nameserver » et « log » nécessitent une adresse.

Cette adresse peut être un nom d’hôte, une adresse IPv4, une adresse IPv6 ou ‘’. Le ‘’ est égal à l’adresse spéciale “0.0.0.0” et peut être utilisé, dans le cas de « bind » ou « dgram-bind », pour écouter sur toutes les adresses IPv4 du système. L’équivalent IPv6 est ‘::’.

Selon l’instruction, un port ou une plage de ports suit l’adresse IP. Cela est obligatoire dans l’instruction « bind », facultatif dans l’instruction « server ».

Cette adresse peut également commencer par une barre oblique « / ». Elle est considérée comme appartenant à la famille « unix », et les caractères « / » et suivants doivent obligatoirement être présents dans le chemin.

Le type de socket ou la méthode de transport par défaut, « datagram » ou « stream », dépend de l’instruction de configuration indiquant l’adresse. En effet, les directives « bind » et « server » utilisent par défaut un type de socket « stream », tandis que les directives « log », « nameserver » ou « dgram-bind » utilisent un type de socket « datagram ».

Optionnellement, un préfixe peut être utilisé pour forcer le type de famille d’adresses et/ou le type de socket et la méthode de transport.

2.9.1. Préfixes de famille d’adresses

‘abns@<name>’ suivant <name> est un espace de noms abstrait (Linux uniquement).

‘abnsz@<name>’ suivant <name> est un espace de noms abstrait terminé par un octet nul (Linux uniquement).

‘fd@<n>’ suivant est un descripteur de fichier <n> hérité du processus parent. Ce descripteur doit être lié et peut ou non déjà être en écoute.

L’adresse ‘ip@<address>[:port1[-port2]]’ suivant <address> est considérée comme une adresse IPv4 ou IPv6 selon la syntaxe. Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut être spécifié, ou doit l’être.

‘ipv4@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv4. Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut être spécifié, ou doit l’être.

‘ipv6@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv6. Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié.

‘sockpair@<n>’ : l’adresse qui suit est le descripteur de fichier d’un socket Unix connecté ou d’une paire de sockets. Lors d’une connexion, l’initiateur crée une paire de sockets connectés et transmet l’un d’eux à l’autre extrémité via le descripteur. L’écouteur attend de recevoir ce descripteur depuis le socket Unix et l’utilise comme celui renvoyé par accept(). Cette option doit être utilisée avec précaution.

           Bugs : Ce protocole est connu pour être peu fiable sous macOS en raison d'un problème dans l'implémentation de sendmsg(2) de macOS. La connexion pourrait ne pas être acceptée correctement.

‘unix@<path>’ : la chaîne qui suit est considérée comme le chemin <path> d’un socket Unix. Ce préfixe permet de déclarer un chemin de socket Unix qui ne commence pas par une barre oblique ‘/’.

2.9.2. Préfixes de type de socket

Les préfixes de famille d’adresses précédents peuvent également être utilisés pour forcer le type de socket et la méthode de transport. La valeur par défaut dépend de l’instruction utilisant cette adresse, mais dans certains cas, l’utilisateur peut la forcer à une autre valeur. C’est notamment le cas de l’instruction « log », dont la valeur par défaut est syslog via UDP, mais où l’on peut forcer l’utilisation de syslog via TCP.

Ces préfixes ont été conçus à usage interne ; les utilisateurs doivent préférer les alias de la section suivante « 2.9.3 Préfixes de protocole ». Toutefois, ils peuvent parfois s’avérer pratiques, par exemple en combinaison avec des sockets héritées identifiées par leur numéro de descripteur de fichier, auquel cas le domaine d’adresse est « fd » et le type de socket doit être déclaré.

Si les utilisateurs ont besoin de l’un de ces préfixes pour obtenir le comportement attendu, car ils ne peuvent pas configurer la même fonctionnalité à l’aide des préfixes de protocole, ils doivent en informer les responsables du maintien.

‘stream+<family>@<address>’ impose le type de socket et la méthode de transport à « stream »

‘dgram+<family>@<address>’ impose le type de socket et la méthode de transport par “datagramme”.

‘quic+<family>@<address>’ impose le type de socket à « datagram » et la méthode de transport à « stream ».

2.9.3. Préfixes de protocole

‘quic4@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv4, mais le type de socket est forcé à « datagram » et la méthode de transport est forcé à « stream ». Selon l’instruction utilisant cette adresse, un port UDP ou une plage de ports peut ou doit être spécifié. Cela équivaut à « quic+ipv4@ ».

‘quic6@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv6, mais le type de socket est forcé à « datagram » et la méthode de transport est forcé à « stream ». Selon l’instruction utilisant cette adresse, un port UDP ou une plage de ports peut ou doit être spécifié. Cela équivaut à « quic+ipv6@ ».

’tcp@<address>[:port1[-port2]]’ suivant <address> est considéré comme une adresse IPv4 ou IPv6 selon la syntaxe, mais le type de socket et la méthode de transport sont forcés à « stream ». Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de « stream+ip@ ».

’tcp4@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv4, mais le type de socket et la méthode de transport sont forcés à « stream ». Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de ‘stream+ipv4@’.

’tcp6@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv6, mais le type de socket et la méthode de transport sont forcés à « stream ». Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de « stream+ipv4@ ».

‘mptcp@<address>[:port1[-port2]]’ suivant <address> est considéré comme une adresse IPv4 ou IPv6 selon la syntaxe, mais le type de socket et la méthode de transport sont forcés à « stream », avec le protocole MPTCP. Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié.

‘mptcp4@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv4, mais le type de socket et la méthode de transport sont forcés à « stream », avec le protocole MPTCP. En fonction de l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié.

‘mptcp6@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv6, mais le type de socket et la méthode de transport sont forcés à « stream », avec le protocole MPTCP. En fonction de l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié.

‘udp@<address>[:port1[-port2]]’ suivant <address> est considéré comme une adresse IPv4 ou IPv6 selon la syntaxe, mais le type de socket et la méthode de transport sont forcés à « datagram ». Selon l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de « dgram+ip@ ».

‘udp4@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv4, mais le type de socket et la méthode de transport sont forcés à « datagram ». En fonction de l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de ‘dgram+ipv4@’.

‘udp6@<address>[:port1[-port2]]’ suivant <address> est toujours considéré comme une adresse IPv6, mais le type de socket et la méthode de transport sont forcés à « datagram ». En fonction de l’instruction utilisant cette adresse, un port ou une plage de ports peut ou doit être spécifié. Il est considéré comme un alias de ‘dgram+ipv4@’.

‘uxdg@<path>’ : la chaîne qui suit est considérée comme le chemin <path> d’un socket Unix, mais la méthode de transport est forcée à “datagram”. Ce préfixe est un alias de ‘dgram+unix@’.

‘uxst@<path>’ : la chaîne qui suit est considérée comme le chemin <path> d’un socket Unix, mais la méthode de transport est forcée à “stream”. Ce préfixe est un alias de ‘stream+unix@’.

Dans les versions futures, d’autres préfixes pourraient être utilisés pour spécifier des protocoles comme QUIC, qui propose un transport de flux basé sur des sockets de type « datagram ».

2.10. Exemples

# Simple configuration for an HTTP proxy listening on port 80 on all
    # interfaces and forwarding requests to a single backend "servers" with a
    # single server "server1" listening on 127.0.0.1:8000
    global
        daemon
        maxconn 256

    defaults
        mode http
        timeout connect 5000ms
        timeout client 50000ms
        timeout server 50000ms

    frontend http-in
        bind *:80
        default_backend servers

    backend servers
        server server1 127.0.0.1:8000 maxconn 32


    # The same configuration defined with a single listen block. Shorter but
    # less expressive, especially in HTTP mode.
    global
        daemon
        maxconn 256

    defaults
        mode http
        timeout connect 5000ms
        timeout client 50000ms
        timeout server 50000ms

    listen http-in
        bind *:80
        server server1 127.0.0.1:8000 maxconn 32

En supposant que HAProxy est dans $PATH, testez ces configurations dans un shell avec :

$ sudo haproxy -f configuration.conf -c

12 - 3. Section globale

Sécurité du processus, réglage des performances, débogage et paramètres du client HTTP

Les paramètres de la section « global » sont applicables à l’ensemble du processus et souvent spécifiques au système d’exploitation. Ils sont généralement définis une fois pour toutes et n’exigent pas de modification une fois correctement configurés. Certains d’entre eux ont des équivalents en ligne de commande.

Les mots-clés suivants sont pris en charge dans la section « global » :

  • Gestion des processus et sécurité

    • 51degrees-allow-unmatched
    • 51degrees-cache-size
    • 51degrees-data-file
    • 51degrees-difference
    • 51degrees-drift
    • 51degrees-property-name-list
    • 51degrees-property-separator
    • 51degrees-use-performance-graph
    • 51degrees-use-predictive-graph
    • ca-base
    • chroot
    • cluster-secret
    • cpu-affinity
    • cpu-map
    • cpu-policy
    • cpu-set
    • crt-base
    • daemon
    • default-path
    • description
    • deviceatlas-json-file
    • deviceatlas-log-level
    • deviceatlas-properties-cookie
    • deviceatlas-separator
    • dns-accept-family
    • expose-deprecated-directives
    • expose-experimental-directives
    • external-check
    • fd-hard-limit
    • gid
    • grace
    • group
    • h1-accept-payload-with-any-method
    • h1-case-adjust
    • h1-case-adjust-file
    • h1-do-not-close-on-insecure-transfer-encoding
    • h2-workaround-bogus-websocket-clients
    • hard-stop-after
    • harden.reject-privileged-ports.tcp
    • harden.reject-privileged-ports.quic
    • insecure-fork-wanted
    • insecure-setuid-wanted
    • issuers-chain-path
    • jwt.decrypt_alg_list
    • jwt.decrypt_enc_list
    • key-base
    • limited-quic
    • localpeer
    • log
    • log-send-hostname
    • log-tag
    • lua-load
    • lua-load-per-thread
    • lua-prepend-path
    • max-threads-per-group
    • mworker-max-reloads
    • nbthread
    • node
    • numa-cpu-mapping
    • ocsp-update.disable
    • ocsp-update.maxdelay
    • ocsp-update.mindelay
    • ocsp-update.httpproxy
    • ocsp-update.mode
    • pidfile
    • pp2-never-send-local
    • presetenv
    • prealloc-fd
    • resetenv
    • set-dumpable
    • set-var
    • setenv
    • ssl-default-bind-ciphers
    • ssl-default-bind-ciphersuites
    • ssl-default-bind-client-sigalgs
    • ssl-default-bind-curves
    • ssl-default-bind-options
    • ssl-default-bind-sigalgs
    • ssl-default-server-ciphers
    • ssl-default-server-ciphersuites
    • ssl-default-server-client-sigalgs
    • ssl-default-server-curves
    • ssl-default-server-options
    • ssl-default-server-sigalgs
    • ssl-dh-param-file
    • ssl-propquery
    • fournisseur-ssl
    • chemin-fournisseur-ssl
    • niveau-sécurité-ssl
    • vérification-serveur-ssl
    • ignorer-ca-auto-signé-ssl
    • statistiques
    • fichier-statistiques
    • limites-strictes
    • uid
    • limite-ressources-n
    • liaison-unix
    • supprimer-variable-environnement
    • utilisateur
    • taille-cache-wurfl
    • fichier-données-wurfl
    • liste-informations-wurfl
    • séparateur-liste-informations-wurfl
  • Optimisation des performances

    • busy-polling
    • max-spread-checks
    • maxcompcpuusage
    • maxcomprate
    • maxconn
    • maxconnrate
    • maxpipes
    • maxsessrate
    • maxsslconn
    • maxsslrate
    • maxzlibmem
    • no-memory-trimming
    • noepoll
    • noevports
    • nogetaddrinfo
    • nokqueue
    • noktls
    • nopoll
    • noreuseport
    • nosplice
    • profiling.memory
    • profiling.tasks
    • server-state-base
    • server-state-file
    • spread-checks
    • ssl-engine
    • ssl-mode-async
    • tune.applet.zero-copy-forwarding
    • tune.buffers.limit
    • tune.buffers.reserve
    • tune.bufsize
    • tune.bufsize.large
    • tune.bufsize.small
    • tune.cli.max-payload-size
    • tune.comp.maxlevel
    • tune.defaults.purge
    • tune.disable-fast-forward
    • tune.disable-zero-copy-forwarding
    • tune.epoll.mask-events
    • tune.events.max-events-at-once
    • tune.fail-alloc
    • tune.fd.edge-triggered
    • tune.h1.be.glitches-threshold
    • tune.h1.fe.glitches-threshold
    • tune.h1.zero-copy-fwd-recv
    • tune.h1.zero-copy-fwd-send
    • tune.h2.be.glitches-threshold
    • tune.h2.be.initial-window-size
    • tune.h2.be.max-concurrent-streams
    • tune.h2.be.max-frames-at-once
    • tune.h2.be.rxbuf
    • tune.h2.fe.glitches-threshold
    • tune.h2.fe.initial-window-size
    • tune.h2.fe.max-concurrent-streams
    • tune.h2.fe.max-frames-at-once
    • tune.h2.fe.max-rst-at-once
    • tune.h2.fe.max-total-streams
    • tune.h2.fe.rxbuf
    • tune.h2.header-table-size
    • tune.h2.initial-window-size
    • tune.h2.max-concurrent-streams
    • tune.h2.max-frame-size
    • tune.h2.zero-copy-fwd-send
    • tune.http.cookielen
    • tune.http.logurilen
    • tune.http.maxhdr
    • tune.idle-pool.shared
    • tune.idletimer
    • tune.lua.bool-sample-conversion
    • tune.lua.burst-timeout
    • tune.lua.forced-yield
    • tune.lua.log.loggers
    • tune.lua.log.stderr
    • tune.lua.maxmem
    • tune.lua.openlibs
    • tune.lua.service-timeout
    • tune.lua.session-timeout
    • tune.lua.task-timeout
    • tune.max-checks-per-thread
    • tune.maxaccept
    • tune.maxpollevents
    • tune.maxrewrite
    • tune.max-rules-at-once
    • tune.memory.hot-size
    • tune.pattern.cache-size
    • tune.peers.max-updates-at-once
    • tune.pipesize
    • tune.pool-high-fd-ratio
    • tune.pool-low-fd-ratio
    • tune.pt.zero-copy-forwarding
    • tune.quic.be.cc.cubic-min-losses
    • tune.quic.be.cc.hystart
    • tune.quic.be.cc.max-frame-loss
    • tune.quic.be.cc.max-win-size
    • tune.quic.be.cc.reorder-ratio
    • tune.quic.be.max-idle-timeout
    • tune.quic.be.sec.glitches-threshold
    • tune.quic.be.stream.data-ratio
    • tune.quic.be.stream.max-concurrent
    • tune.quic.be.stream.rxbuf
    • tune.quic.be.tx.pacing
    • tune.quic.be.tx.udp-gso
    • tune.quic.cc.cubic.min-losses (obsolète)
    • tune.quic.cc-hystart (obsolète)
    • tune.quic.disable-tx-pacing (obsolète)
    • tune.quic.disable-udp-gso (obsolète)
    • tune.quic.fe.cc.cubic-min-losses
    • tune.quic.fe.cc.hystart
    • tune.quic.fe.cc.max-frame-loss
    • tune.quic.fe.cc.max-win-size
    • tune.quic.fe.cc.reorder-ratio
    • tune.quic.frontal.max-idle-timeout
    • tune.quic.frontal.sec.glitches-threshold
    • tune.quic.frontal.sec.retry-threshold
    • tune.quic.frontal.sock-per-conn
    • tune.quic.frontal.stream.data-ratio
    • tune.quic.frontal.stream.max-concurrent
    • tune.quic.frontal.stream.max-total
    • tune.quic.frontal.stream.rxbuf
    • tune.quic.frontal.tx.pacing
    • tune.quic.frontal.tx.udp-gso
    • tune.quic.frontal.max-data-size (obsolète)
    • tune.quic.frontal.max-idle-timeout (obsolète)
    • tune.quic.frontal.max-streams-bidi (obsolète)
    • tune.quic.frontal.max-tx-mem (obsolète)
    • tune.quic.frontal.stream-data-ratio (obsolète)
    • tune.quic.frontal.default-max-window-size (obsolète)
    • tune.quic.ecoute
    • tune.quic.max-frame-loss (obsolète)
    • tune.quic.mem.tx-max
    • tune.quic.reorder-ratio (obsolète)
    • tune.quic.retry-threshold (obsolète)
    • tune.quic.socket-owner (obsolète)
    • tune.quic.zero-copy-fwd-send
    • tune.renice.runtime
    • tune.renice.startup
    • tune.rcvbuf.backend
    • tune.rcvbuf.client
    • tune.rcvbuf.frontend
    • tune.rcvbuf.server
    • tune.recv_enough
    • tune.ring.queues
    • tune.runqueue-depth
    • tune.sched.low-latency
    • tune.sndbuf.backend
    • tune.sndbuf.client
    • tune.sndbuf.frontend
    • tune.sndbuf.server
    • tune.streams-elasticity
    • tune.stick-counters
    • tune.ssl.cachesize
    • tune.ssl.capture-buffer-size
    • tune.ssl.capture-cipherlist-size (obsolète)
    • tune.ssl.certificate-compression
    • tune.ssl.default-dh-param
    • tune.ssl.force-private-cache
    • tune.ssl.hard-maxrecord
    • tune.ssl.keylog
    • tune.ssl.keyupdate-rate-limit
    • tune.ssl.lifetime
    • tune.ssl.maxrecord
    • tune.ssl.ssl-ctx-cache-size
    • tune.ssl.ocsp-update.maxdelay (obsolète)
    • tune.ssl.ocsp-update.mindelay (obsolète)
    • tune.takeover-other-tg-connections
    • tune.vars.global-max-size
    • tune.vars.proc-max-size
    • tune.vars.reqres-max-size
    • tune.vars.sess-max-size
    • tune.vars.txn-max-size
    • tune.zlib.memlevel
    • tune.zlib.windowsize
  • Débogage

    • anonkey
    • debug.counters
    • force-cfg-parser-pause
    • quiet
    • warn-blocked-traffic-after
    • zero-warning
  • HTTPClient

    • httpclient.resolvers.disabled
    • httpclient.resolvers.id
    • httpclient.resolvers.prefer
    • httpclient.retries
    • httpclient.ssl.ca-file
    • httpclient.ssl.verify
    • httpclient.timeout.connect

3.1. Gestion des processus et sécurité

51degrees-data-file <file path>

51degrees-data-file <file path>

Chemin du fichier de données 51Degrees à utiliser pour fournir les services de détection de périphérique. Le fichier doit être décompressé et accessible par HAProxy, avec les autorisations appropriées.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES.

51degrees-property-name-list [<string> ...]

51degrees-property-name-list [<string> ...]

Une liste de noms de propriétés 51Degrees à charger à partir de l’ensemble de données. Une liste complète des noms est disponible sur le site web 51Degrees : https://51degrees.com/resources/property-dictionary

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES.

51degrees-property-separator <char>

51degrees-property-separator <char>

Caractère ajouté à la fin de chaque valeur de propriété dans un en-tête de réponse contenant des résultats 51Degrees. Si non défini, la valeur par défaut est « , ».

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES.

51degrees-cache-size <number>

51degrees-cache-size <number>

Définit la taille du cache du convertisseur 51Degrees à <number> entrées. Il s’agit d’un cache LRU qui conserve les détections précédentes de périphériques et leurs résultats. Par défaut, ce cache est désactivé.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES.

51degrees-use-performance-graph { on | off }

51degrees-use-performance-graph { on | off }

Active (‘on’) ou désactive (‘off’) l’utilisation du graphe de performance dans le processus de détection. La valeur par défaut dépend de la bibliothèque 51Degrees.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES et 51DEGREES_VER=4.

51degrees-use-predictive-graph { on | off }

51degrees-use-predictive-graph { on | off }

Active (‘on’) ou désactive (‘off’) l’utilisation du graphe prédictif dans le processus de détection. La valeur par défaut dépend de la bibliothèque 51Degrees.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES et 51DEGREES_VER=4.

51degrees-drift <number>

51degrees-drift <number>

Définit la valeur de dérive que la détection peut autoriser.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES et 51DEGREES_VER=4.

51degrees-difference <number>

51degrees-difference <number>

Définit la valeur de différence autorisée par une détection.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES et 51DEGREES_VER=4.

51degrees-allow-unmatched { on | off }

51degrees-allow-unmatched { on | off }

Active (‘on’) ou désactive (‘off’) l’utilisation des nœuds non appariés dans le processus de détection. La valeur par défaut dépend de la bibliothèque 51Degrees.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_51DEGREES et 51DEGREES_VER=4.

acme.scheduler { auto | off }

acme.scheduler { auto | off }

Active ou désactive le planificateur ACME.

Le planificateur ACME démarre au démarrage de HAProxy. Il parcourt les certificats et lance une tâche de renouvellement ACME lorsque la valeur notAfter est dépassée de curtime + (notAfter - notBefore) / 12, ou de 7 jours si notBefore n’est pas définie. Le planificateur s’endort ensuite et se réveille après 12 heures.

La valeur par défaut est « auto ».

Voir aussi : acme

ca-base <dir>

ca-base <dir>

Attribue un répertoire par défaut pour récupérer les certificats CA et les listes de révocation de certificats (CRL) lorsqu’un chemin relatif est utilisé avec les directives « ca-file », « ca-verify-file » ou « crl-file ». Les emplacements absolus spécifiés dans « ca-file », « ca-verify-file » et « crl-file » ont la priorité et ignorent « ca-base ».

chroot { <jail dir> | auto }

chroot { <jail dir> | auto }

Change le répertoire courant vers <jail dir> et effectue un chroot() dans ce répertoire avant de réduire les privilèges. Cela augmente le niveau de sécurité en cas d’exploitation d’une vulnérabilité inconnue, car cela rend très difficile pour l’attaquant d’exploiter le système. Il est essentiel de s’assurer que <jail dir> est à la fois vide et non accessible en écriture par quiconque. Lorsque le processus est lancé avec des privilèges de superutilisateur, le chroot() est effectué directement. Sur Linux, lorsqu’il est lancé sans privilèges, HAProxy tente de l’effectuer depuis un nouvel espace utilisateur créé avec unshare(CLONE_NEWUSER); si ce mécanisme n’est pas disponible, le chroot() échoue avec l’erreur habituelle.

En tant que cas particulier, <jail dir> peut être défini sur « auto », auquel cas HAProxy crée un répertoire temporaire anonyme, le supprime, puis effectue un chroot dedans. La prison résultante n’a pas de nom dans le système de fichiers, est vide et en lecture seule, ce qui élimine la nécessité de préparer un répertoire dédié pour la prison.

Lorsque HAProxy est lancé avec des privilèges de superutilisateur, un avertissement est affiché si aucun chroot n’est utilisé, afin d’encourager les utilisateurs à toujours utiliser ce mécanisme. Si, pour une raison quelconque, il existe une raison impérative de ne pas utiliser chroot (par exemple, l’accès à un serveur via un socket UNIX dont le chemin est peu pratique), il reste possible de supprimer l’avertissement en ajoutant explicitement « chroot / », ce qui présente l’avantage d’être visible dans la configuration.

close-spread-time <time>

close-spread-time <time>

Définir une fenêtre de temps pendant laquelle les connexions inactives et les connexions actives en cours de fermeture sont réparties en cas d’arrêt doux. Après la réception d’un SIGUSR1 et l’expiration de la période de grâce (le cas échéant), les connexions inactives seront toutes fermées en même temps si cette option n’est pas définie, et les connexions HTTP actives ou HTTP2 seront terminées après la réception de la requête suivante, soit en ajoutant une ligne « Connection: close » à la réponse HTTP, soit en envoyant un cadre GOAWAY en cas de HTTP2. Lorsque cette option est définie, la fermeture des connexions sera répartie sur cette fenêtre <time>. Si le délai de répartition de la fermeture est défini sur « infinite », la fermeture des connexions actives pendant un arrêt doux sera désactivée. L’en-tête « Connection: close » ne sera plus ajouté aux réponses HTTP (ni GOAWAY pour HTTP2) et les connexions inactives ne seront fermées qu’une fois leur délai d’expiration atteint (selon les délais configurés).

Arguments :

<time>  is a time window (by default in milliseconds) during which
        connection closing will be spread during a soft-stop operation, or
        "infinite" if active connection closing should be disabled.

Il est recommandé de définir ce paramètre à une valeur inférieure à celle utilisée dans l’option « hard-stop-after », si celle-ci est utilisée, afin que toutes les connexions aient la possibilité de se fermer correctement avant l’arrêt du processus.

Voir aussi : grace, hard-stop-after, idle-close-on-response

cluster-secret <secret>

cluster-secret <secret>

Définir une chaîne ASCII secrète partagée entre plusieurs nœuds appartenant au même cluster. Elle peut être utilisée à différentes fins. Elle est notamment utilisée pour dériver des jetons de réinitialisation sans état pour toutes les connexions QUIC instanciées par ce processus. C’est également le cas pour dériver les secrets utilisés pour chiffrer les jetons Retry.

Si ce paramètre n’est pas défini, une valeur aléatoire sera sélectionnée au démarrage du processus. Cela permet d’utiliser des fonctionnalités qui en dépendent, bien que certaines limitations s’appliquent.

cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>[,...] [...]

cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>[,...] [...]

Sur certains systèmes d’exploitation, il est possible d’attribuer un groupe de threads ou un thread à un ensemble spécifique de processeurs. Cela signifie que les threads désignés ne s’exécuteront jamais sur d’autres processeurs. La directive « cpu-map » spécifie les ensembles de processeurs pour des threads individuels ou des groupes de threads. Le premier argument est une plage de groupes de threads, suivie éventuellement d’un ensemble de threads. Ces plages ont le format suivant :

all | odd | even | number[-[number]]

<number> doit être un nombre compris entre 1 et 32 ou 64, selon la taille mot de la machine. Tous les identifiants de groupe au-dessus de « thread-groups » et tous les identifiants de thread au-dessus de la taille mot de la machine sont ignorés. Tous les numéros de thread sont relatifs au groupe auquel ils appartiennent. Il est possible de spécifier une plage en utilisant deux tels nombres séparés par un trait d’union (’-’). Il est également possible de spécifier tous les threads à la fois en utilisant « all », uniquement les nombres impairs en utilisant « odd » ou les nombres pairs en utilisant « even », tout comme avec la directive « thread » bind. Les seconds et futurs arguments sont des ensembles de processeurs. Chaque ensemble de processeurs est soit un nombre unique commençant à 0 pour le premier processeur, soit une plage composée de deux tels nombres séparés par un trait d’union (’-’). Ces numéros de processeur et plages peuvent être répétés en les séparant par des virgules ou en ajoutant de nouvelles plages en tant qu’arguments supplémentaires sur la même ligne. Hors des systèmes d’exploitation Linux et BSD, il peut y avoir une limitation sur l’indice maximal de processeur à 31 ou 63. Plusieurs directives « cpu-map » peuvent être spécifiées, mais chaque directive « cpu-map » remplace les précédentes lorsqu’elles se chevauchent.

Les plages peuvent être définies partiellement. La borne supérieure peut être omise. Dans ce cas, elle est remplacée par la valeur maximale correspondante, 32 ou 64 selon la taille du mot machine.

Le préfixe « auto: » peut être ajouté avant l’ensemble de threads pour permettre à HAProxy de lier automatiquement un ensemble de threads à un processeur en incrémentant les threads et les ensembles de processeurs. Pour être valide, les deux ensembles doivent avoir la même taille. Quel que soit l’ordre de déclaration des ensembles de processeurs, le lien s’établit du plus bas au plus élevé. Il n’est pas pris en charge d’avoir à la fois un groupe et une plage de threads avec le préfixe « auto: ». Une seule plage est prise en charge ; l’autre doit être un nombre fixe.

Notez que les plages de groupes sont prises en charge pour des raisons historiques. De nos jours, un nombre isolé désigne un groupe de threads et doit valoir 1 si les groupes de threads ne sont pas utilisés, et spécifier une plage ou un nombre de threads exige d’ajouter “1/” devant s’ils ne sont pas utilisés. Enfin, “1” est strictement équivalent à “1/all” et désigne tous les threads du groupe.

Exemples :

cpu-map 1/all 0-3 # bind all threads of the first group on the
                  # first 4 CPUs

cpu-map 1/1- 0-   # will be replaced by "cpu-map 1/1-64 0-63"
                  # or "cpu-map 1/1-32 0-31" depending on the machine's
                  # word size.

# all these lines bind thread 1 to the cpu 0, the thread 2 to cpu 1
# and so on.
cpu-map auto:1/1-4   0-3
cpu-map auto:1/1-4   0-1 2-3
cpu-map auto:1/1-4   3 2 1 0
cpu-map auto:1/1-4   3,2,1,0

# bind each thread to exactly one CPU using all/odd/even keyword
cpu-map auto:1/all   0-63
cpu-map auto:1/even  0-31
cpu-map auto:1/odd   32-63

# invalid cpu-map because thread and CPU sets have different sizes.
cpu-map auto:1/1-4   0    # invalid
cpu-map auto:1/1     0-3  # invalid

# map 40 threads of those 4 groups to individual CPUs
cpu-map auto:1/1-10   0-9
cpu-map auto:2/1-10   10-19
cpu-map auto:3/1-10   20-29
cpu-map auto:4/1-10   30-39

# Map 80 threads to one physical socket and 80 others to another socket
# without forcing assignment. These are split into 4 groups since no
# group may have more than 64 threads.
cpu-map 1/1-40   0-39,80-119    # node0, siblings 0 & 1
cpu-map 2/1-40   0-39,80-119
cpu-map 3/1-40   40-79,120-159  # node1, siblings 0 & 1
cpu-map 4/1-40   40-79,120-159

cpu-affinity <affinity>

cpu-affinity <affinity>

Définit la manière dont les threads doivent être liés aux processeurs. Il accepte actuellement les valeurs suivantes :

  • par-cœur : chaque thread sera lié à tous les threads matériels d’un cœur.
  • par-groupe : chaque thread sera lié à tous les threads matériels du groupe. C’est le comportement par défaut, sauf si « threads-per-core 1 » est utilisé dans « cpu-policy ». « par-groupe » accepte un argument facultatif, permettant de préciser la manière dont les processeurs doivent être alloués. Lorsqu’une liste de processeurs est plus grande que le nombre maximal de processeurs par groupe autorisé et doit être répartie entre plusieurs groupes, une option supplémentaire permet de choisir la manière dont les groupes seront liés à ces processeurs :
    • auto : chaque groupe de threads ne sera affecté qu’à une part équitable de cœurs processeurs contigus, dédiés exclusivement à ce groupe et non partagés avec d’autres groupes. C’est le comportement par défaut, car il est généralement plus optimal.
    • lache : chaque groupe pourra toujours utiliser n’importe quel processeur de la liste. Cela entraîne généralement plus de contention, mais peut parfois aider à mieux gérer les charges parasites s’exécutant sur les mêmes processeurs.
  • auto : la valeur « per-group » sera utilisée, sauf si « threads-per-core 1 » est spécifié dans « cpu-policy », auquel cas la valeur « per-core » sera utilisée. Cette option est la valeur par défaut.
  • per-thread : chaque thread sera lié à un seul thread matériel. Si « threads-per-core 1 » est utilisé dans « cpu-policy », chaque thread sera lié à un thread matériel d’un cœur différent.
  • per-ccx : chaque thread sera lié à tous les threads matériels d’un CCX.

cpu-policy <policy> [threads-per-core 1 | auto]

cpu-policy <policy> [threads-per-core 1 | auto]

Sélectionne la politique d’allocation du CPU à utiliser.

Sur les systèmes multi-CPU, plusieurs raisons peuvent justifier de ne pas utiliser tous les cœurs disponibles, and/or afin de les regrouper en groupes de threads distincts, pour des raisons de performance, de latence, de coût ou de gestion des ressources au niveau du système. La directive « cpu-set » permet déjà d’exclure un certain nombre de cœurs, mais une fois cette opération effectuée, il est nécessaire de décider comment affecter les cœurs restants aux threads et groupes de threads.

Ce mappage est généralement effectué à l’aide de la directive « cpu-map », bien qu’il puisse être particulièrement difficile à maintenir sur des systèmes hétérogènes.

La directive « cpu-policy » permet de choisir parmi un petit nombre de politiques d’allocation à utiliser à la place lorsque « cpu-map » n’est pas utilisée. Les politiques suivantes sont actuellement prises en charge, « performance » étant la politique par défaut :

  • none aucun post-traitement particulier n’est effectué. Tous les processeurs activés seront utilisables, et si le nombre de threads n’est pas défini, il sera fixé au nombre de processeurs disponibles, mais sans dépasser 32 sur les systèmes 32 bits ou 64 sur les systèmes 64 bits, par groupe de threads. Le nombre de groupes de threads, s’il n’est pas défini, sera fixé à 1.

  • efficacité, exactement comme « group-by-ccx » ci-dessous, sauf que les clusters de CPU composés de cœurs dont les performances dépassent de plus de 25 % celles du cœur suivant moins performant sont exclus. Ce sont généralement des cœurs « big » ou « performance ». Cela signifie qu’en cas de détection de plusieurs types de cœurs de CPU, seul le cœur efficace sera utilisé. Cette configuration peut être pertinente en cas de charges modérées lorsque les cœurs les plus puissants doivent être disponibles pour une application ou un composant de sécurité. Certains processeurs modernes disposent d’un grand nombre de tels cœurs efficaces, capables collectivement de fournir un niveau de performance acceptable tout en consommant moins d’énergie.

  • premier nœud utilisable si les processeurs n’ont pas été précédemment restreints au démarrage (par exemple à l’aide de l’outil “taskset”), et si la directive “nbthread” n’a pas été définie, alors le premier nœud NUMA ayant des processeurs activés sera utilisé, et ce nombre de processeurs sera utilisé comme nombre de threads. Un seul groupe de threads sera activé avec tous ceux-ci, dans la limite de 32 ou 64 selon le système.

  • group-by-2-ccx identique à « group-by-ccx » ci-dessous, mais crée un groupe tous les deux CCX. Cela peut être pertinent sur des processeurs disposant de nombreux CCX comportant peu de cœurs chacun, afin d’éviter de créer trop de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’il peut entraîner des effets très négatifs sur les performances lorsque la communication entre CCX est lente. Cette option est généralement déconseillée.

  • group-by-2-clusters : identique à « group-by-cluster », mais crée un groupe tous les deux clusters. Cela peut être pertinent sur des processeurs disposant de nombreux clusters comprenant chacun peu de cœurs, afin d’éviter de créer trop de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’il peut entraîner des effets très négatifs sur les performances lorsque la communication entre les clusters est lente. Cette option est généralement déconseillée.

  • group-by-3-ccx identique à « group-by-ccx » ci-dessous, mais crée un groupe tous les trois CCX. Cela peut être pertinent sur des processeurs disposant de nombreux CCX à faible nombre de cœurs chacun, afin d’éviter de créer trop de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’une telle configuration peut entraîner des effets très négatifs sur les performances lorsque la communication entre CCX est lente. Cette option est généralement déconseillée.

  • group-by-3-clusters : identique à « group-by-cluster », mais crée un groupe tous les trois clusters. Cela peut être pertinent sur des processeurs disposant de nombreux clusters comprenant chacun peu de cœurs, afin d’éviter de créer un trop grand nombre de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’une telle configuration peut entraîner des effets néfastes sur les performances lorsque la communication entre les clusters est lente. Cette configuration est généralement déconseillée.

  • group-by-4-ccx identique à « group-by-ccx » ci-dessous, mais crée un groupe tous les quatre CCX. Cela peut être pertinent sur des processeurs disposant de nombreux CCX à faible nombre de cœurs chacun, afin d’éviter de créer trop de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’une telle configuration peut entraîner des effets très négatifs sur les performances lorsque la communication entre CCX est lente. Cette option est généralement déconseillée.

  • group-by-4-clusters : identique à « group-by-cluster », mais crée un groupe tous les quatre clusters. Cela peut être pertinent sur des processeurs disposant de nombreux clusters comprenant chacun peu de cœurs, afin d’éviter de créer trop de groupes, ou pour lisser légèrement la répartition lorsque tous les cœurs ne sont pas utilisés. Veuillez noter qu’il peut entraîner des effets très négatifs sur les performances lorsque la communication entre les clusters est lente. Cette option est généralement déconseillée.

  • group-by-ccx si ni « nbthread » ni « nbtgroups » ne sont définis, un groupe de threads est créé pour chaque complexe de processeurs (« CCX ») disposant de processeurs disponibles, chaque groupe comportant autant de threads que de processeurs. Un CCX regroupe des processeurs ayant un accès similairement rapide à la mémoire cache de niveau supérieur (« LLC »), généralement la L3 cache. Sur la plupart des machines modernes, il est essentiel pour les performances de ne pas mélanger des processeurs provenant de CCX éloignés au sein du même groupe de threads. Tous les threads d’un groupe sont ensuite liés à tous les processeurs du CCX, afin que les communications intra-groupe restent locales au CCX sans imposer un lien trop strict. Les limites par groupe de threads et les limites des groupes de threads sont respectées. Cette configuration est recommandée sur les systèmes multi-socket et NUMA, ainsi que sur les processeurs présentant des latences inter-CCX élevées.

  • group-by-cluster si ni « nbthread » ni « nbtgroups » ne sont définis, un groupe de threads est créé pour chaque cluster de processeur disposant de processeurs disponibles, chacun avec autant de threads que de processeurs. Tous les threads d’un groupe sont liés à tous les processeurs du cluster afin que les communications intra-groupe restent locales au cluster sans imposer une liaison trop stricte. Les limites par groupe de threads et les limites des groupes de threads sont respectées. Cette configuration est recommandée sur les systèmes multi-socket et NUMA, ainsi que sur les processeurs présentant de mauvaises latences inter-CCX. Sur la plupart des machines serveur, les clusters et les CCX sont identiques, mais sur les machines hétérogènes (« performance » vs « efficacité » ou « big » vs « little »), un cluster est généralement constitué d’une partie d’un CCX composée uniquement de processeurs très similaires (même type, différence de fréquence maximale de +/-5%). Cette différence est visible sur les ordinateurs portables et les postes de travail modernes utilisés par les développeurs et les administrateurs pour valider les configurations.

  • performances identiques à celles de « group-by-ccx » ci-dessus, à ceci près que les clusters CPU composés de cœurs dont les performances sont inférieures à 80 % de celles du cœur suivant plus performant sont exclus. Ce sont généralement des cœurs « petits » ou « efficaces », dont l’ajout apporte généralement peu de gains significatifs et peut facilement être contre-productif (par exemple, lors des échanges TLS). En général, conserver ces cœurs pour d’autres tâches, comme la gestion du réseau, s’avère bien plus efficace. Sur les systèmes de développement, ils peuvent également être utilisés pour exécuter des outils auxiliaires tels que des générateurs de charge ou des outils de surveillance. Il s’agit de la politique par défaut.

  • ressource qui fonctionne comme « group-by-cluster » ci-dessus, sauf que seul le cluster CPU le plus petit et le plus efficace sera utilisé, tandis que tous les autres seront ignorés. Cela peut être utilisé pour limiter l’utilisation des ressources au strict minimum permettant encore des performances décentes, par exemple pour réduire davantage la consommation d’énergie ou minimiser le nombre de cœurs nécessaires sur certains systèmes loués dans une configuration sidecar, afin de faciliter la mise à l’échelle du système vers le bas. Notez qu’en cas de présence d’un seul cluster, celui-ci sera toutefois entièrement utilisé.

Un mot-clé facultatif peut être ajouté : « threads-per-core ». Il peut accepter deux valeurs : « 1 » et « auto ». Si réglé sur « 1 », alors une seule thread par cœur sera créée, indépendamment du nombre de threads matériels que possède le cœur. Si réglé sur « auto », alors une thread sera créée par thread matériel. Si aucune affinité n’est spécifiée et que « threads-per-core 1 » est utilisé, alors l’affinité sera par défaut par cœur.

Voir aussi : « cpu-map », « cpu-set », « nbthread »

cpu-set <directive>...

cpu-set <directive>...

Permet de décrire de manière symbolique les ensembles de processeurs sur lesquels s’exécuter. La directive prend en charge les mots-clés suivants : - reset : annule toute limitation précédente qui aurait pu être héritée par un gestionnaire de services ou une commande « taskset », par exemple. - drop-cpu <set> : ne pas lier aux processeurs de cet ensemble. - only-cpu <set> : ne pas lier aux processeurs n’appartenant pas à cet ensemble. - drop-node <set> : ne pas lier aux processeurs appartenant à cette nœud NUMA. - only-node <set> : ne pas lier aux processeurs n’appartenant pas à ce nœud NUMA. - drop-cluster <set> : ne pas lier aux processeurs de ce numéro de cluster matériel. - only-cluster <set> : ne pas lier aux processeurs d’autres numéros de cluster matériel. - drop-core <set> : ne pas lier aux processeurs de ce numéro de cœur matériel. - only-core <set> : ne pas lier aux processeurs d’autres numéros de cœur matériel. - drop-thread <set> : ne pas lier aux processeurs de ce numéro de thread matériel. - only-thread <set> : ne pas lier aux processeurs d’autres numéros de thread matériel. Voir également : « cpu-policy »

crt-base <dir>

crt-base <dir>

Attribue un répertoire par défaut pour récupérer les certificats SSL lorsqu’un chemin relatif est utilisé avec les directives crtfile ou crt. Les emplacements absolus spécifiés prévalent et ignorent crt-base.

daemon

daemon

Met le processus en arrière-plan. Il s’agit du mode de fonctionnement recommandé. Il équivaut à l’argument de ligne de commande “-D”. Il peut être désactivé par l’argument de ligne de commande “-db”. Cette option est ignorée en mode systemd.

default-path { current | config | parent | origin <path> }

default-path { current | config | parent | origin <path> }

Par défaut, HAProxy charge tous les fichiers dont le chemin est relatif à partir du répertoire depuis lequel le processus est lancé. Dans certains cas, il peut être souhaitable de forcer tous les chemins relatifs à commencer à partir d’un emplacement différent, comme si le processus avait été lancé depuis cet emplacement. C’est précisément l’objectif de cette directive. Techniquement, elle effectue un changement temporaire de répertoire (chdir()) vers l’emplacement désigné pendant le traitement de chaque fichier de configuration, puis revient au répertoire d’origine après avoir traité chaque fichier. Elle prend un argument indiquant la politique à appliquer lors du chargement des fichiers dont le chemin ne commence pas par une barre oblique (’/’): - “current” indique que tous les fichiers relatifs doivent être chargés à partir du répertoire depuis lequel le processus est lancé ; c’est la valeur par défaut.

- "config" indique que tous les fichiers relatifs doivent être chargés à partir du répertoire contenant le fichier de configuration. Plus précisément, si le fichier de configuration contient une barre oblique ('/'), la plus longue partie jusqu'à la dernière barre oblique est utilisée comme répertoire de changement, sinon le répertoire courant est utilisé. Ce mode est pratique pour regrouper des cartes, des fichiers d'erreur, des certificats et des scripts Lua dans des paquets déplaçables. Lorsque plusieurs fichiers de configuration sont chargés, le répertoire est mis à jour pour chacun d'eux.

-  « parent » indique que tous les fichiers relatifs doivent être chargés depuis le répertoire parent du répertoire contenant le fichier de configuration. Plus précisément, si le fichier de configuration contient une barre oblique ('/'), ".." est ajouté au plus long segment jusqu'à la dernière barre oblique, qui est utilisé comme répertoire de changement, sinon le répertoire est "..". Ce mode est pratique pour regrouper des cartes, des fichiers d'erreur, des certificats et des scripts Lua ensemble sous forme de paquets déplaçables, tout en permettant à chaque composant d'être situé dans un sous-répertoire différent (par exemple, « config/ », « certs/ », « maps/ », ...).

-  « origin » indique que tous les fichiers relatifs doivent être chargés à partir du chemin désigné (obligatoire). Cette option peut être utilisée pour simplifier la gestion de plusieurs instances HAProxy s'exécutant en parallèle sur un système, où chaque instance utilise un préfixe différent, tout en rendant le reste des sections facilement déplaçables.

Chaque directive « default-path » remplace instantanément toute directive précédente et peut entraîner un changement de répertoire. Bien que cela doive toujours entraîner le comportement souhaité, il ne s’agit pas d’une bonne pratique d’utiliser plusieurs directives default-path, et si elles sont utilisées, la politique doit rester cohérente dans tous les fichiers de configuration.

Avertissement : certains éléments de configuration, tels que les cartes ou les certificats, sont identifiés de manière unique par leur chemin configuré. En utilisant une disposition déplaçable, il devient possible que plusieurs d’entre eux se retrouvent avec le même nom unique, ce qui rend difficile leur mise à jour en cours d’exécution, en particulier lorsque plusieurs fichiers de configuration sont chargés depuis des répertoires différents. Il est essentiel d’observer une stratégie stricte de nommage de fichiers sans collision avant d’adopter des chemins relatifs. Une approche robuste pourrait consister à préfixer tous les noms de fichiers par le nom du site correspondant, ou à le faire au niveau du répertoire.

description <text>

description <text>

Ajoutez un texte qui décrit l’instance.

Veuillez noter qu’il est nécessaire d’échapper certains caractères (par exemple #) et que ce texte est inséré dans une page HTML, vous devez donc éviter d’utiliser les caractères “<” et “>”.

deviceatlas-json-file <path>

deviceatlas-json-file <path>

Définit le chemin du fichier de données JSON DeviceAtlas à charger par l’API. Le chemin doit désigner un fichier JSON valide et être accessible au processus HAProxy.

deviceatlas-log-level <value>

deviceatlas-log-level <value>

Définit le niveau d’information retourné par l’API. Cette directive est facultative et vaut 0 par défaut si non définie.

deviceatlas-properties-cookie <name>

deviceatlas-properties-cookie <name>

Définit le nom du cookie client utilisé pour détecter si le composant côté client DeviceAtlas a été utilisé lors de la requête. Cette directive est facultative et vaut DAPROPS par défaut si elle n’est pas définie.

deviceatlas-separator <char>

deviceatlas-separator <char>

Définit le séparateur de caractères pour les résultats des propriétés de l’API. Cette directive est facultative et vaut | par défaut si elle n’est pas définie.

dns-accept-family <family>[,...]

dns-accept-family <family>[,...]

Par défaut, les résolveurs DNS acceptent à la fois les adresses IPv4 et IPv6. Ce comportement peut être influencé par les mots-clés « resolve-prefer » dans les lignes server, ainsi que par l’argument family de l’action « do-resolve », mais il s’agit uniquement d’une préférence qui ne bloque pas l’utilisation de l’autre famille lorsque celle-ci est la seule disponible. Dans certains environnements où le double empilement n’est pas utilisable, la découverte d’un enregistrement DNS inaccessible uniquement en IPv6 peut entraîner des problèmes importants, car il remplacerait un enregistrement IPv4 précédent qui aurait pu continuer à fonctionner jusqu’à la requête suivante. L’option globale « dns-accept-family » permet d’imposer l’utilisation d’une seule famille d’adresses (ou des deux). L’argument est une liste séparée par des virgules des mots suivants : - « ipv4 » : interroger et accepter les adresses IPv4 (enregistrements « A ») - « ipv6 » : interroger et accepter les adresses IPv6 (enregistrements « AAAA ») - « auto » : utiliser IPv4, et IPv6 si le système dispose d’une passerelle par défaut pour celle-ci. Le résultat de la dernière vérification est mis en cache pendant 30 secondes.

Lorsqu’une seule famille est utilisée, aucune requête n’est envoyée aux résolveurs pour l’autre famille, et toute réponse provenant de cette dernière est ignorée. La valeur par défaut depuis la version 3.3 est « auto », qui active effectivement les deux familles uniquement une fois que l’IPv6 a été vérifié comme routable, sinon elle reste sur IPv4. Voir également : « resolve-prefer », « do-resolve »

expose-deprecated-directives

expose-deprecated-directives

Cette instruction doit apparaître avant d’utiliser certains directives marquées comme obsolètes afin de supprimer les avertissements et de garantir que le fichier de configuration ne sera pas rejeté. Toutes les directives obsolètes ne sont pas concernées, uniquement celles pour lesquelles aucune solution de remplacement n’existe.

expose-experimental-directives

expose-experimental-directives

Cette directive doit apparaître avant toute utilisation de directives marquées comme expérimentales, faute de quoi le fichier de configuration sera rejeté. Veuillez noter que les fonctionnalités couvertes par cette option ne sont pas garanties d’être stables et peuvent présenter des dysfonctionnements pendant le cycle de maintenance. Les développeurs les maintiendront dans un état de meilleur effort pendant la mise au point de la prochaine version, et s’efforceront de toute évidence d’éviter toute rupture, sans garantie. Pour ces raisons, ces fonctionnalités ne sont pas censées être prises en charge au-delà du lancement de la prochaine version LTS. Les utilisateurs souhaitant expérimenter ces fonctionnalités sont invités à effectuer une mise à jour rapide afin de bénéficier des améliorations apportées à ces fonctionnalités. Pour savoir si cette directive est encore nécessaire, il est simple : si elle est activée sans être utilisée par une telle fonctionnalité, un avertissement sera émis pour suggérer de la désactiver. Ainsi, en l’absence d’avertissement, cela signifie qu’elle est encore nécessaire.

external-check [preserve-env]

external-check [preserve-env]

Permet d’utiliser un agent externe pour effectuer les contrôles d’état. Cette fonctionnalité est désactivée par défaut en tant que mesure de sécurité, et même activée, les contrôles peuvent échouer sauf si « insecure-fork-wanted » est également activé. Si le programme lancé utilise un exécutable setuid (ce qui devrait en réalité être évité), vous devrez peut-être également définir « insecure-setuid-wanted » dans la section globale. Par défaut, les contrôles démarrent dans un environnement propre ne contenant que les variables définies dans la commande « external-check » de la section backend. Il peut parfois être souhaitable de préserver l’environnement, par exemple lorsque des scripts complexes récupèrent leurs chemins ou informations supplémentaires à partir de celui-ci. Cela peut être réalisé en ajoutant le mot-clé « preserve-env ». Dans ce cas, il est fortement conseillé de ne pas exécuter le programme en tant qu’utilisateur setuid ni en tant qu’utilisateur privilégié, afin d’éviter toute exposition à des attaques potentielles. Voir « option external-check », « insecure-fork-wanted » et « insecure-setuid-wanted » pour plus de détails.

fd-hard-limit <number>

fd-hard-limit <number>

Définit une limite supérieure au nombre maximum de descripteurs de fichiers utilisés par le processus, indépendamment des limites système. Bien que les paramètres « ulimit-n » et « maxconn » puissent être utilisés pour imposer une valeur, lorsque ces paramètres ne sont pas définis, le processus sera limité à la limite dure du paramètre RLIMIT_NOFILE tel que rapporté par la commande « ulimit -n -H ». Toutefois, certains systèmes d’exploitation modernes autorisent désormais des valeurs extrêmement élevées ici (de l’ordre d’un milliard), ce qui consommerait bien trop de mémoire vive pour une utilisation régulière. Le paramètre fd-hard-limit est fourni afin d’imposer une limite éventuellement plus basse à cette limite. Cela signifie qu’il respectera toujours les limites imposées par le système lorsqu’elles sont inférieures à <number>, mais utilisera la valeur spécifiée si les limites imposées par le système sont plus élevées. Par défaut, fd-hard-limit est défini à 1048576. Cette valeur par défaut peut être modifiée via la variable de compilation DEFAULT_MAXFD, qui peut servir de limite maximale (noyau) système, si la limite dure RLIMIT_NOFILE est extrêmement élevée. La définition de fd-hard-limit dans la section globale permet de remplacer temporairement la valeur fournie via DEFAULT_MAXFD au moment de la compilation. Dans l’exemple ci-dessous, aucune autre configuration n’est spécifiée et la valeur de maxconn s’ajustera automatiquement à la plus faible entre « fd-hard-limit » et la limite RLIMIT_NOFILE.

global
    # use as many FDs as possible but no more than 50000
    fd-hard-limit 50000

Voir aussi : ulimit-n, maxconn

gid <number>

gid <number>

Change l’identifiant de groupe du processus en <number>. Il est recommandé que cet identifiant de groupe soit dédié à HAProxy ou à un petit ensemble de démons similaires. HAProxy doit être lancé avec un utilisateur appartenant à ce groupe, ou avec des privilèges de superutilisateur. Notez qu’en cas de lancement depuis un utilisateur ayant des groupes supplémentaires, HAProxy ne pourra supprimer ces groupes que s’il est lancé avec des privilèges de superutilisateur. Voir également « group » et « uid ».

grace <time>

grace <time>

Définit un délai entre SIGUSR1 et l’arrêt doux réel.

Arguments :

<time>  is an extra delay (by default in milliseconds) after receipt of the
        SIGUSR1 signal that will be waited for before proceeding with the
        soft-stop operation.

Cela est utilisé pour assurer la compatibilité avec les environnements hérités où le processus HAProxy doit être arrêté, mais où certains composants externes doivent détecter l’état avant que les écouteurs ne soient déliés. Le principe consiste à définir la variable interne « stopping » (qui est rapportée par la fonction d’extraction d’échantillon « stopping ») à true, tout en maintenant l’acceptation des connexions par les écouteurs sans interruption, jusqu’à expiration du délai, après quoi l’arrêt doux classique s’effectuera. Cette option ne doit pas être utilisée avec des processus qui sont rechargés, car cela empêcherait le processus ancien de se délier, et pourrait empêcher le nouveau processus de démarrer, ou simplement provoquer des problèmes.

Exemple :

global
  grace 10s

# Returns 200 OK until stopping is set via SIGUSR1
frontend ext-check
  bind:9999
  monitor-uri /ext-check
  monitor fail if { stopping }

Veuillez noter qu’une approche plus souple et durable consisterait, pour un système d’orchestration, à définir une variable globale depuis la ligne de commande, à utiliser cette variable pour répondre aux vérifications externes, puis à envoyer le signal SIGUSR1 après un délai.

Exemple :

# Returns 200 OK until proc.stopping is set to non-zero. May be done
# from HTTP using set-var(proc.stopping) or from the CLI using:
# > set var proc.stopping int(1)
frontend ext-check
  bind:9999
  monitor-uri /ext-check
  monitor fail if { var(proc.stopping) -m int gt 0 }

Voir aussi : hard-stop-after, monitor

group <group name>

group <group name>

Similaire à « gid » mais utilise le GID du nom de groupe <group name> provenant de /etc/group.. Voir également « gid » et « user ».

h1-accept-payload-with-any-method

h1-accept-payload-with-any-method

N’interdit pas les requêtes HTTP/1.0 GET/HEAD/DELETE dont le corps provoque une réponse HTTP 413 Payload Too Large.

Bien que cela soit explicitement autorisé dans HTTP/1.1, HTTP/1.0 ne précise pas clairement ce point, et certains serveurs anciens ne s’attendent pas à avoir de charge utile et ne vérifient jamais la longueur du corps (via les en-têtes Content-Length ou Transfer-Encoding). Cela signifie que certains intermédiaires peuvent correctement gérer la charge utile pour les requêtes HTTP/1.0 GET/HEAD/DELETE, tandis que d’autres peuvent la ignorer totalement. Cela peut entraîner des problèmes de sécurité, car une attaque de camouflage de requête est possible. Par conséquent, par défaut, HAProxy rejette les requêtes HTTP/1.0 GET/HEAD/DELETE comportant une charge utile.

Toutefois, cela peut poser problème avec certains clients anciens. Dans ce cas, cette option globale peut être configurée.

h1-do-not-close-on-insecure-transfer-encoding

h1-do-not-close-on-insecure-transfer-encoding

Conformément à la spécification HTTP/1.1 (RFC9112#6.1), la présence simultanée d’un champ d’en-tête Transfer-Encoding et d’un champ d’en-tête Content-Length dans un même message représente un risque sérieux d’attaque par camouflage de contenu si un agent HTTP/1.0 se trouve dans la chaîne en amont ou en aval, et, en pareil cas, un agent doit absolument fermer la connexion après la réponse afin d’éviter toute exploitation. Toutefois, cela peut avoir un impact sur les performances avec certains clients très anciens, notamment s’ils doivent renégocier une connexion TLS pour chaque requête. Cette option est mise à disposition afin de demander à HAProxy de ne pas appliquer cette règle, et de ne faire que nettoyer le message tout en maintenant la connexion ouverte après la réponse. Cette action ne peut être entreprise que si l’on est absolument certain qu’aucun agent HTTP/1.0 n’est présent dans la chaîne et que toutes les implémentations situées en amont d’HAProxy sont pleinement conformes à HTTP/1.1 aux règles applicables à ces champs d’en-tête. Dans tous les cas, HAProxy continuera à ignorer et à supprimer le champ Content-Length superflu afin de ne pas induire en erreur le prochain saut.

Lorsqu’on active cette option pour contourner un client ou un serveur ancien défectueux, il est essentiel de comprendre que, qu’il en soit besoin ou non, un tel agent qui enfreint cette règle court le risque d’avoir ses messages tronqués par des agents anciens qui considèrent Content-Length et ignorent Transfer-Encoding, car la taille cumulée des tailles des tronçons encodés n’est pas prise en compte. En conséquence, la règle ci-dessus n’est pas seulement une question de sécurité, mais aussi une mesure visant à éliminer les agents susceptibles de rencontrer des problèmes de communication en raison d’incompatibilités avec des versions plus anciennes.

h1-case-adjust <from> <to>

h1-case-adjust <from> <to>

Définit l’ajustement de casse à appliquer, lorsqu’il est activé, au nom de l’en-tête <from>, pour le convertir en <to> avant de l’envoyer aux clients ou serveurs HTTP/1. <from> doit être en minuscules, et <from> ainsi que <to> doivent ne différer que par leur casse. Cette directive peut être répétée si plusieurs noms d’en-tête doivent être ajustés. Les entrées en double ne sont pas autorisées. Si un grand nombre de noms d’en-tête doivent être ajustés, il peut être plus pratique d’utiliser « h1-case-adjust-file ». Veuillez noter qu’aucune transformation ne sera appliquée à moins que « option h1-case-adjust-bogus-client » ou « option h1-case-adjust-bogus-server » ne soit spécifiée dans un proxy.

Il n’existe pas de cas standard pour les noms d’en-têtes, car, comme indiqué dans RFC7230, ils sont insensibles à la casse. Les applications doivent donc les traiter de manière insensible à la casse. Toutefois, certaines applications incorrectes violent les normes et s’appuient erronément sur les cas les plus couramment utilisés par les navigateurs. Ce problème devient critique avec HTTP/2 car tous les noms d’en-têtes doivent être échangés en minuscules, et HAProxy adopte la même convention. Tous les noms d’en-têtes sont envoyés en minuscules aux clients et aux serveurs, indépendamment de la version HTTP.

Les applications qui ne traitent pas correctement les requêtes ou les réponses peuvent nécessiter l’utilisation temporaire de telles solutions de contournement afin d’ajuster les noms d’en-têtes envoyés pendant la durée nécessaire à la correction de l’application. Veuillez noter qu’une application qui requiert de telles solutions de contournement pourrait être vulnérable aux attaques d’envoi de contenu masqué et doit être corrigée absolument.

Exemple :

global
  h1-case-adjust content-length Content-Length

Voir « h1-case-adjust-file », « option h1-case-adjust-bogus-client » et « option h1-case-adjust-bogus-server ».

h1-case-adjust-file <hdrs-file>

h1-case-adjust-file <hdrs-file>

Définit un fichier contenant une liste de paires key/value utilisées pour ajuster la casse de certains noms d’en-têtes avant de les envoyer aux clients ou serveurs HTTP/1. Le fichier <hdrs-file> doit contenir deux noms d’en-têtes par ligne. Le premier doit être en minuscules, et les deux doivent différer uniquement par leur casse. Les lignes commençant par ‘#’ sont ignorées, tout comme les lignes vides. Les tabulations et espaces en début et fin de ligne sont supprimés. Les entrées en double ne sont pas autorisées. Veuillez noter qu’aucune transformation ne sera appliquée à moins que « option h1-case-adjust-bogus-client » ou « option h1-case-adjust-bogus-server » soit spécifiée dans un proxy.

Si cette directive est répétée, seule la dernière sera traitée. Il s’agit d’une alternative à la directive « h1-case-adjust » lorsque de nombreux noms d’en-têtes doivent être ajustés. Veuillez lire les risques associés à son utilisation.

Voir « h1-case-adjust », « option h1-case-adjust-bogus-client » et « option h1-case-adjust-bogus-server ».

h2-workaround-bogus-websocket-clients

h2-workaround-bogus-websocket-clients
  1. Cela désactive l’annonce de la prise en charge des websockets h2 aux clients. Cela peut être utilisé pour contourner les clients présentant des problèmes lors de l’implémentation du RFC8441 relativement récent, tels que Firefox . Pour permettre aux clients de passer automatiquement à http/1.1 pour le tunnel websocket, spécifiez la prise en charge de h2 dans la ligne bind en utilisant “alpn” sans mot-clé explicite “proto”. Si cette option était précédemment activée, elle peut être désactivée en préfixant le mot-clé par “no”.

hard-stop-after <time>

hard-stop-after <time>

Définit le temps maximum autorisé pour effectuer une extinction douce propre.

Arguments :

<time>  is the maximum time (by default in milliseconds) for which the
        instance will remain alive when a soft-stop is received via the
        SIGUSR1 signal.

Cela peut être utilisé pour garantir que l’instance s’arrête même si des connexions restent ouvertes pendant un arrêt doux (par exemple avec des délais d’expiration longs pour un proxy en mode tcp). Cela s’applique aussi bien en mode TCP qu’en mode HTTP.

Exemple :

global
  hard-stop-after 30s

Voir aussi : grace

harden.reject-privileged-ports.tcp { on | off }

harden.reject-privileged-ports.tcp { on | off }
harden.reject-privileged-ports.quic { on | off }

Protection par protocole activée/désactivée, qui interdit les communications avec les clients utilisant des ports privilégiés comme port source. Cette plage de ports est définie conformément au RFC 6335. Par défaut, la protection est active pour le protocole QUIC, car ce comportement est suspect et peut être utilisé dans le cadre d’une attaque d’usurpation d’identité ou d’amplification DNS/NTP.

http-err-codes [+-]<range>[,...] [...]

http-err-codes [+-]<range>[,...] [...]

Remplace, réduit ou étend la liste des codes d’état qui définissent une erreur selon les codes de terminaison et le compteur “http_err_cnt” dans les tables de persistance. La plage par défaut pour les erreurs est 400 à 499, mais dans certains contextes, certains utilisateurs préfèrent exclure des codes spécifiques, notamment lors du suivi des erreurs client (par exemple, 404 sur des systèmes à contenus générés dynamiquement). Voir également « http-fail-codes » et “http_err_cnt”.

Une plage spécifiée sans ‘+’ ni ‘-’ redéfinit la plage existante par la nouvelle plage. Une plage commençant par ‘+’ étend la plage existante pour inclure également la plage spécifiée, qui peut chevaucher ou non la plage existante. Une plage commençant par ‘-’ retire la plage spécifiée de la plage existante. Une plage est composée d’un nombre compris entre 100 et 599, suivi éventuellement de “-” et d’un autre nombre supérieur ou égal au premier pour indiquer la borne supérieure de la plage. Plusieurs plages peuvent être séparées par des virgules pour une même opération add/del/replace.

Exemple :

http-err-codes 400,402-444,446-480,490   # sets exactly these codes
http-err-codes 400-499 -450 +500         # sets 400 to 500 except 450
http-err-codes -450-459                  # removes 450 to 459 from range
http-err-codes +501,505                  # adds 501 and 505 to range

http-fail-codes [+-]<range>[,...] [...]

http-fail-codes [+-]<range>[,...] [...]

Remplace, réduit ou étend la liste des codes d’état qui définissent une erreur selon les codes de terminaison et le compteur “http_fail_cnt” dans les tables de persistance. La plage par défaut des erreurs est comprise entre 500 et 599, à l’exception des codes 501 et 505, qui peuvent être déclenchés par les clients et indiquent normalement une erreur du serveur pour traiter la requête. Certains utilisateurs préfèrent exclure certains codes dans certains contextes où ils sont connus pour ne pas être pertinents, par exemple le code 500 dans certains environnements SOAP, où il ne traduit pas nécessairement une erreur du serveur. La syntaxe est identique à celle de http-err-codes ci-dessus. Voir également « http-err-codes » et “http_fail_cnt”.

insecure-fork-wanted

insecure-fork-wanted

Par défaut, HAProxy s’efforce de prévenir toute création de thread ou de processus après son démarrage. Cette mesure est particulièrement importante lors de l’utilisation de fichiers Lua d’origine incertaine, ainsi que lors de l’expérimentation avec des versions de développement pouvant encore contenir des bogues dont l’exploitabilité est incertaine. En général, il s’agit d’une bonne pratique pour s’assurer qu’aucune activité en arrière-plan imprévue ne puisse être déclenchée par le trafic. Toutefois, cela empêche les vérifications externes de fonctionner et peut rompre certains scripts Lua très spécifiques qui dépendent activement de la capacité à fork. Cette option permet de désactiver cette protection. Notez qu’il est une mauvaise idée de la désactiver, car une vulnérabilité dans une bibliothèque ou dans HAProxy lui-même deviendra plus facile à exploiter une fois désactivée. En outre, le fork depuis Lua ou n’importe où ailleurs n’est pas fiable, car le processus forké peut aléatoirement héberger un verrou défini par un autre thread et ne jamais parvenir à terminer une opération. Il est donc fortement recommandé de ne jamais utiliser cette option et de reconsidérer toute charge de travail nécessitant un fork, en la transférant vers une solution plus sûre (comme des agents au lieu de vérifications externes). Cette option prend en charge le préfixe « no » pour la désactiver. Elle peut également être activée via “-dI” en ligne de commande HAProxy.

insecure-setuid-wanted

insecure-setuid-wanted

HAProxy n’a pas besoin d’appeler d’exécutables au moment de l’exécution (sauf lors de l’utilisation de vérifications externes, qui sont fortement déconseillées), et doit même être isolé dans un environnement chroot vide. En conséquence, il n’existe pratiquement aucune raison valable de permettre l’appel d’un exécutable setuid sans que l’utilisateur en soit pleinement conscient des risques. Dans une situation où HAProxy devrait appeler des vérifications externes and/or, la désactivation du chroot pourrait permettre l’exécution d’un programme externe si une vulnérabilité est présente dans une bibliothèque ou dans HAProxy lui-même. Sur Linux, il est possible de verrouiller le processus de manière à ignorer tout bit setuid présent sur un tel exécutable. Cela réduit fortement le risque d’élévation de privilèges dans une telle situation. C’est précisément ce que HAProxy fait par défaut. Si cela pose problème à une vérification externe (par exemple une qui nécessiterait la commande « ping »), il est possible de désactiver cette protection en ajoutant explicitement cette directive dans la section global. Si activée, il est possible de la désactiver à nouveau en préfixant la directive par le mot-clé « no ».

issuers-chain-path <dir>

issuers-chain-path <dir>

Attribue un répertoire pour charger la chaîne de certificats afin de compléter l’émetteur. Tous les fichiers doivent être au format PEM. Pour les certificats chargés avec « crt » ou « crt-list », si la chaîne de certificats n’est pas incluse dans le PEM (appelée couramment certificat intermédiaire), HAProxy complétera la chaîne si l’émetteur du certificat correspond au premier certificat de la chaîne chargée via « issuers-chain-path ». Un fichier « crt » contenant Clé privée + Certificat + IntermediateCA2 + IntermediateCA1 peut être remplacé par Clé privée + Certificat. HAProxy complétera la chaîne si un fichier contenant IntermediateCA2 + IntermediateCA1 est présent dans le répertoire « issuers-chain-path ». Tous les autres certificats ayant le même émetteur partageront la chaîne en mémoire.

Les fonctionnalités OCSP sont capables d’utiliser la chaîne complète lorsqu’aucun champ .issuer n’a été utilisé, ou lorsqu’aucune chaîne n’a été fournie au format PEM.

jwt.decrypt_alg_list <list>

jwt.decrypt_alg_list <list>

Définir la liste des algorithmes autorisés dans les convertisseurs jwt_decrypt_XXX. Les jetons JWT utilisant un algorithme non pris en charge ou désactivé ne seront jamais déchiffrés. Les algorithmes spécifiés doivent avoir le même format que celui décrit dans la section 4.1 de RFC7518 et être séparés par des deux-points. Le nom spécial « ALL » peut être utilisé pour activer tous les algorithmes pris en charge (voir le convertisseur “jwt_decrypt_jwk” pour la liste complète), et un « ! » peut être ajouté au nom d’un algorithme pour le désactiver explicitement. Veuillez noter qu’à moins que « ALL » ne soit spécifié, l’utilisation de cette option désactivera tout algorithme non explicitement mentionné dans la liste fournie.

Exemples :

# Enable all algorithms but the "ECDH-ES" one
jwt.decrypt_alg_list ALL:!ECDH-ES

# Only enable ECDH-ES algorithms
jwt.decrypt_alg_list ECDH-ES:ECDH-ES+A128KW:ECDH-ES+A192KW:ECDH-ES+A256KW

jwt.decrypt_enc_list <list>

jwt.decrypt_enc_list <list>

Définissez la liste des algorithmes de chiffrement autorisés dans les convertisseurs jwt_decrypt_XXX. Les jetons JWT utilisant un algorithme de chiffrement non pris en charge ou désactivé ne seront jamais déchiffrés. Les algorithmes spécifiés doivent avoir le même format que celui indiqué dans section 5.1 de RFC7518 et être séparés par des deux-points. Le nom spécial « ALL » peut être utilisé pour activer tous les algorithmes pris en charge (voir le convertisseur “jwt_decrypt_jwk” pour la liste complète) et un « ! » peut être ajouté au nom d’un algorithme pour le désactiver explicitement. Veuillez noter qu’à moins que « ALL » ne soit spécifié, l’utilisation de cette option désactivera tout algorithme non explicitement mentionné dans la liste fournie.

Exemples :

# Enable only AES GCM encrypting algorithms
jwt.decrypt_enc_list A128GCM:A192GCM:A256GCM

key-base <dir>

key-base <dir>

Attribue un répertoire par défaut pour récupérer les clés privées SSL lorsque l’option « key » utilise un chemin relatif. Les emplacements absolus spécifiés prévalent et ignorent « key-base ». Cette option ne fonctionne qu’avec une ligne de chargement « crt-store ».

limited-quic

limited-quic

Ce paramètre doit être utilisé pour activer explicitement les liaisons d’écouteur QUIC lorsque haproxy est compilé avec une version d’OpenSSL ne prenant pas en charge QUIC. Il active une couche de compatibilité interne à HAProxy qui doit avoir été sélectionnée au moment de la compilation avec USE_QUIC_OPENSSL_COMPAT=1. Cette couche de compatibilité prend en charge la plupart des opérations TLS nécessaires, bien qu’elle ne permette pas la fonctionnalité QUIC 0-RTT.

Cette fonctionnalité est principalement destinée à OpenSSL antérieur à la version 3.5.2, où l’API QUIC n’était pas implémentée ou seulement partiellement. La couche de compatibilité peut toutefois être activée pour les versions 3.5.2 et ultérieures, mais cela est probablement inutile.

Si l’option limited-quic est définie, mais que la couche de compatibilité n’a pas été sélectionnée au moment de la compilation, l’option est ignorée sans message et les opérations QUIC TLS s’appuient sur la bibliothèque TLS.

localpeer <name>

localpeer <name>

Définit le nom de l’instance locale. Ce paramètre sera ignoré si l’argument en ligne de commande “-L” est spécifié ou si cette directive est utilisée après la définition de la section “peers”. Dans ces cas, un message d’avertissement sera émis pendant l’analyse de la configuration.

Cette option définit également la variable d’environnement HAPROXY_LOCALPEER. Voir également “-L” dans le guide de gestion et la section « peers » ci-dessous.

log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]

log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
    [profile <prof>] <facility> [max level [min level]]

Ajoute un serveur syslog global. Plusieurs serveurs globaux peuvent être définis. Ils recevront les journaux relatifs aux démarrages et arrêts, ainsi que tous les journaux des proxies configurés avec « log global ». Voir l’option « log » pour les proxies pour plus de détails.

log-send-hostname [<string>]

log-send-hostname [<string>]

Définit le champ nom d’hôte dans l’en-tête syslog. Si le paramètre facultatif « string » est défini, l’en-tête est défini sur le contenu de la chaîne, sinon il utilise le nom d’hôte du système. Généralement utilisé lorsqu’on ne relaie pas les journaux via un serveur syslog intermédiaire ou pour personnaliser simplement le nom d’hôte affiché dans les journaux.

log-tag <string>

log-tag <string>

Définit le champ tag dans l’en-tête syslog à cette chaîne. La valeur par défaut est le nom du programme tel qu’il a été lancé depuis la ligne de commande, qui est généralement « HAProxy ». Il peut parfois être utile de distinguer plusieurs processus s’exécutant sur le même hôte. Voir également la directive « log-tag » par proxy.

lua-load <file> [ <arg1> [ <arg2> [ ... ] ] ]

lua-load <file> [ <arg1> [ <arg2> [ ... ] ] ]

Ce directive globale charge et exécute un fichier Lua dans le contexte partagé, visible par tous les threads. Toute variable définie dans ce contexte est accessible depuis n’importe quel thread. Il s’agit de la méthode la plus simple et recommandée pour charger des programmes Lua, mais elle ne se prête pas bien à une grande quantité d’appels Lua, car un seul thread peut s’exécuter à la fois sur l’état global. Un programme chargé de cette manière verra toujours la valeur 0 dans la variable “core.thread”. Cette directive peut être utilisée plusieurs fois.

Les arguments sont disponibles dans le fichier Lua à l’aide du code ci-dessous, placé dans le corps du fichier. N’oubliez pas que les tableaux Lua commencent à l’index 1. Une variable déclarée en tant que « local » dans un fichier est disponible dans l’ensemble du fichier et non dans les autres fichiers.

 local args = table.pack(...)

lua-load-per-thread <file> [ <arg1> [ <arg2> [ ... ] ] ]

lua-load-per-thread <file> [ <arg1> [ <arg2> [ ... ] ] ]

Ce directive global charge et exécute un fichier Lua dans chaque thread démarré. Toute variable globale a une visibilité locale au thread, de sorte que chaque thread peut voir une valeur différente. Il est donc fortement recommandé de ne pas utiliser de variables globales dans les programmes chargés de cette manière. Une copie indépendante est chargée et initialisée pour chaque thread, tout est effectué séquentiellement et dans l’ordre numérique des threads de 1 à nbthread. Si certaines opérations doivent être effectuées une seule fois, le programme doit vérifier la variable “core.thread” afin de déterminer quel thread est en cours d’initialisation. Les programmes chargés de cette manière s’exécutent en parallèle sur tous les threads et sont hautement évolutifs. Il s’agit de la méthode recommandée pour charger des fonctions simples qui enregistrent des collectes d’échantillons, des convertisseurs, des actions ou des services, une fois assuré que le programme ne dépend pas de variables globales. Pour des raisons de simplicité, la directive est disponible même si un seul thread est utilisé, ou même si les threads sont désactivés (auquel cas elle équivaut à lua-load). Cette directive peut être utilisée plusieurs fois.

Voir lua-load pour l’utilisation des arguments.

lua-prepend-path <string> [<type>]

lua-prepend-path <string> [<type>]

Préfixe la chaîne donnée suivie d’un point-virgule à la variable Lua package.<type>. <type> doit être soit “path” soit “cpath”. Si <type> n’est pas fourni, sa valeur par défaut est “path”.

Les chemins Lua sont des listes séparées par des points-virgules spécifiant comment la fonction require tente de localiser le fichier source d’une bibliothèque. Les points d’interrogation (?) figurant dans un motif sont remplacés par le nom du module. Le chemin est évalué de gauche à droite. Cela implique que les chemins ajoutés en tête seront vérifiés en premier.

Par exemple, en spécifiant le chemin suivant :

lua-prepend-path /usr/share/haproxy-lua/?/init.lua
lua-prepend-path /usr/share/haproxy-lua/?.lua

Lorsque require "example" est appelé, Lua tentera d’abord de charger le script /usr/share/haproxy-lua/example.lua. Si celui-ci n’existe pas, le script /usr/share/haproxy-lua/example/init.lua sera tenté, puis les chemins par défaut, si celui-ci n’existe pas non plus.

Voir https://www.lua.org/pil/8.1.html pour les détails dans la documentation Lua.

master-worker (deprecated)

master-worker (deprecated)

Mode maître-worker. Il est équivalent à l’argument de ligne de commande “-W”.

Ce mot-clé est obsolète. Veuillez démarrer en mode master-worker en utilisant “-W” ou “-Ws”.

Ce mode lancera un « master » qui fera fork d’un « worker » après lecture de la configuration, afin de traiter le trafic. Le master sert de gestionnaire de processus et surveillera les « workers ».

Utilisez ce mode pour recharger HAProxy directement en envoyant le signal SIGUSR2 au processus principal. Le rechargement demande au processus principal de lire à nouveau la configuration et de créer un nouveau processus worker. Le processus worker précédent sera conservé jusqu’à la fin de ses tâches.

Le mode master-worker est compatible avec le mode en premier plan ou le mode démon.

Par défaut, si un worker quitte avec un code de retour incorrect, par exemple en cas de segmentation fault, tous les workers seront tués et le processus principal s’arrêtera. Il est pratique de combiner ce comportement avec Restart=on-failure dans un fichier d’unité systemd afin de relancer l’ensemble du processus. Si vous ne souhaitez pas ce comportement, vous devez utiliser le mot-clé « no-exit-on-failure ».

Voir également “-W” dans le guide de gestion.

master-worker no-exit-on-failure

master-worker no-exit-on-failure

En mode maître-worker, par défaut, si un worker se termine avec un code de retour incorrect, par exemple en cas de violation d’accès mémoire, tous les workers seront tués et le maître quittera également. Il est pratique de combiner ce comportement avec Restart=on-failure dans un fichier d’unité systemd afin de relancer l’ensemble du processus.

Ce mot-clé permet de maintenir les processus restants en vie lorsque un worker a planté, au lieu de tuer tout le monde. Il doit être utilisé avec précaution, car il n’est destiné qu’à la débogage et pourrait mettre le processus principal dans un état anormal.

max-threads-per-group <number>

max-threads-per-group <number>

Définit le nombre maximal de threads dans un groupe de threads. À moins que le nombre de groupes de threads ne soit fixé avec la directive « thread-groups », HAProxy créera autant de groupes de threads qu’il en faut pour satisfaire le nombre de threads demandé. La valeur minimale est 1, et la valeur maximale est 64 (sur les systèmes 64 bits), ou 32 (sur les systèmes 32 bits). Des valeurs plus faibles réduisent la contention provoquée par les opérations atomiques sur les états partagés, mais peuvent augmenter le nombre de sockets nécessaires pour créer tous les écouteurs et maintenir les connexions backend inactives. Des valeurs plus élevées réduisent ces coûts, au prix d’une utilisation CPU plus élevée en cas de contention, et d’un débit de connexions plus faible. La valeur par défaut est 16, qui représente le meilleur compromis trouvé expérimentalement sur divers systèmes testés, y compris des processeurs x86_64 de plusieurs constructeurs, ainsi que des systèmes Arm64 de grande taille, qu’ils soient exécutés en natif ou sous hyperviseur.

mworker-max-reloads <number>

mworker-max-reloads <number>

En mode maître-ouvrier, cette option limite le nombre de fois qu’un ouvrier peut survivre à une relecture. Si l’ouvrier ne quitte pas après une relecture, une fois que son nombre de relectures dépasse cette valeur, il recevra un SIGTERM. Cette option permet de maintenir sous contrôle le nombre d’ouvrages. Voir également « show proc » dans le guide d’administration.

Par défaut, cette valeur est définie à 50.

nbthread <number>

nbthread <number>

Ce paramètre n’est disponible que si le support des threads a été inclus lors de la compilation. Il fait exécuter HAProxy sur <number> threads. Le paramètre « nbthread » fonctionne également lorsque HAProxy est lancé en mode frontal. Sur certaines plates-formes prenant en charge l’affinité processeur, la valeur par défaut de « nbthread » est automatiquement ajustée au nombre de processeurs auxquels le processus est lié au démarrage. Cela signifie que le nombre de threads peut être facilement ajusté depuis le processus appelant à l’aide de commandes telles que « taskset » ou « cpuset ». Sinon, cette valeur par défaut est égale à 1. La valeur par défaut est indiquée dans la sortie de la commande « HAProxy -vv ». Notez que les valeurs définies ici ou détectées automatiquement sont soumises à la limite fixée par « thread-hard-limit » (le cas échéant).

numa-cpu-mapping

numa-cpu-mapping

Lorsqu’il est exécuté sur une plateforme sensible au NUMA, cette option permet à la directive « cpu-policy » d’inspecter la topologie afin de déterminer l’ensemble optimal de processeurs à utiliser ainsi que le nombre correspondant de threads. Toutefois, si l’affectation appliquée n’est pas optimale sur une architecture particulière, elle peut être désactivée à l’aide de l’instruction « no numa-cpu-mapping ». Ce lien automatique n’est pas appliqué non plus si une directive « nbthread » est présente dans la configuration, si l’affinité du processus est déjà définie (par exemple via la directive « cpu-map » ou l’outil taskset), ou si la directive « cpu-policy » est définie sur une autre valeur. Voir également « cpu-map », « cpu-policy », « cpu-set ».

ocsp-update.disable [ on | off ]

ocsp-update.disable [ on | off ]

Désactive complètement le mécanisme ocsp-update dans HAProxy. Toute configuration ocsp-update sera ignorée. Valeur par défaut : « off ». Voir l’option « ocsp-update » pour plus d’informations sur le mécanisme de mise à jour automatique.

ocsp-update.httpproxy <address>[:port]

ocsp-update.httpproxy <address>[:port]

Permet d’utiliser un proxy HTTP pour les mises à jour OCSP. Cela ne fonctionne qu’avec HTTP ; HTTPS n’est pas pris en charge. Cette option permet à l’updater OCSP d’envoyer une URI absolue dans la requête au proxy.

ocsp-update.maxdelay <number>

ocsp-update.maxdelay <number>
tune.ssl.ocsp-update.maxdelay <number> (deprecated)

Définit l’intervalle maximal entre deux mises à jour automatiques de la même réponse OCSP. Cette durée est exprimée en secondes et vaut 3600 par défaut (1 heure). Elle doit être définie à une valeur supérieure à “ocsp-update.mindelay”. Pour plus d’informations sur le mécanisme de mise à jour automatique, voir l’option « ocsp-update ».

ocsp-update.mindelay <number>

ocsp-update.mindelay <number>
tune.ssl.ocsp-update.mindelay <number> (deprecated)

Définit l’intervalle minimal entre deux mises à jour automatiques de la même réponse OCSP. Cette durée est exprimée en secondes et vaut 300 par défaut (5 minutes). Elle est particulièrement utile pour les réponses OCSP ne disposant pas de temps d’expiration explicite. Elle doit être définie à une valeur inférieure à “ocsp-update.maxdelay”. Pour plus d’informations sur le mécanisme de mise à jour automatique, voir l’option « ocsp-update ».

ocsp-update.mode [ on | off ]

ocsp-update.mode [ on | off ]

Définit le mode par défaut d’actualisation OCSP pour tous les certificats utilisés dans la configuration. Cette option globale peut être remplacée par l’option « ocsp-update » du bloc crt-list. Cette option est définie sur « off » par défaut. Voir l’option « ocsp-update » pour plus d’informations sur le mécanisme d’actualisation automatique.

pidfile <pidfile>

pidfile <pidfile>

Écrit les PID de tous les démons dans le fichier <pidfile> en mode démon, ou le PID du processus principal dans le fichier <pidfile> en mode principal-travailleur. Cette option est équivalente à l’argument en ligne de commande “-p”. Le fichier doit être accessible à l’utilisateur lançant le processus. Voir également « daemon » et « master-worker ».

pp2-never-send-local

pp2-never-send-local

Une erreur dans l’implémentation du protocole PROXY v2 était présente dans HAProxy jusqu’à la version 2.1, provoquant l’émission d’une commande PROXY au lieu d’une commande LOCAL pour les contrôles d’état. Cela est particulièrement mineur mais perturbe les journaux de certains serveurs. Malheureusement, cette erreur a été découverte très tardivement, révélant que certains serveurs, qui n’avaient éventuellement testé leur implémentation du protocole PROXY qu’avec HAProxy, ne gèrent pas correctement la commande LOCAL, et restent définitivement en état « down » lorsque HAProxy les vérifie. Lorsque cela se produit, il est possible d’activer cette option globale afin de revenir temporairement au comportement antérieur (incorrect) pendant le temps nécessaire à la mise en contact des fournisseurs des composants concernés et à leur correction. Cette option est désactivée par défaut et s’applique à tous les serveurs ayant la directive « send-proxy-v2 ».

presetenv <name> <value>

presetenv <name> <value>

Définit la variable d’environnement <name> avec la valeur <value>. Si la variable existe, elle n’est PAS remplacée. Les modifications prennent effet immédiatement, de sorte que la ligne suivante dans le fichier de configuration voit la nouvelle valeur. Voir également « setenv », « resetenv » et « unsetenv ».

prealloc-fd

prealloc-fd

Effectue une ouverture unique du descripteur de fichier maximum, ce qui entraîne une pré-allocation des structures de données du noyau. Cela évite les pauses brèves lorsque nbthread > 1 et qu’HAProxy ouvre un descripteur de fichier nécessitant une extension des structures de données du noyau.

resetenv [<name> ...]

resetenv [<name> ...]

Supprime toutes les variables d’environnement sauf celles spécifiées en argument. Cela permet d’utiliser un environnement propre et contrôlé avant de définir de nouvelles valeurs avec setenv ou unsetenv. Veuillez noter que certaines fonctions internes peuvent utiliser certaines variables d’environnement, telles que les fonctions de manipulation du temps, OpenSSL ou encore les vérifications externes. Cette directive doit être utilisée avec une extrême prudence et uniquement après validation complète. Les modifications prennent effet immédiatement, de sorte que la ligne suivante du fichier de configuration voit le nouvel environnement. Voir également « setenv », « presetenv » et « unsetenv ».

server-state-base <directory>

server-state-base <directory>

Spécifie le préfixe de répertoire à ajouter devant les noms de fichiers d’état des serveurs, pour ceux qui ne commencent pas par un ‘/’. Voir également « server-state-file », « load-server-state-from-file » et « server-state-file-name ».

server-state-file <file>

server-state-file <file>

Spécifie le chemin vers le fichier contenant l’état des serveurs. Si le chemin commence par une barre oblique (’/’), il est considéré comme absolu, sinon il est considéré comme relatif au répertoire spécifié par « server-state-base » (le cas échéant) ou au répertoire courant. Avant de recharger HAProxy, il est possible de sauvegarder l’état actuel des serveurs en utilisant la commande de statistiques « show servers state ». La sortie de cette commande doit être écrite dans le fichier pointé par <file>. Lors du démarrage, avant de traiter le trafic, HAProxy lira, chargera et appliquera l’état de chaque serveur présent dans le fichier et disponible dans sa configuration en cours d’exécution. Voir également « server-state-base » et « show servers state », « load-server-state-from-file » et « server-state-file-name »

set-dumpable [ on | off | libs ]

set-dumpable [ on | off | libs ]

Cette option permet de choisir le comportement en cas de panne du processus. Les options disponibles sont :

  • : cela active le débogage en mémoire au niveau du processus si celui-ci était auparavant désactivé.

  • off désactive le débogage en mode noyau, précédemment activé.

  • libs active la génération de fichiers de débogage contenant une copie intégrée des binaires et des bibliothèques nécessaires. Cette fonction peut être demandée par les développeurs. Dans ce cas, HAProxy tentera de charger les bibliothèques dont il dépend en mémoire et de les conserver en mémoire. Si le processus se bloque, ces éléments seront inclus dans le fichier de débogage, ce qui évite de devoir les récupérer depuis le système de fichiers et élimine tout risque de désynchronisation avec le fichier de débogage. Cette fonction consomme quelques mégaoctets à une dizaine de mégaoctets supplémentaires de mémoire RAM, il est donc préférable de ne pas l’utiliser sur les systèmes à ressources limitées.

Cette option est préférable laissée désactivée par défaut et activée uniquement sur demande d’un développeur. Par défaut, elle est désactivée. Sans argument, elle est par défaut définie sur « on ». Si elle a été activée, elle peut toutefois être fortement désactivée en la préfixant par le mot-clé « no » ou en la définissant sur « off ». Elle n’a aucune incidence sur les performances ni la stabilité, mais tente activement de réactiver les dumps de noyau qui auraient pu être désactivés par des limites de taille de fichier (ulimit -f), des limites de taille de dump (ulimit -c) ou la « dumpabilité » d’un processus après avoir modifié son UID/GID (comme /proc/sys/fs/suid_dumpable sous Linux). Les dumps de noyau peuvent toutefois être limités par les permissions du répertoire courant (vérifiez quel répertoire est utilisé pour le démarrage du fichier), les permissions du répertoire chroot (il peut être nécessaire de désactiver temporairement la directive chroot ou de le déplacer vers un emplacement dédié et accessible en écriture), ou toute autre contrainte spécifique au système. Par exemple, certaines distributions Linux sont réputées pour remplacer le chemin par défaut du fichier de dump par un chemin vers un exécutable non installé sur le système (vérifiez /proc/sys/kernel/core_pattern). En général, il suffit souvent d’écrire « core », « core.%p » ou « /var/log/core/core.%p » pour résoudre le problème. Lorsqu’on tente d’activer cette option en attendant la réapparition d’un problème rare, il est souvent judicieux de d’abord essayer d’obtenir un tel dump en émettant, par exemple, « kill -11 » au processus « HAProxy » et de vérifier qu’un dump est bien généré à l’endroit attendu lors de sa mort.

set-var <var-name> <expr>

set-var <var-name> <expr>

Définit la variable globale ‘<var-name>’ avec le résultat de l’évaluation de l’expression d’extraction <expr>. La variable ‘<var-name>’ ne peut être qu’une variable globale (utilisant le préfixe ‘proc.’). Son fonctionnement est identique à l’action « set-var » dans les règles TCP ou HTTP, à ceci près que l’expression est évaluée au moment de l’analyse de la configuration et que la variable est immédiatement définie. Les fonctions d’extraction d’échantillon et convertisseurs autorisés dans l’expression ne sont que ceux utilisant des données internes, typiquement « int(valeur) » ou « str(valeur) ». Il est également possible de référencer des variables précédemment allouées. Ces variables pourront alors être lues (et modifiées) depuis les ensembles de règles réguliers.

Exemple :

global
    set-var proc.current_state str(primary)
    set-var proc.prio int(100)
    set-var proc.threshold int(200),sub(proc.prio)

set-var-fmt <var-name> <fmt>

set-var-fmt <var-name> <fmt>

Définit la variable globale ‘<var-name>’ à la chaîne résultant de l’évaluation du format de journal <fmt>. La variable ‘<var-name>’ ne peut être qu’une variable globale (en utilisant le préfixe ‘proc.’). Elle fonctionne exactement comme l’action ‘set-var-fmt’ dans les règles TCP ou HTTP, sauf que l’expression est évaluée au moment de l’analyse de la configuration et que la variable est immédiatement définie. Les fonctions d’extraction d’échantillon et convertisseurs autorisés dans l’expression sont uniquement ceux utilisant des données internes, typiquement ‘int(valeur)’ ou ‘str(valeur)’. Il est possible de référencer des variables précédemment allouées. Ces variables seront ensuite accessibles (et modifiables) depuis les ensembles de règles réguliers. Voir la section 8.2.6 pour les détails sur la syntaxe des formats de journal personnalisés.

Exemple :

global
    set-var-fmt proc.current_state "primary"
    set-var-fmt proc.bootid        "%pid|%t"

setcap <name>[,<name>...]

setcap <name>[,<name>...]

Définit une liste de capacités à préserver lors du démarrage et de l’exécution, soit en tant qu’utilisateur non root (uid > 0), soit en démarrant avec uid 0 (root) puis en basculant vers un utilisateur non root. Par défaut, toutes les permissions sont perdues lors du changement d’uid, mais certaines sont souvent nécessaires lors de la connexion à un serveur depuis une adresse étrangère en mode proxy transparent, ou lors de la liaison à un port inférieur à 1024, par exemple lors de l’utilisation de « tune.quic.fe.sock-per-conn default-on », entraînant des configurations s’exécutant entièrement sous uid 0. Affecter des capacités est généralement une solution plus sûre, car seules les capacités nécessaires sont conservées. Cette fonctionnalité est spécifique à l’OS et n’est activée que sous Linux lorsque USE_LINUX_CAP=1 est défini au moment de la compilation. La liste des capacités prises en charge dépend également de l’OS et est indiquée par le message d’erreur affiché en cas de passage d’un nom de capacité invalide ou vide. Plusieurs capacités peuvent être spécifiées, séparées par des virgules. Parmi celles couramment utilisées, “cap_net_raw” permet de lier de manière transparente à une adresse étrangère, et “cap_net_bind_service” permet de lier à un port privilégié et peut être utilisé par QUIC. Si le processus est lancé et exécuté sous le même utilisateur non root, les capacités nécessaires doivent être définies sur le binaire HAProxy à l’aide de setcap, en conjonction avec cette directive. Pour plus de détails sur la configuration des capacités sur le binaire HAProxy, se référer à la section 13.1 Prise en charge des capacités Linux du guide de gestion.

Exemple :

global
    setcap cap_net_bind_service,cap_net_admin

setenv <name> <value>

setenv <name> <value>

Définit la variable d’environnement <name> avec la valeur <value>. Si la variable existe, elle est remplacée. Les modifications prennent effet immédiatement, de sorte que la ligne suivante dans le fichier de configuration voit la nouvelle valeur. Voir également « presetenv », « resetenv » et « unsetenv ».

shm-stats-file <name>

shm-stats-file <name>

Lorsque cette directive est définie, elle active l’utilisation de la mémoire partagée pour le stockage des compteurs de statistiques. <name> est utilisé comme argument de shm_open() pour ouvrir la mémoire partagée à un emplacement unique. Cela signifie également que la directive n’est disponible que sur les systèmes qui prennent en charge shm_open(). Lorsque la mémoire partagée est utilisée pour les statistiques, tous les compteurs partageables des frontaux, backends, écouteurs et serveurs seront stockés dans la mémoire partagée, à condition qu’ils disposent d’un GUID défini. Lors du rechargement de HAProxy, le nouveau processus tentera de scanner la mémoire partagée afin de trouver des objets pouvant être associés aux objets définis dans la configuration, en fonction du GUID et du type ; l’objectif est de pouvoir conserver certaines valeurs de compteurs lors du rechargement. En revanche, lorsque HAProxy est arrêté correctement, les objets de mémoire partagée sont libérés, ce qui signifie que les compteurs sont effectivement réinitialisés. Il est également possible de supprimer manuellement le fichier avant de démarrer un nouveau processus afin de forcer une réinitialisation.

Voir également « guid », « guid-prefix » et « shm-stats-file-max-objects »

shm-stats-file-max-objects <number>

shm-stats-file-max-objects <number>

Ce paramètre définit le nombre maximum d’objets que la mémoire partagée utilisée pour les compteurs partagés pourra stocker par groupe de threads. Il est directement lié à la taille maximale de la shm et sert à « prémapper » la shm à une taille donnée afin d’éviter un remappage en cours d’exécution. Sa valeur par défaut est de 2k, ce qui convient à la plupart des configurations sans risquer une utilisation mémoire inappropriée, mais peut être facilement modifié si nécessaire. haproxy signalera une erreur au démarrage si cette valeur est trop faible pour enregistrer les objets attendus dans la mémoire partagée. Ce paramètre n’est pertinent que lorsque « shm-stats-file » a été défini.

Voir également « thread-groups »

ssl-default-bind-ciphers <ciphers>

ssl-default-bind-ciphers <ciphers>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il définit la chaîne par défaut décrivant la liste des algorithmes de chiffrement (“cipher suite”) négociés lors de l’échange SSL/TLS jusqu’à TLSv1.2 pour toutes les lignes “bind” qui ne définissent pas explicitement leur propre liste. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL. Pour des informations complémentaires et des recommandations, consulter par exemple (https://wiki.mozilla.org/Security/Server_Side_TLS ) et (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Pour la configuration des chiffrements TLSv1.3, se référer à la directive « ssl-default-bind-ciphersuites ». Pour plus d’informations, consulter la directive « bind ».

ssl-default-bind-ciphersuites <ciphersuites>

ssl-default-bind-ciphersuites <ciphersuites>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré et si OpenSSL 1.1.1 ou une version ultérieure a été utilisée pour compiler HAProxy. Il définit la chaîne par défaut décrivant la liste des algorithmes de chiffrement (“cipher suite”) négociés lors de la négociation TLSv1.3 pour toutes les lignes “bind” qui ne définissent pas explicitement leur propre liste. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL, dans la section « ciphersuites ». Pour la configuration des chiffrements TLSv1.2 et versions antérieures, veuillez consulter le mot-clé « ssl-default-bind-ciphers ». Ce paramètre peut accepter des suites de chiffrement TLSv1.2, mais cette fonctionnalité n’est pas documentée et n’est pas recommandée, car elle pourrait être incohérente ou défaillante. Les suites de chiffrement TLSv1.3 par défaut d’OpenSSL sont : “TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256”

TLSv1.3 ne prend en charge que 5 suites de chiffrement :

  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_AES_128_CCM_8_SHA256

Veuillez consulter le mot-clé « bind » pour plus d’informations.

Exemple :

global
    ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256
    ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

ssl-default-bind-client-sigalgs <sigalgs>

ssl-default-bind-client-sigalgs <sigalgs>

Ce paramètre n’est disponible que si la prise en charge d’OpenSSL a été intégrée. Il définit la chaîne par défaut décrivant les algorithmes de signature liés à l’authentification du client pour toutes les lignes “bind” qui ne définissent pas explicitement leur propre liste. La chaîne est une liste d’algorithmes de signature séparés par des deux-points. Chaque algorithme peut prendre l’une des deux formes suivantes : un nom de schéma de signature TLS1.3 (“rsa_pss_rsae_sha256”) ou la forme algorithme de clé publique + condensat (“ECDSA+SHA256”). Une même liste peut contenir les deux formes. Pour plus d’informations sur le format, consultez SSL_CTX_set1_client_sigalgs(3). Une liste d’algorithmes de signature figure également dans la section 4.2.3 de RFC8446 et dans le fichier ssl/t1_lib.c d’OpenSSL. Ce paramètre ne s’applique pas à TLSv1.1 ni aux versions antérieures du protocole, car les algorithmes de signature n’y sont pas négociés séparément. Il est déconseillé de le modifier, sauf si la compatibilité avec un boîtier intermédiaire l’exige.

ssl-default-bind-curves <curves>

ssl-default-bind-curves <curves>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il définit la chaîne par défaut décrivant la liste des algorithmes de courbes elliptiques (“suite de courbes”) négociés lors de l’échange SSL/TLS avec ECDHE. Le format de la chaîne est une liste séparée par des deux-points de noms de courbes. Veuillez consulter le mot-clé « bind » pour plus d’informations.

ssl-default-bind-options [<option>]...

ssl-default-bind-options [<option>]...

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit les options SSL par défaut pour forcer leur activation sur toutes les lignes « bind ». Veuillez consulter le mot-clé « bind » pour consulter les options disponibles.

Exemple :

global
   ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets

ssl-default-bind-sigalgs <sigalgs>

ssl-default-bind-sigalgs <sigalgs>

Ce paramètre n’est disponible que si la prise en charge d’OpenSSL a été intégrée. Il définit la chaîne par défaut décrivant les algorithmes de signature négociés pendant les échanges TLSv1.2 et TLSv1.3 pour toutes les lignes “bind” qui ne définissent pas explicitement leur propre liste. La chaîne est une liste d’algorithmes de signature séparés par des deux-points. Chaque algorithme peut prendre l’une des deux formes suivantes : un nom de schéma de signature TLS1.3 (“rsa_pss_rsae_sha256”) ou la forme algorithme de clé publique + condensat (“ECDSA+SHA256”). Une même liste peut contenir les deux formes. Pour plus d’informations sur le format, consultez SSL_CTX_set1_sigalgs(3). Une liste d’algorithmes de signature figure également dans la section 4.2.3 de RFC8446 et dans le fichier ssl/t1_lib.c d’OpenSSL. Ce paramètre ne s’applique pas à TLSv1.1 ni aux versions antérieures du protocole, car les algorithmes de signature n’y sont pas négociés séparément. Il est déconseillé de le modifier, sauf si la compatibilité avec un boîtier intermédiaire l’exige.

ssl-default-server-ciphers <ciphers>

ssl-default-server-ciphers <ciphers>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne par défaut décrivant la liste des algorithmes de chiffrement négociés lors de l’échange SSL/TLS jusqu’à TLSv1.2 avec le serveur, pour toutes les lignes “server” qui ne définissent pas explicitement leur propre liste. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL. Pour des informations complémentaires et des recommandations, consulter par exemple (https://wiki.mozilla.org/Security/Server_Side_TLS ) et (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Pour la configuration des algorithmes de chiffrement TLSv1.3, se référer à la directive « ssl-default-server-ciphersuites ». Voir également la directive « server » pour plus d’informations.

ssl-default-server-ciphersuites <ciphersuites>

ssl-default-server-ciphersuites <ciphersuites>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré et si OpenSSL 1.1.1 ou une version ultérieure a été utilisée pour compiler HAProxy. Il définit la chaîne par défaut décrivant la liste des algorithmes de chiffrement négociés lors de l’échange TLSv1.3 avec le serveur, pour toutes les lignes « server » qui ne définissent pas explicitement leur propre liste. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL, dans la section « ciphersuites ». Pour la configuration des chiffrements TLSv1.2 et versions antérieures, veuillez consulter le mot-clé « ssl-default-server-ciphers ». Veuillez consulter le mot-clé « server » pour plus d’informations.

ssl-default-server-client-sigalgs <sigalgs>

ssl-default-server-client-sigalgs <sigalgs>

Ce paramètre n’est disponible que si la prise en charge d’OpenSSL a été intégrée. Il définit la chaîne par défaut décrivant les algorithmes de signature liés à l’authentification du client pour toutes les lignes “server” qui ne définissent pas explicitement leur propre liste. La chaîne est une liste d’algorithmes de signature séparés par des deux-points. Chaque algorithme peut prendre l’une des deux formes suivantes : un nom de schéma de signature TLS1.3 (“rsa_pss_rsae_sha256”) ou la forme algorithme de clé publique + condensat (“ECDSA+SHA256”). Une même liste peut contenir les deux formes. Pour plus d’informations sur le format, consultez SSL_CTX_set1_client_sigalgs(3). Une liste d’algorithmes de signature figure également dans la section 4.2.3 de RFC8446 et dans le fichier ssl/t1_lib.c d’OpenSSL. Ce paramètre ne s’applique pas à TLSv1.1 ni aux versions antérieures du protocole, car les algorithmes de signature n’y sont pas négociés séparément. Il est déconseillé de le modifier, sauf si la compatibilité avec un boîtier intermédiaire l’exige.

ssl-default-server-curves <curves>

ssl-default-server-curves <curves>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il définit la chaîne par défaut décrivant la liste des algorithmes de courbes elliptiques (“suite de courbes”) négociés lors de l’échange SSL/TLS avec ECDHE. Le format de la chaîne est une liste séparée par des deux-points de noms de courbes. Veuillez consulter le mot-clé « server » pour plus d’informations.

ssl-default-server-options [<option>]...

ssl-default-server-options [<option>]...

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit les options SSL par défaut pour forcer l’activation sur toutes les lignes « server ». Veuillez consulter le mot-clé « server » pour connaître les options disponibles.

ssl-default-server-sigalgs <sigalgs>

ssl-default-server-sigalgs <sigalgs>

Ce paramètre n’est disponible que si la prise en charge d’OpenSSL a été intégrée. Il définit la chaîne par défaut décrivant les algorithmes de signature négociés pendant les échanges TLSv1.2 et TLSv1.3 avec le serveur pour toutes les lignes “server” qui ne définissent pas explicitement leur propre liste. La chaîne est une liste d’algorithmes de signature séparés par des deux-points. Chaque algorithme peut prendre l’une des deux formes suivantes : un nom de schéma de signature TLS1.3 (“rsa_pss_rsae_sha256”) ou la forme algorithme de clé publique + condensat (“ECDSA+SHA256”). Une même liste peut contenir les deux formes. Pour plus d’informations sur le format, consultez SSL_CTX_set1_sigalgs(3). Une liste d’algorithmes de signature figure également dans la section 4.2.3 de RFC8446 et dans le fichier ssl/t1_lib.c d’OpenSSL. Ce paramètre ne s’applique pas à TLSv1.1 ni aux versions antérieures du protocole, car les algorithmes de signature n’y sont pas négociés séparément. Il est déconseillé de le modifier, sauf si la compatibilité avec un boîtier intermédiaire l’exige.

ssl-dh-param-file <file>

ssl-dh-param-file <file>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il définit les paramètres DH par défaut utilisés lors de l’échange de clés Diffie-Hellman éphémère (DHE) pendant la négociation SSL/TLS, pour toutes les lignes “bind” qui ne définissent pas explicitement leurs propres paramètres. Il sera remplacé par des paramètres DH personnalisés trouvés dans un fichier de certificat si présent. Si des paramètres DH personnalisés ne sont pas spécifiés, ni par l’option ssl-dh-param-file, ni en les définissant directement dans le fichier de certificat, les chiffres DHE ne seront pas utilisés, sauf si tune.ssl.default-dh-param est défini. Dans ce dernier cas, des paramètres DH prédéfinis de la taille spécifiée seront utilisés. L’utilisation de paramètres DH personnalisés est recommandée, car ils sont connus pour être plus sécurisés. Les paramètres DH personnalisés peuvent être générés à l’aide de la commande OpenSSL « openssl dhparam <size> », où la taille doit être d’au moins 2048, car les paramètres DH de 1024 bits ne doivent plus être considérés comme sécurisés.

ssl-passphrase-cmd <cmd> <args> ...

ssl-passphrase-cmd <cmd> <args> ...

Ce paramètre n’est disponible que si le support OpenSSL a été inclus lors de la compilation. Il permet de définir une ligne de commande complète appelée lors du chargement d’un certificat chiffré pendant l’initialisation. La commande peut être un script ou tout autre programme. Elle reçoit comme premier paramètre le chemin vers la clé privée chiffrée, puis les paramètres « args » définis par l’utilisateur, et doit écrire la phrase de passe permettant de déchiffrer la clé privée sur la sortie standard. À chaque chargement d’une nouvelle clé privée chiffrée durant l’initialisation, HAProxy tente d’abord chaque phrase de passe déjà connue, puis appelle à nouveau la commande de phrase de passe si aucune ne fonctionne.

ssl-propquery <query>

ssl-propquery <query>

Ce paramètre n’est disponible que lorsque le support OpenSSL a été intégré et que la version d’OpenSSL est au moins 3.0. Il permet de définir une chaîne de propriétés par défaut utilisée lors de la récupération des algorithmes dans les fournisseurs. Il se comporte de la même manière que l’option openssl propquery et suit la même syntaxe (décrite dans https://www.openssl.org/docs/man3.0/man7/property.html ). Par exemple, si deux fournisseurs sont chargés, celui nommé foo et le fournisseur par défaut, la chaîne propquery “?provider=foo” permet de sélectionner par défaut les implémentations d’algorithmes fournies par le fournisseur foo, et de revenir à celles du fournisseur par défaut en cas d’absence.

ssl-provider <name>

ssl-provider <name>

Ce paramètre n’est disponible que lorsque le support OpenSSL a été intégré et que la version d’OpenSSL est au moins 3.0. Il permet de charger un fournisseur lors de l’initialisation. Si le chargement réussit, les fonctionnalités fournies par le fournisseur chargé peuvent être utilisées par HAProxy. Plusieurs options ssl-provider peuvent être spécifiées dans un fichier de configuration. Les fournisseurs seront chargés dans l’ordre de leur apparition.

Veuillez noter qu’un chargement explicite d’un fournisseur empêche OpenSSL de charger automatiquement le fournisseur « default ». OpenSSL permet également de définir les fournisseurs à charger directement dans son fichier de configuration (par exemple OpenSSL.cnf), de sorte qu’il n’est pas nécessaire d’utiliser l’option « ssl-provider » pour charger des fournisseurs. La commande CLI « show ssl providers » peut être utilisée pour afficher tous les fournisseurs ayant été chargés avec succès.

Le chemin de recherche par défaut du fournisseur OpenSSL est indiqué dans la sortie de la commande « OpenSSL version -a ». Si le fournisseur se trouve dans un autre répertoire, vous pouvez définir la variable d’environnement OPENSSL_MODULES, qui précise le répertoire où se trouve votre fournisseur.

Voir également « ssl-propquery » et « ssl-provider-path ».

ssl-provider-path <path>

ssl-provider-path <path>

Ce paramètre n’est disponible que lorsque le support OpenSSL a été intégré et que la version d’OpenSSL est au moins 3.0. Il permet de spécifier le chemin de recherche utilisé par OpenSSL pour localiser les fournisseurs. Il se comporte de la même manière que la variable d’environnement OPENSSL_MODULES. Il sera utilisé pour toute option ‘ssl-provider’ ultérieure, jusqu’à ce qu’une nouvelle option ‘ssl-provider-path’ soit définie. Voir également « ssl-provider ».

ssl-load-extra-del-ext

ssl-load-extra-del-ext

Ce paramètre permet de configurer la manière dont HAProxy effectue la recherche des fichiers SSL supplémentaires. Par défaut, HAProxy ajoute une nouvelle extension au nom de fichier (par exemple, avec “foobar.crt” charge “foobar.crt.key”). Avec cette option activée, HAProxy supprime l’extension avant d’ajouter la nouvelle (par exemple, avec “foobar.crt” charge “foobar.key”).

Votre fichier crt doit porter une extension “.crt” pour que cette option fonctionne.

Cette option n’est pas compatible avec les extensions de bundle (.ecdsa, .rsa, .dsa) et ne tentera pas de les supprimer.

Cette option est désactivée par défaut. Voir également « ssl-load-extra-files ».

ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>*

ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>*

Ce paramètre modifie la manière dont HAProxy recherche les fichiers non spécifiés lors du chargement des certificats SSL. Cette option s’applique aux certificats associés aux lignes « bind » ainsi qu’aux lignes « server », mais certains fichiers supplémentaires n’auront aucun impact fonctionnel pour les certificats des lignes « server ».

Par défaut, HAProxy découvre automatiquement un grand nombre de fichiers non spécifiés dans la configuration, et vous pouvez souhaiter désactiver ce comportement afin d’optimiser le temps de démarrage.

“none” : charger uniquement les fichiers spécifiés dans la configuration. Ne pas essayer de charger un ensemble de certificats si le fichier n’existe pas. Dans le cas d’un répertoire, ne pas essayer de regrouper les certificats s’ils ont le même nom de base.

« all » : ce comportement est par défaut ; il tente de charger tout : les paquets, sctl, ocsp, l’émetteur, la clé.

“bundle” : Lorsqu’un fichier spécifié dans la configuration n’existe pas, HAProxy tentera de charger un « cert bundle ». Les bundles de certificats ne sont gérés qu’au niveau du frontal et ne fonctionnent pas pour les certificats du backend.

À compter de HAProxy 2.3, les bundles ne sont plus chargés dans le même magasin de certificats OpenSSL ; au lieu de cela, chaque certificat est chargé dans un magasin distinct, ce qui équivaut à déclarer plusieurs directives « crt ». OpenSSL 1.1.1 est requis pour cette fonctionnalité. Cela signifie que les bundles ne sont désormais utilisés qu’à des fins de compatibilité descendante et ne sont plus obligatoires pour configurer une liaison hybride RSA/ECC.

Pour associer ces fichiers PEM à un « bundle de certificats » reconnu par HAProxy, ils doivent être nommés selon la convention suivante : tous les fichiers PEM à regrouper doivent partager le même nom de base, accompagné d’un suffixe indiquant le type de clé. Actuellement, trois suffixes sont pris en charge : rsa, dsa et ecdsa. Par exemple, si www.example.com comporte deux fichiers PEM, un fichier RSA et un fichier ECDSA, ils doivent être nommés : “example.pem.rsa” et “example.pem.ecdsa”. La première partie du nom de fichier est arbitraire ; seul le suffixe est pertinent. Pour charger ce bundle dans HAProxy, indiquez uniquement le nom de base :

Exemple : bind:8443 ssl crt example.pem

Notez que le suffixe n’est pas fourni à HAProxy ; cela indique à HAProxy de rechercher un bundle de certificats.

HAProxy chargera tous les fichiers PEM du bundle comme s’ils étaient configurés séparément dans plusieurs directives « crt ».

Le chargement du bundle n’a plus d’impact sur le chargement du répertoire, puisque les fichiers sont chargés séparément.

En ligne de commande, les bundles sont considérés comme des fichiers distincts, et l’extension du bundle est obligatoire pour les valider.

Les fichiers OCSP (.ocsp), les fichiers émetteurs (.issuer), la transparence des certificats (.sctl) ainsi que les clés privées (.key) sont pris en charge avec le regroupement de plusieurs certificats.

sctl : Essayer de charger “<basename>.sctl” pour chaque mot-clé crt. Si fourni pour un certificat backend, il sera chargé mais n’aura aucun impact fonctionnel.

“ocsp”: Essayer de charger “<basename>.ocsp” pour chaque mot-clé crt. Si fourni pour un certificat backend, il sera chargé mais n’aura aucun impact fonctionnel.

“issuer”: Essayer de charger “<basename>.issuer” si l’émetteur du fichier OCSP n’est pas fourni dans le fichier PEM. Si fourni pour un certificat backend, il sera chargé mais n’aura aucun impact fonctionnel.

“key”: Si la clé privée n’a pas été fournie par le fichier PEM, essayez de charger un fichier “<basename>.key” contenant une clé privée.

Le comportement par défaut est « all ».

Exemple :

ssl-load-extra-files bundle sctl
ssl-load-extra-files sctl ocsp issuer
ssl-load-extra-files none

Voir aussi : « crt », section 5.1 concernant les options de liaison et section 5.2 concernant les options de serveur.

ssl-security-level <number>

ssl-security-level <number>

Ce directive permet de choisir le niveau de sécurité OpenSSL tel qu’il est décrit dans https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html . Le niveau de sécurité sera appliqué à chaque contexte SSL dans HAProxy. Seuls les valeurs comprises entre 0 et 5 sont prises en charge.

La valeur par défaut dépend de votre version d’OpenSSL, de votre distribution et de la manière dont la bibliothèque a été compilée.

Ce directive nécessite au moins OpenSSL 1.1.1.

ssl-server-verify [none|required]

ssl-server-verify [none|required]

Comportement par défaut de la vérification SSL côté serveur. Si défini sur « none », les certificats des serveurs ne sont pas vérifiés. La valeur par défaut est « required », sauf si elle est forcée via l’option en ligne de commande ‘-dV’.

ssl-skip-self-issued-ca

ssl-skip-self-issued-ca

Autorité de certification auto-délivrée, également appelée CA racine x509, constitue l’élément d’ancrage pour la validation de chaîne : en tant que serveur, elle est inutile à envoyer, le client doit la posséder. La configuration standard ne doit pas inclure une telle CA dans le fichier PEM. Cette option permet de conserver une telle CA dans le fichier PEM sans la transmettre au client. Cas d’utilisation : fournir l’émetteur pour OCSP sans nécessiter de fichier ‘.issuer’ et pouvoir le partager via ‘issuers-chain-path’. Cela concerne tous les certificats ne comportant pas de certificats intermédiaires. Cette option est inutile pour BoringSSL ; le champ .issuer est ignoré car les bits OCSP n’en ont pas besoin. Nécessite au moins OpenSSL 1.0.2.

stats calculate-max-counters [on|off]

stats calculate-max-counters [on|off]

Active ou désactive le calcul des compteurs max des statistiques. Si vous n’en avez pas besoin, les désactiver peut légèrement améliorer les performances. La valeur par défaut est activée.

stats maxconn <connections>

stats maxconn <connections>

Par défaut, la socket de statistiques est limitée à 10 connexions simultanées. Il est possible de modifier cette valeur en utilisant « stats maxconn ».

stats socket [<address:port>|<path>] [param*]

stats socket [<address:port>|<path>] [param*]

Lie un socket UNIX à <path> ou une adresse TCPv4/v6 à <address:port>. Les connexions à ce socket renvoient diverses sorties de statistiques et permettent même d’envoyer certains commandes afin de modifier certains paramètres en cours d’exécution. Veuillez consulter la section 9.3 « Commandes de socket Unix » du guide d’administration pour plus de détails.

Tous les paramètres pris en charge par les lignes « bind » sont pris en charge, par exemple pour restreindre l’accès à certains utilisateurs ou leurs droits d’accès. Veuillez consulter section 5.1 pour plus d’informations.

stats timeout <timeout, in milliseconds>

stats timeout <timeout, in milliseconds>

Le délai d’expiration par défaut sur la socket de statistiques est fixé à 10 secondes. Il est possible de modifier cette valeur à l’aide de « stats timeout ». La valeur doit être indiquée en millisecondes, ou être suivie d’une unité de temps parmi { us, ms, s, m, h, d }.

stats-file <path>

stats-file <path>

Chemin vers un fichier de statistiques HAProxy généré. Au démarrage, HAProxy charge les valeurs dans ses compteurs internes. Utilisez la commande en ligne de commande « dump stats-file » pour produire un tel fichier. Voir le manuel de gestion pour plus de détails.

stress-level <level>

stress-level <level>

Activez un code alternatif destiné à exercer une charge sur le binaire HAProxy. Le niveau est un entier compris entre 0 et 9. La valeur par défaut 0 désactive toute exécution de charge. Les niveaux de 1 à 9 augmentent progressivement la pression de charge appliquée au binaire HAProxy. Notez qu’utiliser un niveau positif peut fortement réduire les performances. Ce paramètre doit donc être activé uniquement à des fins de débogage et sur demande explicite d’un développeur.

strict-limits

strict-limits

Fait échouer le processus au démarrage en cas d’échec de setrlimit. HAProxy tente de définir la meilleure valeur setrlimit selon les calculs effectués. En cas d’échec, un avertissement est émis. Cette option garantit un échec explicite de HAProxy lorsque ces limites échouent. Elle est activée par défaut. Elle peut toutefois être désactivée de force en préfixant le mot-clé par « no ».

thread-group <group> [<thread-range>...]

thread-group <group> [<thread-range>...]

Ce paramètre n’est disponible que si le support des threads a été inclus lors de la compilation. Il définit la liste des threads qui composeront le groupe de threads <group>. Les numéros de thread et de groupe commencent à 1. Les plages de threads sont définies soit en indiquant un seul numéro de thread, soit en spécifiant les bornes inférieure et supérieure séparées par un trait d’union ‘-’ (par exemple, « 1-16 »). Les threads non affectés seront automatiquement affectés aux groupes de threads non affectés, et les groupes de threads définis avec cette directive ne recevront jamais plus de threads que ceux définis. Définir plusieurs fois le même groupe remplace les définitions précédentes par la nouvelle. Voir également « nbthread » et « thread-groups ».

thread-groups <number>

thread-groups <number>

Ce paramètre n’est disponible que si le support des threads a été inclus lors de la compilation. Il permet à HAProxy de répartir ses threads en <number> groupes indépendants. Actuellement, la valeur par défaut est 1. Les groupes de threads permettent de réduire le partage entre threads afin de limiter les conflits, au prix d’une configuration plus complexe. C’est également la seule manière d’utiliser plus de 64 threads, car jusqu’à 64 threads par groupe peuvent être configurés. Le nombre maximum de groupes est configuré au moment de la compilation et vaut 16 par défaut. Voir également « nbthread ».

thread-hard-limit <number>

thread-hard-limit <number>

Ce paramètre sert à imposer une limite au nombre de threads, qu’il s’agisse de threads détectés ou configurés. Il est particulièrement utile sur les systèmes d’exploitation où le nombre de threads est détecté automatiquement, lorsque l’on souhaite un nombre de threads inférieur au nombre de processeurs dans des configurations génériques et portables. En effet, bien que « nbthread » impose un nombre de threads qui entraîne un avertissement et de mauvaises performances si supérieur au nombre de processeurs disponibles, « thread-hard-limit » ne fait que limiter le maximum à cette valeur, en ajustant automatiquement le nombre de threads à une valeur inférieure ou égale à celle-ci, sans toutefois augmenter les valeurs inférieures. Si « nbthread » est forcé à une valeur supérieure, « thread-hard-limit » l’emporte, et un avertissement est émis afin que l’anomalie de configuration puisse être corrigée. Par défaut, aucune limite n’est appliquée. Voir également « nbthread ».

uid <number>

uid <number>

Change l’identifiant utilisateur du processus en <number>. Il est recommandé que cet identifiant utilisateur soit dédié à HAProxy ou à un petit ensemble de démons similaires. HAProxy doit être lancé avec des privilèges de superutilisateur afin de pouvoir basculer vers un autre identifiant. Voir également « gid » et « user ».

ulimit-n <number>

ulimit-n <number>

Définit le nombre maximal de descripteurs de fichiers par processus à <number>. Par défaut, il est calculé automatiquement, il est donc recommandé de ne pas utiliser cette option. Si l’objectif est uniquement de limiter le nombre de descripteurs de fichiers, il est préférable d’utiliser « fd-hard-limit » à la place.

Notez que les serveurs dynamiques ne sont pas pris en compte dans ce calcul automatique des ressources. Si vous utilisez un grand nombre de serveurs dynamiques, il peut être nécessaire de spécifier cette valeur manuellement.

Voir aussi : fd-hard-limit, maxconn

unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ] [ group <group> ] [ gid <gid> ]

Fixe les paramètres courants pour les sockets UNIX déclarés dans les instructions « bind ». Cela sert principalement à simplifier la déclaration de ces sockets UNIX et à réduire le risque d’erreurs, car ces paramètres sont fréquemment requis mais sont également spécifiques au processus. Le paramètre <prefix> peut être utilisé pour forcer tous les chemins de socket à être relatifs à ce répertoire. Cela peut être nécessaire pour accéder à un composant situé dans un chroot. Notez que ces chemins sont résolus avant que HAProxy ne s’isole dans un chroot, donc ils sont absolus. Les paramètres <mode>, <user>, <uid>, <group> et <gid> ont tous la même signification que leurs homonymes utilisés dans l’instruction « bind ». Si les deux sont spécifiés, l’instruction « bind » a priorité, ce qui signifie que les paramètres « unix-bind » peuvent être considérés comme des paramètres par défaut au niveau du processus.

unsetenv [<name> ...]

unsetenv [<name> ...]

Supprime les variables d’environnement spécifiées dans les arguments. Cela peut être utile pour masquer certaines informations sensibles qui sont parfois héritées de l’environnement utilisateur lors de certaines opérations. Les variables n’existant pas sont ignorées sans avertissement, de sorte qu’après l’opération, il est certain qu’aucune de ces variables ne reste. Les modifications prennent effet immédiatement, de sorte que la ligne suivante du fichier de configuration ne verra plus ces variables. Voir également « setenv », « presetenv » et « resetenv ».

user <user name>

user <user name>

Similaire à « uid » mais utilise l’UID du nom d’utilisateur <user name> provenant de /etc/passwd.. Voir également « uid » et « group ».

node <name>

node <name>

Seuls les lettres, chiffres, traits d’union et traits de soulignement sont autorisés, comme dans les noms DNS.

Cette instruction est utile dans les configurations HA où deux ou plusieurs processus ou serveurs partagent la même adresse IP. En attribuant un nom de nœud différent à chaque nœud, il devient facile d’identifier instantanément quel serveur traite le trafic.

wurfl-cache-size <size>

wurfl-cache-size <size>

Définit la taille du cache des agents utilisateurs WURFL. Pour des recherches plus rapides, les agents utilisateurs déjà traités sont conservés dans un cache LRU :

  • “0” : aucun cache n’est utilisé.
  • <size> : taille du cache LRU en éléments.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_WURFL=1.

wurfl-data-file <file path>

wurfl-data-file <file path>

Chemin du fichier de données WURFL à utiliser pour fournir les services de détection de périphérique. Le fichier doit être accessible par HAProxy, avec les autorisations appropriées.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_WURFL=1.

wurfl-information-list [<capability>]*

wurfl-information-list [<capability>]*

Une liste séparée par des espaces de capacités WURFL, capacités virtuelles et noms de propriétés que nous prévoyons d’utiliser dans les en-têtes injectés. Une liste complète des noms de capacité et de capacité virtuelle est disponible sur le site web Scientiamobile :

https://www.scientiamobile.com/wurflCapability

Propriétés WURFL valides :

  • wurfl_id Contient l’identifiant du périphérique correspondant.

  • wurfl_root_id Contient l’identifiant racine du périphérique correspondant.

  • wurfl_isdevroot Indique si le périphérique correspondant est un périphérique racine. Les valeurs possibles sont « TRUE » ou « FALSE ».

  • wurfl_useragent L’agent utilisateur d’origine associé à cette requête web particulière.

  • wurfl_api_version Contient une chaîne représentant la version actuellement utilisée de l’API Libwurfl.

  • wurfl_info Chaîne contenant des informations sur le fichier wurfl.xml analysé et son chemin complet.

  • wurfl_last_load_time Contient l’horodatage UNIX du dernier chargement réussi de WURFL.

  • wurfl_normalized_useragent L’agent utilisateur normalisé.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_WURFL=1.

wurfl-information-list-separator <char>

wurfl-information-list-separator <char>

Caractère utilisé pour séparer les valeurs dans un en-tête de réponse contenant les résultats WURFL. Si non défini, une virgule (’,’) sera utilisée par défaut.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_WURFL=1.

wurfl-patch-file [<file path>]

wurfl-patch-file [<file path>]

Une liste des chemins des fichiers de correctifs WURFL. Notez que les correctifs sont chargés au démarrage, donc avant le chroot.

Veuillez noter que cette option n’est disponible que si HAProxy a été compilé avec USE_WURFL=1.

3.2. Optimisation des performances

busy-polling

busy-polling

Dans certaines situations, notamment lorsqu’il s’agit de faibles latences sur des processeurs à fréquence variable ou lorsqu’on exécute dans des machines virtuelles, chaque fois que le processus attend un I/O via le poller, le processeur retourne en veille ou est attribué à une autre machine virtuelle pendant une durée prolongée, ce qui entraîne des latences excessivement élevées. Cette option propose une solution consistant à empêcher le processeur de passer en veille en utilisant toujours un délai d’expiration nul sur les pollers. Cela permet une réduction significative de la latence (de 30 à 100 microsecondes observées), au prix d’un risque accru de surchauffe du processeur. Elle peut même être utilisée avec des threads, auquel cas des threads mal affectés peuvent provoquer de fortes conflits, entraînant une performance dégradée et des valeurs élevées pour les champs CPU stolen dans la sortie de la commande “show info”, indiquant les threads mal configurés. Il est important de ne pas faire exécuter le processus sur le même processeur que les interruptions réseau lorsque cette option est activée. Il est également préférable de ne pas l’utiliser sur plusieurs threads de processeur partageant le même cœur. Cette option est désactivée par défaut. Si elle a été activée, elle peut toutefois être fortement désactivée en la préfixant par le mot-clé “no”. Elle est ignorée par les pollers “select” et “poll”.

Cette option est automatiquement désactivée sur les anciens processus dans le cadre d’un redémarrage sans interruption ; elle évite des conflits CPU excessifs lorsque plusieurs processus persistent pendant un certain temps en attendant la fin de leurs connexions actuelles.

max-spread-checks <delay in milliseconds>

max-spread-checks <delay in milliseconds>

Par défaut, HAProxy tente de répartir le démarrage des contrôles d’état sur l’intervalle de contrôle d’état le plus petit de tous les serveurs d’une ferme. Le principe vise à éviter de surcharger les services exécutés sur le même serveur. Toutefois, lorsqu’on utilise des intervalles de contrôle importants (10 secondes ou plus), les derniers serveurs de la ferme mettent un certain temps avant de commencer à être testés, ce qui peut poser problème. Ce paramètre sert à imposer une limite supérieure au délai entre le premier et le dernier contrôle, même si les intervalles de contrôle des serveurs sont plus longs. Lorsque les serveurs fonctionnent avec des intervalles plus courts, leurs intervalles sont respectés toutefois.

maxcompcpuusage <number>

maxcompcpuusage <number>

Définit l’utilisation maximale du CPU que HAProxy peut atteindre avant de cesser la compression des nouvelles requêtes ou de réduire le niveau de compression des requêtes en cours. Fonctionne comme « maxcomprate », mais mesure l’utilisation du CPU au lieu du débit de données entrantes. La valeur est exprimée en pourcentage de CPU utilisé par HAProxy. Une valeur de 100 désactive la limite. La valeur par défaut est 100. Une valeur inférieure empêchera le traitement de compression de ralentir l’ensemble du processus et d’introduire des latences élevées.

maxcomprate <number>

maxcomprate <number>

Définit le taux maximal d’entrée de compression par processus à <number> kilo-octets par seconde. Pour chaque flux, si la limite est atteinte, le niveau de compression sera réduit pendant le flux. Si la limite est atteinte au début d’un flux, celui-ci ne sera pas compressé du tout. Si la limite n’est pas atteinte, le niveau de compression sera augmenté jusqu’à tune.comp.maxlevel. Une valeur nulle signifie qu’aucune limite n’est appliquée, ce qui est la valeur par défaut.

maxconn <number>

maxconn <number>

Définit le nombre maximal de connexions simultanées par processus vers <number>. Cela équivaut à l’argument en ligne de commande “-n”. La valeur fournie via l’argument en ligne de commande “-n” a priorité sur la valeur maxconn définie dans la section globale. Le processus HAProxy peut également être compilé avec la variable de compilation SYSTEM_MAXCONN, qui sert alors de limite maximale système pour maxconn. Encore une fois, l’argument en ligne de commande “-n” permet, à l’exécution, de contourner la limite définie par SYSTEM_MAXCONN, si elle est configurée. Les proxies cessent d’accepter de nouvelles connexions lorsque maxconn est atteint. La limite douce des descripteurs de fichiers du processus (obtenue avec la commande “ulimit -n”) est automatiquement ajustée en fonction de la valeur maxconn fournie. Voir également “ulimit-n”. Remarque : le poller “select” ne peut pas utiliser de manière fiable plus de 1024 descripteurs de fichiers sur certaines plates-formes. Si votre plate-forme ne prend en charge que “select” et affiche “select FAILED” au démarrage, vous devez réduire la valeur de maxconn jusqu’à ce qu’elle fonctionne (généralement légèrement inférieure à 500). Si la valeur de maxconn n’est pas définie, elle sera calculée automatiquement en fonction des limites actuelles des descripteurs de fichiers, telles que rapportées par la commande “ulimit -nH” (nous prenons la valeur maximale entre les limites dures et douces), puis cette valeur automatique peut être réduite par “fd-hard-limit” et par la limite mémoire, si celle-ci a été imposée via l’option en ligne de commande “-m”. La valeur automatique dépend également de la taille des tampons, de la mémoire allouée à la compression, de la taille du cache SSL, ainsi que de l’utilisation ou non de SSL et de la valeur correspondante maxsslconn (qui peut également être automatique).

Voir aussi : fd-hard-limit, ulimit-n

maxconnrate <number>

maxconnrate <number>

Définit le nombre maximal de connexions par seconde par processus pour <number>. Les proxies cessent d’accepter des connexions lorsque cette limite est atteinte. Cette option peut être utilisée pour limiter la capacité globale, indépendamment de la capacité de chaque frontal. Il est important de noter qu’elle ne peut servir qu’à protéger le service, car il n’y aura pas nécessairement une répartition équitable entre les frontaux lorsque la limite est atteinte ; il est donc recommandé de limiter également chaque frontal à une valeur proche de sa part attendue. En outre, réduire tune.maxaccept peut améliorer la justesse de répartition.

maxpipes <number>

maxpipes <number>

Définit le nombre maximal de tubes par processus à <number>. Actuellement, les tubes ne sont utilisés que par le splice TCP basé sur le noyau. Étant donné qu’un tube contient deux descripteurs de fichiers, la valeur de « ulimit-n » sera augmentée en conséquence. La valeur par défaut est maxconn/4, qui semble suffisante pour la plupart des utilisations intensives. Le code de splice alloue et libère dynamiquement les tubes, et peut revenir à une copie standard, aussi une valeur trop faible peut-elle uniquement affecter les performances.

maxsessrate <number>

maxsessrate <number>

Définit le nombre maximal de sessions par processus et par seconde à <number>. Les proxies cessent d’accepter des connexions lorsque cette limite est atteinte. Cette option peut être utilisée pour limiter la capacité globale, indépendamment de la capacité de chaque frontal. Il est important de noter qu’elle ne peut servir qu’à protéger le service, car il n’y aura pas nécessairement une répartition équitable entre les frontaux lorsque la limite est atteinte ; il est donc recommandé de limiter également chaque frontal à une valeur proche de sa part attendue. En outre, réduire tune.maxaccept peut améliorer la justesse de répartition.

maxsslconn <number>

maxsslconn <number>

Définit le nombre maximal de connexions SSL concurrentes par processus à <number>. Par défaut, aucune limite spécifique SSL n’est appliquée, ce qui signifie que le paramètre maxconn global s’applique à toutes les connexions. Définir cette limite évite que OpenSSL n’utilise trop de mémoire et ne plante lorsque malloc retourne NULL (car il ne vérifie pas de manière fiable ces conditions). Notez que la limite s’applique aussi bien aux connexions entrantes qu’aux sortantes, de sorte qu’une connexion qui est déchiffrée puis chiffrée compte pour 2 connexions SSL. Si cette valeur n’est pas définie, mais qu’une limite mémoire est imposée, cette valeur sera automatiquement calculée en fonction de la limite mémoire, de maxconn, de la taille du tampon, de la mémoire allouée à la compression, de la taille du cache SSL, et de l’utilisation de SSL dans les frontaux, les backends ou les deux. Si ni maxconn ni maxsslconn ne sont spécifiés alors qu’une limite mémoire est présente, HAProxy ajustera automatiquement ces valeurs afin que 100 % des connexions puissent être établies en SSL sans risque, et tiendra compte des côtés où SSL est activé (frontal, backend, les deux).

maxsslrate <number>

maxsslrate <number>

Définit le nombre maximal de sessions SSL par processus et par seconde à <number>. Les écouteurs SSL cessent d’accepter des connexions lorsque cette limite est atteinte. Cette option peut être utilisée pour limiter l’utilisation globale du CPU SSL, indépendamment de la capacité de chaque frontal. Il est important de noter qu’elle ne peut servir qu’à protéger le service, car les frontaux ne seront pas nécessairement équitablement partagés lorsque la limite est atteinte ; il est donc recommandé de limiter également chaque frontal à une valeur proche de sa part attendue. Il est également important de noter que les sessions sont comptabilisées avant leur entrée dans la pile SSL, et non après, ce qui protège également la pile contre des échanges malformés. Réduire tune.maxaccept peut également améliorer l’équité.

maxzlibmem <number>

maxzlibmem <number>

Définit la quantité maximale de mémoire RAM en mégaoctets par processus utilisable par zlib. Lorsque cette quantité maximale est atteinte, les flux futurs ne seront pas compressés tant que de la mémoire ne sera pas disponible. Si la valeur est définie à 0, aucune limite n’est appliquée. La valeur par défaut est 0. Cette valeur est disponible en octets via le socket UNIX avec la commande « show info », sur la ligne « MaxZlibMemUsage » ; la mémoire utilisée par zlib est indiquée par « ZlibMemUsage » en octets.

no-memory-trimming

no-memory-trimming

Désactive le découpage de mémoire (“malloc_trim”) à certains moments où des tentatives sont effectuées pour récupérer une grande quantité de mémoire (en cas de pénurie de mémoire ou lors d’un rechargement). Le découpage de mémoire force l’allocateur du système à parcourir toutes les zones inutilisées et à les libérer. Cette opération est généralement considérée comme une bonne pratique, afin de laisser plus de mémoire disponible à un nouveau processus alors que l’ancien est peu susceptible d’en faire un usage significatif. Toutefois, certains systèmes gérant des dizaines à des centaines de milliers de connexions concurrentes peuvent subir une fragmentation mémoire importante, ce qui peut rendre cette opération de libération extrêmement longue. Pendant cette période, aucune nouvelle demande ne passe par le processus, les nouvelles connexions ne sont plus acceptées, certaines vérifications de santé peuvent échouer, et le superviseur peut même déclencher la mort du processus inactif, laissant une énorme image mémoire. Si cela se produit, il est conseillé d’utiliser cette option pour désactiver le découpage et cesser de tenter d’être bienveillant envers le nouveau processus. Notez que les allocateurs mémoire avancés ne souffrent généralement pas de ce problème.

noepoll

noepoll

Désactive l’utilisation du système de sondage d’événements « epoll » sous Linux. Équivalent à l’argument en ligne de commande « -de ». Le système de sondage suivant utilisé sera généralement « poll ». Voir également « nopoll ».

noevports

noevports

Désactive l’utilisation du système de sondage d’événements par ports sur les systèmes SunOS dérivés de Solaris 10 et versions ultérieures. Cela équivaut à l’argument en ligne de commande “-dv”. Le système de sondage suivant utilisé sera généralement “poll”. Voir également “nopoll”.

nogetaddrinfo

nogetaddrinfo

Désactive l’utilisation de getaddrinfo(3) pour la résolution de noms. Équivalent à l’argument en ligne de commande « -dG ». La fonction gethostbyname(3) dépréciée sera utilisée.

nokqueue

nokqueue

Désactive l’utilisation du système de sondage d’événements “kqueue” sur BSD. Équivalent à l’argument en ligne de commande “-dk”. Le système de sondage suivant utilisé sera généralement “poll”. Voir également “nopoll”.

noktls

noktls

Désactive l’utilisation de ktls. Cela équivaut à l’argument de ligne de commande “-dT”.

nopoll

nopoll

Désactive l’utilisation du système de sondage d’événements « poll ». Cela équivaut à l’argument en ligne de commande « -dp ». Le système de sondage suivant utilisé sera « select ». Il ne devrait jamais être nécessaire de désactiver « poll », car il est disponible sur toutes les plates-formes prises en charge par HAProxy. Voir également « nokqueue », « noepoll » et « noevports ».

noreuseport

noreuseport

Désactive l’utilisation de SO_REUSEPORT – voir socket(7). Cela équivaut à l’argument en ligne de commande « -dR ».

nosplice

nosplice

Désactive l’utilisation du splice TCP du noyau entre sockets sous Linux. Cela équivaut à l’argument en ligne de commande “-dS”. Les données seront alors copiées à l’aide d’appels recv/send conventionnels et plus portables. Le splice TCP du noyau est limité à certaines versions récentes du noyau 2.6. La plupart des versions comprises entre 2.6.25 et 2.6.28 présentent des bogues et transmettent des données corrompues, elles ne doivent donc pas être utilisées. Cette option facilite la désactivation globale du splice du noyau en cas de doute. Voir également « option splice-auto », « option splice-request » et « option splice-response ».

profiling.memory { on | off }

profiling.memory { on | off }

Active (‘on’) ou désactive (‘off’) le profilage mémoire par fonction. Cela permet de conserver des statistiques d’utilisation des appels à malloc/calloc/realloc/free dans tout le processus (y compris dans les bibliothèques), qui seront rapportées en ligne de commande via la commande « show profiling ». Cette fonction est principalement destinée à être utilisée lorsqu’une utilisation mémoire anormale est observée et qu’elle ne peut être expliquée par les pools ou d’autres informations disponibles. La perte de performance est généralement d’environ 1 %, peut-être un peu plus sur des machines fortement multithreadées, ce qui la rend normalement adaptée à une utilisation en production. Le même effet peut également être obtenu en temps réel en ligne de commande à l’aide de la commande « set profiling memory », consulter le manuel de gestion.

profiling.tasks { auto | on | off | lock | no-lock | memory | no-memory }*

profiling.tasks { auto | on | off | lock | no-lock | memory | no-memory }*

Active (‘on’) ou désactive (‘off’) le profilage CPU par tâche. Lorsque cette option est définie sur ‘auto’, le profilage s’active automatiquement sur un thread lorsqu’il commence à subir une latence moyenne de 1000 microsecondes ou plus, comme indiqué dans le champ d’activité “avg_loop_us”, et se désactive automatiquement lorsque la latence redescend en dessous de 990 microsecondes (valeur moyenne calculée sur les 1024 itérations précédentes, ce qui empêche toute variation rapide et atténue fortement les pics brusques). Il peut également se déclencher spontanément de temps à autre sur des systèmes surchargés, des conteneurs ou machines virtuelles, ou lorsque le système échange (ce qui doit absolument ne jamais se produire sur un répartiteur de charge).

Lorsque le profilage des tâches est activé, HAProxy peut également collecter le temps passé par chaque tâche avec un verrou détenu ou en attente d’un verrou, ainsi que le temps passé en attente d’une allocation mémoire réussie en cas de perte dans le cache de pool. Cela peut parfois aider à comprendre certaines causes de latence. Pour cela, les mots-clés supplémentaires « lock » (pour activer la collecte du temps passé avec un verrou), « no-lock » (pour la désactiver), « memory » (pour activer la collecte du temps d’allocation mémoire) ou « no-memory » (pour la désactiver) peuvent être utilisés. Par défaut, ils ne sont pas activés, car ils peuvent avoir un impact CPU non négligeable sur les systèmes fortement sollicités (3 à 10 %). Notez que la surcharge n’est prise en compte que lorsque le profilage est effectivement en cours d’exécution, de sorte qu’en mode « auto », elle n’apparaît que lorsque HAProxy décide de l’activer.

Le profilage CPU par tâche peut être très utile pour identifier où le temps est consommé et quelles requêtes ont quel effet sur d’autres requêtes. Activer cette fonctionnalité affecte généralement les performances globales de moins de 1 %, aussi est-il recommandé de la laisser sur la valeur par défaut « auto » afin qu’elle ne s’active que lorsqu’un problème est détecté. Cette fonctionnalité nécessite un système prenant en charge l’appel système clock_gettime(2) avec les identifiants d’horloge CLOCK_MONOTONIC et CLOCK_THREAD_CPUTIME_ID ; sinon, le temps rapporté sera nul. Cette option peut être modifiée en cours d’exécution à l’aide de la commande « set profiling » en ligne de commande.

spread-checks <0..50, in percent>

spread-checks <0..50, in percent>

Parfois, il est souhaitable d’éviter d’envoyer les agents et les contrôles d’état aux serveurs à des intervalles exacts, par exemple lorsque de nombreux serveurs logiques sont situés sur le même serveur physique. Grâce à ce paramètre, il devient possible d’ajouter une certaine aléatoire à l’intervalle de contrôle, compris entre 0 et +/- 50 %. Une valeur comprise entre 2 et 5 semble donner de bons résultats. La valeur par défaut reste à 0.

ssl-engine <name> [algo <comma-separated list of algorithms>]

ssl-engine <name> [algo <comma-separated list of algorithms>]

Définit le moteur OpenSSL à <name>. La liste des valeurs valides pour <name> peut être obtenue à l’aide de la commande « openssl engine ». Cette instruction peut être utilisée plusieurs fois ; elle active simplement plusieurs moteurs cryptographiques. Référencer un moteur non pris en charge empêchera HAProxy de démarrer. Notez que de nombreux moteurs entraînent une performance HTTPS inférieure à celle du logiciel pur avec les processeurs récents. L’option « algo » définit les algorithmes par défaut fournis par un ENGINE à l’aide de la fonction OPENSSL ENGINE_set_default_string(). Une valeur de « ALL » utilise le moteur pour toutes les opérations cryptographiques. Si aucune liste d’algorithmes n’est spécifiée, la valeur « ALL » est utilisée. Une liste séparée par des virgules d’algorithmes différents peut être indiquée, notamment : RSA, DSA, DH, EC, RAND, CIPHERS, DIGESTS, PKEY, PKEY_CRYPTO, PKEY_ASN1. Ce format est identique à celui utilisé dans le fichier de configuration OpenSSL : https://www.openssl.org/docs/man1.0.2/apps/config.html

HAProxy version 2.6 a désactivé la prise en charge des moteurs dans la version par défaut. Cette option n’est disponible que si HAProxy a été compilé avec cette fonctionnalité. Si le moteur ssl est requis, HAProxy peut être recompilé avec le drapeau USE_ENGINE=1.

ssl-mode-async

ssl-mode-async

Ajoute le mode SSL_MODE_ASYNC au contexte SSL. Cela active les opérations TLS asynchrones I/O si des moteurs SSL capables de traitement asynchrone sont utilisés. L’implémentation actuelle prend en charge un maximum de 32 moteurs. L’API ASYNC d’OpenSSL ne prend pas en charge le déplacement des tampons read/write et n’est pas conforme à la gestion des tampons de HAProxy. Par conséquent, le mode asynchrone est désactivé pour les opérations read/write (il n’est activé que lors des échanges d’initialisation et de renégociation).

tune.applet.zero-copy-forwarding { on | off }

tune.applet.zero-copy-forwarding { on | off }

Active (« on ») ou désactive (« off ») le transfert zéro-copie des données pour les applets. Il est activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding.

tune.buffers.limit <number>

tune.buffers.limit <number>

Définit une limite rigide sur le nombre de tampons pouvant être alloués par processus. La valeur par défaut est zéro, ce qui signifie sans limite. La limite est automatiquement ajustée afin de respecter les tampons réservés en cas d’urgence, de sorte que l’utilisateur n’ait pas à effectuer des calculs complexes. Forcer cette valeur peut être particulièrement utile pour limiter la quantité de mémoire qu’un processus peut utiliser, tout en conservant un comportement raisonnable. Lorsque cette limite est atteinte, une tâche demandant un tampon attend qu’un autre soit libéré. En général, le temps d’attente est très court et imperceptible, à condition que les limites restent raisonnables. Toutefois, certaines limitations historiques ont affaibli ce mécanisme au fil des versions, et il est connu qu’en cas de pénurie prolongée, certaines tâches peuvent se bloquer jusqu’à expiration de leur délai d’expiration, il est donc préférable d’éviter d’utiliser cette option sauf si strictement nécessaire.

tune.buffers.reserve <number>

tune.buffers.reserve <number>

Définit le nombre de tampons par thread qui sont pré-alloués et réservés pour une utilisation exclusive en cas de pénurie de mémoire entraînant des échecs d’allocation. La valeur minimale est 0 et la valeur par défaut est 4. Aucune raison ne justifie qu’un utilisateur modifie cette valeur, sauf si un développeur principal le recommande pour une raison très spécifique.

tune.bufsize <size>

tune.bufsize <size>

Définit la taille de tampon à cette valeur (en octets). Des valeurs plus faibles permettent à plus de flux de coexister dans la même quantité de mémoire RAM, tandis que des valeurs plus élevées permettent à certaines applications avec des cookies très volumineux de fonctionner. La valeur par défaut est 16384 et peut être modifiée au moment de la compilation. Il est fortement recommandé de ne pas modifier cette valeur par défaut, car des valeurs trop basses peuvent interrompre certains services tels que les statistiques, et des valeurs supérieures à la taille par défaut augmentent l’utilisation de la mémoire, pouvant entraîner une exhaustion de la mémoire système. Il est nécessaire de diminuer au moins le paramètre global maxconn du même facteur que celui-ci est augmenté. En outre, l’utilisation de HTTP/2 impose que cette valeur soit au moins 16384. Si une requête HTTP est plus grande que (tune.bufsize - tune.maxrewrite), HAProxy renvoie une erreur HTTP 400 (Requête incorrecte). De même, si une réponse HTTP est plus grande que cette taille, HAProxy renvoie une erreur HTTP 502 (Bad Gateway). Notez que la valeur définie par ce paramètre est automatiquement arrondie à la multiple suivante de 8 sur les machines 32 bits et de 16 sur les machines 64 bits.

tune.bufsize.large <size>

tune.bufsize.large <size>

Définit la taille en octets des tampons volumineux. Par défaut, le support des tampons volumineux n’est pas activé ; il doit être activé explicitement en définissant cette valeur.

Ces tampons sont conçus pour être utilisés dans certains contextes spécifiques où une quantité de données supérieure doit être tamponnée sans modifier la taille des tampons réguliers. Les tampons volumineux ne sont pas utilisés implicitement.

Notez qu’en cas de configuration de grands tampons, trois tampons spéciaux de grande taille seront alloués pour chaque thread au démarrage, à usage interne.

tune.bufsize.small <size>

tune.bufsize.small <size>

Définit la taille en octets des tampons petits. La valeur par défaut est 1024.

Ces tampons sont conçus pour être utilisés dans certains contextes spécifiques où la consommation mémoire est limitée, mais où il semble inutile d’allouer un tampon complet. Si toutefois un petit tampon s’avère insuffisant, une réallocation est effectuée automatiquement afin de passer à un tampon de taille standard.

Pour l’instant, il est utilisé automatiquement uniquement par le protocole HTTP/3 pour émettre les en-têtes de réponse. Sinon, le support des petits tampons peut être activé pour des proxies spécifiques via l’option « use-small-buffers ».

Voir aussi : option use-small-buffers

tune.cli.max-payload-size <size>

tune.cli.max-payload-size <size>

Définit la taille maximale autorisée pour le chargement utile transmis à une commande en ligne de commande.

En ligne de commande, une ligne de commande est limitée par la taille de la mémoire tampon. Cela signifie que toutes les commandes et leurs arguments doivent tenir dans une mémoire tampon pour être traitées, à l’exclusion de la charge utile qui peut être transmise à la dernière commande de la ligne de commande. Cette charge utile peut être allouée dans une zone dédiée si nécessaire. Sa taille est limitée par ce paramètre. La valeur par défaut est 128 Ko.

Bien que cette valeur doive être suffisamment élevée pour la plupart des utilisations, si elle est modifiée, elle doit être choisie avec soin. Une valeur excessive peut avoir un impact sur les performances de HAProxy. Selon la commande utilisée, une charge importante peut nécessiter un traitement long et risquer de déclencher le watchdog.

Veuillez consulter le manuel de gestion pour obtenir les détails concernant l’interface en ligne de commande.

tune.comp.maxlevel <number>

tune.comp.maxlevel <number>

Définit le niveau de compression maximal. Le niveau de compression influence l’utilisation du processeur pendant la compression. Cette valeur affecte l’utilisation du processeur pendant la compression. Chaque flux utilisant la compression initialise l’algorithme de compression avec cette valeur. La valeur par défaut est 1.

tune.defaults.purge

tune.defaults.purge

Pour prendre en charge les backends dynamiques, toutes les sections de paramètres par défaut nommés sont désormais conservées en mémoire après analyse. Cela est nécessaire car les backends ajoutés en temps réel doivent être basés sur un ensemble de paramètres par défaut nommé pour leur configuration.

Cela peut consommer une quantité importante de mémoire si le nombre d’instances defaults est important. Dans ce cas, et si la fonctionnalité de backend dynamique n’est pas nécessaire, il est possible d’utiliser cette option pour forcer la suppression de la section defaults après son analyse. Il reste toutefois obligatoire de conserver la section defaults référencée, qui contient des paramètres ne pouvant pas être copiés par les proxies qui la référencent. Par exemple, c’est le cas si la section defaults définit des règles TCP/HTTP ou un jeu de règles tcpcheck.

tune.disable-fast-forward

tune.disable-fast-forward

Désactive le transfert accéléré des données. Il s’agit d’un mécanisme d’optimisation du transfert de données consistant à acheminer les données directement d’un côté à l’autre sans réveiller le flux. Grâce à cette directive, il est possible de désactiver cette optimisation. Notez qu’elle désactive également tout transfert par assemblage TCP noyau ainsi que le transfert sans copie. Cette commande n’est pas destinée à une utilisation régulière ; elle sera généralement proposée uniquement par les développeurs lors de sessions de débogage complexes.

tune.disable-zero-copy-forwarding

tune.disable-zero-copy-forwarding

Désactive globalement le transfert zéro-copie des données. Il s’agit d’un mécanisme d’optimisation du transfert rapide des données en évitant l’utilisation du tampon du canal. Grâce à cette directive, il est possible de désactiver cette optimisation. Notez qu’elle désactive également tout transfert direct TCP du noyau.

Voir aussi : tune.pt.zero-copy-forwarding, tune.applet.zero-copy-forwarding, tune.h1.zero-copy-fwd-recv, tune.h1.zero-copy-fwd-send, tune.h2.zero-copy-fwd-send, tune.quic.zero-copy-fwd-send

tune.epoll.mask-events <event[,...]>

tune.epoll.mask-events <event[,...]>

Au fil de l’histoire d’HAProxy, plusieurs problèmes complexes ont été rencontrés, dus à des bogues dans le mécanisme epoll du noyau Linux. Ces problèmes sont généralement très rares et impossibles à reproduire en dehors de l’environnement du rapporteur, et ne peuvent être contournés que par la désactivation d’epoll au profit de poll, ce qui n’est pas satisfaisant dans les environnements exigeant de hautes performances. Chaque fois, ces problèmes affectent uniquement des types d’événements très spécifiques (et rares), et la possibilité de masquer ces événements peut constituer une solution de contournement plus acceptable. Cette option permet cette possibilité en autorisant l’ignoration silencieuse de quelques événements peu courants, qu’elle remplace par une entrée (qui indique un événement entrant non spécifié). L’effet est d’éviter les chemins rapides de traitement des erreurs dans certaines parties du code, et de ne recourir qu’aux chemins communs. Cette option ne doit jamais être utilisée, sauf sur recommandation explicite d’un expert chargé de diagnostiquer ou de contourner un bogue du noyau.

L’option prend un seul argument, qui est une liste séparée par des virgules de mots, chacun désignant un événement à masquer. La liste des événements actuellement pris en charge est la suivante : - « err » : masque l’événement EPOLLERR - « hup » : masque les événements EPOLLHUP - « rdhup » : masque les événements EPOLLRDHUP

Exemple :

# mask all non-traffic epoll events:
tune.epoll.mask-events err,hup,rdhup

tune.events.max-events-at-once <number>

tune.events.max-events-at-once <number>

Définit le nombre d’événements pouvant être traités simultanément par un gestionnaire de tâche asynchrone (via l’API event_hdl). <number> doit être compris entre 1 et 10 000. Une valeur élevée peut entraîner une contention de threads en raison du traitement intensif de la tâche sans interruption, tandis qu’une valeur faible peut entraîner un réamorçage constant de la tâche, car elle ne parvient pas à consommer suffisamment d’événements par exécution et ne parvient pas à suivre le producteur d’événements. La valeur par défaut peut être imposée au moment de la compilation, sinon elle est définie par défaut à 100.

tune.fail-alloc

tune.fail-alloc

Si compilé avec DEBUG_FAIL_ALLOC ou démarré avec “-dMfail”, indique le pourcentage de chances qu’une tentative d’allocation échoue. Doit être compris entre 0 (aucun échec) et 100 (aucun succès). Cela est utile pour déboguer et s’assurer que les échecs de mémoire sont gérés correctement. Si non défini, le ratio est de 0. Toutefois, l’option en ligne de commande “-dMfail” le fixe automatiquement à un taux d’échec de 1 %, de sorte qu’il n’est pas nécessaire de modifier la configuration pour les tests.

tune.fd.edge-triggered { on | off } [ EXPERIMENTAL ]

tune.fd.edge-triggered { on | off }  [ EXPERIMENTAL ]

Active (‘on’) ou désactive (‘off’) le mode de sondage déclenché par bord pour les descripteurs de fichiers (FD) qui le supportent. Ce paramètre n’est actuellement pris en charge qu’avec epoll. Il peut réduire notablement le nombre d’appels à epoll_ctl() et améliorer légèrement les performances dans certains scénarios. Cette fonctionnalité reste expérimentale : elle peut entraîner des connexions bloquées en cas de bogues non corrigés, et est désactivée par défaut.

tune.glitches.kill.cpu-usage <number>

tune.glitches.kill.cpu-usage <number>

Définit le seuil minimal d’utilisation du CPU compris entre 0 et 100, au-delà duquel les connexions présentant trop de perturbations seront tuées. Cela s’applique aux connexions ayant atteint leur seuil de perturbations. Dans les environnements où des connexions très longues se comportent souvent mal sans avoir d’impact sur les performances, il peut être souhaitable de les conserver malgré leur mauvais comportement, à condition qu’elles n’entraînent pas de dégradation, et de ne commencer à les tuer uniquement lorsque l’utilisation du CPU devient élevée. Ce paramètre permet de spécifier qu’une connexion atteignant son seuil de perturbations sera activement tuée lorsque l’utilisation du CPU atteint ou dépasse ce niveau, mais jamais lorsqu’elle est inférieure. Notez que l’utilisation du CPU est mesurée par thread, de sorte qu’une seule connexion malveillante peut être tuée. La valeur par défaut est zéro, ce qui signifie qu’une connexion atteignant son seuil de perturbations sera automatiquement tuée. Une règle empirique consisterait à définir cette valeur à deux fois l’utilisation du CPU habituelle, ou à l’utilisation courante du CPU plus la moitié de l’utilisation en veille (par exemple, si le CPU atteint habituellement 60 %, une valeur de 80 peut être pertinente). Ce paramètre n’a aucun effet sans tune.h2.fe.glitches-threshold, tune.quic.fe.sec.glitches-threshold ou tune.h1.fe.glitches-threshold. Voir également les paramètres globaux “tune.h2.fe.glitches-threshold”, “tune.h1.fe.glitches-threshold” et “tune.quic.fe.sec.glitches-threshold”.

tune.h1.be.glitches-threshold <number>

tune.h1.be.glitches-threshold <number>

Définit le seuil du nombre d’anomalies sur une connexion backend HTTP/1, au-delà duquel cette connexion sera automatiquement fermée. Cela permet de fermer automatiquement les connexions défaillantes sans avoir à écrire des règles explicites pour elles. La valeur par défaut est zéro, ce qui indique qu’aucun seuil n’est défini, de sorte qu’aucun événement ne provoquera la fermeture d’une connexion. Les événements courants incluent des en-têtes mal formés qui ont toutefois été acceptés par “accept-unsafe-violations-in-http-response”. Une valeur non nulle doit généralement être placée dans les centaines ou les milliers pour être efficace sans affecter les serveurs légèrement défectueux. Il est également possible de ne fermer les connexions que lorsque la consommation CPU dépasse un certain seuil, en utilisant “tune.glitches.kill.cpu-usage”. Notez qu’une fermeture gracieuse est tentée à 75 % du seuil configuré en annonçant un GOAWAY pour un flux futur. Cela garantit qu’une connexion légèrement défaillante cessera d’être utilisée après un certain temps sans risquer d’interrompre les transferts en cours.

Voir également : tune.h1.fe.glitches-threshold, bc_glitches et tune.glitches.kill.cpu-usage

tune.h1.fe.glitches-threshold <number>

tune.h1.fe.glitches-threshold <number>

Définit le seuil du nombre d’incidents sur une connexion frontale HTTP/1 au-delà duquel cette connexion sera automatiquement fermée. Cela permet de fermer automatiquement les connexions défaillantes sans avoir à écrire des règles explicites pour elles. La valeur par défaut est zéro, ce qui indique qu’aucun seuil n’est défini, de sorte qu’aucun événement ne provoquera la fermeture d’une connexion. Les événements courants incluent des en-têtes mal formés qui ont toutefois été acceptés par “accept-unsafe-violations-in-http-request”. Une valeur non nulle doit généralement être fixée à plusieurs centaines ou milliers pour être efficace sans affecter les clients légèrement erronés. Il est également possible de ne fermer les connexions que lorsque la consommation du processeur dépasse un certain seuil, en utilisant “tune.glitches.kill.cpu-usage”. Notez qu’une fermeture gracieuse est tentée à 75 % du seuil configuré en annonçant un GOAWAY pour un flux futur. Cela garantit qu’un client légèrement non conforme aura l’opportunité de créer une nouvelle connexion et de continuer à fonctionner sans être affecté, sans jamais déclencher une fermeture brutale qui risquerait d’interrompre des transferts en cours.

Voir également : tune.h1.be.glitches-threshold, fc_glitches et tune.glitches.kill.cpu-usage

tune.h1.zero-copy-fwd-recv { on | off }

tune.h1.zero-copy-fwd-recv { on | off }

Active (« on ») ou désactive (« off ») les réceptions en copie zéro des données pour le multiplexeur H1. Activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-send

tune.h1.zero-copy-fwd-send { on | off }

tune.h1.zero-copy-fwd-send { on | off }

Active (« on ») ou désactive (« off ») l’envoi en copie zéro des données pour le multiplexeur H1. Il est activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-recv

tune.h2.be.glitches-threshold <number>

tune.h2.be.glitches-threshold <number>

Définit le seuil du nombre de glitchs sur une connexion backend, au-delà duquel cette connexion sera automatiquement interrompue. Cela permet d’interrompre automatiquement les connexions défaillantes sans avoir à écrire des règles explicites pour elles. La valeur par défaut est zéro, ce qui indique qu’aucun seuil n’est défini, de sorte qu’aucun événement ne provoquera la fermeture d’une connexion. Attention, certains serveurs H2 peuvent occasionnellement provoquer quelques glitchs sur des connexions longues, aussi toute valeur non nulle ici devrait probablement être de l’ordre des centaines ou des milliers pour être efficace sans affecter les serveurs légèrement défaillants. Il est également possible de ne tuer les connexions qu’après dépassement d’un certain seuil d’utilisation du CPU, en utilisant “tune.glitches.kill.cpu-usage”. Notez qu’une fermeture gracieuse est tentée à 75 % du seuil configuré en annonçant un GOAWAY pour un flux futur. Cela garantit qu’une connexion légèrement défaillante cessera d’être utilisée après un certain temps sans risquer d’interrompre les transferts en cours.

Voir également : tune.h2.fe.glitches-threshold, bc_glitches et tune.glitches.kill.cpu-usage

tune.h2.be.initial-window-size <number>

tune.h2.be.initial-window-size <number>

Définit la taille initiale de la fenêtre HTTP/2 pour les connexions sortantes, soit le nombre d’octets que le serveur peut envoyer avant d’attendre une confirmation de la part de HAProxy. Ce paramètre n’a d’effet que sur le contenu du payload, et non sur les en-têtes. En l’absence de réglage, la valeur par défaut commune définie par tune.h2.initial-window-size s’applique. Il peut être pertinent d’augmenter légèrement cette valeur afin d’accélérer les téléchargements ou de réduire la charge CPU sur les serveurs, au prix d’une injustice entre clients. Il est préférable d’utiliser tune.h2.be.rxbuf à la place, qui ne provoque aucune injustice. Ce paramètre n’affecte pas la consommation de ressources.

Voir également : tune.h2.initial-window-size.

tune.h2.be.max-concurrent-streams <number>

tune.h2.be.max-concurrent-streams <number>

Définit le nombre maximum de flux simultanés par connexion sortante (HTTP/2) (c’est-à-dire le nombre de requêtes en attente sur une connexion unique vers un serveur). Si ce paramètre n’est pas défini, la valeur par défaut définie par tune.h2.max-concurrent-streams s’applique. Une valeur inférieure à la valeur par défaut de 100 peut améliorer la réactivité d’un site au détriment de la maintenance de plus nombreuses connexions établies vers les serveurs. Lorsque l’option « http-reuse » est définie sur « always », il est recommandé de réduire cette valeur afin d’éviter de mélanger trop de clients différents sur la même connexion, car si un client est plus lent que les autres, un mécanisme connu sous le nom de « blocage en tête de file » a tendance à provoquer un effet en cascade sur la vitesse de téléchargement de tous les clients partageant une connexion (dans ce cas, il est conseillé de maintenir tune.h2.be.initial-window-size faible). Il est fortement recommandé de ne pas augmenter cette valeur ; certains pourraient trouver optimal de fonctionner avec des valeurs faibles (généralement 1 à 5).

tune.h2.be.max-frames-at-once <number>

tune.h2.be.max-frames-at-once <number>

Définit le nombre maximal de trames entrantes HTTP/2 traitées simultanément sur une connexion backend. Il peut être utile de le définir à une valeur faible (quelques dizaines à quelques centaines) lorsqu’on traite des tampons très volumineux, afin de maintenir une faible latence et une meilleure équité entre plusieurs connexions. La valeur par défaut est zéro, ce qui signifie qu’aucune limitation n’est appliquée.

tune.h2.be.rxbuf <size>

tune.h2.be.rxbuf <size>

Définit la taille de la mémoire tampon de réception HTTP/2 pour les connexions sortantes, en octets. Cette taille sera arrondie au multiple suivant de tune.bufsize et sera partagée entre toutes les transmissions de données (cadres HEADERS et DATA). Dans tous les cas, une mémoire tampon sera toujours attribuée à chaque flux, et 7/8 des mémoires tampons non utilisées seront partagées entre les flux en téléchargement de charge utile, permettant d’améliorer significativement les performances de téléchargement et d’éviter le blocage par tête de file (HoL) sur les connexions backend partagées entre plusieurs clients lorsque http-reuse est défini sur « always ». La fenêtre par flux annoncée est automatiquement ajustée pour refléter l’espace disponible, de sorte qu’en pratique il ne sera pas nécessaire de modifier tune.h2.be.initial-window-size. Si la valeur définie est inférieure à celle requise pour gérer tous les flux, la valeur minimale sera utilisée. La valeur par défaut est d’environ 1600k (100 flux avec des tampons de 16ko chacun).

Voir aussi : tune.h2.be.initial-window-size, tune.h2.fe.rxbuf, http-reuse.

tune.h2.fe.glitches-threshold <number>

tune.h2.fe.glitches-threshold <number>

Définit le seuil du nombre de perturbations sur une connexion frontale, au-delà duquel cette connexion sera automatiquement interrompue. Cela permet d’interrompre automatiquement les connexions défaillantes sans avoir à écrire des règles explicites pour elles. La valeur par défaut est zéro, ce qui indique qu’aucun seuil n’est défini, de sorte qu’aucun événement ne provoquera la fermeture d’une connexion. Prenez garde que certains clients H2 peuvent occasionnellement provoquer quelques perturbations sur des connexions longues, aussi toute valeur non nulle ici devrait probablement être de l’ordre des centaines ou des milliers pour être efficace sans affecter les clients légèrement défectueux. Il est également possible de n’interrompre les connexions qu’au-delà d’un certain seuil d’utilisation du processeur, en utilisant “tune.glitches.kill.cpu-usage”. Notez qu’une fermeture correcte est tentée à 75 % du seuil configuré en annonçant un GOAWAY pour un flux futur. Cela garantit qu’un client légèrement non conforme aura l’opportunité de créer une nouvelle connexion et de continuer à fonctionner sans être affecté, sans jamais déclencher la fermeture brutale, ce qui risquerait d’interrompre les transferts en cours.

Voir également : tune.h2.be.glitches-threshold, fc_glitches et tune.glitches.kill.cpu-usage

tune.h2.fe.initial-window-size <number>

tune.h2.fe.initial-window-size <number>

Définit la taille initiale de fenêtre HTTP/2 pour les connexions entrantes, soit le nombre d’octets que le client peut envoyer avant d’attendre une confirmation de la part de HAProxy. Ce paramètre n’a d’effet que sur le contenu du corps (c’est-à-dire le corps des requêtes POST), et non sur les en-têtes. Si ce paramètre n’est pas défini, la valeur par défaut commune définie par tune.h2.initial-window-size s’applique. Il peut être pertinent d’augmenter cette valeur afin de permettre des téléchargements plus rapides. La valeur par défaut est égale à tune.bufsize (16384), ce qui permet au moins 1,25 Mbps de bande passante par flux avec un temps de ping de 100 ms, ou 125 Mbps avec un temps de ping de 1 ms. Ce paramètre n’affecte pas l’utilisation des ressources. Utiliser des valeurs trop élevées peut entraîner une perte de réactivité côté client si des pages sont chargées en parallèle avec de grands téléchargements. Il est préférable d’utiliser tune.h2.fe.rxbuf à la place, qui ne provoque aucune injustice.

Voir également : tune.h2.initial-window-size.

tune.h2.fe.max-concurrent-streams <number> [args...]

tune.h2.fe.max-concurrent-streams <number> [args...]

Définit le nombre maximum de flux simultanés par connexion entrante (HTTP/2) (c’est-à-dire le nombre de requêtes en attente sur une connexion unique depuis un client). Si ce paramètre n’est pas défini, la valeur par défaut définie par tune.h2.max-concurrent-streams s’applique. Une valeur plus élevée que la valeur par défaut de 100 peut parfois améliorer légèrement le temps de chargement des pages pour des sites complexes comportant de nombreux objets de petite taille sur des réseaux à forte latence, mais peut également entraîner une utilisation accrue de la mémoire en permettant au client d’allouer plus de ressources en même temps. La valeur par défaut de 100 est généralement appropriée, et il est recommandé de ne pas modifier cette valeur. Une concurrence plus élevée a également un impact sur la charge de traitement et la latence lors de la gestion d’un grand nombre de connexions qui utilisent elles-mêmes de nombreux flux, et peut réduire la barrière contre les attaques par déni de service. La commande prend en charge les arguments optionnels suivants après le nombre :

  • rq-load { <number> | auto | ignore } :
The optional argument "rq-load" permits to dynamically adjust the
advertised concurrency based on the executing thread's run-queue load:
as long as the thread's load remains below the indicated threshold, the
configured streams limit will be advertised. When the thread's load
increases beyond the configured limit, the advertised streams limit will be
decreased proportionally to the square of the excess ratio. Target load
levels between 50 and 100 generally show very good moderation under heavy
loads. Alternately, instead of specifying an explicit number, the keyword
accepts "ignore", which is the default and means that the thread's
run-queue load will not be considered to moderate the advertised streams
limit, and "auto", which sets the limit to the "tune.runqueue-depth"
value, which generally provides good results without having to tweak
the configuration any further.
  • min <number> :
This sets the minimum advertised concurrency level when rq-load is used,
even if this results in a higher load than the configured target. This
allows to maintain a good level of interactivity on a site under very
heavy load. The minimum and default value is 1, but values between 5
and 15 can improve user experience.

Exemple :

tune.h2.fe.max-concurrent-streams 100 rq-load auto min 15

tune.h2.fe.max-frames-at-once <number>

tune.h2.fe.max-frames-at-once <number>

Définit le nombre maximal de trames entrantes HTTP/2 traitées simultanément sur une connexion frontale. Il peut être utile de le définir à une valeur faible (quelques dizaines à quelques centaines) lors de la gestion de très grands tampons afin de maintenir une faible latence et une meilleure équité entre plusieurs connexions. La valeur par défaut est zéro, ce qui signifie qu’aucune limitation n’est appliquée.

tune.h2.fe.max-rst-at-once <number>

tune.h2.fe.max-rst-at-once <number>

Définit le nombre maximal de HTTP/2 entrants RST_STREAM qui seront traités simultanément sur une connexion frontale. Dès réception du nombre spécifié de trames RST_STREAM, le gestionnaire de connexion sera placé dans une file d’attente à faible priorité et traité après toutes les autres tâches. Il peut être utile de le définir à une valeur très faible (1 ou quelques unités) afin de réduire significativement les impacts des inondations RST_STREAM. Les RST_STREAM se produisent effectivement lorsque l’utilisateur clique sur le bouton Arrêter dans son navigateur, mais les quelques millisecondes supplémentaires dues à ce ré-empilement sont généralement imperceptibles, tout en étant généralement efficaces pour réduire fortement la charge provoquée par de telles inondations. La valeur par défaut est zéro, ce qui signifie qu’aucune limitation n’est appliquée.

tune.h2.fe.max-total-streams <number>

tune.h2.fe.max-total-streams <number>

Définit le nombre maximal de flux totaux traités par connexion entrante pour HTTP/2. Dès que cette limite est atteinte, HAProxy envoie un cadre GOAWAY gracieux informant le client qu’il fermera la connexion après la fermeture de tous les flux en cours. En pratique, les clients ferment généralement aussi rapidement que possible lorsqu’ils reçoivent ce cadre, puis établissent une nouvelle connexion pour les requêtes suivantes. Cette approche peut être utile et souhaitable dans des situations où les clients restent connectés très longtemps et provoquent un déséquilibre au sein d’une ferme. Par exemple, dans certains environnements hautement dynamiques, il est possible qu’un nouveau répartiteur de charge soit instancié en temps réel pour s’adapter à une augmentation de charge, et qu’une fois la charge redescendue, il doive être arrêté sans rompre les connexions établies. En définissant une limite ici, les connexions auront une durée de vie limitée et seront régulièrement renouvelées, certaines pouvant être établies vers d’autres nœuds, afin que les ressources existantes soient rapidement libérées.

Il est important de comprendre qu’il existe une relation implicite entre cette limite et “tune.h2.fe.max-concurrent-streams” ci-dessus. En effet, HAProxy acceptera toujours le traitement de toutes les connexions potentiellement en cours entre le client et le frontal, de sorte que la limite annoncée sera toujours automatiquement augmentée de la valeur configurée dans max-concurrent-streams, qui servira de limite stricte au-delà de laquelle une violation par un client non conforme entraînera la fermeture de la connexion. Ainsi, lors du comptage du nombre de requêtes par connexion à partir des journaux, tout nombre compris entre max-total-streams et (max-total-streams + max-concurrent-streams) peut être observé, selon la vitesse à laquelle les connexions sont créées par le client.

La valeur par défaut est zéro, ce qui impose aucune limite au-delà de celles implicites par le protocole (2^30 ≈ 1,07 milliard). Des valeurs autour de 1000 peuvent déjà entraîner une renouvellement fréquent des connexions sans provoquer de latence perceptible pour la plupart des clients. Définir cette valeur trop basse peut entraîner une augmentation de la charge CPU due aux reconnexions TLS fréquentes, ainsi qu’une augmentation du temps de chargement des pages. Veuillez noter que certains outils de test de charge ne prennent pas en charge les reconnexions et peuvent signaler des erreurs avec ce paramètre ; il peut donc être nécessaire de le désactiver lors de l’exécution de benchmarks de performance. Voir également “tune.h2.fe.max-concurrent-streams”.

tune.h2.fe.rxbuf <size>

tune.h2.fe.rxbuf <size>

Définit la taille de la mémoire tampon de réception HTTP/2 pour les connexions entrantes, en octets. Cette taille sera arrondie au multiple suivant de tune.bufsize et sera partagée entre toutes les transmissions de données (cadres HEADERS et DATA). Dans tous les cas, une mémoire tampon sera toujours attribuée à chaque flux, et 7/8 des mémoires tampons non utilisées seront partagées entre les flux transmettant des charges utiles, permettant d’améliorer significativement les performances de transmission. La fenêtre par flux annoncée est automatiquement ajustée pour refléter l’espace disponible, de sorte qu’en pratique il ne devrait pas être nécessaire de modifier tune.h2.fe.initial-window-size. Si la valeur définie est inférieure à celle requise pour gérer tous les flux, la valeur minimale sera utilisée. La valeur par défaut de 1600k (100 flux avec des tampons de 16 ko chacun) permet une vitesse de transmission d’environ 130 Mbps pour un client ayant un RTT de 100 ms.

Voir également : tune.h2.fe.initial-window-size et tune.h2.be.rxbuf.

tune.h2.header-table-size <number>

tune.h2.header-table-size <number>

Définit la taille du tableau dynamique d’en-têtes HTTP/2. La valeur par défaut est de 4096 octets et ne peut pas dépasser 65536 octets. Une valeur plus élevée peut aider certains clients à envoyer des requêtes plus compactes, selon leurs capacités. Cette quantité de mémoire est consommée pour chaque connexion HTTP/2. Il est recommandé de ne pas la modifier.

tune.h2.initial-window-size <number>

tune.h2.initial-window-size <number>

Définit la valeur par défaut de la taille initiale de la fenêtre HTTP/2, sur les connexions entrantes et sortantes. Cette valeur est utilisée pour les connexions entrantes lorsque tune.h2.fe.initial-window-size n’est pas définie, et pour les connexions sortantes lorsque tune.h2.be.initial-window-size n’est pas définie. Ce paramètre est utilisé à la fois comme valeur initiale et comme minimum par flux. La valeur par défaut est égale à 16384 (tune.bufsize), ce qui permet, pour les téléchargements, une bande passante d’au moins 1,25 Mbps par flux sur un réseau affichant un temps de ping de 100 ms, ou 125 Mbps sur un réseau local à 1 ms. Lorsque le nombre de tampons reçus est inférieur au maximum, dans les limites définies par tune.h2.be.rxbuf et tune.h2.fe.rxbuf, les tampons non utilisés sont partagés entre les flux en réception. En conséquence, il n’est normalement pas utile de modifier cette valeur par défaut. Étant donné qu’un changement de cette valeur par défaut augmente à la fois les vitesses de téléchargement et provoque une plus grande injustice entre les clients lors des téléchargements, il est recommandé d’utiliser plutôt les paramètres spécifiques aux côtés tune.h2.fe.initial-window-size et tune.h2.be.initial-window-size.

tune.h2.log-errors { none | connection | stream }

tune.h2.log-errors { none | connection | stream }

Définit le niveau d’erreurs dans le démultiplexeur H2 qui déclenchera une journalisation. La valeur par défaut est « stream », ce qui signifie que toute erreur de décodage rencontrée dans le démultiplexeur entraînera l’émission d’un journal. La valeur « connection » indique que seules les erreurs entraînant l’invalidation de la connexion produiront une journalisation. Enfin, « none » indique qu’aucune erreur de décodage ne produira de journal. Il est recommandé de définir au moins « connection » afin de détecter les anomalies protocolaires, même si cela implique de passer temporairement à « none » pendant les périodes difficiles.

tune.h2.max-concurrent-streams <number>

tune.h2.max-concurrent-streams <number>

Définit le nombre maximal par défaut de flux simultanés par connexion (HTTP/2) (c’est-à-dire le nombre de requêtes en cours sur une connexion unique). Cette valeur est utilisée pour les connexions entrantes lorsque tune.h2.fe.max-concurrent-streams n’est pas définie, et pour les connexions sortantes lorsque tune.h2.be.max-concurrent-streams n’est pas définie. La valeur par défaut est 100. L’impact varie selon le côté ; veuillez consulter les deux paramètres ci-dessus pour plus de détails. Il est recommandé de ne pas utiliser ce paramètre et de passer aux paramètres par côté à la place. Une valeur nulle désactive la limite, permettant à un client unique de créer autant de flux qu’autorisé par HAProxy. Il est fortement recommandé de ne pas modifier cette valeur.

tune.h2.max-frame-size <number>

tune.h2.max-frame-size <number>

Définit la taille maximale de trame HTTP/2 que HAProxy annonce être prêt à recevoir de ses pairs. La valeur par défaut est la plus grande entre 16384 et la taille de tampon (tune.bufsize). En tout état de cause, HAProxy n’annonce pas de prise en charge de tailles de trames supérieures à celles des tampons. Le principal objectif de ce paramètre est de permettre de limiter la taille maximale de trame lorsqu’on utilise des tampons de grande taille. Des tailles de trames trop importantes peuvent avoir un impact sur les performances ou provoquer un comportement anormal chez certains pairs. Il est fortement recommandé de ne pas modifier cette valeur.

tune.h2.zero-copy-fwd-send { on | off }

tune.h2.zero-copy-fwd-send { on | off }

Active (« on ») ou désactive (« off ») l’envoi en copie zéro des données pour le multiplexeur H2. Activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding

tune.http.cookielen <number>

tune.http.cookielen <number>

Définit la longueur maximale des cookies capturés. Il s’agit de la valeur maximale autorisée pour la directive « capture cookie xxx len yyy », toute valeur supérieure étant automatiquement tronquée à cette valeur. Il est important de ne pas définir une valeur trop élevée, car toutes les captures de cookies allouent toujours cette taille, quelle que soit leur valeur configurée (elles partagent un même pool). Cette valeur est par requête et par réponse, donc la mémoire allouée est deux fois cette valeur par connexion. Si non spécifié, la limite est fixée à 63 caractères. Il est recommandé de ne pas modifier cette valeur.

tune.http.logurilen <number>

tune.http.logurilen <number>

Définit la longueur maximale de l’URI de requête dans les journaux. Cela empêche le troncature des URI de requête longs contenant des chaînes de requête précieuses dans les lignes de journal. Ceci n’est pas lié aux limites syslog. Si vous augmentez cette limite, vous pouvez également augmenter le paramètre ’log … len yyy’. Votre démon syslog peut également nécessiter des directives de configuration spécifiques. La valeur par défaut est 1024.

tune.http.maxhdr <number>

tune.http.maxhdr <number>

Définit le nombre maximal d’en-têtes autorisés dans les messages HTTP reçus. Lorsqu’un message contient un nombre d’en-têtes supérieur à cette valeur (y compris la première ligne), il est rejeté avec un code d’état « 400 Bad Request » pour une requête, ou « 502 Bad Gateway » pour une réponse. La valeur par défaut est 101, suffisante pour toutes les utilisations, étant donné que le serveur Apache largement déployé utilise la même limite. Il peut être utile d’augmenter cette limite temporairement afin de permettre le fonctionnement d’une application défectueuse jusqu’à sa correction. La plage acceptée est 1..32767. Prenez en compte que chaque nouvel en-tête consomme 32 bits de mémoire par flux, n’augmentez donc pas cette limite de manière excessive.

Notez que HTTP/1.1 est un protocole texte, il n’existe donc aucune limite particulière lors de l’envoi du message. La limite appliquée lors de l’analyse du message est suffisante. HTTP/2 et HTTP/3 sont des protocoles binaires et nécessitent une étape de codage. Une limite est également définie lors du codage des en-têtes afin de respecter les contraintes imposées par les protocoles. Cette limite est suffisamment élevée, mais n’est pas documentée intentionnellement. La même limite s’applique aux premières étapes du décodage, pour la même raison.

tune.idle-pool.shared { full | on | off }

tune.idle-pool.shared { full | on | off }

Contrôle le partage des pools de connexions inactives entre les threads pour un même serveur. Il peut être activé pour tous les threads d’un même groupe de threads (‘on’), activé pour tous les threads (‘full’) ou désactivé (‘off’). La valeur par défaut consiste à partager les pools entre les threads du même groupe de threads (‘on’), afin de minimiser le nombre de connexions persistantes vers un serveur et d’optimiser le taux de réutilisation des connexions. Le partage avec des threads provenant d’autres groupes de threads peut avoir un impact sur les performances, et n’est pas activé par défaut, mais peut être utile si la réutilisation maximale des connexions est une priorité. Pour faciliter le débogage ou en cas de suspicion de bug dans HAProxy concernant la réutilisation des connexions, il peut être pratique de désactiver de force le partage des pools inactifs entre plusieurs threads, et de forcer cette option à « off ». Il est fortement déconseillé de désactiver cette option sans définir une valeur conservatrice sur « pool-low-conn » pour tous les serveurs qui dépendent de la réutilisation des connexions afin d’atteindre un haut niveau de performance, sinon les connexions pourraient être fermées très fréquemment à mesure que le nombre de threads augmente.

tune.idletimer <timeout>

tune.idletimer <timeout>

Définit la durée après laquelle HAProxy considère qu’un tampon vide est probablement associé à un flux inactif. Cela permet d’ajuster de manière optimale certaine taille de paquets lors du transfert de données importantes et petites de façon alternée. La décision d’utiliser splice() ou d’envoyer des tampons volumineux en SSL est influencée par ce paramètre. La valeur est exprimée en millisecondes, comprise entre 0 et 65535. Une valeur nulle signifie que HAProxy ne tentera pas de détecter les flux inactifs. La valeur par défaut est 1000, qui semble correctement détecter les pauses utilisateur (par exemple, lire une page avant de cliquer). Il n’y a aucune raison de modifier cette valeur. Veuillez consulter tune.ssl.maxrecord ci-dessous.

tune.listener.default-shards { by-process | by-thread | by-group }

tune.listener.default-shards { by-process | by-thread | by-group }

Par défaut, toutes les lignes « bind » créent une seule partition, c’est-à-dire un seul socket que tous les threads du processus écoutent. Avec un grand nombre de threads, cela n’est pas très efficace et peut même entraîner un surcroît important de charge dans le noyau pour mettre à jour l’état de surveillance ou distribuer les événements aux différents threads. Les systèmes d’exploitation modernes prennent en charge l’équilibrage des connexions entrantes, un mécanisme qui permet de lier plusieurs sockets à la même adresse et au même port, et de répartir uniformément toutes les connexions entrantes entre ces sockets afin que chaque thread ne voie que les connexions en attente dans le socket auquel il est lié. Cela réduit considérablement la charge côté noyau et améliore les performances dans le chemin des connexions entrantes. Ce mécanisme est généralement activé dans HAProxy à l’aide de l’option « shards » sur les lignes « bind », qui vaut 1 par défaut, ce qui signifie qu’un écouteur est unique par processus. Sur les systèmes disposant de nombreux processeurs, il peut être plus pratique de modifier ce paramètre par défaut en « by-thread » afin de toujours créer un socket d’écoute par thread, ou en « by-group » afin de toujours créer un socket d’écoute par groupe de threads. Faites attention à l’utilisation des descripteurs de fichiers avec « by-thread », car chaque écouteur nécessite autant de sockets qu’il y a de threads. Certains systèmes d’exploitation (par exemple FreeBSD) limitent à 256 le nombre de sockets sur une même adresse. Notez que « by-group » reste équivalent à « by-process » pour les configurations par défaut impliquant un seul groupe de threads, et revient à partager le même socket sur les systèmes qui ne prennent pas en charge ce mécanisme. La valeur par défaut est « by-group », avec un retour à « by-process » pour les systèmes ou familles de sockets qui ne prennent pas en charge les liaisons multiples.

tune.listener.multi-queue { on | fair | off }

tune.listener.multi-queue { on | fair | off }

Active (‘on’ / ‘fair’) ou désactive (‘off’) le mécanisme d’acceptation multi-file d’écouteur, qui répartit le trafic entrant sur tous les threads auxquels une directive « bind » est autorisée, plutôt que de les réserver à lui seul. Cela permet une répartition plus uniforme du trafic et une meilleure évolutivité, en particulier dans les environnements où les threads peuvent être déséquilibrés en charge en raison d’activités externes (par exemple, des interruptions réseau qui convergent sur un même thread). Le mode par défaut, « on », optimise le choix du thread en sélectionnant, parmi un échantillon, celui qui possède le moins de connexions. Il s’agit souvent du meilleur choix lorsque les connexions sont longues, car il parvient à maintenir tous les threads occupés. Un deuxième mode, « fair », parcourt tous les threads indépendamment de leur charge instantanée. Il peut être plus adapté aux connexions de courte durée, ou sur des machines disposant d’un très grand nombre de threads, où la probabilité de trouver le thread le moins chargé avec le mode « on » est faible. Enfin, il est possible de désactiver de force le mécanisme de redistribution en utilisant « off », notamment pour le dépannage, ou dans les cas où les connexions sont de courte durée et où l’on estime que le système d’exploitation assure déjà une répartition suffisamment efficace. La valeur par défaut est « on ».

tune.lua.bool-sample-conversion { normal | pre-3.1-bug }

tune.lua.bool-sample-conversion { normal | pre-3.1-bug }

Indiquez explicitement à HAProxy comment gérer les objets d’extraction d’échantillon lors de leur transmission à Lua. En effet, lors de l’utilisation des convertisseurs natifs, les extraits d’échantillons ou les variables provenant de scripts Lua (parmi d’autres) sont convertis du type interne smp en type Lua équivalent. En raison d’une implémentation historique, une ambiguïté existe concernant la gestion des booléens : lors de la conversion Lua → HAProxy smp, les booléens sont correctement conservés, mais lors de la conversion HAProxy smp → Lua, les booléens étaient par erreur convertis en entiers. Cela signifie qu’une extraction d’échantillon ou un convertisseur retournant un booléen renverrait un entier 0 ou 1 lorsqu’il est utilisé depuis Lua. Malheureusement, en Lua, les booléens et les entiers ne sont pas interchangeables. Ainsi, pour éviter toute ambiguïté, “tune.lua.bool-sample-conversion” doit être explicitement défini sur « normal » (ce qui signifie abandonner le comportement historique pour une meilleure cohérence) ou sur “pre-3.1-bug” (forcer le comportement historique afin de prévenir les dysfonctionnements des scripts existants). Si l’option n’est pas définie explicitement et qu’un script Lua est chargé à partir de la configuration, HAProxy émettra un avertissement, et l’option passera implicitement à “pre-3.1-bug” afin de conserver le comportement historique. Il est recommandé de définir cette option sur « normal » après avoir vérifié que les scripts Lua en cours d’utilisation gèrent correctement les échantillons HAProxy booléens comme des booléens.

Ce paramètre doit être défini avant toute directive « lua-load » ou « lua-load-per-thread » pour être pris en compte, sinon il est ignoré.

tune.lua.burst-timeout <timeout>

tune.lua.burst-timeout <timeout>

Le délai d’expiration « burst » s’applique à tout gestionnaire Lua. Si le gestionnaire ne parvient pas à se terminer ou à effectuer une suspension avant l’expiration du délai, il sera interrompu afin d’éviter les conflits de thread, d’empêcher le trafic de ne pas être servi trop longtemps, et d’empêcher finalement le processus de planter en raison de l’activation du watchdog. Contrairement aux autres délais d’expiration Lua, qui sont cumulatifs lors des suspensions, le délai d’expiration « burst » garantit que le temps passé dans une seule fenêtre d’exécution Lua ne dépasse pas le délai configuré.

Ici, « yield » signifie que l’exécution Lua est effectivement interrompue, soit par un appel explicite à une fonction de type lua-yielding, telle que core.(m)sleep() ou core.yield(), soit suite à une interruption forcée automatique (voir tune.lua.forced-yield), et qu’elle sera reprise ultérieurement lorsque la tâche associée sera remise en planification. Tous les gestionnaires Lua ne peuvent pas effectuer de yield : il convient de distinguer les gestionnaires pouvant effectuer un yield de ceux qui ne peuvent pas.

Pour les gestionnaires récupérables (tâches, actions…), atteindre le délai d’expiration signifie que “tune.lua.forced-yield” pourrait être trop élevé pour le système ; le réduire pourrait améliorer la situation, mais il pourrait aussi être pertinent de vérifier si l’ajout de rendus manuels à certains points clés au sein de la fonction Lua aide ou non. Cela peut également indiquer que le gestionnaire passe trop de temps dans une fonction spécifique de la bibliothèque Lua qui ne peut pas être interrompue.

Pour les gestionnaires intransigeants (convertisseurs Lua, extraits d’échantillon), cela peut simplement indiquer que le gestionnaire effectue trop de calculs, ce qui peut résulter d’une conception inappropriée, étant donné que ces gestionnaires, qui bloquent souvent le flux d’exécution de la requête, doivent se terminer rapidement afin de permettre la progression du traitement de la requête. Une approche courante de résolution consisterait à optimiser davantage la fonction Lua en termes de vitesse, car réduire “tune.lua.forced-yield” n’aiderait pas.

Ce délai d’expiration ne prend en compte que l’exécution pure du runtime Lua. Si Lua effectue un appel à core.sleep, le temps d’attente n’est pas pris en compte. Le délai d’expiration par défaut est de 1000 ms.

Note : si un cycle de ramasse-miettes Lua est initié depuis le gestionnaire (soit explicitement demandé, soit déclenché automatiquement par Lua après un certain temps), la durée de ce cycle sera également prise en compte.

En effet, il n’existe aucun moyen de déduire la durée du cycle de ramassage automatique (GC), ce qui peut entraîner certains faux positifs sur des systèmes saturés (où le GC peine à suivre et consomme la majeure partie du temps d’exécution disponible). Si tel était le cas, voici quelques pistes de résolution :

- vérification de la possibilité d'optimiser le script afin de réduire l'utilisation mémoire Lua
- ajustement des paramètres de GC Lua et/ou demande de cycles de GC manuels
  (voir : https://www.lua.org/manual/5.4/manual.html#pdf-collectgarbage)
- augmentation de tune.lua.burst-timeout

Définir la valeur à 0 désactive entièrement cette protection.

tune.lua.forced-yield <number>

tune.lua.forced-yield <number>

Ce directive force le moteur Lua à effectuer une suspension à chaque <number> d’instructions exécutées. Cela permet d’interrompre un script long et permet au planificateur HAProxy de traiter d’autres tâches, comme l’acceptation de connexions ou le transfert de trafic. La valeur par défaut est de 10 000 instructions pour les scripts chargés avec « lua-load-per-thread » et de MAX(500, 10 000 / nbthread) instructions pour les scripts chargés avec « lua-load » (valeur optimale pour les performances tout en évitant les conflits de thread dus à la concurrence pour le verrou global Lua).

Si HAProxy exécute fréquemment du code Lua mais que plus de réactivité est nécessaire, cette valeur peut être réduite. Si le code Lua est assez long et que son résultat est absolument nécessaire pour traiter les données, la valeur de <number> peut être augmentée, mais celle-ci doit être définie avec prudence, car dans un contexte multithreadé, elle pourrait accroître la contention.

tune.lua.log.loggers { on | off }

tune.lua.log.loggers { on | off }

Active (‘on’) ou désactive (‘off’) la journalisation de la sortie des scripts LUA via les journaux applicables au proxy actuel, le cas échéant.

Par défaut, ‘on’.

tune.lua.log.stderr { on | auto | off }

tune.lua.log.stderr { on | auto | off }

Active (‘on’) ou désactive (‘off’) la journalisation de la sortie des scripts LUA via stderr. Lorsqu’elle est définie sur ‘auto’, la journalisation via stderr est activée de manière conditionnelle si l’une des conditions suivantes est remplie :

- tune.lua.log.loggers est défini sur « off »
- le script est exécuté dans un contexte non proxy sans logger global
- le script est exécuté dans un contexte proxy sans logger attaché

Veuillez noter que, lorsqu’elle est activée, cette journalisation s’ajoute à la journalisation configurée via tune.lua.log.loggers.

Valeur par défaut : « auto ».

tune.lua.maxmem <number>

tune.lua.maxmem <number>

Définit la quantité maximale de mémoire RAM en mégaoctets par processus utilisable par Lua. Par défaut, elle est nulle, ce qui signifie sans limite. Il est important de définir une limite afin d’assurer qu’une erreur dans un script ne provoque pas l’épuisement de la mémoire du système.

tune.lua.openlibs [all | none | <lib>[,<lib>...]]

tune.lua.openlibs [all | none | <lib>[,<lib>...]]

Sélectionne les bibliothèques standard Lua à charger lors de l’initialisation de l’état Lua. L’argument est une liste séparée par des virgules de noms de bibliothèques provenant de l’ensemble suivant : table, io, os, string, math, utf8, package, debug. Les valeurs spéciales « all » et « none » peuvent être utilisées à la place d’une liste. « none » ne peut pas être combinée avec des noms de bibliothèques. La valeur par défaut est « all ».

Les bibliothèques base et coroutine sont toujours chargées, quelle que soit cette configuration : base fournit les fonctions Lua de base sur lesquelles HAProxy s’appuie, et coroutine est requise car HAProxy remplace coroutine.create() par une implémentation sécurisée propre à son environnement.

Notez que les appels à fork() et la création de nouveaux threads sont déjà bloqués par défaut dans HAProxy, quelle que soit cette configuration, et ne peuvent être réactivés qu’à l’aide de la directive globale « insecure-fork-wanted ». Restreindre l’ensemble des bibliothèques chargées réduit davantage la surface d’attaque exposée aux scripts Lua. En particulier : - l’omission de « os » empêche l’utilisation de os.execute() et os.exit() - l’omission de « io » empêche l’utilisation de io.open() et io.popen() - l’omission de « package » empêche le chargement de modules C natifs via require() - l’omission de « debug » empêche l’inspection interne de HAProxy via debug.getupvalue(), debug.getmetatable() ou debug.sethook()

Exemples :

tune.lua.openlibs none                    # only base + coroutine
tune.lua.openlibs string,math,table,utf8  # safe subset, no I/O or OS
tune.lua.openlibs all                     # default, load everything

Ce paramètre doit être défini avant toute directive « lua-load », « lua-load-per-thread » ou « lua-prepend-path », faute de quoi une erreur de parsing est renvoyée.

tune.lua.service-timeout <timeout>

tune.lua.service-timeout <timeout>

Ce délai d’expiration correspond à l’exécution des services Lua. Il est utile pour empêcher les boucles infinies ou des durées d’exécution trop longues en Lua. Ce délai ne prend en compte que le runtime pur Lua. Si le code Lua effectue une pause, celle-ci n’est pas prise en compte. La valeur par défaut est de 4 s.

tune.lua.session-timeout <timeout>

tune.lua.session-timeout <timeout>

Ce délai d’expiration correspond à l’exécution des sessions Lua. Il est utile pour empêcher les boucles infinies ou des durées d’exécution trop longues en Lua. Ce délai ne prend en compte que l’exécution réelle du runtime Lua. Si la session Lua effectue une pause, celle-ci n’est pas prise en compte. La valeur par défaut est de 4 s.

tune.lua.task-timeout <timeout>

tune.lua.task-timeout <timeout>

Le but est le même que “tune.lua.session-timeout”, mais ce délai d’expiration est dédié aux tâches. Par défaut, ce délai d’expiration n’est pas défini, car une tâche peut rester active pendant toute la durée de vie de HAProxy. Par exemple, une tâche utilisée pour vérifier les serveurs.

tune.max-checks-per-thread <number>

tune.max-checks-per-thread <number>

Définit le nombre de contrôles d’état actifs par thread au-delà duquel un thread tentera activement de rechercher un thread moins chargé pour exécuter le contrôle d’état, ou le mettra en file d’attente jusqu’à ce que le nombre de contrôles d’état actifs en cours d’exécution sur ce thread diminue. La valeur par défaut est zéro, ce qui signifie qu’aucune limite n’est définie. Ce paramètre peut être nécessaire dans certains environnements exécutant un très grand nombre de contrôles coûteux avec de nombreux threads lorsque la charge semble inégale, ce qui peut entraîner des délais d’expiration aléatoires des contrôles d’état au démarrage, notamment lors de l’utilisation d’OpenSSL 3.0, qui est environ 20 fois plus intensif en ressources CPU pour les contrôles d’état que les versions antérieures. Cela permettra de répartir équitablement le travail des contrôles d’état sur tous les threads. La grande majorité des configurations n’a pas besoin de modifier ce paramètre. Veuillez noter qu’une valeur trop faible peut considérablement ralentir les contrôles d’état si ces derniers sont lents à s’exécuter.

tune.maxaccept <number>

tune.maxaccept <number>

Définit le nombre maximal de connexions consécutives qu’un processus peut accepter d’affilée avant de passer à d’autres tâches. En mode mono-processus, des valeurs plus élevées permettaient d’obtenir de meilleures performances aux débits de connexion élevés, bien que cela ne soit plus pertinent avec la mise en file d’attente multiple. Cette valeur s’applique individuellement à chaque écouteur, de sorte que le nombre de processus auxquels un écouteur est lié est pris en compte. Sa valeur par défaut est 4, qui a montré les meilleurs résultats. Si une valeur nettement plus élevée a été héritée d’une configuration ancienne, il peut être utile de la supprimer, car cela améliore à la fois les performances et réduit le temps de réponse. En mode multi-processus, cette valeur est divisée par deux fois le nombre de processus auxquels l’écouteur est lié. Affecter la valeur -1 désactive complètement cette limitation. Il est normalement inutile de modifier cette valeur.

tune.maxpollevents <number>

tune.maxpollevents <number>

Définit le nombre maximal d’événements pouvant être traités simultanément lors d’un appel au système de sondage. La valeur par défaut est adaptée au système d’exploitation. Il a été observé qu’une réduction de cette valeur en dessous de 200 tend à diminuer légèrement la latence au détriment de la bande passante réseau, tandis qu’une augmentation au-dessus de 200 tend à échanger latence contre une bande passante légèrement accrue. La valeur configurée doit être inférieure ou égale à 1000000.

tune.maxrewrite <number>

tune.maxrewrite <number>

Définit l’espace mémoire réservé à cette taille en octets. Cet espace réservé est utilisé pour la réécriture ou l’ajout d’en-têtes. Les premières lectures sur les sockets ne rempliront jamais plus de bufsize-maxrewrite. Historiquement, cette valeur était définie par défaut à la moitié de bufsize, bien que cela n’ait pas beaucoup de sens puisqu’il est rare d’avoir un grand nombre d’en-têtes à ajouter. Une valeur trop élevée empêche le traitement des requêtes ou réponses volumineuses. Une valeur trop faible empêche l’ajout d’en-têtes supplémentaires aux requêtes déjà importantes ou aux requêtes POST. Il est généralement conseillé de la définir à environ 1024. Elle est automatiquement ajustée à la moitié de bufsize si elle est supérieure à cette valeur. Cela signifie que vous n’avez pas à vous soucier de cette option lors du changement de bufsize.

tune.max-rules-at-once <number>

tune.max-rules-at-once <number>

Définit le nombre maximum de règles pouvant être évaluées simultanément dans les fonctions d’évaluation de règlesets, à condition qu’elles prennent en charge la suspension. En effet, il n’est pas rare de rencontrer des configurations comportant un grand nombre de règles telles que « tcp-request content » ou « http-request ». Un grand nombre de règles combiné à des actions exigeant beaucoup de ressources processeur (par exemple, des actions agissant sur le contenu) peut entraîner une contention de thread, car toutes les règles d’un même règleset sont évaluées dans la même boucle d’interrogation si l’évaluation n’est pas interrompue. Cette option garantit qu’au plus <number> règles ne peuvent être exécutées dans la même boucle d’interrogation pour les règlesets orientés contenu (ceux qui prennent déjà en charge la suspension en raison de l’inspection du contenu). Elle force ainsi la fonction d’évaluation à suspendre, de manière à revenir dans la boucle d’interrogation suivante pour poursuivre l’évaluation.

Les jeux de règles affectés sont :

  • “tcp-request content”
  • “tcp-response content”
  • “http-request”
  • “http-response”

La valeur par défaut est 50.

tune.memory.hot-size <number>

tune.memory.hot-size <number>

Définit la quantité de mémoire par thread qui sera conservée en cache local et qui ne pourra jamais être récupérée par d’autres threads. L’accès à cette mémoire est très rapide (sans verrouillage), et en disposer d’une quantité suffisante est essentiel pour maintenir un bon niveau de performance en cas de forte contention de threads. La valeur est exprimée en octets, et sa valeur par défaut est configurée au moment de la compilation via CONFIG_HAP_POOL_CACHE_SIZE, qui vaut par défaut 524288 (512 ko). Une valeur plus élevée peut améliorer les performances dans certains scénarios d’utilisation, notamment lorsque les profils de performance indiquent une forte contrainte d’allocation mémoire. L’expérience montre qu’une valeur optimale se situe entre une et deux fois la taille du cache L2 par cœur processeur. Des valeurs trop élevées ont un impact négatif sur les performances en provoquant une utilisation inefficace des caches L3 des processeurs, et consomment davantage de mémoire. Il est recommandé de ne pas modifier cette valeur, ou de le faire par petites incréments. Pour désactiver complètement les caches CPU par thread, une valeur très faible pourrait fonctionner, mais il est préférable d’utiliser “-dMno-cache” en ligne de commande.

tune.notsent-lowat.client <size>

tune.notsent-lowat.client <size>
tune.notsent-lowat.server <size>

Ajuste le tamponage par socket du noyau afin de signaler que le côté émetteur d’une socket est plein dès que la quantité de données tamponnées atteint cette valeur augmentée de la taille de fenêtre mesurée. Le principe consiste à maintenir dans les tampons socket la quantité strictement nécessaire de données, plus une petite marge correspondant à ce qui serait envoyé au moment où haproxy tente de réémettre. Une valeur faible (généralement proche de tune.bufsize) permet de réduire significativement la consommation mémoire dans les tampons système et de diminuer la latence au niveau de l’application due au vidage des données tamponnées. Cette configuration est généralement plus efficace et plus précise que tune.sndbuf.client et tune.sndbuf.client sur les systèmes qui la supportent. Elle s’applique par connexion (connexion depuis un client ou connexion vers un serveur selon le paramètre) et n’est utilisée que pour les connexions TCP. La valeur par défaut est zéro, ce qui signifie sans limite. Cette option n’est disponible que sous Linux.

tune.pattern.cache-size <number>

tune.pattern.cache-size <number>

Définit la taille du cache de recherche de motifs à <number> entrées. Il s’agit d’un cache LRU qui conserve les recherches précédentes et leurs résultats. Ce cache est utilisé par les ACLs et les cartes lors de recherches de motifs lentes, à savoir celles utilisant les méthodes de correspondance « sub », « reg », « dir », « dom », « end », « bin », ainsi que les chaînes insensibles à la casse. Il s’applique aux expressions de motif, ce qui signifie qu’il peut mémoriser le résultat d’une recherche parmi tous les motifs spécifiés sur une ligne de configuration (y compris ceux chargés à partir de fichiers). Il invalide automatiquement les entrées mises à jour via des actions HTTP ou en ligne de commande. La taille par défaut du cache est fixée à 10 000 entrées, ce qui limite son empreinte à environ 5 Mo par process/thread sur les systèmes 32 bits et 8 Mo par process/thread sur les systèmes 64 bits, les caches étant thread/process locaux. Le risque de collision dans ce cache est très faible, de l’ordre de la taille du cache divisée par 2^64. En pratique, avec 10 000 requêtes par seconde et une taille de cache par défaut de 10 000 entrées, il y a 1 % de chance qu’une attaque par force brute provoque une collision unique après 60 ans, ou 0,1 % après 6 ans. Ce risque est considéré comme bien inférieur à celui d’une corruption mémoire causée par des composants vieillissants. Si ce niveau de risque n’est pas acceptable, le cache peut être désactivé en définissant ce paramètre à 0.

tune.peers.max-updates-at-once <number>

tune.peers.max-updates-at-once <number>

Définit le nombre maximal de mises à jour de table de persistance que HAProxy tentera de traiter en une seule fois lors de l’envoi de messages. Récupérer les données pour ces mises à jour nécessite des opérations de verrouillage qui peuvent être intensives en ressources CPU sur des machines fortement multithreadées si non limitées, et peuvent également augmenter la latence du trafic pendant le transfert initial par lots entre un processus plus ancien et un processus plus récent. À l’inverse, des valeurs faibles peuvent également entraîner un surcoût CPU plus élevé et prendre plus de temps à s’achever. La valeur par défaut est 200, et il est conseillé de ne pas la modifier.

tune.pipesize <size>

tune.pipesize <size>

Définit la taille de la mémoire tampon du noyau pour les tubes à cette taille (en octets). Par défaut, les tubes ont la taille par défaut du système. Toutefois, dans certains cas, notamment lors de l’utilisation du découpage TCP, il peut améliorer les performances d’augmenter la taille des tubes, en particulier si l’on soupçonne que les tubes ne sont pas pleins et que de nombreuses appels à splice() sont effectués. Cela a une incidence sur la taille mémoire du noyau, donc cette valeur ne doit pas être modifiée si les impacts ne sont pas compris.

tune.pool-high-fd-ratio <number>

tune.pool-high-fd-ratio <number>

Ce paramètre définit le nombre maximal de descripteurs de fichiers (en pourcentage) utilisés globalement par HAProxy par rapport au nombre maximal de descripteurs de fichiers que HAProxy peut utiliser avant de commencer à tuer les connexions inactives lorsque nous ne pouvons pas réutiliser une connexion et devons en créer une nouvelle. La valeur par défaut est 25 (un quart du nombre de descripteurs signifie qu’environ la moitié du nombre maximal de connexions frontales peut maintenir une connexion inactif derrière, tout au-delà de ce seuil ne semble généralement pas pertinent dans le cas général lorsqu’on cible la réutilisation des connexions).

tune.pool-low-fd-ratio <number>

tune.pool-low-fd-ratio <number>

Ce paramètre définit le nombre maximal de descripteurs de fichiers (en pourcentage) utilisés globalement par HAProxy par rapport au nombre maximal de descripteurs de fichiers que HAProxy peut utiliser avant de cesser de placer les connexions dans le pool inactif pour réutilisation. La valeur par défaut est 20.

tune.pt.zero-copy-forwarding { on | off }

tune.pt.zero-copy-forwarding { on | off }

Active (‘on’) ou désactive (‘off’) le transfert zéro-copie des données pour le multiplexeur en pass-through. À utiliser uniquement si le splice du noyau est également configuré. Activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding, option splice-auto, option splice-request et option splice-response

tune.quic.be.cc.cubic-min-losses <number>

tune.quic.be.cc.cubic-min-losses <number>
tune.quic.fe.cc.cubic-min-losses <number>

Définit le nombre de paquets perdus nécessaires pour que l’algorithme de contrôle de congestion Cubic considère réellement un événement de perte. En règle générale, tout événement de perte est considéré comme le résultat d’une congestion et suffisant pour que Cubic reparte d’une fenêtre plus petite. Toutefois, des expérimentations montrent qu’il existe diverses causes de pertes qui ne sont pas du tout dues à une congestion et qui peuvent simplement être qualifiées de pertes erronées, pour lesquelles l’ajustement de la fenêtre n’a aucun effet, sauf à ralentir la communication. Une mauvaise qualité du signal radio, une livraison hors ordre, une utilisation élevée du CPU par un client entraînant des délais aléatoires, ainsi que des imprécisions du timer système peuvent être parmi les causes courantes de ce phénomène. Ce paramètre permet de rendre Cubic un peu plus tolérant aux pertes erronées en modifiant le nombre minimum de pertes cumulées entre deux ACKs nécessaires pour considérer un événement de perte, qui est par défaut de 1. Des gains significatifs ont été observés expérimentalement, mais toujours accompagnés d’une augmentation de la bande passante gaspillée par les retransmissions et d’un risque accru de saturation des liens congestionnés. La valeur 2 peut être utilisée ponctuellement pour comparer certains métriques. N’allez jamais au-delà de 2 sans une analyse préalable par un expert. La valeur par défaut et minimale est 1. Utilisez toujours 1.

tune.quic.cc.cubic.min-losses <number> (deprecated)

tune.quic.cc.cubic.min-losses <number> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.cc.hystart { on | off }

tune.quic.be.cc.hystart { on | off }
tune.quic.fe.cc.hystart { on | off }

Active (‘on’) ou désactive (‘off’) l’algorithme HyStart++ (RFC 9406) pour les connexions QUIC, utilisé comme substitution à la phase de démarrage lent des algorithmes de contrôle de congestion, qui peut entraîner une perte élevée de paquets. Il est désactivé par défaut.

tune.quic.cc-hystart { on | off } (deprecated)

tune.quic.cc-hystart { on | off } (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.cc.max-frame-loss <number>

tune.quic.be.cc.max-frame-loss <number>
tune.quic.fe.cc.max-frame-loss <number>

Définit la limite à partir de laquelle un cadre QUIC unique peut être marqué comme perdu. Si cette limite est dépassée, la connexion est considérée comme défaillante et est fermée immédiatement.

La valeur par défaut est 10.

tune.quic.max-frame-loss <number> (deprecated)

tune.quic.max-frame-loss <number> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.cc.max-win-size <size>

tune.quic.be.cc.max-win-size <size>
tune.quic.fe.cc.max-win-size <size>

Définit la taille maximale par défaut de la fenêtre du contrôleur de congestion pour une connexion QUIC unique, côté frontal ou backend. La valeur doit être indiquée sous forme d’entier, éventuellement suivie d’un suffixe « k », « m » ou « g ». Elle doit être comprise entre 10k et 4g.

Le multiplexeur QUIC utilise également la taille actuelle de la fenêtre de congestion pour déterminer s’il peut allouer de nouveaux tampons de flux lors de l’émission de données. En conséquence, la taille maximale de la fenêtre de congestion sert également de limite à cet allocateur.

La valeur par défaut est de 480 ko.

Voir également les options de liaison et de serveur « quic-cc-algo ».

tune.quic.frontend.default-max-window-size <size> (deprecated)

tune.quic.frontend.default-max-window-size <size> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.cc.reorder-ratio <0..100, in percent>

tune.quic.be.cc.reorder-ratio <0..100, in percent>
tune.quic.fe.cc.reorder-ratio <0..100, in percent>

Le ratio appliqué au seuil de réordonnancement des paquets calculé. Il peut déclencher une détection de perte de paquets élevée lorsqu’il est trop petit.

La valeur par défaut est 50.

tune.quic.reorder-ratio <0..100, in percent> (deprecated)

tune.quic.reorder-ratio <0..100, in percent> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.max-idle-timeout <timeout>

tune.quic.be.max-idle-timeout <timeout>
tune.quic.fe.max-idle-timeout <timeout>

Définit le paramètre de transport QUIC max_idle_timeout sur le côté frontal ou backend. Il suit le format de temps HAProxy et s’exprime en millisecondes. Ce paramètre détermine la durée après laquelle une connexion est fermée silencieusement si elle est restée inactif pendant une période effective. Les deux extrémités s’appuient sur la même valeur négociée : - le minimum des deux paramètres si les deux ne sont pas nuls, - le maximum si seulement l’un des deux n’est pas nul, - si les deux paramètres sont nuls, cette fonctionnalité est désactivée.

Valeur par défaut : 30 s.

tune.quic.frontend.max-idle-timeout <timeout> (deprecated)

tune.quic.frontend.max-idle-timeout <timeout> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.sec.glitches-threshold <number>

tune.quic.be.sec.glitches-threshold <number>
tune.quic.fe.sec.glitches-threshold <number>

Définit le seuil du nombre de glitchs par connexion, côté frontal ou backend, au-delà duquel la connexion est automatiquement interrompue. Cela permet de tuer automatiquement les connexions défaillantes sans avoir à écrire de règles explicites pour elles. La valeur par défaut est zéro, ce qui indique qu’aucun seuil n’est défini, donc aucune occurrence ne provoquera la fermeture d’une connexion. Attention, certains clients QUIC peuvent occasionnellement provoquer quelques glitchs sur des connexions longues, donc toute valeur non nulle ici devrait probablement être de l’ordre des centaines ou des milliers pour être efficace sans affecter les clients légèrement défaillants. Il est également possible de ne tuer les connexions que lorsque la consommation du CPU dépasse un certain seuil, en utilisant “tune.glitches.kill.cpu-usage”.

Voir aussi : fc_glitches, tune.glitches.kill.cpu-usage

tune.quic.frontend.glitches-threshold <number> (deprecated)

tune.quic.frontend.glitches-threshold <number> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.fe.sec.retry-threshold <number>

tune.quic.fe.sec.retry-threshold <number>

Active dynamiquement la fonctionnalité Retry pour tous les écouteurs QUIC configurés dès que ce nombre de connexions en demi-ouverture est atteint. Une connexion en demi-ouverture est une connexion dont la négociation n’a pas encore été correctement terminée ni échouée. Pour être fonctionnel, ce paramètre nécessite que le secret de cluster soit défini ; sinon, il sera ignoré silencieusement (voir le paramètre « cluster-secret »). Ce paramètre sera également ignoré silencieusement si l’utilisation du Retry QUIC a été forcée (voir le paramètre « quic-force-retry »).

La valeur par défaut est 100.

Consultez https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 pour plus d’informations sur la réessai QUIC.

tune.quic.retry-threshold <number> (deprecated)

tune.quic.retry-threshold <number> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.fe.sock-per-conn { default-on | force-off }

tune.quic.fe.sock-per-conn { default-on | force-off }

Spécifie globalement la manière dont les connexions frontend QUIC utiliseront le socket pour les opérations receive/send. Les connexions peuvent partager le socket de l’écouteur ou chacune peut allouer son propre socket.

Valeur par défaut : « default-on ». Cette option permet d’attribuer une socket dédiée à chaque connexion QUIC. Elle est recommandée pour obtenir les meilleurs performances avec un trafic QUIC important. Elle est également la seule manière d’assurer correctement l’arrêt doux sans perte de données pour les connexions QUIC, et de gérer efficacement les erreurs temporaires lors de l’opération sendto(). Toutefois, cette option dépend de fonctionnalités avancées du pilote réseau UDP. Si la plateforme est jugée incompatible, HAProxy basculera automatiquement en mode « force-off » au démarrage. Veuillez noter que les écouteurs QUIC sur des ports privilégiés peuvent nécessiter d’être exécutés en tant qu’uid 0, ou une configuration spécifique au système pour autoriser l’uid cible à lier ces ports, comme des capacités système. Voir également la directive globale « setcap ».

La valeur « force-off » indique que les transferts QUIC se produiront sur le socket d’écoute partagé. Cette option peut constituer un bon compromis pour un trafic faible, car elle permet de réduire la consommation de descripteurs de fichiers. Toutefois, les performances ne seront pas optimales en raison d’une utilisation accrue du CPU si les écouteurs sont partagés entre de nombreux threads ou si un grand nombre de connexions QUIC peuvent être utilisées simultanément.

Ce paramètre s’applique conjointement à chaque option de liaison « quic-socket ». Si le mode « default-on » est utilisé dans le réglage global, il est activé pour chaque écouteur, sauf pour ceux configurés avec « quic-socket listener ». En revanche, si « force-off » est utilisé globalement, il s’applique à chaque instance d’écouteur, indépendamment de leur configuration individuelle.

tune.quic.socket-owner { connection | listener } (deprecated)

tune.quic.socket-owner { connection | listener } (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. La nouvelle option s’appelle “tune.quic.fe.sock-per-conn”, avec la valeur héritée « connection » correspondant à « default-on » et « listener » à « force-off ».

tune.quic.be.stream.data-ratio <0..100, in percent>

tune.quic.be.stream.data-ratio <0..100, in percent>
tune.quic.fe.stream.data-ratio <0..100, in percent>

Ce paramètre permet de configurer la limite maximale du nombre d’octets de données en transit sur chaque flux. Il est exprimé en pourcentage par rapport au paramètre de connexion QUIC rxbuf du flux, le résultat étant arrondi vers le haut à bufsize.

La valeur par défaut est 90. Cette valeur convient à la plupart des scénarios web courants, où les téléchargements sont effectués uniquement pour un ou quelques flux, tandis que les autres sont utilisés uniquement pour les téléchargements. Si la limite de connexion rxbuf reste à un niveau raisonnable, cela garantit qu’uniquement une partie des flux ouverts peut atteindre sa capacité maximale.

Dans le cas d’une application utilisant de nombreux flux de téléchargement en parallèle et souffrant d’un manque d’équité entre ces flux, il peut être pertinent de réduire ce ratio, afin d’améliorer l’équité et de réduire la bande passante par flux.

Voir aussi : “tune.quic.be.stream.rxbuf”, “tune.quic.fe.stream.rxbuf”, “tune.quic.be.stream.max-concurrent”, “tune.quic.fe.stream.max-concurrent”

tune.quic.frontend.stream-data-ratio <0..100, in percent> (deprecated)

tune.quic.frontend.stream-data-ratio  <0..100, in percent> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.stream.max-concurrent <number>

tune.quic.be.stream.max-concurrent <number>
tune.quic.fe.stream.max-concurrent <number>

Du côté frontal, cette valeur est utilisée comme valeur du paramètre de transport initial_max_streams_bidi annoncé. Elle est imposée comme nombre maximal de flux bidirectionnels que le pair distant sera autorisé à ouvrir simultanément pendant la durée de vie de la connexion. Cela limite effectivement le nombre de requêtes clientes HTTP/3 simultanées.

Valeur par défaut : 100. Notez que si vous la réduisez, cela peut limiter les capacités de mise en mémoire tampon des flux en réception, ce qui entraînerait un débit de téléchargement médiocre. Cette situation peut être corrigée en augmentant le paramètre de connexion QUIC stream rxbuf.

Du côté backend, cela est appliqué localement par HAProxy afin de limiter le nombre de requêtes simultanées multiplexées sur une seule connexion. Ce paramètre peut être restreint davantage par le contrôle de flux du pair. Il peut être nécessaire de réduire la valeur par défaut de 100 afin d’améliorer la réactivité d’un site, au prix d’un nombre plus élevé de connexions backend ouvertes. De même que du côté frontal, ce paramètre influence directement la capacité de tamponnage en réception, mais cette fois-ci en limitant la capacité de téléchargement HTTP. La taille du tampon de réception des flux QUIC peut être augmentée lorsqu’on traite principalement des réponses HTTP dont la taille dépasse “tune.bufsize”.

Voir aussi : “tune.quic.be.stream.rxbuf”, “tune.quic.fe.stream.rxbuf”, “tune.quic.be.stream.data-ratio”, “tune.quic.fe.stream.data-ratio”

tune.quic.fe.stream.max-total <number>

tune.quic.fe.stream.max-total <number>

Définit le nombre maximal de requêtes pouvant être traitées par une connexion QUIC unique. Dès que ce seuil est atteint, la connexion est fermée de manière propre. Dans HTTP/3, cela se traduit par un cadre GOAWAY. La connexion est définitivement fermée une fois toutes les transmissions restantes terminées.

Ce paramètre est appliqué comme une limite stricte sur la connexion via le mécanisme de contrôle de flux QUIC. Si un pair la violer, la connexion sera immédiatement fermée.

Ce paramètre peut être utilisé pour obliger les clients à ouvrir de nouvelles connexions de temps à autre afin de poursuivre l’émission de requêtes et éviter de maintenir des connexions trop longtemps. Toutefois, des valeurs faibles augmenteront la latence du côté client, ainsi que la consommation CPU des deux côtés en raison des échanges TLS.

La valeur par défaut est 0, ce qui signifie qu’aucune limite spécifique n’est appliquée, en dehors de la limitation imposée par le protocole QUIC (2^60, soit plus d’un milliard de milliards).

tune.quic.frontend.max-streams-bidi <number> (deprecated)

tune.quic.frontend.max-streams-bidi <number> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.stream.rxbuf <size>

tune.quic.be.stream.rxbuf <size>
tune.quic.fe.stream.rxbuf <size>

Ce paramètre constitue la limite maximale stricte du nombre d’octets de données en transit sur une connexion QUIC au niveau du frontal. Il est réutilisé comme valeur du paramètre de transport initial_max_data. Il influence directement le débit de téléchargement du pair, en fonction de la latence et de la consommation mémoire par connexion dans HAProxy.

Par défaut, la valeur est définie à 0, ce qui indique qu’elle doit être générée automatiquement comme le produit de max-concurrent et de bufsize. Cette valeur peut être augmentée, par exemple, si une application backend dépend de transferts massifs sur des réseaux à forte latence.

Voir aussi : “tune.quic.be.stream.max-concurrent”, “tune.quic.fe.stream.max-concurrent”, “tune.quic.be.stream.data-ratio”, “tune.quic.fe.stream.data-ratio”

tune.quic.frontend.max-data-size <size> (deprecated)

tune.quic.frontend.max-data-size <size> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.tx.pacing { on | off }

tune.quic.be.tx.pacing { on | off }
tune.quic.fe.tx.pacing { on | off }

Active (‘on’) ou désactive (‘off’) le support du réglage du débit pour l’émission QUIC. Par défaut, il est activé. Le but du réglage du débit est de lisser l’émission des données afin de réduire les pertes réseau. Dans la plupart des scénarios, il améliore significativement le débit en évitant les retransmissions. Toutefois, il peut être utile de le désactiver sur des réseaux présentant des caractéristiques de latence très élevées bandwidth/low afin d’éviter des délais indésirables et de réduire la consommation CPU.

Voir également les options de liaison et de serveur « quic-cc-algo ».

tune.quic.disable-tx-pacing (deprecated)

tune.quic.disable-tx-pacing (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.be.tx.udp-gso { on | off }

tune.quic.be.tx.udp-gso { on | off }
tune.quic.fe.tx.udp-gso { on | off }

Active (‘on’) ou désactive (‘off’) la prise en charge du GSO UDP pour l’émission QUIC. Par défaut, cette fonctionnalité est activée. Ce mécanisme du noyau permet d’émettre plusieurs datagrammes en une seule appel système, ce qui est plus efficace pour les transferts volumineux. Il peut être utile de la désactiver sur recommandation d’un développeur lorsqu’une anomalie est suspectée lors de l’émission.

tune.quic.disable-udp-gso (deprecated)

tune.quic.disable-udp-gso (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.listen { on | off }

tune.quic.listen { on | off }

Désactive le protocole de transport QUIC du côté frontal. Tous les écouteurs QUIC seront toujours créés, mais ils n’écouteront pas les datagrammes entrants. Ainsi, aucun trafic QUIC ne sera traité par HAProxy du côté frontal.

Valeur par défaut : « on ». Si un problème est suspecté avec le trafic QUIC, cette option permet de basculer facilement les écouteurs QUIC sans modifier chaque ligne de configuration individuellement.

Voir également l’extraction d’échantillon “quic_enabled”.

tune.quic.mem.tx-max <size>

tune.quic.mem.tx-max <size>

Définit la quantité maximale de mémoire utilisable par la pile QUIC au niveau du transport pour l’émission. Cela sert à la fois de limite aux octets en vol et aux tampons de sortie du multiplexeur. Notez que, afin d’éviter les conflits entre threads, cette limite n’est pas strictement appliquée, ce qui permet qu’elle soit dépassée occasionnellement. En outre, chaque connexion pourra toujours utiliser une fenêtre d’au moins 2 datagrammes, aussi une valeur appropriée de maxconn doit-elle être utilisée en complément.

tune.quic.frontend.max-tx-mem <size> (deprecated)

tune.quic.frontend.max-tx-mem <size> (deprecated)

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5. Il fait partie du processus d’unification de la configuration QUIC. Si utilisé, ce paramètre ne sera appliqué qu’aux connexions frontal.

tune.quic.zero-copy-fwd-send { on | off }

tune.quic.zero-copy-fwd-send { on | off }

Active (« on ») ou désactive (« off ») l’envoi en copie zéro des données pour le multiplexeur QUIC. Il est activé par défaut.

Voir aussi : tune.disable-zero-copy-forwarding

tune.renice.runtime <number>

tune.renice.runtime <number>

Cette option de configuration prend une valeur comprise entre -20 et 19. Elle applique une priorité de planification telle que documentée dans man 2 setpriority. Cette priorité est appliquée après l’analyse de la configuration, ce qui signifie qu’elle ne s’applique qu’au processus worker ou au processus autonome. Elle est généralement configurée pour attribuer une priorité supérieure à celle d’un processus effectuant l’analyse de configuration (tune.renice.startup).

Voir aussi : tune.renice.startup

tune.renice.startup <number>

tune.renice.startup <number>

Cette option de configuration prend une valeur comprise entre -20 et 19. Elle applique une priorité de planification telle que documentée dans man 2 setpriority. Cette priorité est appliquée avant l’application du reste de la configuration, ce qui peut être utile si vous souhaitez réduire la priorité pendant l’analyse de la configuration. Cette priorité est appliquée au processus autonome ou au worker avant l’analyse de la configuration. Une fois la configuration analysée, la priorité précédente est restaurée, sauf si tune.renice.runtime est utilisé.

Voir aussi : tune.renice.runtime

tune.rcvbuf.backend <size>

tune.rcvbuf.backend  <size>
tune.rcvbuf.frontend <size>

Pour la taille du tampon de réception du socket noyau sur les sockets non connectés, jusqu’à cette taille. Cela peut être utilisé avec QUIC en mode écouteur et avec le transfert de journaux sur le frontal. Les tampons système par défaut peuvent parfois être trop petits pour les sockets recevant une forte charge de trafic agrégé, entraînant des pertes et éventuellement des retransmissions (dans le cas de QUIC), ce qui peut ralentir la mise en place des connexions sous une charge élevée. La valeur est exprimée en octets, appliquée à chaque socket. En mode écouteur, les sockets sont partagés entre toutes les connexions, et le nombre total de sockets dépend de la valeur « shards » de la ligne « bind ». Il n’existe pas de valeur optimale ; une bonne valeur correspond au produit de la taille attendue par connexion multipliée par le nombre attendu de connexions. Le noyau peut réduire les valeurs trop grandes. Voir également “tune.rcvbuf.client” et “tune.rcvbuf.server” pour leurs équivalents sur les sockets connectés, ainsi que “tune.sndbuf.backend” et “tune.sndbuf.frontend” pour le paramètre d’envoi.

tune.rcvbuf.client <size>

tune.rcvbuf.client <size>
tune.rcvbuf.server <size>

Force la taille du tampon de réception socket du noyau du côté client ou serveur à la valeur spécifiée, en octets. Cette valeur s’applique à tous les frontaux et backends TCP/HTTP. Elle devrait normalement jamais être définie, et la taille par défaut (0) permet au noyau d’ajuster automatiquement cette valeur en fonction de la mémoire disponible. Toutefois, il peut parfois être utile de la définir à des valeurs très faibles (par exemple 4096) afin de réduire l’utilisation de la mémoire noyau en empêchant celui-ci de tamponner des quantités trop importantes de données reçues. Des valeurs plus faibles augmentent toutefois significativement l’utilisation du CPU.

tune.recv_enough <size>

tune.recv_enough <size>

HAProxy utilise certains indicateurs pour détecter qu’une lecture courte indique la fin des tampons de socket. L’un d’eux est qu’une lecture retourne plus de <recv_enough> octets, valeur par défaut de 10136 (7 segments de 1448 chacun). Cette valeur par défaut peut être modifiée par ce paramètre afin de mieux gérer les charges de travail comportant de nombreuses messages courts, comme les sessions telnet ou SSH.

tune.ring.queues <number>

tune.ring.queues <number>

Définit le nombre de files d’écriture situées devant les tampons circulaires. Cela peut influer sur l’utilisation du CPU lors des sessions de débogage, et une valeur trop faible ou trop élevée peut avoir un impact important. La valeur optimale a été déterminée expérimentalement par les développeurs, et il n’y a aucune raison de la modifier sauf si explicitement indiqué afin de résoudre des problèmes spécifiques. Ce paramètre ne doit pas être conservé dans la configuration après une mise à jour de version, car sa valeur optimale peut évoluer au fil du temps.

tune.runqueue-depth <number>

tune.runqueue-depth <number>

Définit le nombre maximal de tâches pouvant être traitées simultanément lors de l’exécution des tâches. La valeur par défaut dépend du nombre de threads, mais se situe entre 35 et 280, des valeurs qui tendent à offrir les débits de requêtes les plus élevés et les latences les plus faibles. Augmenter cette valeur peut entraîner une augmentation de la latence lors du traitement de I/Os, tandis qu’une valeur trop faible peut engendrer un surcoût. Les nombres élevés de threads bénéficient de valeurs plus faibles. Lors de l’expérimentation avec des valeurs beaucoup plus élevées, il peut être utile d’activer également tune.sched.low-latency et éventuellement tune.fd.edge-triggered afin de limiter la latence maximale au niveau le plus bas possible.

tune.sched.low-latency { on | off }

tune.sched.low-latency { on | off }

Active (‘on’) ou désactive (‘off’) le planificateur de tâches à faible latence. Par défaut, HAProxy traite les tâches de plusieurs classes une classe à la fois, car c’est la méthode la plus efficace. Toutefois, lorsqu’on utilise de grandes valeurs pour tune.runqueue-depth, cela peut avoir un effet mesurable sur la latence des requêtes ou des connexions. Lorsque ce paramètre à faible latence est activé, les tâches des classes de priorité inférieure sont toujours exécutées avant les autres, si elles existent. Cela permet de réduire la latence maximale subie par de nouvelles requêtes ou connexions au milieu d’un trafic massif, au prix d’un impact plus élevé sur ce trafic important. Pour une utilisation régulière, il est préférable de le laisser désactivé. La valeur par défaut est off.

tune.sndbuf.backend <size>

tune.sndbuf.backend  <size>
tune.sndbuf.frontend <size>

Pour la taille de la mémoire tampon d’envoi du socket noyau sur les sockets non connectés, jusqu’à cette taille. Cela peut être utilisé pour la journalisation UNIX et UDP côté backend, ainsi que pour QUIC en mode écouteur côté frontal. Les tampons système par défaut peuvent parfois être trop petits pour les sockets partagés entre de nombreuses connexions (ou émetteurs de journaux), entraînant des pertes et éventuellement des retransmissions, ce qui ralentit la mise en place de nouvelles connexions sous fort trafic. La valeur est exprimée en octets, appliquée à chaque socket. En mode écouteur, les sockets sont partagés entre toutes les connexions, et le nombre total de sockets dépend de la valeur « shards » de la ligne « bind ». Il n’existe pas de valeur optimale ; une bonne valeur correspond au produit de la taille attendue par connexion multipliée par le nombre attendu de connexions. Le noyau peut réduire les valeurs trop grandes. Voir également “tune.sndbuf.client” et “tune.sndbuf.server” pour leurs équivalents sur les sockets connectés, ainsi que “tune.rcvbuf.backend” et “tune.rcvbuf.frontend” pour le paramètre de réception.

tune.sndbuf.client <size>

tune.sndbuf.client <size>
tune.sndbuf.server <size>

Force la taille du tampon d’envoi socket du noyau du côté client ou serveur à la valeur spécifiée en octets. Cette valeur s’applique à tous les frontaux et backends TCP/HTTP. Elle devrait normalement ne jamais être définie, et la taille par défaut (0) permet au noyau d’ajuster automatiquement cette valeur en fonction de la mémoire disponible. Toutefois, il peut parfois être utile de la définir à des valeurs très faibles (par exemple 4096) afin de réduire l’utilisation de la mémoire noyau en empêchant celui-ci de tamponner des quantités trop importantes de données reçues. Des valeurs plus faibles augmentent toutefois significativement l’utilisation du CPU. Un autre cas d’usage consiste à éviter les délais d’expiration d’écriture avec des clients extrêmement lents, en empêchant le noyau d’attendre qu’une grande partie du tampon soit lue avant de notifier à nouveau HAProxy. Voir également tune.notsent-lowat.client et tune.notsent-lowat.server pour des paramètres plus efficaces permettant de contrôler plus finement l’utilisation de la mémoire et la réactivité sous Linux sans nuire aux performances.

tune.ssl.cachesize <number>

tune.ssl.cachesize <number>

Définit la taille du cache global des sessions SSL, en nombre de blocs. Un bloc est suffisamment grand pour contenir une session encodée sans certificat de pair. Une session encodée avec certificat de pair est stockée dans plusieurs blocs, selon la taille du certificat de pair. Un bloc utilise environ 200 octets de mémoire (selon le calcul sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE utilisé pour la fonction shctx_init). La valeur par défaut peut être imposée au moment de la compilation, sinon elle vaut 20000. Lorsque le cache est plein, les entrées les moins utilisées sont supprimées et réaffectées. Des valeurs plus élevées réduisent la fréquence de cette suppression, donc le nombre de négociations SSL coûteuses en ressources CPU, en garantissant que toutes les utilisations conservent leur session aussi longtemps que possible. Toutes les entrées sont pré-allouées au démarrage. Définir cette valeur à 0 désactive le cache des sessions SSL.

tune.ssl.capture-buffer-size <number>

tune.ssl.capture-buffer-size <number>
tune.ssl.capture-cipherlist-size <number> (deprecated)

Définit la taille maximale de la mémoire tampon utilisée pour capturer la liste des chiffres du client hello, la liste des extensions, la liste des courbes elliptiques et les formats de points de courbe elliptique. Si la valeur est 0 (valeur par défaut), la capture est désactivée ; sinon, une mémoire tampon est allouée pour chaque connexion SSL/TLS.

tune.ssl.certificate-compression { auto | off }

tune.ssl.certificate-compression { auto | off }

Ce paramètre permet de configurer la prise en charge de la compression des certificats, une extension (RFC 8879) du TLS 1.3.

Lorsqu’il est défini sur « auto », la valeur par défaut de la bibliothèque TLS est utilisée.

Avec « off », HAProxy tente de désactiver explicitement le support de la fonctionnalité. HAProxy ne tentera plus d’envoyer des certificats compressés ni d’accepter des certificats compressés.

Configure les côtés backend et frontal.

Ce mot-clé est pris en charge par OpenSSL >= 3.2.0.

La valeur par défaut est auto.

tune.ssl.default-dh-param <number>

tune.ssl.default-dh-param <number>

Définit la taille maximale des paramètres de Diffie-Hellman utilisés pour générer la clé ephemeral/temporary en cas d’échange de clés DHE. La taille finale tentera de correspondre à la taille de la clé RSA (ou DSA) du serveur (par exemple, une clé DH temporaire de 2048 bits pour une clé RSA de 2048 bits), mais ne dépassera pas cette valeur maximale. Seules les valeurs égales ou supérieures à 1024 sont autorisées. Des valeurs plus élevées augmenteront la charge CPU, et les valeurs supérieures à 1024 bits ne sont pas prises en charge par les clients Java 7 et antérieurs. Cette valeur n’est pas utilisée si des paramètres de Diffie-Hellman statiques sont fournis directement dans le fichier de certificat ou à l’aide de la directive ssl-dh-param-file. Si ni default-dh-param ni ssl-dh-param-file n’est défini, et si le fichier PEM du serveur d’un frontal donné ne spécifie pas ses propres paramètres DH, alors les chiffres DHE seront indisponibles pour ce frontal.

tune.ssl.force-private-cache

tune.ssl.force-private-cache

Cette option désactive le partage du cache de session SSL entre tous les processus. Elle ne devrait normalement pas être utilisée, car elle entraîne de nombreuses renegotiations du fait que les clients accèdent à un processus aléatoire. Toutefois, elle peut être nécessaire sur certains systèmes d’exploitation où aucune méthode de synchronisation du cache SSL n’est disponible. Dans ce cas, l’ajout d’une première couche de répartition de charge basée sur un hachage avant la couche SSL peut limiter l’impact de l’absence de partage de session.

tune.ssl.hard-maxrecord <number>

tune.ssl.hard-maxrecord <number>

Définit le nombre maximal d’octets passés à SSL_write() à tout moment. La valeur par défaut 0 signifie qu’aucune limite n’est appliquée. Contrairement à tune.ssl.maxrecord, ce paramètre ne sera pas ajusté dynamiquement. Des enregistrements plus petits peuvent réduire le débit, mais peuvent être nécessaires lors de la gestion de clients à faible empreinte.

tune.ssl.keylog { on | off }

tune.ssl.keylog { on | off }

Cette option active la journalisation des clés TLS. Elle doit être utilisée avec précaution, car elle consomme davantage de mémoire par session SSL et peut réduire les performances. Elle est désactivée par défaut.

Ces extractions d’échantillon doivent être utilisées pour générer le fichier SSLKEYLOGFILE nécessaire pour décrypter le trafic avec Wireshark.

https://tlswg.org/sslkeylogfile/draft-ietf-tls-keylogfile.html

La variable SSLKEYLOG est une série de lignes formatées de cette manière :

<Label> <space> <ClientRandom> <space> <Secret>

Le ClientRandom est fourni par l’extraction d’échantillon %[ssl_fc_client_random,hex], le secret et l’étiquette peuvent être trouvés dans le tableau ci-dessous. Vous devez générer un fichier SSLKEYLOGFILE contenant toutes les étiquettes de ce tableau.

Les extraits d’échantillons suivants sont des chaînes hexadécimales et n’ont pas besoin d’être convertis.

  SSLKEYLOGFILE Label             |  Sample fetches for the Secrets
  --------------------------------|-----------------------------------------
  CLIENT_EARLY_TRAFFIC_SECRET     |  %[ssl_xx_client_early_traffic_secret]
  CLIENT_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_xx_client_handshake_traffic_secret]
  SERVER_HANDSHAKE_TRAFFIC_SECRET |  %[ssl_xx_server_handshake_traffic_secret]
  CLIENT_TRAFFIC_SECRET_0         |  %[ssl_xx_client_traffic_secret_0]
  SERVER_TRAFFIC_SECRET_0         |  %[ssl_xx_server_traffic_secret_0]
  EXPORTER_SECRET                 |  %[ssl_xx_exporter_secret]
  EARLY_EXPORTER_SECRET           |  %[ssl_xx_early_exporter_secret]

Ces récupérations existent côté frontal (fc) ou côté backend (bc) ; remplacez « xx » par « fc » ou « bc » pour utiliser le bon côté.

Cela n’est disponible qu’avec OpenSSL 1.1.1, et est utile avec la session TLS1.3.

Si vous souhaitez générer le contenu d’un fichier SSLKEYLOGFILE avec TLS < 1.3, vous n’avez besoin que de cette ligne :

CLIENT_RANDOM %[ssl_fc_client_random,hex] %[ssl_fc_session_key,hex]

Une journalisation complète de clés pourrait être générée avec un format de journalisation de cette manière, même si cela n’est pas idéal pour syslog :

log-format "CLIENT_EARLY_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_early_traffic_secret]\n
            CLIENT_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_client_handshake_traffic_secret]\n
            SERVER_HANDSHAKE_TRAFFIC_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_server_handshake_traffic_secret]\n
            CLIENT_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_client_traffic_secret_0]\n
            SERVER_TRAFFIC_SECRET_0 %[ssl_bc_client_random,hex] %[ssl_bc_server_traffic_secret_0]\n
            EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_exporter_secret]\n
            EARLY_EXPORTER_SECRET %[ssl_bc_client_random,hex] %[ssl_bc_early_exporter_secret]"

HAProxy fournit également les formats ci-dessus sous forme de variables d’environnement prédéfinies, pouvant être utilisées directement dans une directive « log-format » :

$HAPROXY_KEYLOG_FC_LOG_FMT   frontend (client-facing) connection keys
$HAPROXY_KEYLOG_BC_LOG_FMT   backend (server-facing) connection keys

tune.ssl.keyupdate-rate-limit <limit>

tune.ssl.keyupdate-rate-limit <limit>

Limite la quantité de KeyUpdate par seconde que nous acceptons à <limit> avant de la considérer comme une inondation, et de tuer la connexion. Le traitement des KeyUpdate est coûteux en ressources CPU, et il n’y a peu de raisons de recevoir un grand nombre de ces messages. Une valeur de « 0 » désactive la limitation de débit. La valeur par défaut est 100.

tune.ssl.lifetime <timeout>

tune.ssl.lifetime <timeout>

Définit la durée pendant laquelle une session SSL mise en cache peut rester valide. Cette durée est exprimée en secondes et vaut 300 par défaut (5 minutes). Il est important de comprendre qu’elle ne garantit pas que les sessions resteront actives aussi longtemps, car si la mémoire tampon est pleine, les sessions inactives les plus anciennes seront supprimées, même si leur durée de vie configurée n’est pas atteinte. L’utilité réelle de ce paramètre est de prévenir l’utilisation de sessions trop longtemps.

tune.ssl.maxrecord <number>

tune.ssl.maxrecord <number>

Définit la quantité maximale d’octets transmis à SSL_write() au début du transfert de données. Valeur par défaut 0 signifie qu’aucune limite n’est appliquée. Au-delà de SSL/TLS, le client ne peut décrypter les données qu’une fois qu’il a reçu un enregistrement complet. Avec de grands enregistrements, cela signifie que les clients peuvent devoir télécharger jusqu’à 16 ko de données avant de commencer à les traiter. Limiter cette valeur peut améliorer les temps de chargement des pages sur les navigateurs situés sur des réseaux à haute latence ou à faible bande passante. Il est recommandé de trouver des valeurs optimales qui tiennent dans 1 ou 2 segments TCP (généralement 1448 octets sur Ethernet avec les horodatages TCP activés, ou 1460 lorsque les horodatages sont désactivés), en tenant compte de l’overhead ajouté par SSL/TLS. Des valeurs typiques de 1419 et 2859 ont donné de bons résultats lors des tests. Utilisez « strace -e trace=write » pour déterminer la meilleure valeur. HAProxy passera automatiquement à ce paramètre après avoir détecté une connexion inactif (voir tune.idletimer ci-dessus). Voir également tune.ssl.hard-maxrecord.

tune.ssl.ssl-ctx-cache-size <number>

tune.ssl.ssl-ctx-cache-size <number>

Définit la taille du cache utilisé pour stocker les certificats générés, sur <number> entrées. Il s’agit d’un cache LRU. Comme la génération dynamique d’un certificat SSL est coûteuse, ceux-ci sont mis en mémoire tampon. La taille du cache par défaut est fixée à 1000 entrées.

tune.streams-elasticity <number>

tune.streams-elasticity <number>

Définit un pourcentage cible de flux par connexion frontale par rapport au nombre maximum de connexions simultanées (maxconn) lorsque toutes les connexions sont établies. Ce métrique s’applique aux protocoles multiplexés comme HTTP/2 ou QUIC, où chaque connexion peut recevoir plusieurs flux. Au moins un flux est toujours garanti, donc le pourcentage doit être d’au moins 100 %. Pendant la mise en place de la connexion, HAProxy annonce dynamiquement des flux supplémentaires jusqu’à la limite configurée, tout en maintenant le rapport cible. À l’établissement de la connexion, chaque connexion frontale reçoit au moins un flux ; les flux supplémentaires sont attribués selon le pourcentage cible et les limites de flux configurées. Cela garantit une allocation de flux efficace dans des conditions de charge variables (plus de flux en cas de faible charge, moins de flux en cas de forte charge).

Les sites très dynamiques, avec de nombreux objets par page, bénéficient de ratios élevés, permettant un grand nombre de flux par connexion. Les sites utilisant en moyenne moins de flux (WebSocket, code d’application) peuvent préférer des ratios plus faibles, proches de 120 ou 150 (20 à 50 % de flux supplémentaires par rapport aux connexions), afin d’éviter un nombre excessif de flux sous charge soutenue.

La valeur par défaut est 0, ce qui signifie qu’aucune restriction n’est appliquée à ce niveau, de sorte que seules les configurations H2 et QUIC s’appliquent (avec le paramètre par défaut de 100 flux par connexion, ce qui correspond à 10000 %). Ce paramètre reste recommandé pour les déploiements de petite taille (maxconn d’environ mille). Les configurations de taille modérée (quelques milliers à dizaines de milliers de connexions) fixent généralement ce ratio entre 1000 et 5000, permettant 10 à 50 flux par connexion en charge maximale. Les déploiements à grande échelle (centaines de milliers à millions de connexions) peuvent utiliser des valeurs plus faibles (120 à 200) afin de supporter en moyenne 1,2 à 2 flux par connexion en charge maximale.

Contrairement à HTTP/2, QUIC est capable d’ajuster dynamiquement le nombre de flux simultanés pendant la durée de vie de la connexion. Toutefois, le contrôle de flux QUIC est plus strict que celui de HTTP/2, aussi est-il préférable, lors de son utilisation, de spécifier des valeurs suffisamment élevées pour éviter une latence supplémentaire sur la connexion. Il existe également une limitation pour les écouteurs QUIC avec 0-RTT activé. Dans ce cas, la valeur initiale annoncée au pair ignorera l’élasticité des flux et se fondera uniquement sur le paramètre “tune.quic.fe.stream.max-concurrent”. Toutefois, le principe d’élasticité des flux restera effectif au-delà de cette annonce initiale pendant la durée de vie de la connexion.

Surveiller le nombre total de flux actifs sur les backends, y compris les files d’attente, constitue un indicateur pratique de charge cible durable et aide à éviter le surdimensionnement.

tune.stick-counters <number>

tune.stick-counters <number>

Définit le nombre de compteurs de persistance pouvant être suivis simultanément par une connexion ou une requête via les actions “track-sc*” dans les règles “tcp-request” ou “http-request”. La valeur par défaut est définie au moment de la compilation par la macro MAX_SESS_STK_CTR, et vaut 3. Il est possible de modifier cette valeur et d’ignorer celle fournie au moment de la compilation, mais celle-ci ne peut pas dépasser 100. L’augmentation de cette valeur peut être nécessaire lors du portage de configurations complexes vers HAProxy, mais les utilisateurs sont avertis des coûts associés : chaque entrée consomme 16 octets par connexion et 16 octets par requête, toutes lesquelles doivent être allouées et initialisées à zéro pour toutes les requêtes, même lorsque non utilisées. Ainsi, une valeur de 10 entraîne une augmentation de la consommation mémoire par requête de 320 octets et provoque l’effacement de cette mémoire pour chaque requête, ce qui a un impact mesurable sur le processeur. À l’inverse, lorsque aucune règle “track-sc” n’est utilisée, la valeur peut être réduite (0 étant autorisé pour désactiver entièrement les compteurs de persistance).

tune.takeover-other-tg-connections <value>

tune.takeover-other-tg-connections <value>

Par défaut, nous n’essaierons pas d’utiliser des connexions inactives provenant d’autres groupes de threads. Ce comportement peut toutefois être modifié. Les valeurs valides pour <value> sont : « none », la valeur par défaut, si elle est utilisée, aucune tentative ne sera faite pour utiliser des connexions inactives provenant d’autres groupes de threads, « restricted », dans lequel nous n’essaierons de récupérer une connexion inactives d’un autre groupe de thread que si nous utilisons des protocoles ne pouvant pas créer de nouvelles connexions, tels que le HTTP inversé, ainsi qu’en cas d’utilisation de strict-maxconn, ou « full », dans lequel nous chercherons toujours dans les autres groupes de threads des connexions inactives. Notez que l’utilisation de connexions provenant d’autres groupes de threads peut entraîner des pertes de performance, donc cette option ne doit être utilisée que si nécessaire. Notez que ce comportement est désormais contrôlé par tune.idle-pool.shared, et ce mot-clé est conservé uniquement pour assurer la compatibilité avec les configurations anciennes, et sera déprécié.

tune.vars.global-max-size <size>

tune.vars.global-max-size <size>
tune.vars.proc-max-size <size>
tune.vars.reqres-max-size <size>
tune.vars.sess-max-size <size>
tune.vars.txn-max-size <size>

Ces cinq paramètres permettent de gérer la quantité maximale de mémoire utilisée par le système de variables. « global » limite la quantité totale de mémoire disponible pour toutes les portées. « proc » limite la mémoire pour la portée processus, « sess » pour la portée session, « txn » pour la portée transaction, et « reqres » pour la mémoire allouée à chaque traitement de requête ou réponse. La comptabilité mémoire est hiérarchique, ce qui signifie que les limites plus grossières incluent les limites plus fines : « proc » inclut « sess », « sess » inclut « txn », et « txn » inclut « reqres ».

Par exemple, lorsque “tune.vars.sess-max-size” est limité à 100, “tune.vars.txn-max-size” et “tune.vars.reqres-max-size” ne peuvent pas dépasser 100 non plus. Si nous créons une variable “txn.var” contenant 100 octets, tout l’espace disponible est utilisé. Notez qu’un dépassement des limites en temps d’exécution ne provoque pas de message d’erreur, mais les valeurs pourraient être tronquées ou corrompues. Veillez donc à prévoir avec précision la quantité d’espace nécessaire pour stocker toutes vos variables.

tune.zlib.memlevel <number>

tune.zlib.memlevel <number>

Définit le paramètre memLevel lors de l’initialisation de zlib pour chaque flux. Il détermine la quantité de mémoire à allouer pour l’état interne de compression. Une valeur de 1 utilise la mémoire minimale mais est lente et réduit le taux de compression, tandis qu’une valeur de 9 utilise la mémoire maximale pour une vitesse optimale. Peut être une valeur comprise entre 1 et 9. La valeur par défaut est 8.

tune.zlib.windowsize <number>

tune.zlib.windowsize <number>

Définit la taille de fenêtre (la taille de la mémoire tampon d’historique) en tant que paramètre d’initialisation de zlib pour chaque flux. Des valeurs plus élevées de ce paramètre entraînent une meilleure compression au détriment de l’utilisation mémoire. Peut être une valeur comprise entre 8 et 15. La valeur par défaut est 15.

3.3. Débogage

anonkey <key>

anonkey <key>

Cela définit la clé d’anonymisation globale à <key>, qui doit être un nombre de 32 bits compris entre 0 et 4294967295. Il s’agit de la clé utilisée par défaut par les commandes en ligne de commande lorsque le mode anonymisé est activé. Cette clé peut également être définie en temps réel à partir de la commande en ligne de commande « set anon global-key ». Voir également l’argument de ligne de commande “-dC” dans le manuel de gestion.

debug.counters { on | off }

debug.counters { on | off }

Active (‘on’) ou désactive (‘off’) la mise à jour des compteurs d’événements dans le code. Ces compteurs sont ceux rapportés sous le type “CNT” dans la commande CLI “debug counters”. Ces compteurs ne sont disponibles que si le code a été compilé avec DEBUG_COUNTERS défini à une valeur égale ou supérieure à 1. Avec la valeur 1, les compteurs ne sont pas mis à jour par défaut (“debug.counters off”), et avec la valeur 2, ils sont mis à jour par défaut (“debug.counters on”). Il n’existe normalement aucune raison de modifier ce paramètre, sauf si une demande est formulée par un développeur, ou si l’on soupçonne une consommation anormale de CPU (auquel cas, une remontée aux développeurs est nécessaire, accompagnée d’un dump des compteurs). Il est également possible de modifier cet état en temps réel à l’aide de la commande CLI “debug counters”. Veuillez consulter le manuel de gestion.

force-cfg-parser-pause <timeout>

force-cfg-parser-pause <timeout>

Cette commande met en pause le parseur de configuration pendant <timeout> millisecondes. Cela est utile en développement ou pour tester les délais d’expiration des scripts d’initialisation, notamment pour simuler un rechargement très long. Elle nécessite que l’option expose-experimental-directives soit activée.

<timeout> est la valeur de délai d’expiration spécifiée en millisecondes par défaut, mais peut être exprimée dans toute autre unité si le nombre est suivi de l’unité, comme expliqué en haut de ce document.

Exemple :

global
    expose-experimental-directives
    force-cfg-parser-pause 10s

quick-exit

quick-exit

Cela accélère la sortie du processus ancien lors d’un rechargement en ignorant la libération des objets mémoire et des écouteurs, puisque tous ces éléments sont récupérés par le système d’exploitation à la mort du processus. Les gains sont négligeables (de l’ordre de quelques centaines de millisecondes au maximum, pour des configurations très volumineuses). L’utilisation principale concerne en réalité le cas où un bug est détecté dans le code de deinit(), car cela permet de le contourner. Il est préférable de ne pas utiliser cette option sauf instruction explicite des développeurs.

quiet

quiet

N’affichez aucun message lors du démarrage. Cela équivaut à l’argument de ligne de commande “-q”.

warn-blocked-traffic-after <time>

warn-blocked-traffic-after <time>

Cela permet d’ajuster le délai après lequel une tâche bloquée, empêchant le trafic, déclenche l’envoi d’un avertissement sur la sortie d’erreur standard. Le délai est exprimé en millisecondes et vaut 100 ms par défaut. Les valeurs autorisées doivent être comprises entre 1 ms et 1000 ms inclus. Des valeurs plus faibles provoquent fréquemment des avertissements, tandis que des valeurs plus élevées les déclenchent rarement. Le watchdog tue quand même une tâche en erreur qui ne répond pas deux fois pendant une seconde, aussi un délai d’avertissement de 1000 ms ne déclenchera normalement aucun avertissement. Il est recommandé de garder des valeurs comprises entre 10 et 100 ms afin de détecter des anomalies de configuration pouvant dégrader l’expérience utilisateur, entraînant des temps de réponse longs ou des saccades lors des sessions interactives. Par exemple, une fonction Lua d’extraction mal conçue effectuant des calculs lourds, ou un fichier de carte map_reg ou map_regm très volumineux avec un coût d’évaluation élevé, peuvent provoquer de tels problèmes. Pour comparaison, une poignée de main TLS peut consommer entre un et deux millisecondes, et la compression d’un tampon de réponse HTTP de 16 ko est d’environ une milliseconde. La sortie contient un dump de thread de la tâche défaillante, avec un backtrace et certains contextes qui aident à identifier où le temps est consommé.

zero-warning

zero-warning

Lorsque cette option est définie, HAProxy refusera de démarrer si un avertissement a été émis lors du traitement de la configuration et de son application. Cela signifie que les avertissements concernant des combinaisons de paramètres incorrectes, les avertissements relatifs à des limites très élevées qui ne pouvaient pas être appliquées, etc., entraînent une sortie avec erreur au démarrage. Quelques avertissements tardifs au démarrage ne peuvent pas être détectés par cette option, tels que l’échec de suppression des groupes supplémentaires lors du changement d’ID de groupe en mode “daemon” ou “master-worker”, ou l’échec de marquer le processus comme dumpable après le fork(). Cette option ne détecte pas les avertissements émis en cours d’exécution. Il est fortement recommandé de définir cette option sur les configurations qui ne sont pas fréquemment modifiées, car elle aide à détecter des erreurs subtiles et à maintenir la configuration propre et compatible à long terme. Notez que “haproxy -c” signalera également des erreurs dans ce cas. Cette option est équivalente à l’argument en ligne de commande “-dW”.

3.4. Ajustement du client HTTP

HTTPClient est une bibliothèque HTTP interne, pouvant être utilisée par divers sous-systèmes, par exemple dans des scripts LUA. HTTPClient n’est pas utilisé dans le chemin de données, autrement dit, il n’a rien à voir avec le trafic HTTP passant par HAProxy.

httpclient.resolvers.disabled <on|off>

httpclient.resolvers.disabled <on|off>

Désactive la résolution DNS du httpclient. Empêche la création de la section « default » des résolveurs.

Valeur par défaut : désactivé.

httpclient.resolvers.id <resolvers id>

httpclient.resolvers.id <resolvers id>

Cette option définit la section resolvers avec laquelle le httpclient tentera de résoudre.

L’option par défaut est l’identifiant de résolveur « default ». Par défaut, si cette option n’est pas utilisée, la résolution est simplement désactivée si la section n’est pas trouvée.

Toutefois, lorsque cette option est activée explicitement, une erreur de configuration est générée si elle échoue à charger.

httpclient.resolvers.prefer <ipv4|ipv6>

httpclient.resolvers.prefer <ipv4|ipv6>

Cette option permet de choisir la famille d’IP à utiliser lors de la résolution, ce qui est pratique lorsque IPv6 n’est pas disponible sur votre réseau. L’option par défaut est « ipv6 ».

httpclient.retries <number>

httpclient.retries <number>

Cette option permet de configurer le nombre d’essais de rétention du httpclient en cas d’échec d’une requête. Elle a le même effet que la directive « retries » dans un backend.

Valeur par défaut : 3.

httpclient.ssl.ca-file <cafile>

httpclient.ssl.ca-file <cafile>

Cette option définit le fichier ca à utiliser pour vérifier le certificat du serveur. Elle accepte les mêmes paramètres que l’option « ca-file » sur la ligne serveur.

Par défaut, et lorsque cette option n’est pas utilisée, la valeur est « @system-ca », qui tente de charger les certificats de la autorité de certification du système. En cas d’échec, le protocole SSL sera désactivé pour le httpclient.

Toutefois, lorsque cette option est activée explicitement, une erreur de configuration est générée en cas d’échec.

httpclient.ssl.verify [none|required]

httpclient.ssl.verify [none|required]

Fonctionne de la même manière que l’option verify sur les lignes server. Si elle est définie sur « none », les certificats des serveurs ne sont pas vérifiés. L’option par défaut est « required ».

Par défaut, et lorsque cette option n’est pas utilisée, la valeur est « required ». Si l’échec se produit, le protocole SSL sera désactivé pour le httpclient.

Toutefois, lorsque cette option est activée explicitement, une erreur de configuration est générée en cas d’échec.

httpclient.timeout.connect <timeout>

httpclient.timeout.connect <timeout>

Définir le délai maximal d’attente pour une tentative de connexion par défaut pour le client HTTP.

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

La valeur par défaut est de 5000 ms.

13 - 4. Proxies

Défauts, frontal, backend, écouteurs, mots-clés proxy et références d’action

La configuration du proxy peut être située dans un ensemble de sections :

  • defaults [<name>] [ depuis <defaults_name> ]
  • frontal <name> [ depuis <defaults_name> ]
  • backend <name> [ depuis <defaults_name> ]
  • écouter <name> [ depuis <defaults_name> ]

Une section « frontend » décrit un ensemble de sockets d’écoute acceptant les connexions clientes.

Une section « backend » décrit un ensemble de serveurs auxquels le proxy se connectera pour acheminer les connexions entrantes.

Une section « listen » définit un proxy complet comprenant ses parties frontale et arrière regroupées dans une même section. Elle est généralement utile pour le trafic TCP uniquement.

Une section « defaults » réinitialise toutes les paramètres aux valeurs documentées et définit de nouveaux paramètres utilisables par les sections ultérieures. Toutes les sections « frontend », « backend » et « listen » prennent toujours leurs paramètres initiaux à partir d’une section « defaults », par défaut la dernière apparaissant avant la section nouvellement créée. Il est possible de désigner explicitement une section « defaults » spécifique pour charger les paramètres initiaux en indiquant son nom sur la ligne de section après le mot-clé facultatif « from ». Bien que les sections « defaults » n’imposent pas de nom, il est recommandé de les nommer pour une meilleure lisibilité. C’est également la seule manière de désigner une section spécifique à utiliser à la place de la précédente par défaut. Étant donné que les noms de sections « defaults » sont facultatifs, une vérification très permissive est appliquée par défaut à leur nom, qui peut même se chevaucher. Toutefois, si une section « defaults » est référencée par une autre section, son nom doit respecter la syntaxe imposée aux noms de proxy, et ce nom doit être unique parmi les sections « defaults ». Veuillez noter qu’indépendamment de ce qui est actuellement autorisé, il est recommandé d’éviter les noms de section en double en général et de respecter la même syntaxe que pour les noms de proxy. Cette règle pourrait être imposée dans une version future. En outre, un avertissement est émis si une section « defaults » est utilisée explicitement par un proxy tout en étant également utilisée implicitement par un autre, car elle est la dernière définie. Il est fortement conseillé de ne pas mélanger ces deux modes d’utilisation, en utilisant toujours des références explicites ou en ajoutant une dernière section « defaults » commune réservée à toutes les utilisations implicites.

Notez qu’il est même possible qu’une section defaults prenne ses paramètres initiaux à partir d’une autre, et hérite ainsi des paramètres à travers plusieurs niveaux de sections defaults. Cela peut être pratique pour établir certains profils de configuration afin de regrouper des paramètres par défaut (par exemple, TCP contre HTTP ou délais courts contre délais longs), mais cela peut rapidement devenir difficile à suivre.

Par défaut, les sections defaults nommées sont conservées après l’analyse de la configuration. Cela permet de les réutiliser pour la création dynamique de backends. Ce comportement peut être modifié globalement via le mot-clé “tune.defaults.purge”.

Tous les noms de proxy doivent être composés de lettres majuscules et minuscules, de chiffres, de ‘-’ (tiret), ‘_’ (souligné), ‘.’ (point) et ‘:’ (deux-points). Les noms d’ACL sont sensibles à la casse, ce qui signifie que « www » et « WWW » représentent deux proxies différents.

Historiquement, tous les noms de proxy pouvaient se chevaucher sous certaines conditions (par exemple, lorsqu’ils ne possédaient pas les mêmes capacités frontend/backend), mais cela provoquait trop de problèmes dans les journaux ainsi que des ambiguïtés lors des opérations en ligne de commande, des noms de tables de persistance et de la récupération des statistiques. Il est désormais obligatoire que deux proxies aient des noms différents, quelle que soit leur capacité respective.

Actuellement, deux modes de proxy majeurs sont pris en charge : « tcp », également appelé couche 4, et « http », également appelé couche 7. En mode couche 4, HAProxy transfère simplement le trafic bidirectionnel entre deux extrémités. En mode couche 7, HAProxy analyse le protocole et peut interagir avec celui-ci en autorisant, bloquant, redirigeant, ajoutant, modifiant ou supprimant des contenus arbitraires dans les requêtes ou les réponses, selon des critères arbitraires.

En mode HTTP, le traitement appliqué aux requêtes et réponses transitées sur une connexion dépend de la combinaison des options HTTP du frontal et du backend. HAProxy prend en charge 3 modes de connexion :

  • KAL : maintien de la connexion ouverte (« option http-keep-alive »), qui est le mode par défaut : toutes les requêtes et réponses sont traitées, et les connexions restent ouvertes mais inactives entre les réponses et les nouvelles requêtes.

  • SCL : fermeture du serveur (“option http-server-close”) : la connexion orientée serveur est fermée après la réception de la fin de la réponse, mais la connexion orientée client reste ouverte.

  • CLO : fermeture (“option httpclose”) : la connexion est fermée après la fin de la réponse, et l’en-tête “Connection: close” est ajouté dans les deux sens.

Le mode effectif appliqué à une connexion passant par un frontal et un backend peut être déterminé par les deux modes de proxy selon la matrice suivante, mais en résumé, les modes sont symétriques, keep-alive est l’option la plus faible et close est l’option la plus forte.

               Backend mode
                | KAL | SCL | CLO
            ----+-----+-----+----
            KAL | KAL | SCL | CLO
            ----+-----+-----+----
   mode     SCL | SCL | SCL | CLO
            ----+-----+-----+----
            CLO | CLO | CLO | CLO

Il est possible de chaîner un frontend TCP à un backend HTTP. Cette configuration est sans intérêt si seule la circulation HTTP est traitée. Toutefois, elle peut être utilisée pour gérer plusieurs protocoles au sein du même frontend. Dans ce cas, la connexion client est d’abord traitée comme une connexion TCP brute avant d’être mise à niveau vers HTTP. Avant la mise à niveau, les traitements de contenu sont effectués sur des données brutes. Une fois la mise à niveau effectuée, les données sont analysées et stockées à l’aide d’une représentation interne appelée HTX, et il n’est plus possible de s’appuyer sur la représentation brute. Il n’existe aucun moyen de revenir en arrière.

Il existe deux types de mises à jour : les mises à jour in situ et les mises à jour destructrices. La première implique une mise à jour TCP vers HTTP/1. Dans HTTP/1, le traitement des requêtes est sérialisé, de sorte que le flux applicatif peut être préservé. La seconde implique une mise à jour TCP vers HTTP/2. Étant donné qu’il s’agit d’un protocole multiplexé, le flux applicatif ne peut être associé à aucun flux HTTP/2 et est donc détruit. De nouveaux flux applicatifs sont ensuite créés lorsque HAProxy reçoit de nouveaux flux HTTP/2 au niveau inférieur, dans le multiplexeur H2. Il est important de comprendre cette différence, car elle change radicalement la manière de traiter les données. Lorsqu’une mise à jour HTTP/1 est effectuée, les traitements appliqués sur les données brutes ne sont ni perdus ni réexécutés, tandis qu’en cas de mise à jour HTTP/2, les flux applicatifs sont distincts et toutes les règles frontales sont systématiquement évaluées sur chacun. Comme indiqué, le premier flux, le flux TCP, est détruit, mais uniquement après l’évaluation des règles frontales.

Il existe un autre point important à comprendre lorsqu’un traitement HTTP est effectué à partir d’un proxy TCP. Bien que HAProxy soit capable d’analyser HTTP/1 en temps réel à l’aide des règles tcp-request, il n’est pas possible pour HTTP/2. Seul le préambule HTTP/2 peut être analysé. Il s’agit d’une limitation majeure concernant l’analyse du contenu HTTP en TCP. Concrètement, il n’est possible de déterminer qu’avec certitude si les données reçues sont au format HTTP. Par exemple, il n’est pas possible de choisir un backend en fonction de la valeur de l’en-tête Host, alors qu’il s’agit d’une opération triviale dans HTTP/1.. Heureusement, une solution existe pour atténuer cet inconvénient.

Il existe deux façons d’effectuer une mise à niveau HTTP. La première, méthode historique, consiste à sélectionner un backend HTTP. La mise à niveau a lieu lorsque le backend est défini. Ainsi, pour les mises à niveau in situ, seule la configuration du backend est prise en compte dans le traitement des données HTTP. Pour les mises à niveau destructrices, le flux applicatif est détruit, ce qui arrête son traitement. Avec cette méthode, les possibilités de choisir un backend avec une connexion HTTP/2 sont réellement limitées, comme mentionné ci-dessus, et un peu inutiles car le flux est détruit. La deuxième méthode consiste à effectuer la mise à niveau pendant l’évaluation des règles tcp-request content, grâce à l’action « switch-mode http ». Dans ce cas, la mise à niveau est effectuée dans le contexte du frontal et il est possible de définir des directives HTTP dans ce frontal. Pour les mises à niveau in situ, elle offre toute la puissance de l’analyse HTTP dès que possible. Elle n’est pas très éloignée d’un frontal HTTP. Pour les mises à niveau destructrices, cela ne change rien, sauf qu’il est inutile de choisir un backend sur une information limitée. Il s’agit bien sûr de la méthode recommandée. Ainsi, tester le protocole de la requête dans les règles tcp-request content pour effectuer une mise à niveau HTTP est suffisant. Toutes les manipulations HTTP restantes peuvent être déplacées vers le jeu de règles http-request du frontal. Mais gardez à l’esprit que les règles tcp-request content sont toujours évaluées sur chaque flux, ce qui ne peut pas être modifié.

4.1. Matrice des mots-clés proxy

La liste suivante de mots-clés est prise en charge. La plupart d’entre eux ne peuvent être utilisés que dans un ensemble limité de types de sections. Certains sont marqués comme « dépréciés » car ils sont hérités d’une ancienne syntaxe pouvant prêter à confusion ou être fonctionnellement limitée, et de nouveaux mots-clés recommandés ont été introduits pour les remplacer. Les mots-clés marqués par «(*)» peuvent être inversés de manière optionnelle en utilisant le préfixe « no », par exemple « no option contstats ». Cette fonctionnalité est utile lorsque l’option est activée par défaut et doit être désactivée pour une instance spécifique. Ces options peuvent également être préfixées par « default » afin de restaurer les paramètres par défaut, indépendamment de ce qui a été spécifié dans une section « defaults » précédente. Les mots-clés pris en charge dans les sections « defaults » marqués par «(!) » ne sont pris en charge que dans les sections « defaults » nommées, et non dans les sections anonymes.

Note : Certains directives dangereuses et non recommandées sont intentionnellement omises dans la matrice suivante. Cela est voulu. Ces directives sont documentées. Mais leur omission dans cette liste constitue une autre manière de dissuader toute personne souhaitant les utiliser.

 keyword                              defaults   frontend   listen    backend
------------------------------------+----------+----------+---------+---------
acl                                       X (!)      X         X         X
backlog                                   X          X         X         -
balance                                   X          -         X         X
be-unpublished                            -          -         X         X
bind                                      -          X         X         -
capture cookie                            -          X         X         -
capture request header                    -          X         X         -
capture response header                   -          X         X         -
clitcpka-cnt                              X          X         X         -
clitcpka-idle                             X          X         X         -
clitcpka-intvl                            X          X         X         -
compression                               X          X         X         X
cookie                                    X          -         X         X
crt                                       -          X         X         -
declare capture                           -          X         X         -
default-server                            X          -         X         X
default_backend                           X          X         X         -
description                               -          X         X         X
disabled                                  X          X         X         X
dispatch                    (deprecated)  -          -         X         X
email-alert from                          X          X         X         X
email-alert level                         X          X         X         X
email-alert mailers                       X          X         X         X
email-alert myhostname                    X          X         X         X
email-alert to                            X          X         X         X
enabled                                   X          X         X         X
errorfile                                 X          X         X         X
errorfiles                                X          X         X         X
errorloc                                  X          X         X         X
errorloc302                               X          X         X         X
-- keyword -------------------------- defaults - frontend - listen -- backend -
errorloc303                               X          X         X         X
error-log-format                          X          X         X         -
external-check command                    X          -         X         X
external-check path                       X          -         X         X
force-persist                             -          -         X         X
force-be-switch                           -          X         X         -
filter                                    -          X         X         X
filter-sequence                           -          X         X         X
fullconn                                  X          -         X         X
guid                                      -          X         X         X
hash-balance-factor                       X          -         X         X
hash-preserve-affinity                    X          -         X         X
hash-type                                 X          -         X         X
http-after-response                       X (!)      X         X         X
http-check comment                        X          -         X         X
http-check connect                        X          -         X         X
http-check disable-on-404                 X          -         X         X
http-check expect                         X          -         X         X
http-check send                           X          -         X         X
http-check send-state                     X          -         X         X
http-check set-var                        X          -         X         X
http-check unset-var                      X          -         X         X
http-error                                X          X         X         X
http-request                              X (!)      X         X         X
http-response                             X (!)      X         X         X
http-reuse                                X          -         X         X
http-send-name-header                     X          -         X         X
id                                        -          X         X         X
ignore-persist                            -          -         X         X
load-server-state-from-file               X          -         X         X
log                                  (*)  X          X         X         X
log-format                                X          X         X         -
log-format-sd                             X          X         X         -
log-tag                                   X          X         X         X
log-steps                                 X          X         X         -
max-keep-alive-queue                      X          -         X         X
max-session-srv-conns                     X          X         X         -
maxconn                                   X          X         X         -
mode                                      X          X         X         X
monitor fail                              -          X         X         -
monitor-uri                               X          X         X         -
option abortonclose                  (*)  X          X         X         X
option allbackups                    (*)  X          -         X         X
option checkcache                    (*)  X          -         X         X
option clitcpka                      (*)  X          X         X         -
option contstats                     (*)  X          X         X         -
option disable-h2-upgrade            (*)  X          X         X         -
option dontlog-normal                (*)  X          X         X         -
option dontlognull                   (*)  X          X         X         -
-- keyword -------------------------- defaults - frontend - listen -- backend -
option external-check                     X          -         X         X
option forwardfor                         X          X         X         X
option forwarded                     (*)  X          -         X         X
option h1-case-adjust-bogus-client   (*)  X          X         X         -
option h1-case-adjust-bogus-server   (*)  X          -         X         X
option http-buffer-request           (*)  X          X         X         X
option http-drop-request-trailers    (*)  X          -         -         X
option http-drop-response-trailers   (*)  X          -         X         -
option http-ignore-probes            (*)  X          X         X         -
option http-keep-alive               (*)  X          X         X         X
option http-no-delay                 (*)  X          X         X         X
option http-pretend-keepalive        (*)  X          -         X         X
option http-restrict-req-hdr-names        X          X         X         X
option http-server-close             (*)  X          X         X         X
option http-use-proxy-header         (*)  X          X         X         -
option httpchk                            X          -         X         X
option httpclose                     (*)  X          X         X         X
option httplog                            X          X         X         -
option httpslog                           X          X         X         -
option idle-close-on-response        (*)  X          X         X         -
option independent-streams           (*)  X          X         X         X
option ldap-check                         X          -         X         X
option log-health-checks             (*)  X          -         X         X
option log-separate-errors           (*)  X          X         X         -
option logasap                       (*)  X          X         X         -
option mysql-check                        X          -         X         X
option nolinger                      (*)  X          X         X         X
option originalto                         X          X         X         X
option persist                       (*)  X          -         X         X
option pgsql-check                        X          -         X         X
option prefer-last-server            (*)  X          -         X         X
option redispatch                    (*)  X          -         X         X
option redis-check                        X          -         X         X
option smtpchk                            X          -         X         X
option socket-stats                  (*)  X          X         X         -
option splice-auto                   (*)  X          X         X         X
option splice-request                (*)  X          X         X         X
option splice-response               (*)  X          X         X         X
option spop-check                         X          -         X         X
option srvtcpka                      (*)  X          -         X         X
option ssl-hello-chk                      X          -         X         X
-- keyword -------------------------- defaults - frontend - listen -- backend -
option tcp-check                          X          -         X         X
option tcp-smart-accept              (*)  X          X         X         -
option tcp-smart-connect             (*)  X          -         X         X
option tcpka                              X          X         X         X
option tcplog                             X          X         X         -
option transparent      (deprecated) (*)  X          -         X         X
option use-small-buffers             (*)  X          -         X         X
persist rdp-cookie                        X          -         X         X
quic-initial                              X (!)      X         X         -
rate-limit sessions                       X          X         X         -
redirect                                  -          X         X         X
-- keyword -------------------------- defaults - frontend - listen -- backend -
retries                                   X          -         X         X
retry-on                                  X          -         X         X
server                                    -          -         X         X
server-state-file-name                    X          -         X         X
server-template                           -          -         X         X
source                                    X          -         X         X
srvtcpka-cnt                              X          -         X         X
srvtcpka-idle                             X          -         X         X
srvtcpka-intvl                            X          -         X         X
stats admin                               -          X         X         X
stats auth                                X          X         X         X
stats enable                              X          X         X         X
stats hide-version                        X          X         X         X
stats http-request                        -          X         X         X
stats realm                               X          X         X         X
stats refresh                             X          X         X         X
stats scope                               X          X         X         X
stats show-desc                           X          X         X         X
stats show-legends                        X          X         X         X
stats show-node                           X          X         X         X
stats show-version                        X          X         X         X
stats uri                                 X          X         X         X
-- keyword -------------------------- defaults - frontend - listen -- backend -
stick match                               -          -         X         X
stick on                                  -          -         X         X
stick store-request                       -          -         X         X
stick store-response                      -          -         X         X
stick-table                               -          X         X         X
tcp-check comment                         X          -         X         X
tcp-check connect                         X          -         X         X
tcp-check expect                          X          -         X         X
tcp-check send                            X          -         X         X
tcp-check send-lf                         X          -         X         X
tcp-check send-binary                     X          -         X         X
tcp-check send-binary-lf                  X          -         X         X
tcp-check set-var                         X          -         X         X
tcp-check unset-var                       X          -         X         X
tcp-request connection                    X (!)      X         X         -
tcp-request content                       X (!)      X         X         X
tcp-request inspect-delay                 X (!)      X         X         X
tcp-request session                       X (!)      X         X         -
tcp-response content                      X (!)      -         X         X
tcp-response inspect-delay                X (!)      -         X         X
timeout check                             X          -         X         X
timeout client                            X          X         X         -
timeout client-fin                        X          X         X         -
timeout client-hs                         X          X         X         -
timeout connect                           X          -         X         X
timeout http-keep-alive                   X          X         X         X
timeout http-request                      X          X         X         X
timeout queue                             X          -         X         X
timeout server                            X          -         X         X
timeout server-fin                        X          -         X         X
timeout tarpit                            X          X         X         X
timeout tunnel                            X          -         X         X
transparent                 (deprecated)  X          -         X         X
unique-id-format                          X          X         X         X
unique-id-header                          X          X         X         -
use_backend                               -          X         X         -
use-fcgi-app                              -          -         X         X
use-server                                -          -         X         X
------------------------------------+----------+----------+---------+---------
 keyword                              defaults   frontend   listen    backend

4.2. Référence des mots-clés triés par ordre alphabétique

Cette section décrit chaque mot-clé et son utilisation.

acl <aclname> <criterion> [flags] [operator] <value> ...

acl <aclname> <criterion> [flags] [operator] <value> ...

Déclarer ou compléter une liste d’accès.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les ACL définies dans une section defaults ne sont pas visibles depuis d’autres sections qui l’utilisent.

Exemple :

acl invalid_src  src          0.0.0.0/7 224.0.0.0/3
acl invalid_src  src_port     0:1023
acl local_dst    hdr(host) -i localhost

Voir section 7 concernant l’utilisation des ACL.

backlog <conns>

backlog <conns>

Fournir des indications au système concernant la taille approximative du tampon d’écoute souhaitée

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<conns>   is the number of pending connections. Depending on the operating
          system, it may represent the number of already acknowledged
          connections, of non-acknowledged ones, or both.

Cette option n’est significative que pour les écouteurs en mode flux, y compris ceux utilisant QUIC. Son comportement, toutefois, n’est pas identique à celui des instances QUIC.

Pour tous les écouteurs sauf QUIC, afin de se protéger contre les attaques par inondation SYN, une solution consiste à augmenter la taille de la file d’attente des SYN du système. Selon le système, cette valeur peut être ajustable via un paramètre système, ne pas être ajustable du tout, ou dépendre des indications fournies par l’application au moment de l’appel système listen(). Par défaut, HAProxy transmet la valeur maxconn du frontal à l’appel système listen(). Sur les systèmes pouvant utiliser cette valeur, il peut parfois être utile de pouvoir spécifier une valeur différente, d’où la présence de ce paramètre backlog.

Sous Linux 2.4, le paramètre est ignoré par le système. Sous Linux 2.6, il est utilisé comme indication et le système accepte au plus la plus petite puissance de deux supérieure, sans dépasser certaines limites (généralement 32768).

Pour les écouteurs QUIC, le paramètre backlog définit une limite partagée entre le nombre maximal de poignées d’établissement actives et le nombre de connexions en attente d’acceptation. La phase de poignée dépend principalement de la latence réseau avec le pair distant, tandis que la deuxième phase dépend uniquement de la charge de HAProxy. Lorsqu’une de ces limites est atteinte, haproxy commence à rejeter les paquets INITIAL, empêchant toute nouvelle allocation de connexion, jusqu’à ce que l’excédent de connexions commence à diminuer. Cette situation peut entraîner un passage silencieux des navigateurs vers des versions HTTP inférieures et le basculement vers TCP.

Voir également : « maxconn » et le guide d’ajustement du système d’exploitation cible.

balance <algorithm> [ <arguments> ]

balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]

Définir l’algorithme de répartition de charge à utiliser dans un backend.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<algorithm> is the algorithm used to select a server when doing load
            balancing. This only applies when no persistence information
            is available, or when a connection is redispatched to another
            server. <algorithm> may be one of the following:

  roundrobin  Each server is used in turns, according to their weights.
              This is the smoothest and fairest algorithm when the server's
              processing time remains equally distributed. This algorithm
              is dynamic, which means that server weights may be adjusted
              on the fly for slow starts for instance. It is limited by
              design to 4095 active servers per backend. Note that in some
              large farms, when a server becomes up after having been down
              for a very short time, it may sometimes take a few hundreds
              requests for it to be re-integrated into the farm and start
              receiving traffic. This is normal, though very rare. It is
              indicated here in case you would have the chance to observe
              it, so that you don't worry. Note: weights are ignored for
              backends in LOG mode.

  static-rr   Each server is used in turns, according to their weights.
              This algorithm is as similar to roundrobin except that it is
              static, which means that changing a server's weight on the
              fly will have no effect. On the other hand, it has no design
              limitation on the number of servers, and when a server goes
              up, it is always immediately reintroduced into the farm, once
              the full map is recomputed. It also uses slightly less CPU to
              run (around -1%). This algorithm is not usable in LOG mode.

  leastconn   The server with the lowest number of connections receives the
              connection. Round-robin is performed within groups of servers
              of the same load to ensure that all servers will be used. Use
              of this algorithm is recommended where very long sessions are
              expected, such as LDAP, SQL, TSE, etc... but is not very well
              suited for protocols using short sessions such as HTTP. This
              algorithm is dynamic, which means that server weights may be
              adjusted on the fly for slow starts for instance. It will
              also consider the number of queued connections in addition to
              the established ones in order to minimize queuing. This
              algorithm is not usable in LOG mode.

  first       The first server with available connection slots receives the
              connection. The servers are chosen from the lowest numeric
              identifier to the highest (see server parameter "id"), which
              defaults to the server's position in the farm. Once a server
              reaches its maxconn value, the next server is used. It does
              not make sense to use this algorithm without setting maxconn.
              The purpose of this algorithm is to always use the smallest
              number of servers so that extra servers can be powered off
              during non-intensive hours. This algorithm ignores the server
              weight, and brings more benefit to long session such as RDP
              or IMAP than HTTP, though it can be useful there too. In
              order to use this algorithm efficiently, it is recommended
              that a cloud controller regularly checks server usage to turn
              them off when unused, and regularly checks backend queue to
              turn new servers on when the queue inflates. Alternatively,
              using "http-check send-state" may inform servers on the load.
              This algorithm is not usable in LOG mode.

  hash        Takes a regular sample expression in argument. The expression
              is evaluated for each request and hashed according to the
              configured hash-type. The result of the hash is divided by
              the total weight of the running servers to designate which
              server will receive the request. This can be used in place of
              "source", "uri", "hdr()", "url_param()", "rdp-cookie" to make
              use of a converter, refine the evaluation, or be used to
              extract data from local variables for example. When the data
              is not available, round robin will apply. This algorithm is
              static by default, which means that changing a server's
              weight on the fly will have no effect, but this can be
              changed using "hash-type". This algorithm is not usable for
              backends in LOG mode, please use "log-hash" instead.

  source      The source IP address is hashed and divided by the total
              weight of the running servers to designate which server will
              receive the request. This ensures that the same client IP
              address will always reach the same server as long as no
              server goes down or up. If the hash result changes due to the
              number of running servers changing, many clients will be
              directed to a different server. This algorithm is generally
              used in TCP mode where no cookie may be inserted. It may also
              be used on the Internet to provide a best-effort stickiness
              to clients which refuse session cookies. This algorithm is
              static by default, which means that changing a server's
              weight on the fly will have no effect, but this can be
              changed using "hash-type". See also the "hash" option above.
              This algorithm is not usable for backends in LOG mode.

  uri         This algorithm hashes either the left part of the URI (before
              the question mark) or the whole URI (if the "whole" parameter
              is present) and divides the hash value by the total weight of
              the running servers. The result designates which server will
              receive the request. This ensures that the same URI will
              always be directed to the same server as long as no server
              goes up or down. This is used with proxy caches and
              anti-virus proxies in order to maximize the cache hit rate.
              Note that this algorithm may only be used in an HTTP backend.
              This algorithm is static by default, which means that
              changing a server's weight on the fly will have no effect,
              but this can be changed using "hash-type".

              This algorithm supports two optional parameters "len" and
              "depth", both followed by a positive integer number. These
              options may be helpful when it is needed to balance servers
              based on the beginning of the URI only. The "len" parameter
              indicates that the algorithm should only consider that many
              characters at the beginning of the URI to compute the hash.
              Note that having "len" set to 1 rarely makes sense since most
              URIs start with a leading "/".

              The "depth" parameter indicates the maximum directory depth
              to be used to compute the hash. One level is counted for each
              slash in the request. If both parameters are specified, the
              evaluation stops when either is reached.

              A "path-only" parameter indicates that the hashing key starts
              at the first '/' of the path. This can be used to ignore the
              authority part of absolute URIs, and to make sure that HTTP/1
              and HTTP/2 URIs will provide the same hash. See also the
              "hash" option above.

  url_param   The URL parameter specified in argument will be looked up in
              the query string of each HTTP GET request.

              If the modifier "check_post" is used, then an HTTP POST
              request entity will be searched for the parameter argument,
              when it is not found in a query string after a question mark
              ('?') in the URL. The message body will only start to be
              analyzed once either the advertised amount of data has been
              received or the request buffer is full. In the unlikely event
              that chunked encoding is used, only the first chunk is
              scanned. Parameter values separated by a chunk boundary, may
              be randomly balanced if at all. This keyword used to support
              an optional <max_wait> parameter which is now ignored.

              If the parameter is found followed by an equal sign ('=') and
              a value, then the value is hashed and divided by the total
              weight of the running servers. The result designates which
              server will receive the request.

              This is used to track user identifiers in requests and ensure
              that a same user ID will always be sent to the same server as
              long as no server goes up or down. If no value is found or if
              the parameter is not found, then a round robin algorithm is
              applied. Note that this algorithm may only be used in an HTTP
              backend. This algorithm is static by default, which means
              that changing a server's weight on the fly will have no
              effect, but this can be changed using "hash-type". See also
              the "hash" option above.

  hdr(<name>) The HTTP header <name> will be looked up in each HTTP
              request. Just as with the equivalent ACL 'hdr()' function,
              the header name in parenthesis is not case sensitive. If the
              header is absent or if it does not contain any value, the
              roundrobin algorithm is applied instead.

              An optional 'use_domain_only' parameter is available, for
              reducing the hash algorithm to the main domain part with some
              specific headers such as 'Host'. For instance, in the Host
              value "haproxy.1wt.eu", only "1wt" will be considered.

              This algorithm is static by default, which means that
              changing a server's weight on the fly will have no effect,
              but this can be changed using "hash-type". See also the
              "hash" option above.

  random
  random(<draws>)
              A random number will be used as the key for the consistent
              hashing function. This means that the servers' weights are
              respected, dynamic weight changes immediately take effect, as
              well as new server additions. Random load balancing can be
              useful with large farms or when servers are frequently added
              or removed as it may avoid the hammering effect that could
              result from roundrobin or leastconn in this situation. The
              hash-balance-factor directive can be used to further improve
              fairness of the load balancing, especially in situations
              where servers show highly variable response times. When an
              argument <draws> is present, it must be an integer value one
              or greater, indicating the number of draws before selecting
              the least loaded of these servers. It was indeed demonstrated
              that picking the least loaded of two servers is enough to
              significantly improve the fairness of the algorithm, by
              always avoiding to pick the most loaded server within a farm
              and getting rid of any bias that could be induced by the
              unfair distribution of the consistent list. Higher values N
              will take away N-1 of the highest loaded servers at the
              expense of performance. With very high values, the algorithm
              will converge towards the leastconn's result but much slower.
              In addition, for large server farms with very low loads (or
              perfect balance), comparing loads will often lead to a tie,
              so in case of equal loads between all measured servers, their
              request rate over the last second are compared, which allows
              to better balance server usage over time in the same spirit
              as roundrobin does, and smooth consistent hash unfairness.
              The default value is 2, which generally shows very good
              distribution and performance. For large farms with low loads
              (less than a few requests per second per server), it may help
              to raise it to 3 or even 4. This algorithm is also known as
              the Power of Two Random Choices and is described here:
              http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf

              For backends in LOG mode, the number of draws is ignored and
              a single random is picked since there is no notion of server
              load. Random log balancing can be useful with large farms or
              when servers are frequently added or removed from the pool of
              available servers as it may avoid the hammering effect that
              could result from roundrobin in this situation.

  rdp-cookie
  rdp-cookie(<name>)
              The RDP cookie <name> (or "mstshash" if omitted) will be
              looked up and hashed for each incoming TCP request. Just as
              with the equivalent ACL 'req.rdp_cookie()' function, the name
              is not case-sensitive. This mechanism is useful as a degraded
              persistence mode, as it makes it possible to always send the
              same user (or the same session ID) to the same server. If the
              cookie is not found, the normal roundrobin algorithm is
              used instead.

              Note that for this to work, the frontend must ensure that an
              RDP cookie is already present in the request buffer. For this
              you must use 'tcp-request content accept' rule combined with
              a 'req.rdp_cookie_cnt' ACL.

              This algorithm is static by default, which means that
              changing a server's weight on the fly will have no effect,
              but this can be changed using "hash-type". See also the
              "hash" option above.

  log-hash    Takes a comma-delimited list of converters in argument. These
              converters are applied in sequence to the input log message,
              and the result will be cast as a string then hashed according
              to the configured hash-type. The resulting hash will be used
              to select the destination server among the ones declared in
              the log backend. The goal of this algorithm is to be able to
              extract a key within the final log message using string
              converters and then be able to stick to the same server thanks
              to the hash. Only "map-based" hashes are supported for now.
              This algorithm is only usable for backends in LOG mode, for
              others, please use "hash" instead.

  sticky      Tries to stick to the same server as much as possible. The
              first server in the list of available servers receives all
              the log messages. When the server goes DOWN, the next server
              in the list takes its place. When a previously DOWN server
              goes back UP it is added at the end of the list so that the
              sticky server doesn't change until it becomes DOWN.

<arguments> is an optional list of arguments which may be needed by some
            algorithms. Right now, only "url_param", "uri" and "log-hash"
            support an optional argument.

L’algorithme de répartition de charge d’un backend est défini sur « random » lorsque aucun autre algorithme, mode ni option n’a été défini. L’algorithme ne peut être défini qu’une seule fois pour chaque backend.

Avec les schémas d’authentification qui exigent la même connexion, comme NTLM, les algorithmes basés sur l’URI ne doivent pas être utilisés, car ils entraîneraient la redirection des requêtes ultérieures vers des serveurs backend différents, rompant ainsi les hypothèses non valides sur lesquelles repose NTLM.

TCP/HTTP Exemples :

balance roundrobin
balance url_param userid
balance url_param session_id check_post 64
balance hdr(User-Agent)
balance hdr(host)
balance hdr(Host) use_domain_only
balance hash req.cookie(clientid)
balance hash var(req.client_id)
balance hash req.hdr_ip(x-forwarded-for,-1),ipmask(24)

Exemples de backend de journalisation :

global
  log backend@mylog-rrb local0 # send all logs to mylog-rrb backend
  log backend@mylog-hash local0 # send all logs to mylog-hash backend

backend mylog-rrb
  mode log
  balance roundrobin

  server s1 udp@127.0.0.1:514 # will receive 50% of log messages
  server s2 udp@127.0.0.1:514

backend mylog-hash
  mode log

  # extract "METHOD URL PROTO" at the end of the log message,
  # and let haproxy hash it so that log messages generated from
  # similar requests get sent to the same syslog server:
  balance log-hash 'field(-2,\")'

  # server list here
  server s1 127.0.0.1:514
  #...

Remarque : les limitations et précautions suivantes relatives à l’utilisation de l’extension “check_post” avec “url_param” doivent être prises en compte :

- toutes les requêtes POST sont prises en compte, car il n'existe aucun moyen de déterminer si les paramètres se trouvent dans le corps ou dans l'entité, qui peut contenir des données binaires. Il peut donc être nécessaire d'utiliser une autre méthode pour limiter le traitement des requêtes POST ne comportant pas de paramètres URL dans le corps. (voir acl http_end)

-  utiliser une valeur `<max_wait>` supérieure à la taille du tampon de requête n'a pas de sens et est inutile. La taille du tampon est définie au moment de la compilation et vaut 16 ko par défaut.

- L'encodage de contenu n'est pas pris en charge, la recherche de paramètres échouera probablement ; la répartition de charge passera alors en mode Round Robin.

- Attendu : la directive 100-continue n'est pas prise en charge, la répartition de charge passera en mode Round Robin.

- Transfer-Encoding (RFC7230 3.3.1) n'est pris en charge que dans le premier morceau.
    Si la valeur entière du paramètre n'est pas présente dans le premier morceau, la sélection du serveur est indéfinie (en réalité, elle est déterminée par la quantité effectivement présente dans le premier morceau).

- Cette fonctionnalité ne prend pas en charge la génération d'une réponse 100, 411 ou 501.

- Dans certains cas, une requête "check_post" peut tenter de scanner tout le contenu du corps d’un message. La lecture se termine normalement lorsqu’un espace blanc linéaire ou un caractère de contrôle est détecté, indiquant la fin d’une éventuelle liste de paramètres d’URL. Ce comportement n’est probablement pas préoccupant pour les corps de message de type SGML.

Voir aussi : « dispatch », « cookie », « transparent », « hash-type ».

be-unpublished

be-unpublished

Instructe le backend à démarrer dans l’état non publié.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

En pratique, toutes les règles use_backend et default_backend provenant d’un autre proxy qui font référence au proxy actuel sont ignorées, et les règles de commutation de contenu suivantes sont évaluées. Cette comportement peut cependant être contourné à l’aide d’une règle « force-be-switch ».

Cet état est similaire à celui de désactivation, mais avec quelques différences. Premièrement, un backend non publié sera entièrement initialisé, y compris les contrôles d’état des serveurs, qui restent actifs. Enfin, un backend peut être rendu publiquement accessible via la commande « publish backend » sur la ligne de commande. Voir le manuel de gestion.

Voir aussi : « force-be-switch »

bind [<address>]:<port_range> [, ...] [param*]

bind [<address>]:<port_range> [, ...] [param*]
bind /<path> [, ...] [param*]

Définissez une ou plusieurs adresses d’écoute et/ou ports dans un frontal.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<address>     is optional and can be a host name, an IPv4 address, an IPv6
              address, or '*'. It designates the address the frontend will
              listen on. If unset, all IPv4 addresses of the system will be
              listened on. The same will apply for '*' or the system's
              special address "0.0.0.0". The IPv6 equivalent is '::'. Note
              that for UDP, specific OS features are required when binding
              on multiple addresses to ensure the correct network interface
              and source address will be used on response. In other way,
              for QUIC listeners only bind on multiple addresses if running
              with a modern enough systems.

              Optionally, an address family prefix may be used before the
              address to force the family regardless of the address format,
              which can be useful to specify a path to a unix socket with
              no slash ('/'). Currently supported prefixes are:
                - 'ipv4@'  -> address is always IPv4
                - 'ipv6@'  -> address is always IPv6
                - 'udp@'   -> address is resolved as IPv4 or IPv6 and
                  protocol UDP is used. Currently those listeners are
                  supported only in log-forward sections.
                - 'udp4@'  -> address is always IPv4 and protocol UDP
                  is used. Currently those listeners are supported
                  only in log-forward sections.
                - 'udp6@'  -> address is always IPv6 and protocol UDP
                  is used. Currently those listeners are supported
                  only in log-forward sections.
                - 'unix@'  -> address is a path to a local unix socket
                - 'abns@'  -> address is in abstract namespace (Linux only).
                - 'abnsz@'  -> address is in abstract namespace (Linux only)
                   but it is explicitly zero-terminated. This means no \0
                   padding is used to complete sun_path. It is useful to
                   interconnect with programs that don't implement the
                   default abns naming logic that haproxy uses.
                - 'fd@<n>' -> use file descriptor <n> inherited from the
                  parent. The fd must be bound and may or may not already
                  be listening.
                - 'sockpair@<n>'-> like fd@ but you must use the fd of a
                  connected unix socket or of a socketpair. The bind waits
                  to receive a FD over the unix socket and uses it as if it
                  was the FD of an accept(). Should be used carefully.
                - 'quic4@' -> address is resolved as IPv4 and protocol UDP
                  is used. Note that to achieve the best performance with a
                  large traffic you should keep "tune.quic.fe.sock-per-conn
                  default-on". Else QUIC connections will be multiplexed
                  over the listener socket. Another alternative would be to
                  duplicate QUIC listener instances over several threads,
                  for example using "shards" keyword to at least reduce
                  thread contention.
                - 'quic6@' -> address is resolved as IPv6 and protocol UDP
                  is used. The performance note for QUIC over IPv4 applies
                  as well.
                - 'rhttp@' [ EXPERIMENTAL ] -> used for reverse HTTP.
                  Address must be a server with the format
                  '<backend>/<server>'. The server will be used to
                  instantiate connections to a remote address. The listener
                  will try to maintain "nbconn" connections. This is an
                  experimental features which requires
                  "expose-experimental-directives" on a line before this
                  bind.

              You may want to reference some environment variables in the
              address parameter, see section 2.3 about environment
              variables.

<port_range>  is either a unique TCP port, or a port range for which the
              proxy will accept connections for the IP address specified
              above. The port is mandatory for TCP listeners. Note that in
              the case of an IPv6 address, the port is always the number
              after the last colon (':'). A range can either be:
               - a numerical port (ex: '80')
               - a dash-delimited ports range explicitly stating the lower
                 and upper bounds (ex: '2000-2100') which are included in
                 the range.

              Particular care must be taken against port ranges, because
              every <address:port> couple consumes one socket (= a file
              descriptor), so it's easy to consume lots of descriptors
              with a simple range, and to run out of sockets. Also, each
              <address:port> couple must be used only once among all
              instances running on a same system. Please note that binding
              to ports lower than 1024 generally require particular
              privileges to start the program, which are independent of
              the 'uid' parameter.

<path>        is a UNIX socket path beginning with a slash ('/'). This is
              alternative to the TCP listening port. HAProxy will then
              receive UNIX connections on the socket located at this place.
              The path must begin with a slash and by default is absolute.
              It can be relative to the prefix defined by "unix-bind" in
              the global section. Note that the total length of the prefix
              followed by the socket path cannot exceed some system limits
              for UNIX sockets, which commonly are set to 107 characters.

<param*>      is a list of parameters common to all sockets declared on the
              same line. These numerous parameters depend on OS and build
              options and have a complete section dedicated to them. Please
              refer to section 5 to for more details.

Il est possible de spécifier une liste de combinaisons adresse:port séparées par des virgules. Le frontal écoutera alors sur toutes ces adresses. Il n’existe aucune limite fixe au nombre d’adresses et de ports sur lesquels un frontal peut écouter, ni aucune limite au nombre d’instructions « bind » dans un frontal.

Exemple :

listen http_proxy
    bind:80,:443
    bind 10.0.0.1:10080,10.0.0.1:10443
    bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy

listen http_https_proxy
    bind:80
    bind:443 ssl crt /etc/haproxy/site.pem

listen http_https_proxy_explicit
    bind ipv6@:80
    bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem
    bind unix@ssl-frontend.sock user root mode 600 accept-proxy

listen external_bind_app1
    bind "fd@${FD_APP1}"

listen h3_quic_proxy
    bind quic4@10.0.0.1:8888 ssl crt /etc/mycrt

Note : En ce qui concerne les sockets de l’espace de noms abstrait sous Linux, les sockets HAProxy « abns » utilisent la longueur entière de sun_path pour la longueur de l’adresse. Certains autres programmes, comme socat, utilisent par défaut uniquement la longueur de chaîne. Passez l’option « ,unix-tightsocklen=0 » à toute définition de socket abstrait dans socat pour la rendre compatible avec celle de HAProxy, ou utilisez à la place la famille de sockets HAProxy « abnsz ».

Voir également : « source », « option forwardfor », « unix-bind » et la documentation du protocole PROXY, ainsi que section 5 concernant les options bind.

capture cookie <name> len <length>

capture cookie <name> len <length>

Capturez et enregistrez un cookie dans la requête et dans la réponse.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<name>    is the beginning of the name of the cookie to capture. In order
          to match the exact name, simply suffix the name with an equal
          sign ('='). The full name will appear in the logs, which is
          useful with application servers which adjust both the cookie name
          and value (e.g. ASPSESSIONXXX).

<length>  is the maximum number of characters to report in the logs, which
          include the cookie name, the equal sign and the value, all in the
          standard "name=value" form. The string will be truncated on the
          right if it exceeds <length>.

Seul le premier cookie est capturé. Les en-têtes de requête « cookie » et les en-têtes de réponse « set-cookie » sont surveillés. Cela est particulièrement utile pour détecter des bugs applicatifs provoquant une chevauchement ou un vol de session entre utilisateurs, car les cookies de l’utilisateur ne devraient normalement changer que sur une page de connexion.

Lorsqu’un cookie n’est pas fourni par le client, la colonne de journal associée indique « - ». Lorsqu’une requête ne provoque pas l’attribution d’un cookie par le serveur, une « - » est indiquée dans la colonne de réponse.

La capture est effectuée uniquement dans le frontend, car il est nécessaire que le format des journaux ne change pas pour un frontend donné en fonction des backends. Cela pourrait évoluer à l’avenir. Notez qu’il ne peut y avoir qu’une seule instruction « capture cookie » dans un frontend. La longueur maximale de capture est définie par le paramètre global “tune.http.cookielen” et vaut 63 caractères par défaut. Il n’est pas possible de spécifier une capture dans une section « defaults ».

Exemple :

capture cookie ASPSESSION len 32

Voir également : « capture d’en-tête de requête », « capture d’en-tête de réponse » ainsi que la section 8 concernant la journalisation.

capture request header <name> len <length>

capture request header <name> len <length>

Capturez et enregistrez la dernière occurrence de l’en-tête de requête spécifié.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<name>    is the name of the header to capture. The header names are not
          case-sensitive, but it is a common practice to write them as they
          appear in the requests, with the first letter of each word in
          upper case. The header name will not appear in the logs, only the
          value is reported, but the position in the logs is respected.

<length>  is the maximum number of characters to extract from the value and
          report in the logs. The string will be truncated on the right if
          it exceeds <length>.

La valeur complète de la dernière occurrence de l’en-tête est capturée. La valeur sera ajoutée aux journaux entre accolades (’{}’). Si plusieurs en-têtes sont capturés, ils seront séparés par une barre verticale (’|’) et apparaîtront dans le même ordre que leur déclaration dans la configuration. Les en-têtes inexistants seront journalisés sous forme de chaîne vide. Les utilisations courantes de la capture d’en-têtes de requête incluent le champ “Host” dans les environnements de hébergement virtuel, le champ “Content-length” lorsqu’un téléchargement est pris en charge, le champ “User-agent” pour distinguer rapidement les utilisateurs réels des robots, et le champ “X-Forwarded-For” dans les environnements proxy afin de déterminer l’origine de la requête.

Notez que lors de la capture d’en-têtes tels que « User-agent », certains espaces peuvent être enregistrés, ce qui complique l’analyse des journaux. Veillez donc à ce que vous enregistrez, si vous savez que votre analyseur de journaux n’est pas suffisamment intelligent pour s’appuyer sur les accolades.

Il n’y a aucune limite au nombre d’en-têtes de requête capturés ni à leur longueur, bien qu’il soit recommandé de les limiter afin de réduire l’utilisation mémoire par flux. Pour maintenir un format de journal cohérent pour un même frontal, les captures d’en-têtes ne peuvent être déclarées qu’au sein d’un frontend. Il n’est pas possible de spécifier une capture dans une section « defaults ».

Exemple :

capture request header Host len 15
capture request header X-Forwarded-For len 15
capture request header Referer len 15

Voir aussi : « capture cookie », « capture d’en-tête de réponse » ainsi que la section 8 concernant la journalisation.

capture response header <name> len <length>

capture response header <name> len <length>

Capturez et enregistrez la dernière occurrence de l’en-tête de réponse spécifié.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<name>    is the name of the header to capture. The header names are not
          case-sensitive, but it is a common practice to write them as they
          appear in the response, with the first letter of each word in
          upper case. The header name will not appear in the logs, only the
          value is reported, but the position in the logs is respected.

<length>  is the maximum number of characters to extract from the value and
          report in the logs. The string will be truncated on the right if
          it exceeds <length>.

La valeur complète de la dernière occurrence de l’en-tête est capturée. Le résultat sera ajouté aux journaux entre accolades (’{}’) après les en-têtes de requête capturés. Si plusieurs en-têtes sont capturés, ils seront séparés par une barre verticale (’|’) et apparaîtront dans le même ordre qu’ils ont été déclarés dans la configuration. Les en-têtes inexistants seront journalisés sous forme de chaîne vide. Les utilisations courantes des en-têtes de réponse capturés incluent l’en-tête “Content-length”, qui indique le nombre d’octets attendus en retour, et l’en-tête “Location” pour suivre les redirections.

Il n’y a aucune limite au nombre d’en-têtes de réponse capturés ni à leur longueur, bien qu’il soit recommandé de les garder faibles afin de limiter l’utilisation mémoire par flux. Pour maintenir un format de journal cohérent pour un même frontal, les captures d’en-têtes ne peuvent être déclarées qu’au niveau d’un frontal. Il n’est pas possible de spécifier une capture dans une section « defaults ».

Exemple :

capture response header Content-length len 9
capture response header Location len 15

Voir aussi : « capture cookie », « capture en-tête de requête », ainsi que la section 8 concernant la journalisation.

clitcpka-cnt <count>

clitcpka-cnt <count>

Définit le nombre maximal d’enquêtes keepalive TCP qui doivent être envoyées avant de fermer la connexion du côté client.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<count>   is the maximum number of keepalive probes.

Ce mot-clé correspond à l’option de socket TCP_KEEPCNT. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_probes) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir aussi : « option clitcpka », « clitcpka-idle », « clitcpka-intvl ».

clitcpka-idle <timeout>

clitcpka-idle <timeout>

Définit le délai pendant lequel la connexion doit rester inactif avant que TCP ne commence à envoyer des sondes de maintien de connexion, si activé, l’envoi des paquets TCP keepalive côté client.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<timeout> is the time the connection needs to remain idle before TCP starts
          sending keepalive probes. It is specified in seconds by default,
          but can be in any other unit if the number is suffixed by the
          unit, as explained at the top of this document.

Ce mot-clé correspond à l’option de socket TCP_KEEPIDLE. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_time) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir aussi : « option clitcpka », « clitcpka-cnt », « clitcpka-intvl ».

clitcpka-intvl <timeout>

clitcpka-intvl <timeout>

Définit le délai entre les sondes keepalive individuelles du côté client.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<timeout> is the time between individual keepalive probes. It is specified
          in seconds by default, but can be in any other unit if the number
          is suffixed by the unit, as explained at the top of this
          document.

Ce mot-clé correspond à l’option de socket TCP_KEEPINTVL. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_intvl) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir aussi : « option clitcpka », « clitcpka-cnt », « clitcpka-idle ».

compression algo <algorithm> ...

compression algo <algorithm> ...
compression algo-req <algorithm>
compression algo-res <algorithm>
compression type <mime type> ...

Activer la compression HTTP.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

algo     is followed by the list of supported compression algorithms for
         responses (legacy keyword)
algo-req is followed by compression algorithm for request (only one is
  provided).
algo-res is followed by the list of supported compression algorithms for
         responses.
type     is followed by the list of MIME types that will be compressed for
         responses (legacy keyword).
type-req is followed by the list of MIME types that will be compressed for
         requests.
type-res is followed by the list of MIME types that will be compressed for
         responses.

Les algorithmes actuellement pris en charge sont :

identity     this is mostly for debugging, and it was useful for developing
             the compression feature. Identity does not apply any change on
             data.

gzip         applies gzip compression. This setting is only available when
             support for zlib or libslz was built in.

deflate      same as "gzip", but with deflate algorithm and zlib format.
             Note that this algorithm has ambiguous support on many
             browsers and no support at all from recent ones. It is
             strongly recommended not to use it for anything else than
             experimentation. This setting is only available when support
             for zlib or libslz was built in.

raw-deflate  same as "deflate" without the zlib wrapper, and used as an
             alternative when the browser wants "deflate". All major
             browsers understand it and despite violating the standards,
             it is known to work better than "deflate", at least on MSIE
             and some versions of Safari. Do not use it in conjunction
             with "deflate", use either one or the other since both react
             to the same Accept-Encoding token. This setting is only
             available when support for zlib or libslz was built in.

La compression sera activée en fonction de l’en-tête de requête Accept-Encoding. Avec la valeur identity, cet en-tête n’est pas pris en compte. Si les serveurs backend prennent en charge la compression HTTP, ces directives n’auront aucun effet : HAProxy détectera la réponse compressée et ne la comprimera pas à nouveau. Si les serveurs backend ne prennent pas en charge la compression HTTP et qu’un en-tête Accept-Encoding est présent dans la requête, HAProxy comprimera la réponse correspondante.

La compression est désactivée lorsque : - la requête ne déclare pas d’algorithme de compression pris en charge dans l’en-tête « Accept-Encoding » - le message de réponse n’est pas HTTP/1.1 ou supérieur - le code de statut HTTP n’est pas l’un des codes suivants : 200, 201, 202 ou 203 - la réponse ne contient ni l’en-tête « Content-Length » ni un en-tête « Transfer-Encoding » dont la dernière valeur est « chunked » - la réponse contient un en-tête « Content-Type » dont la première valeur commence par « multipart » - la réponse contient la valeur « no-transform » dans l’en-tête « Cache-control » - l’en-tête « User-Agent » correspond à « Mozilla/4 », sauf si c’est MSIE 6 sous XP SP2, ou MSIE 7 et versions ultérieures - la réponse contient un en-tête « Content-Encoding », indiquant que la réponse est déjà compressée (voir déchargement de compression) - la réponse contient un en-tête « ETag » invalide ou plusieurs en-têtes « ETag » - la taille du contenu est inférieure à la taille minimale (voir compression minsize-res)

Note : La compression n’émet pas l’en-tête Warning.

Exemples :

compression algo gzip
compression type text/html text/plain

Voir également : « compression offload », « compression direction », « compression minsize-req » et « compression minsize-res »

compression minsize-req <size>

compression minsize-req <size>
compression minsize-res <size>

Définit la taille minimale du contenu en octets pour la compression soit appliquée.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Les charges plus petites que cette taille ne seront pas compressées, évitant ainsi une surcharge CPU inutile pour des données qui ne bénéficieraient pas significativement de la compression. « minsize-req » s’applique aux requêtes et « minsize-res » aux réponses. La valeur par défaut est 0.

compression offload

compression offload

Fait fonctionner HAProxy en tant qu’accélérateur de compression uniquement.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

L’option « offload » fait que HAProxy supprime l’en-tête Accept-Encoding afin d’empêcher les backends de compresser les réponses. Il est fortement recommandé de ne pas procéder ainsi, car cela implique que toute la charge de compression sera effectuée au niveau du seul point où HAProxy est installé. Toutefois, dans certains scénarios de déploiement, HAProxy peut être placé devant une passerelle défectueuse présentant une implémentation incorrecte de la compression HTTP, dont la désactivation n’est pas possible. Dans ce cas, HAProxy peut être utilisé pour empêcher cette passerelle d’émettre des charges utiles non valides. Dans ce contexte, supprimer simplement l’en-tête dans la configuration ne fonctionne pas, car cette opération s’applique avant l’analyse de l’en-tête, ce qui empêche HAProxy de procéder à la compression. L’option « offload » doit alors être utilisée pour de tels scénarios.

Si cette option est utilisée dans une section defaults, un avertissement est émis et l’option est ignorée.

Voir aussi : « compression type », « compression algo », « compression direction »

compression direction <direction> (deprecated)

compression direction <direction> (deprecated)

Permet à HAProxy de compresser à la fois les requêtes et les réponses. Les valeurs valides sont « request », pour compresser uniquement les requêtes, « response », pour compresser uniquement les réponses, ou « both », lorsque vous souhaitez compresser les deux. La valeur par défaut est « response ».

Cette directive n’est pertinente que lorsque la « compression filtre » ancienne était activée, car avec les filtres comp-req et comp-res, la direction de compression est redondante.

Peut être utilisé dans les contextes suivants : http

Voir aussi : « compression type », « compression algo », « compression offload »

cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]

cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
              [ postonly ] [ preserve ] [ httponly ] [ secure ]
              [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
              [ dynamic ] [ attr <value> ]*

Activez la persistance basée sur les cookies dans un backend.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<name>    is the name of the cookie which will be monitored, modified or
          inserted in order to bring persistence. This cookie is sent to
          the client via a "Set-Cookie" header in the response, and is
          brought back by the client in a "Cookie" header in all requests.
          Special care should be taken to choose a name which does not
          conflict with any likely application cookie. Also, if the same
          backends are subject to be used by the same clients (e.g.
          HTTP/HTTPS), care should be taken to use different cookie names
          between all backends if persistence between them is not desired.

rewrite   This keyword indicates that the cookie will be provided by the
          server and that HAProxy will have to modify its value to set the
          server's identifier in it. This mode is handy when the management
          of complex combinations of "Set-cookie" and "Cache-control"
          headers is left to the application. The application can then
          decide whether or not it is appropriate to emit a persistence
          cookie. Since all responses should be monitored, this mode
          doesn't work in HTTP tunnel mode. Unless the application
          behavior is very complex and/or broken, it is advised not to
          start with this mode for new deployments. This keyword is
          incompatible with "insert" and "prefix".

insert    This keyword indicates that the persistence cookie will have to
          be inserted by HAProxy in server responses if the client did not

          already have a cookie that would have permitted it to access this
          server. When used without the "preserve" option, if the server
          emits a cookie with the same name, it will be removed before
          processing. For this reason, this mode can be used to upgrade
          existing configurations running in the "rewrite" mode. The cookie
          will only be a session cookie and will not be stored on the
          client's disk. By default, unless the "indirect" option is added,
          the server will see the cookies emitted by the client. Due to
          caching effects, it is generally wise to add the "nocache" or
          "postonly" keywords (see below). The "insert" keyword is not
          compatible with "rewrite" and "prefix".

prefix    This keyword indicates that instead of relying on a dedicated
          cookie for the persistence, an existing one will be completed.
          This may be needed in some specific environments where the client
          does not support more than one single cookie and the application
          already needs it. In this case, whenever the server sets a cookie
          named <name>, it will be prefixed with the server's identifier
          and a delimiter. The prefix will be removed from all client
          requests so that the server still finds the cookie it emitted.
          Since all requests and responses are subject to being modified,
          this mode doesn't work with tunnel mode. The "prefix" keyword is
          not compatible with "rewrite" and "insert". Note: it is highly
          recommended not to use "indirect" with "prefix", otherwise server
          cookie updates would not be sent to clients.

indirect  When this option is specified, no cookie will be emitted to a
          client which already has a valid one for the server which has
          processed the request. If the server sets such a cookie itself,
          it will be removed, unless the "preserve" option is also set. In
          "insert" mode, this will additionally remove cookies from the
          requests transmitted to the server, making the persistence
          mechanism totally transparent from an application point of view.
          Note: it is highly recommended not to use "indirect" with
          "prefix", otherwise server cookie updates would not be sent to
          clients.

nocache   This option is recommended in conjunction with the insert mode
          when there is a cache between the client and HAProxy, as it
          ensures that a cacheable response will be tagged non-cacheable if
          a cookie needs to be inserted. This is important because if all
          persistence cookies are added on a cacheable home page for
          instance, then all customers will then fetch the page from an
          outer cache and will all share the same persistence cookie,
          leading to one server receiving much more traffic than others.
          See also the "insert" and "postonly" options.

postonly  This option ensures that cookie insertion will only be performed
          on responses to POST requests. It is an alternative to the
          "nocache" option, because POST responses are not cacheable, so
          this ensures that the persistence cookie will never get cached.
          Since most sites do not need any sort of persistence before the
          first POST which generally is a login request, this is a very
          efficient method to optimize caching without risking to find a
          persistence cookie in the cache.
          See also the "insert" and "nocache" options.

preserve  This option may only be used with "insert" and/or "indirect". It
          allows the server to emit the persistence cookie itself. In this
          case, if a cookie is found in the response, HAProxy will leave it
          untouched. This is useful in order to end persistence after a
          logout request for instance. For this, the server just has to
          emit a cookie with an invalid value (e.g. empty) or with a date in
          the past. By combining this mechanism with the "disable-on-404"
          check option, it is possible to perform a completely graceful
          shutdown because users will definitely leave the server after
          they logout.

httponly  This option tells HAProxy to add an "HttpOnly" cookie attribute
          when a cookie is inserted. This attribute is used so that a
          user agent doesn't share the cookie with non-HTTP components.
          Please check RFC6265 for more information on this attribute.

secure    This option tells HAProxy to add a "Secure" cookie attribute when
          a cookie is inserted. This attribute is used so that a user agent
          never emits this cookie over non-secure channels, which means
          that a cookie learned with this flag will be presented only over
          SSL/TLS connections. Please check RFC6265 for more information on
          this attribute.

domain    This option allows to specify the domain at which a cookie is
          inserted. It requires exactly one parameter: a valid domain
          name. If the domain begins with a dot, the browser is allowed to
          use it for any host ending with that name. It is also possible to
          specify several domain names by invoking this option multiple
          times. Some browsers might have small limits on the number of
          domains, so be careful when doing that. For the record, sending
          10 domains to MSIE 6 or Firefox 2 works as expected.

maxidle   This option allows inserted cookies to be ignored after some idle
          time. It only works with insert-mode cookies. When a cookie is
          sent to the client, the date this cookie was emitted is sent too.
          Upon further presentations of this cookie, if the date is older
          than the delay indicated by the parameter (in seconds), it will
          be ignored. Otherwise, it will be refreshed if needed when the
          response is sent to the client. This is particularly useful to
          prevent users who never close their browsers from remaining for
          too long on the same server (e.g. after a farm size change). When
          this option is set and a cookie has no date, it is always
          accepted, but gets refreshed in the response. This maintains the
          ability for admins to access their sites. Cookies that have a
          date in the future further than 24 hours are ignored. Doing so
          lets admins fix timezone issues without risking kicking users off
          the site.

maxlife   This option allows inserted cookies to be ignored after some life
          time, whether they're in use or not. It only works with insert
          mode cookies. When a cookie is first sent to the client, the date
          this cookie was emitted is sent too. Upon further presentations
          of this cookie, if the date is older than the delay indicated by
          the parameter (in seconds), it will be ignored. If the cookie in
          the request has no date, it is accepted and a date will be set.
          Cookies that have a date in the future further than 24 hours are
          ignored. Doing so lets admins fix timezone issues without risking
          kicking users off the site. Contrary to maxidle, this value is
          not refreshed, only the first visit date counts. Both maxidle and
          maxlife may be used at the time. This is particularly useful to
          prevent users who never close their browsers from remaining for
          too long on the same server (e.g. after a farm size change). This
          is stronger than the maxidle method in that it forces a
          redispatch after some absolute delay.

dynamic   Activate dynamic cookies. When used, a session cookie is
          dynamically created for each server, based on the IP and port
          of the server, and a secret key, specified in the
          "dynamic-cookie-key" backend directive.
          The cookie will be regenerated each time the IP address change,
          and is only generated for IPv4/IPv6.

attr      This option tells HAProxy to add an extra attribute when a
          cookie is inserted. The attribute value can contain any
          characters except control ones or ";". This option may be
          repeated.

Il ne peut y avoir qu’un seul cookie de persistance par backend HTTP, et celui-ci peut être déclaré dans une section defaults. La valeur du cookie sera la valeur indiquée après le mot-clé « cookie » dans une déclaration server. Si aucun cookie n’est déclaré pour un serveur donné, le cookie n’est pas défini.

Exemples :

cookie JSESSIONID prefix
cookie SRV insert indirect nocache
cookie SRV insert postonly indirect
cookie SRV insert indirect nocache maxidle 30m maxlife 8h

Voir aussi : « balance source », « capture cookie », « server » et « ignore-persist ».

declare capture [ request | response ] len <length>

declare capture [ request | response ] len <length>

Déclare une plage de capture.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<length> is the length allowed for the capture.

Cette déclaration n’est disponible que dans la section frontend ou listen, mais l’emplacement réservé peut être utilisé dans les backends. Le mot-clé « request » alloue une plage de capture destinée à être utilisée dans la requête, et le mot-clé « response » alloue une plage de capture destinée à être utilisée dans la réponse.

Voir aussi : « capture-req », « capture-res » (convertisseurs d’échantillon), “capture.req.hdr”, “capture.res.hdr” (extractions d’échantillon), « http-request capture » et « http-response capture ».

default-server [param*]

default-server [param*]

Modifier les options par défaut d’un serveur dans un backend

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<param*>  is a list of parameters for this server. The "default-server"
          keyword accepts an important number of options and has a complete
          section dedicated to it. Please refer to section 5 for more
          details.

Exemple :

default-server inter 1000 weight 13

Voir également : « server » et section 5 concernant les options du serveur

default_backend <backend>

default_backend <backend>

Spécifiez le backend à utiliser lorsque aucune règle “use_backend” n’a été matchée.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<backend> is the name of the backend to use.

Lorsque l’on effectue un commutateur de contenu entre un frontal et des backends en utilisant le mot-clé “use_backend”, il est souvent utile d’indiquer quel backend sera utilisé lorsque aucune règle ne correspond. Il s’agit généralement du backend dynamique, qui intercepte toutes les requêtes non déterminées.

Si un backend est désactivé ou non publié, les règles default_backend qui le ciblent seront ignorées et le traitement des flux restera sur le proxy d’origine.

Exemple :

use_backend     dynamic  if  url_dyn
use_backend     static   if  url_css url_img extension_img
default_backend dynamic

Voir également : “use_backend”

description <string>

description <string>

Décrivez un écouteur, un frontal ou un backend.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Arguments : chaîne

Permet d’ajouter une phrase de description de l’objet lié dans la page de statistiques HTML de HAProxy. La description s’affichera à droite du nom de l’objet qu’elle décrit. Aucun besoin d’échapper les espaces dans les arguments <string>.

disabled

disabled

Désactivez un proxy, un frontal ou un backend.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Le mot-clé « disabled » est utilisé pour désactiver une instance, principalement afin de libérer un port d’écoute ou de désactiver temporairement un service. L’instance sera toujours créée et sa configuration vérifiée, mais elle sera initialisée dans l’état « arrêté » et apparaîtra ainsi dans les statistiques. Elle ne recevra aucune requête, ni ne transmettra de vérifications de santé ni de journaux. Il est possible de désactiver plusieurs instances en même temps en ajoutant le mot-clé « disabled » dans une section « defaults ».

Par défaut, un backend désactivé ne peut pas être sélectionné pour le commutateur de contenu. Toutefois, une partie du trafic peut ignorer cette règle lorsque force-be-switch est utilisé.

Voir aussi : « enabled », « force-be-switch »

dispatch <address>:<port> (deprecated)

dispatch <address>:<port>   (deprecated)

Définir une adresse de serveur par défaut

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<address> is the IPv4 address of the default server. Alternatively, a
          resolvable hostname is supported, but this name will be resolved
          during start-up.

<ports>   is a mandatory port specification. All connections will be sent
          to this port, and it is not permitted to use port offsets as is
          possible with normal servers.

Le mot-clé « dispatch » désigne un serveur par défaut utilisé lorsque aucun autre serveur ne peut accepter la connexion. À l’origine, il était utilisé pour acheminer les connexions non persistantes vers un chargeur d’équilibre auxiliaire. En raison de sa syntaxe simple, il a également été utilisé pour des relais TCP simples. Il est recommandé de ne pas l’utiliser afin d’améliorer la clarté, et d’utiliser à la place la directive « server ».

Ce mot-clé est obsolète depuis la version 3.3 et sera supprimé dans la version 3.5 en raison de limitations internes (absence de prise en charge du SSL, des connexions inactives, etc.). Son utilisation génère un avertissement qui peut être supprimé en activant la directive « expose-deprecated-directives » dans la section globale.

La bonne manière de procéder sans cette directive consiste à déclarer simplement un serveur avec la même adresse et le même port. Si la directive « dispatch » est combinée à d’autres serveurs, ces derniers doivent être configurés avec un poids nul afin de ne jamais être sélectionnés par l’algorithme de répartition de charge.

Exemple :

backend deprecated_setup
    dispatch 192.168.100.100:80 # external load balancer's address
    server s1 192.168.100.1:80 cookie S1 check
    server s2 192.168.100.2:80 cookie S2 check

backend modern_setup
    server external_lb 192.168.100.100:80
    server s1 192.168.100.1:80 cookie S1 check weight 0
    server s2 192.168.100.2:80 cookie S2 check weight 0

Voir également : « server »

dynamic-cookie-key <string>

dynamic-cookie-key <string>

Définir la clé secrète dynamique pour un backend.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : La clé secrète à utiliser.

Lorsque les cookies dynamiques sont activés (voir la directive « dynamic » pour les cookies), un cookie dynamique est créé pour chaque serveur (sauf si un cookie est explicitement spécifié dans la ligne « server »), en utilisant un hachage de l’adresse IP du serveur, du port TCP et de la clé secrète. Ainsi, il est possible d’assurer la persistance de session à travers plusieurs équilibreurs de charge, même si les serveurs sont ajoutés ou supprimés dynamiquement.

enabled

enabled

Activez un proxy, un frontal ou un backend.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Le mot-clé « enabled » est utilisé pour activer explicitement une instance, lorsque les paramètres par défaut ont été définis sur « disabled ». Cette utilisation est très rare.

Voir aussi : « disabled »

errorfile <code> <file>

errorfile <code> <file>

Renvoyer le contenu d’un fichier au lieu des erreurs générées par HAProxy

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<code>    is the HTTP status code. Currently, HAProxy is capable of
          generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410,
          413, 414, 425, 429, 431, 500, 501, 502, 503, and 504.

<file>    designates a file containing the full HTTP response. It is
          recommended to follow the common practice of appending ".http" to
          the filename so that people do not confuse the response with HTML
          error pages, and to use absolute paths, since files are read
          before any chroot is performed.

Il est important de comprendre que ce mot-clé n’a pas pour but de réécrire les erreurs renvoyées par le serveur, mais les erreurs détectées et renvoyées par HAProxy. C’est pourquoi la liste des erreurs prises en charge est limitée à un ensemble réduit.

Le code 200 est émis en réponse aux requêtes correspondant à une règle « monitor-uri ».

Les fichiers sont analysés au démarrage de HAProxy et doivent être valides selon la spécification HTTP. Ils ne doivent pas dépasser la taille de tampon configurée (BUFSIZE), qui est généralement de 16 ko, faute de quoi une erreur interne sera renvoyée. Il est également recommandé de ne pas référencer de contenus locaux (par exemple des images) afin d’éviter les boucles entre le client et HAProxy lorsque tous les serveurs sont hors service, ce qui provoquerait une erreur au lieu d’une image. Enfin, la réponse ne peut pas dépasser (tune.bufsize - tune.maxrewrite) afin que les règles « http-after-response » puissent encore fonctionner (voir “tune.maxrewrite”).

Les fichiers sont lus en même temps que la configuration et conservés en mémoire. Pour cette raison, les erreurs sont toujours renvoyées, même lorsque le processus est chrooté, et aucune modification de fichier n’est prise en compte pendant l’exécution du processus. Une méthode simple pour développer ces fichiers consiste à les associer au code d’état 403 et à interroger une URL bloquée.

Voir aussi : « http-error », « errorloc », « errorloc302 », « errorloc303 »

Exemple :

errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null  # work around Chrome pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http

errorfiles <name> [<code> ...]

errorfiles <name> [<code> ...]

Importez, en totalité ou en partie, les fichiers d’erreur définis dans la section <name> http-errors.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<name>  is the name of an existing http-errors section.

<code>  is a HTTP status code. Several status code may be listed.
        Currently, HAProxy is capable of generating codes 200, 400, 401,
        403, 404, 405, 407, 408, 410, 413, 414, 425, 429, 431, 500, 501,
        502, 503, and 504.

Les erreurs définies dans la section http-errors sous le nom <name> sont importées dans le proxy actuel. Si aucun code d’état n’est spécifié, tous les fichiers d’erreur de la section http-errors sont importés. Sinon, seuls les fichiers d’erreur associés aux codes d’état indiqués sont importés. Ces fichiers d’erreur remplacent les erreurs personnalisées déjà définies pour le proxy. Ils peuvent être remplacés par des fichiers ultérieurs. Fonctionnellement, cela revient exactement à déclarer tous les fichiers d’erreur manuellement à l’aide des directives “errorfile”.

Voir également : « http-error », « errorfile », « errorloc », « errorloc302 », « errorloc303 » et section 12.4 concernant les erreurs HTTP.

Exemple :

errorfiles generic
errorfiles site-1 403 404

errorloc <code> <url>

errorloc <code> <url>
errorloc302 <code> <url>

Renvoyer une redirection HTTP vers une URL au lieu des erreurs générées par HAProxy

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<code>    is the HTTP status code. Currently, HAProxy is capable of
          generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410,
          413, 414, 425, 429, 431, 500, 501, 502, 503, and 504.

<url>     it is the exact contents of the "Location" header. It may contain
          either a relative URI to an error page hosted on the same site,
          or an absolute URI designating an error page on another site.
          Special care should be given to relative URIs to avoid redirect
          loops if the URI itself may generate the same error (e.g. 500).

Il est important de comprendre que ce mot-clé n’a pas pour but de réécrire les erreurs renvoyées par le serveur, mais les erreurs détectées et renvoyées par HAProxy. C’est pourquoi la liste des erreurs prises en charge est limitée à un ensemble réduit.

Le code 200 est émis en réponse aux requêtes correspondant à une règle « monitor-uri ».

Notez que les deux mots-clés renvoient le code d’état HTTP 302, qui indique au client de récupérer l’URL désignée en utilisant la même méthode HTTP. Cela peut poser des problèmes importants en cas de méthodes autres que GET, comme POST, car l’URL envoyée au client pourrait ne pas être autorisée pour une requête autre que GET. Pour contourner ce problème, utilisez plutôt « errorloc303 », qui envoie le code d’état HTTP 303, indiquant au client que l’URL doit être récupérée à l’aide d’une requête GET.

Voir aussi : « http-error », « errorfile », « errorloc303 »

errorloc303 <code> <url>

errorloc303 <code> <url>

Renvoyer une redirection HTTP vers une URL au lieu des erreurs générées par HAProxy

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<code>    is the HTTP status code. Currently, HAProxy is capable of
          generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410,
          413, 414, 425, 429, 431, 500, 501, 502, 503, and 504.

<url>     it is the exact contents of the "Location" header. It may contain
          either a relative URI to an error page hosted on the same site,
          or an absolute URI designating an error page on another site.
          Special care should be given to relative URIs to avoid redirect
          loops if the URI itself may generate the same error (e.g. 500).

Il est important de comprendre que ce mot-clé n’a pas pour but de réécrire les erreurs renvoyées par le serveur, mais les erreurs détectées et renvoyées par HAProxy. C’est pourquoi la liste des erreurs prises en charge est limitée à un ensemble réduit.

Le code 200 est émis en réponse aux requêtes correspondant à une règle « monitor-uri ».

Notez que les deux mots-clés renvoient le code d’état HTTP 303, qui indique au client de récupérer l’URL désignée en utilisant la méthode HTTP GET. Cela résout les problèmes habituels liés à « errorloc » et au code 302. Il est possible que certains navigateurs très anciens, conçus avant HTTP/1.1, ne le supportent pas, mais aucun problème de ce type n’a été signalé à ce jour.

Voir aussi : « http-error », « errorfile », « errorloc », « errorloc302 »

email-alert from <emailaddr>

email-alert from <emailaddr>

Déclare l’adresse email à utiliser à la fois dans l’enveloppe et l’en-tête des alertes par courriel. Il s’agit de l’adresse depuis laquelle les alertes par courriel sont envoyées.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<emailaddr> is the from email address to use when sending email alerts

Exige également que les paramètres « email-alert mailers » et « email-alert to » soient définis, et, le cas échéant, active l’envoi d’alertes par courriel pour le proxy.

Voir aussi : « email-alert level », « email-alert mailers », « email-alert myhostname », « email-alert to », section 12.3 concernant les serveurs de messagerie.

email-alert level <level>

email-alert level <level>

Déclare le niveau maximal de journalisation des messages pour lesquels des alertes par courriel seront envoyées. Cela agit comme un filtre sur l’envoi des alertes par courriel.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<level> One of the 8 syslog levels:
          emerg alert crit err warning notice info  debug
        The above syslog levels are ordered from lowest to highest.

Par défaut, le niveau est alert

Exige également que les paramètres « email-alert from », « email-alert mailers » et « email-alert to » soient définis ; si c’est le cas, l’envoi d’alertes par courriel est activé pour le proxy.

Les alertes sont envoyées lorsque :

  • Un serveur non mis en pause est marqué comme hors service lorsque <level> est à l’état d’alerte ou inférieur
  • Un serveur mis en pause est marqué comme hors service lorsque <level> est à l’état d’information ou inférieur
  • Un serveur est marqué comme opérationnel ou passe en état de vidage lorsque <level> est à l’état d’information ou inférieur
  • L’option log-health-checks est activée, <level> est à l’état d’information ou inférieur, et une mise à jour de l’état du contrôle d’état a lieu

Voir aussi : « email-alert from », « email-alert mailers », « email-alert myhostname », « email-alert to », section 12.3 concernant les serveurs de messagerie.

email-alert mailers <mailersect>

email-alert mailers <mailersect>

Déclare les serveurs de messagerie à utiliser lors de l’envoi d’alertes par courrier électronique

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<mailersect> is the name of the mailers section to send email alerts.

Exige également que les paramètres « email-alert from » et « email-alert to » soient définis ; si c’est le cas, l’envoi d’alertes par courriel est activé pour le proxy.

Voir également : « email-alert from », « email-alert level », « email-alert myhostname », « email-alert to », section 12.3 concernant les serveurs de messagerie.

email-alert myhostname <hostname>

email-alert myhostname <hostname>

Déclare l’adresse du nom d’hôte à utiliser lors de la communication avec les serveurs de messagerie.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<hostname> is the hostname to use when communicating with mailers

Par défaut, le nom d’hôte du système est utilisé.

Exige également que les paramètres « email-alert from », « email-alert mailers » et « email-alert to » soient définis ; si c’est le cas, l’envoi d’alertes par courriel est activé pour le proxy.

Voir également : « email-alert from », « email-alert level », « email-alert mailers », « email-alert to », section 12.3 concernant les serveurs de messagerie.

email-alert to <emailaddr>

email-alert to <emailaddr>

Déclarez à la fois l’adresse du destinataire dans l’enveloppe et l’adresse de destination dans l’en-tête des alertes par courriel. C’est l’adresse à laquelle les alertes par courriel sont envoyées.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<emailaddr> is the to email address to use when sending email alerts

Exige également que les paramètres « email-alert mailers » et « email-alert to » soient définis, et, le cas échéant, active l’envoi d’alertes par courriel pour le proxy.

Voir aussi : « email-alert from », « email-alert level », « email-alert mailers », « email-alert myhostname », section 12.3 concernant les serveurs de messagerie.

error-log-format <fmt>

error-log-format <fmt>

Spécifie la chaîne de format de journalisation à utiliser en cas d’erreur de connexion du côté frontal.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Ce directive spécifie la chaîne de format de journalisation utilisée pour les journaux contenant des informations relatives aux erreurs, aux délais d’expiration, aux réessais, aux redirigements ou aux codes d’état HTTP 5xx. Ce format sera brièvement utilisé pour chaque ligne de journal concernée par l’option « log-separate-errors », y compris les erreurs de connexion décrites dans la section 8.2.5 .

Si la directive est utilisée dans une section defaults, tous les frontaux ultérieurs utiliseront le même format de journalisation. Veuillez consulter section 8.2.6 qui traite en détail la chaîne de format de journalisation personnalisée.

La directive « error-log-format » remplace les directives « error-log-format » précédentes.

force-persist { if | unless } <condition>

force-persist { if | unless } <condition>

Déclare une condition pour forcer la persistance sur les serveurs inaccessibles

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Par défaut, les requêtes ne sont pas acheminées vers les serveurs hors service. Il est possible de forcer ce comportement en utilisant « option persist », mais cette option est inconditionnelle et redirige vers un serveur valide si « option redispatch » est activée. Cela laisse très peu de possibilités pour forcer certaines requêtes à atteindre un serveur artificiellement marqué comme hors service lors d’opérations de maintenance.

L’instruction « force-persist » permet de déclarer diverses conditions basées sur des ACL qui, lorsqu’elles sont remplies, font en sorte qu’une requête ignore l’état « hors service » d’un serveur et tente tout de même de s’y connecter. Cela permet de démarrer un serveur, qui continue de renvoyer une erreur aux contrôles d’état, tout en permettant d’exécuter un navigateur spécialement configuré pour tester le service. Parmi les méthodes pratiques, on peut utiliser une adresse IP source spécifique, ou un cookie spécifique. Le cookie présente l’avantage de pouvoir être facilement added/removed depuis le navigateur à partir d’une page de test. Une fois le service validé, il devient possible d’ouvrir le service au monde entier en renvoyant une réponse valide aux contrôles d’état.

La persistance forcée est activée lorsque la condition « if » est remplie, ou sauf si la condition « unless » est remplie. Le réacheminement final est toujours désactivé lors de son utilisation.

Voir aussi : « option redispatch », « ignore-persist », « persist » et section 7 concernant l’utilisation des ACL.

external-check command <command>

external-check command <command>

Exécutable à exécuter lors d’un contrôle externe

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<command> is the external command to run

Les arguments passés à la commande sont :

<proxy_address> <proxy_port> <server_address> <server_port>

Les <proxy_address> et <proxy_port> sont dérivés de la première écouteur qui est soit IPv4, soit IPv6, soit une socket UNIX. Dans le cas d’un écouteur de socket UNIX, le proxy_address sera le chemin de la socket et <proxy_port> sera la chaîne “NOT_USED”. Dans une section backend, il n’est pas possible de déterminer un écouteur, et les deux valeurs <proxy_address> et <proxy_port> auront pour valeur la chaîne “NOT_USED”.

Certains valeurs sont également fournies via des variables d’environnement.

Variables d’environnement :

HAPROXY_PROXY_ADDR      The first bind address if available (or empty if not
                        applicable, for example in a "backend" section).

HAPROXY_PROXY_ID        The backend id.

HAPROXY_PROXY_NAME      The backend name.

HAPROXY_PROXY_PORT      The first bind port if available (or empty if not
                        applicable, for example in a "backend" section or
                        for a UNIX socket).

HAPROXY_SERVER_ADDR     The server address.

HAPROXY_SERVER_CURCONN  The current number of connections on the server.

HAPROXY_SERVER_ID       The server id.

HAPROXY_SERVER_MAXCONN  The server max connections.

HAPROXY_SERVER_NAME     The server name.

HAPROXY_SERVER_PORT     The server port if available (or empty for a UNIX
                        socket).

HAPROXY_SERVER_SSL      "0" when SSL is not used, "1" when it is used

HAPROXY_SERVER_PROTO    The protocol used by this server, which can be one
                        of "cli" (the haproxy CLI), "syslog" (syslog TCP
                        server), "peers" (peers TCP server), "h1" (HTTP/1.x
                        server), "h2" (HTTP/2 server), or "tcp" (any other
                        TCP server).

PATH                    The PATH environment variable used when executing
                        the command may be set using "external-check path".

Si la commande exécutée se termine avec un statut zéro, le contrôle est considéré comme réussi ; sinon, le contrôle est considéré comme échoué.

Exemple :

external-check command /bin/true

Voir aussi : « external-check », « option external-check », « external-check path »

external-check path <path>

external-check path <path>

Valeur de la variable d’environnement PATH utilisée lors de l’exécution d’un contrôle externe

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<path> is the path used when executing external command to run

Le chemin par défaut est “”.

Exemple :

external-check path "/usr/bin:/bin"

Voir aussi : « external-check », « option external-check », « external-check command »

force-be-switch { if | unless } <condition>

force-be-switch { if | unless } <condition>

Permet le choix d’une instance backend, même si elle est désactivée ou non publiée, lors du commutateur de contenu. Cette règle peut être utilisée par les administrateurs pour tester le trafic vers des services avant de les exposer au monde extérieur.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Voir aussi : « be-unpublished », « disabled »

filter <name> [param*]

filter <name> [param*]

Ajoutez le filtre <name> à la liste des filtres associée au proxy.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Arguments :

<name>     is the name of the filter. Officially supported filters are
           referenced in section 9.

<param*>   is a list of parameters accepted by the filter <name>. The
           parsing of these parameters are the responsibility of the
           filter. Please refer to the documentation of the corresponding
           filter (section 9) for all details on the supported parameters.

Plusieurs occurrences de la ligne de filtre peuvent être utilisées pour le même proxy. Le même filtre peut être référencé plusieurs fois si nécessaire.

Exemple :

listen
  bind *:80

  filter trace name BEFORE-HTTP-COMP
  filter compression
  filter trace name AFTER-HTTP-COMP

  compression algo gzip
  compression offload

  server srv1 192.168.0.1:80

Voir aussi : section 9 , « filter-sequence »

filter-sequence { requête | réponse } <filter_list>

Spécifie l’ordre d’exécution des filtres déclarés sur le proxy.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Liste séparée par des virgules de noms de filtres (<filter_list>) pour spécifier l’ordre d’exécution des filtres déclarés sur le proxy, respectivement pour le chemin de la requête ou de la réponse.

Lorsque filter-sequence n’est pas spécifié pour un chemin donné (par exemple : requête vs réponse), l’ordre dans lequel les filtres sont déclarés sur le proxy est utilisé.

Si la séquence de filtres omet certains filtres déclarés sur le proxy, ceux-ci ne seront pas exécutés. Ceci constitue une méthode efficace pour désactiver temporairement un filtre sans le supprimer de la configuration.

Exemple :

global
   lua-load my-filter.lua # defines custom "lua.my-filter"
frontend myfront
   filter comp-req
   filter comp-res
   filter lua.my-filter

   filter-sequence request lua.my-filter,comp-req
   filter-sequence response lua.my-filter,comp-res

Voir aussi : « filter »

fullconn <conns>

fullconn <conns>

Spécifiez à quelle charge du backend les serveurs atteindront leur maxconn

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<conns>   is the number of connections on the backend which will make the
          servers use the maximal number of connections.

Lorsqu’un serveur dispose d’un paramètre « maxconn » défini, cela signifie que son nombre de connexions simultanées ne dépassera jamais cette valeur. En outre, si un paramètre « minconn » est également défini, cela indique une limite dynamique qui suit la charge du backend. Le serveur acceptera alors toujours au moins <minconn> connexions, jamais plus de <maxconn>, et la limite sera ajustée progressivement entre ces deux valeurs lorsque le backend dispose de moins de <conns> connexions simultanées. Cela permet de limiter la charge sur les serveurs en conditions normales, tout en permettant de la pousser davantage en cas de charges importantes, sans surcharger les serveurs en cas de charges exceptionnelles.

Étant donné qu’il est difficile d’obtenir cette valeur correcte, HAProxy la définit automatiquement à 10 % de la somme des maxconns de tous les frontaux pouvant rediriger vers ce backend (selon les règles “use_backend” et “default_backend”). Ainsi, il est sans risque de la laisser non définie. Toutefois, les règles “use_backend” impliquant des noms dynamiques ne sont pas prises en compte, car il n’existe aucun moyen de savoir si elles pourraient correspondre ou non.

Exemple :

# The servers will accept between 100 and 1000 concurrent connections each
# and the maximum of 1000 will be reached when the backend reaches 10000
# connections.
backend dynamic
   fullconn   10000
   server     srv1   dyn1:80 minconn 100 maxconn 1000
   server     srv2   dyn2:80 minconn 100 maxconn 1000

Voir aussi : « maxconn », « server »

guid <string>

guid <string>

Spécifiez un identifiant global unique sensible à la casse pour ce proxy.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

<string> doit être unique dans l’ensemble de la configuration haproxy, pour tous les types d’objets. Le format n’est pas spécifié afin de permettre à l’utilisateur de choisir sa politique d’affectation de noms. La seule restriction est sa longueur, qui ne peut pas dépasser 127 caractères. Toutes les valeurs alphanumériques ainsi que les caractères ‘.’, ‘:’, ‘-’ et ‘_’ sont autorisés. Voir également « shm-stats-file ».

hash-balance-factor <factor>

hash-balance-factor <factor>

Spécifiez le facteur de répartition pour le hachage cohérent à charge bornée

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | non | oui

Arguments :

<factor> is the control for the maximum number of concurrent requests to
         send to a server, expressed as a percentage of the average number
         of concurrent requests across all of the active servers.

Spécifier un « hash-balance-factor » pour un serveur avec « hash-type consistent » active un algorithme qui empêche qu’un serveur reçoive trop de requêtes en même temps, même si certaines buckets de hachage reçoivent beaucoup plus de requêtes que d’autres. La mise à <factor> de 0 (valeur par défaut) désactive cette fonctionnalité. Sinon, <factor> est un pourcentage supérieur à 100. Par exemple, si <factor> est égal à 150, aucun serveur ne pourra avoir une charge supérieure à 1,5 fois la charge moyenne. Si des poids de serveurs sont utilisés, ceux-ci seront respectés.

Si le serveur de première choix est déclaré inapte, l’algorithme sélectionne un autre serveur en fonction du hachage de la requête, jusqu’à trouver un serveur disposant de capacité supplémentaire. Une valeur plus élevée de <factor> autorise un déséquilibre plus important entre les serveurs, tandis qu’une valeur plus faible de <factor> signifie qu’en moyenne, plus de serveurs seront examinés, ce qui impacte les performances. Des valeurs raisonnables se situent entre 125 et 200.

Ce paramètre est également utilisé par « balance random », qui repose en interne sur le mécanisme de hachage cohérent.

Voir également : « balance » et « hash-type ».

hash-preserve-affinity { always | maxconn | maxqueue }

hash-preserve-affinity { always | maxconn | maxqueue }

Spécifiez une méthode d’affectation des flux aux serveurs avec la répartition de charge par hachage lorsque les serveurs sont saturés ou ont une file d’attente pleine.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Les valeurs suivantes peuvent être spécifiées :

- "always" : il s'agit de la stratégie par défaut. Un flux est affecté à un serveur en fonction d'un hachage, indépendamment du fait que le serveur soit actuellement surchargé.

- "maxconn" : lorsque sélectionné, les serveurs ayant la valeur "maxconn" définie et actuellement saturés sont ignorés. Un autre serveur est sélectionné en suivant l'anneau de hachage. Cela n'a aucun effet sur les serveurs qui n'ont pas défini "maxconn". Si tous les serveurs sont saturés, la requête est mise en file d'attente sur le dernier serveur de l'anneau de hachage situé avant le serveur initialement sélectionné.

- "maxqueue" : lorsque sélectionné, les serveurs ayant la valeur "maxconn" définie, ainsi que "maxqueue" définie sur une valeur non nulle (taille de file limitée) et dont la file est actuellement pleine sont ignorés. Un autre serveur est sélectionné en suivant l'anneau de hachage. Cette option n'a aucun effet sur les serveurs qui ne définissent pas à la fois "maxconn" et "maxqueue".

Voir aussi : « maxconn », « maxqueue », « hash-balance-factor »

hash-type <method> <function> <modifier>

hash-type <method> <function> <modifier>

Spécifiez une méthode à utiliser pour mapper les hachages sur les serveurs

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<method> is the method used to select a server from the hash computed by
         the <function>:

  map-based   the hash table is a static array containing all alive servers.
              The hashes will be very smooth, will consider weights, but
              will be static in that weight changes while a server is up
              will be ignored. This means that there will be no slow start.
              Also, since a server is selected by its position in the array,
              most mappings are changed when the server count changes. This
              means that when a server goes up or down, or when a server is
              added to a farm, most connections will be redistributed to
              different servers. This can be inconvenient with caches for
              instance.

  consistent  the hash table is a tree filled with many occurrences of each
              server. The hash key is looked up in the tree and the closest
              server is chosen. This hash is dynamic, it supports changing
              weights while the servers are up, so it is compatible with the
              slow start feature. It has the advantage that when a server
              goes up or down, only its associations are moved. When a
              server is added to the farm, only a few part of the mappings
              are redistributed, making it an ideal method for caches.
              However, due to its principle, the distribution will never be
              very smooth and it may sometimes be necessary to adjust a
              server's weight or its ID to get a more balanced distribution.
              In order to get the same distribution on multiple load
              balancers, it is important that all servers have the exact
              same IDs. Note: consistent hash uses sdbm and avalanche if no
              hash function is specified.

<function> is the hash function to be used:

   sdbm   this function was created initially for sdbm (a public-domain
          reimplementation of ndbm) database library. It was found to do
          well in scrambling bits, causing better distribution of the keys
          and fewer splits. It also happens to be a good general hashing
          function with good distribution, unless the total server weight
          is a multiple of 64, in which case applying the avalanche
          modifier may help.

   djb2   this function was first proposed by Dan Bernstein many years ago
          on comp.lang.c. Studies have shown that for certain workload this
          function provides a better distribution than sdbm. It generally
          works well with text-based inputs though it can perform extremely
          poorly with numeric-only input or when the total server weight is
          a multiple of 33, unless the avalanche modifier is also used.

   wt6    this function was designed for HAProxy while testing other
          functions in the past. It is not as smooth as the other ones, but
          is much less sensible to the input data set or to the number of
          servers. It can make sense as an alternative to sdbm+avalanche or
          djb2+avalanche for consistent hashing or when hashing on numeric
          data such as a source IP address or a visitor identifier in a URL
          parameter.

   crc32  this is the most common CRC32 implementation as used in Ethernet,
          gzip, PNG, etc. It is slower than the other ones but may provide
          a better distribution or less predictable results especially when
          used on strings.

   none   don't hash the key, the key will be used as a hash, this can be
          useful to manually hash the key using a converter for that purpose
          and let haproxy use the result directly. The operation will
          convert the key to a string if it is not already, and parse it as
          an integer whose value will be used as the key. Some input key
          types might not be relevant here (e.g. IP addresses).

<modifier> indicates an optional method applied after hashing the key:

   avalanche   This directive indicates that the result from the hash
               function above should not be used in its raw form but that
               a 4-byte full avalanche hash must be applied first. The
               purpose of this step is to mix the resulting bits from the
               previous hash in order to avoid any undesired effect when
               the input contains some limited values or when the number of
               servers is a multiple of one of the hash's components (64
               for SDBM, 33 for DJB2). Enabling avalanche tends to make the
               result less predictable, but it's also not as smooth as when
               using the original function. Some testing might be needed
               with some workloads. This hash is one of the many proposed
               by Bob Jenkins.

Le type de hachage par défaut est « map-based » et est recommandé pour la plupart des utilisations. La fonction par défaut est « sdbm ». Le choix d’une fonction doit être fondé sur la plage des valeurs à hacher.

Voir aussi : « balance », « hash-balance-factor », « hash-preserve-affinity », « server »

http-after-response <action> <options...> [ { if | unless } <condition> ]

http-after-response <action> <options...> [ { if | unless } <condition> ]

Contrôle d’accès pour toutes les réponses au niveau 7 (serveur, applet/service et internes).

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

L’instruction http-after-response définit un ensemble de règles applicables au traitement au niveau couche 7. Ces règles sont évaluées dans l’ordre de leur déclaration lorsqu’elles sont rencontrées dans une section frontend, listen ou backend. Comme ces règles s’appliquent aux réponses, les règles du backend sont évaluées en premier, suivies par celles du frontend. Toute règle peut éventuellement être suivie d’une condition basée sur une ACL, auquel cas elle n’est évaluée que si la condition est vraie.

Contrairement aux règles http-response, celles-ci s’appliquent à toutes les réponses, tant aux réponses du serveur qu’aux réponses générées par HAProxy. Ces règles sont évaluées à la fin de l’analyse des réponses, avant la phase de transfert des données.

La condition est évaluée juste avant l’exécution de l’action, et celle-ci est exécutée exactement une fois. Il n’y a donc aucun problème si une action modifie un élément vérifié dans le cadre de la condition. Cela signifie également que plusieurs actions peuvent s’appuyer sur la même condition, de sorte que la première action qui modifie l’évaluation de la condition suffit à désactiver implicitement les actions restantes. Cette approche est utilisée, par exemple, lorsqu’il s’agit d’attribuer une valeur à une variable à partir de différentes sources lorsque celle-ci est vide. Il n’y a aucune limite au nombre d’instructions « http-after-response » par instance.

Le premier mot-clé après « http-after-response » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour cette action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « HTTP Aft »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Note : Les erreurs émises en phase précoce de l’analyse de la requête sont gérées par le multiplexeur à un niveau inférieur, avant toute analyse HTTP. Ainsi, aucun jeu de règles http-after-response n’est évalué sur ces erreurs.

Exemple :

http-after-response set-header Strict-Transport-Security "max-age=31536000"
http-after-response set-header Cache-Control "no-store,no-cache,private"
http-after-response set-header Pragma "no-cache"

http-check comment <string>

http-check comment <string>

Définit un commentaire pour la règle http-check suivante, signalé dans les journaux en cas d’échec.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<string>  is the comment message to add in logs if the following http-check
          rule fails.

Il ne fonctionne qu’avec les règles connect, send et expect. Il est utile pour produire des rapports d’erreurs conviviaux.

Voir également : « option httpchk », « http-check connect », « http-check send » et « http-check expect ».

http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]

http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
                   [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
                   [proto <name>] [comment <msg>]

Ouvre une nouvelle connexion pour effectuer un contrôle d’état HTTP

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

default      Use default options of the server line to do the health
             checks. The server options are used only if not redefined.

port <expr>  if not set, check port or server port is used.
             It tells HAProxy where to open the connection to.
             <port> must be a valid TCP port source integer, from 1 to
             65535 or an sample-fetch expression.

addr <ip>    defines the IP address to do the health check.

send-proxy   send a PROXY protocol string

via-socks4   enables outgoing health checks using upstream socks4 proxy.

ssl          opens a ciphered connection

sni <sni>    specifies the SNI to use to do health checks over SSL.

alpn <alpn>  defines which protocols to advertise with ALPN. The protocol
             list consists in a comma-delimited list of protocol names,
             for instance: "h2,http/1.1". If it is not set, the server ALPN
             is used.

proto <name> forces the multiplexer's protocol to use for this connection.
             It must be an HTTP mux protocol and it must be usable on the
             backend side. The list of available protocols is reported in
             haproxy -vv.

linger       cleanly close the connection instead of using a single RST.

Tout comme les contrôles d’état tcp-check, il est possible de configurer la connexion à utiliser pour effectuer un contrôle d’état HTTP. Cette directive doit également être utilisée pour décrire un scénario impliquant plusieurs échanges request/response, éventuellement sur des ports différents ou avec des serveurs distincts.

Lorsqu’aucun port TCP n’est configuré dans la ligne server ni dans la directive server port, le premier étape de la séquence http-check doit consister à préciser le port à l’aide de la directive « http-check connect ».

Dans un ensemble de règles http-check, une directive « connect » est obligatoire ; il est également obligatoire de commencer l’ensemble de règles par une règle « connect ». L’objectif est de garantir que l’administrateur sait ce qu’il fait.

Lorsqu’une connexion doit démarrer le jeu de règles, elle peut encore être précédée par des règles set-var, unset-var ou comment.

Exemples :

# check HTTP and HTTPs services on a server.
# first open port 80 thanks to server line port directive, then
# tcp-check opens port 443, ciphered and run a request on it:
option httpchk

http-check connect
http-check send meth GET uri / ver HTTP/1.1 hdr host haproxy.1wt.eu
http-check expect status 200-399
http-check connect port 443 ssl sni haproxy.1wt.eu
http-check send meth GET uri / ver HTTP/1.1 hdr host haproxy.1wt.eu
http-check expect status 200-399

server www 10.0.0.1 check port 80

Voir également : « option httpchk », « http-check send », « http-check expect »

http-check disable-on-404

http-check disable-on-404

Activer un mode maintenance en cas de réponse HTTP/404 aux vérifications de santé

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsque cette option est activée, un serveur renvoyant un code HTTP 404 est exclu du chargement de la répartition, mais continue de recevoir les connexions persistantes. Cette fonctionnalité offre une méthode très pratique aux administrateurs Web pour effectuer un arrêt progressif de leurs serveurs. Il est également important de noter qu’un serveur détecté comme défaillant pendant qu’il était en ce mode ne déclenche pas d’alerte, uniquement un avis. Si le serveur répond à nouveau avec un code 2xx ou 3xx, il est immédiatement réintégré dans la ferme. L’état affiché sur la page de statistiques indique « NOLB » pour un serveur en ce mode. Il est essentiel de noter que cette option ne fonctionne qu’en conjonction avec l’option « httpchk ». Si cette option est utilisée avec « http-check expect », elle a priorité sur celle-ci, de sorte que les réponses 404 sont toujours considérées comme une interruption douce. Notez également qu’un serveur arrêté reste arrêté même s’il répond avec un code 404. Cette option n’est évaluée que pour les serveurs en cours d’exécution.

Voir également : « option httpchk » et « http-check expect ».

http-check expect [min-recv <int>] [comment <msg>]

http-check expect [min-recv <int>] [comment <msg>]
                  [ok-status <st>] [error-status <st>] [tout-status <st>]
                  [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                  [!] <match> <pattern>

Effectuez des contrôles d’état HTTP en tenant compte du contenu de la réponse ou de codes d’état spécifiques

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

min-recv  is optional and can define the minimum amount of data required to
          evaluate the current expect rule. If the number of received bytes
          is under this limit, the check will wait for more data. This
          option can be used to resolve some ambiguous matching rules or to
          avoid executing costly regex matches on content known to be still
          incomplete. If an exact string is used, the minimum between the
          string length and this parameter is used. This parameter is
          ignored if it is set to -1. If the expect rule does not match,
          the check will wait for more data. If set to 0, the evaluation
          result is always conclusive.

ok-status <st>     is optional and can be used to set the check status if
                   the expect rule is successfully evaluated and if it is
                   the last rule in the tcp-check ruleset. "L7OK", "L7OKC",
                   "L6OK" and "L4OK" are supported:
                     - L7OK : check passed on layer 7
                     - L7OKC: check conditionally passed on layer 7, set
                               server to NOLB state.
                     - L6OK : check passed on layer 6
                     - L4OK : check passed on layer 4
                   By default "L7OK" is used.

error-status <st>  is optional and can be used to set the check status if
                   an error occurred during the expect rule evaluation.
                   "L7OKC", "L7RSP", "L7STS", "L6RSP" and "L4CON" are
                   supported:
                     - L7OKC: check conditionally passed on layer 7, set
                               server to NOLB state.
                     - L7RSP: layer 7 invalid response - protocol error
                     - L7STS: layer 7 response error, for example HTTP 5xx
                     - L6RSP: layer 6 invalid response - protocol error
                     - L4CON: layer 1-4 connection problem
                   By default "L7RSP" is used.

tout-status <st>   is optional and can be used to set the check status if
                   a timeout occurred during the expect rule evaluation.
                   "L7TOUT", "L6TOUT", and "L4TOUT" are supported:
                     - L7TOUT: layer 7 (HTTP/SMTP) timeout
                     - L6TOUT: layer 6 (SSL) timeout
                     - L4TOUT: layer 1-4 timeout
                   By default "L7TOUT" is used.

on-success <fmt>   is optional and can be used to customize the
                   informational message reported in logs if the expect
                   rule is successfully evaluated and if it is the last rule
                   in the tcp-check ruleset. <fmt> is a Custom log format
                   string (see section 8.2.6).

on-error <fmt>     is optional and can be used to customize the
                   informational message reported in logs if an error
                   occurred during the expect rule evaluation. <fmt> is a
                   Custom log format string (see section 8.2.6).

status-code <expr> is optional and can be used to set the check status code
                   reported in logs, on success or on error. <expr> is a
                   standard HAProxy expression formed by a sample-fetch
                   followed by some converters.

<match>   is a keyword indicating how to look for a specific pattern in the
          response. The keyword may be one of "status", "rstatus", "hdr",
          "fhdr", "string", or "rstring". The keyword may be preceded by an
          exclamation mark ("!") to negate the match. Spaces are allowed
          between the exclamation mark and the keyword. See below for more
          details on the supported keywords.

<pattern> is the pattern to look for. It may be a string, a regular
          expression or a more complex pattern with several arguments. If
          the string pattern contains spaces, they must be escaped with the
          usual backslash ('\').

Par défaut, l’option « option httpchk » considère que les codes de réponse 2xx et 3xx sont valides, et que les autres sont invalides. Lorsque « http-check expect » est utilisé, il définit ce qui est considéré comme valide ou invalide. Une seule instruction « http-check » est autorisée dans un backend. Si un serveur ne répond pas ou expiré, le contrôle échoue évidemment. Les correspondances disponibles sont :

status <codes>:  test the status codes found parsing <codes> string. it
                  must be a comma-separated list of status codes or range
                  codes. A health check response will be considered as
                  valid if the response's status code matches any status
                  code or is inside any range of the list. If the "status"
                  keyword is prefixed with "!", then the response will be
                  considered invalid if the status code matches.

rstatus <regex>: test a regular expression for the HTTP status code.
                  A health check response will be considered valid if the
                  response's status code matches the expression. If the
                  "rstatus" keyword is prefixed with "!", then the response
                  will be considered invalid if the status code matches.
                  This is mostly used to check for multiple codes.

hdr  { name | name-lf } [ -m <meth> ] <name>
     [ { value | value-lf } [ -m <meth> ] <value>:
                  test the specified header pattern on the HTTP response
                  headers. The name pattern is mandatory but the value
                  pattern is optional. If not specified, only the header
                  presence is verified. <meth> is the matching method,
                  applied on the header name or the header value. Supported
                  matching methods are "str" (exact match), "beg" (prefix
                  match), "end" (suffix match), "sub" (substring match) or
                  "reg" (regex match). If not specified, exact matching
                  method is used. If the "name-lf" parameter is used,
                  <name> is evaluated as a Custom log format string (see
                  section 8.2.6). If "value-lf" parameter is used, <value>
                  is evaluated as a log-format string. These parameters
                  cannot be used with the regex matching method. Finally,
                  the header value is considered as comma-separated
                  list. Note that matchings are case insensitive on the
                  header names.

fhdr { name | name-lf } [ -m <meth> ] <name>
     [ { value | value-lf } [ -m <meth> ] <value>:
                  test the specified full header pattern on the HTTP
                  response headers. It does exactly the same as the "hdr"
                  keyword, except the full header value is tested, commas
                  are not considered as delimiters.

string <string>: test the exact string match in the HTTP response body.
                  A health check response will be considered valid if the
                  response's body contains this exact string. If the
                  "string" keyword is prefixed with "!", then the response
                  will be considered invalid if the body contains this
                  string. This can be used to look for a mandatory word at
                  the end of a dynamic page, or to detect a failure when a
                  specific error appears on the check page (e.g. a stack
                  trace).

rstring <regex>: test a regular expression on the HTTP response body.
                  A health check response will be considered valid if the
                  response's body matches this expression. If the "rstring"
                  keyword is prefixed with "!", then the response will be
                  considered invalid if the body matches the expression.
                  This can be used to look for a mandatory word at the end
                  of a dynamic page, or to detect a failure when a specific
                  error appears on the check page (e.g. a stack trace).

string-lf <fmt>: test a Custom log format string (see section 8.2.6) match
                  in the HTTP response body. A health check response will
                  be considered valid if the response's body contains the
                  string resulting of the evaluation of <fmt>, which
                  follows the log-format rules. If prefixed with "!", then
                  the response will be considered invalid if the body
                  contains the string.

Il est important de noter que les réponses seront limitées à une taille définie par l’option globale “tune.bufsize”, qui vaut par défaut 16384 octets. Ainsi, les réponses trop grandes peuvent ne pas contenir le motif obligatoire lors de l’utilisation de « string » ou de « rstring ». Si une réponse de grande taille est absolument nécessaire, il est possible de modifier la taille maximale par défaut en définissant la variable globale. Toutefois, il convient de garder à l’esprit que l’analyse de réponses très grandes peut consommer des cycles CPU, notamment lors de l’utilisation d’expressions régulières, et qu’il est toujours préférable de cibler les vérifications sur des ressources plus petites.

Dans un jeu de règles http-check, la dernière règle expect peut être implicite. Si aucune règle expect n’est spécifiée après le dernier « http-check send », une règle expect implicite est définie pour correspondre aux codes d’état 2xx ou 3xx. Cela signifie que cette règle est également définie lorsque aucune règle « http-check » n’est présente du tout, à condition que seule l’option « option httpchk » soit définie.

Enfin, si « http-check expect » est combiné avec « http-check disable-on-404 », alors ce dernier a la priorité lorsque le serveur répond avec le code 404.

Exemples :

# only accept status 200 as valid
http-check expect status 200,201,300-310

# be sure a sessid coookie is set
http-check expect hdr name "set-cookie" value -m beg "sessid="

# consider SQL errors as errors
http-check expect ! string SQL\ Error

# consider status 5xx only as errors
http-check expect ! rstatus ^5

# check that we have a correct hexadecimal tag before /html
http-check expect rstring <!--tag:[0-9a-f]*--></html>

Voir également : « option httpchk », « http-check connect », « http-check disable-on-404 » et « http-check send ».

http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]

http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
                [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
                [comment <msg>]

Ajoutez une liste éventuelle d’en-têtes et/ou un corps à la requête envoyée lors des contrôles d’état HTTP.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

meth <method>  is the optional HTTP method used with the requests. When not
               set, the "OPTIONS" method is used, as it generally requires
               low server processing and is easy to filter out from the
               logs. Any method may be used, though it is not recommended
               to invent non-standard ones.

uri <uri>      is optional and set the URI referenced in the HTTP requests
               to the string <uri>. It defaults to "/" which is accessible
               by default on almost any server, but may be changed to any
               other URI. Query strings are permitted.

uri-lf <fmt>   is optional and set the URI referenced in the HTTP requests
               using the Custom log format <fmt> (see section 8.2.6). It
               defaults to "/" which is accessible by default on almost any
               server, but may be changed to any other URI. Query strings
               are permitted.

ver <version>  is the optional HTTP version string. It defaults to
               "HTTP/1.0" but some servers might behave incorrectly in HTTP
               1.0, so turning it to HTTP/1.1 may sometimes help. Note that
               the Host field is mandatory in HTTP/1.1, use "hdr" argument
               to add it.

hdr <name> <fmt>  adds the HTTP header field whose name is specified in
                  <name> and whose value is defined by <fmt>, which follows
                  the Custom log format rules described in section 8.2.6.

body <string>  add the body defined by <string> to the request sent during
               HTTP health checks. If defined, the "Content-Length" header
               is thus automatically added to the request.

body-lf <fmt>  add the body defined by the Custom log format <fmt> (see
               section 8.2.6) to the request sent during HTTP health
               checks. If defined, the "Content-Length" header is thus
               automatically added to the request.

En plus de la ligne de requête définie par la directive « option httpchk », cette méthode est la façon valide d’ajouter des en-têtes et éventuellement un corps à la requête envoyée lors des contrôles d’état HTTP. Si un corps est défini, l’en-tête « Content-Length » associé est automatiquement ajouté. Par conséquent, cet en-tête ou l’en-tête « Transfer-encoding » ne doit pas être présent dans la requête fournie par « http-check send ». S’ils sont présents, ils seront ignorés. La méthode ancienne consistant à ajouter des en-têtes après la chaîne de version sur la ligne « option httpchk » est désormais obsolète.

De plus, « http-check send » ne prend pas en charge la persistance de connexion HTTP. Veillez à ce qu’un en-tête « Connection: close » soit automatiquement ajouté, sauf si un en-tête Connection a déjà été configuré via une entrée hdr.

Notez que l’en-tête Host et l’autorité de requête, lorsqu’ils sont tous deux définis, sont automatiquement synchronisés. Cela signifie que, lorsque la requête HTTP est envoyée, l’insertion d’un en-tête Host entraîne une mise à jour correspondante de l’autorité de requête. Par conséquent, ne vous étonnez pas si la valeur de l’en-tête Host remplace l’autorité de requête configurée.

Notez également que, pour l’instant, aucun en-tête Host n’est ajouté automatiquement dans les requêtes HTTP/1.1 ou ultérieures. Vous devez l’ajouter explicitement.

Voir également : « option httpchk », « http-check send-state » et « http-check expect ».

http-check send-state

http-check send-state

Activer l’émission d’un en-tête d’état avec les contrôles d’état HTTP

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsque cette option est activée, HAProxy enverra systématiquement un en-tête spécial « X-HAProxy-Server-State » contenant une liste de paramètres indiquant à chaque serveur la manière dont HAProxy le perçoit. Cette fonctionnalité peut être utilisée, par exemple, lorsque un serveur est manipulé sans accès à HAProxy et que l’opérateur doit savoir si HAProxy le considère toujours comme actif ou non, ou s’il s’agit du dernier serveur d’une ferme.

L’en-tête est composé de champs séparés par des points-virgules, le premier étant un mot (“UP”, “DOWN”, “NOLB”), éventuellement suivi d’un nombre de vérifications valides avant la transition, tel qu’il apparaît dans l’interface de statistiques. Les en-têtes suivants sont au format “<variable>=<value>”, indiquant, dans un ordre quelconque, certaines valeurs disponibles dans l’interface de statistiques : - une variable “address”, contenant l’adresse du backend. Cela correspond au champ <address> dans la déclaration du serveur. Pour les sockets Unix, cela affichera “unix”.

-  une variable "port", contenant le port du serveur backend. Cela correspond au champ `<port>` dans la déclaration du serveur. Pour les sockets Unix, la valeur sera "unix".

- une variable "name", contenant le nom du backend suivi d'un slash ("/") puis le nom du serveur. Cette variable peut être utilisée lorsque serveur est vérifié dans plusieurs backends.

- une variable "node" contenant le nom du nœud HAProxy, tel qu'indiqué dans la variable globale "node", sinon le nom d'hôte du système si non spécifié.

- une variable "weight" indiquant le poids du serveur, un slash ("/") et le poids total de la ferme (en ne comptant que les serveurs utilisables). Cela permet de savoir si d'autres serveurs sont disponibles pour prendre en charge la charge en cas de défaillance de celui-ci.

- une variable "scur" indiquant le nombre actuel de connexions simultanées sur le serveur, suivie d'une barre oblique ("/") puis du nombre total de connexions sur tous les serveurs du même backend.

- une variable "qcur" indiquant le nombre actuel de requêtes dans la file d'attente du serveur.

Exemple d’un en-tête reçu par le serveur d’application :

>>>  X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \
       scur=13/22; qcur=0

Voir également : « option httpchk », « http-check disable-on-404 » et « http-check send ».

http-check set-var(<var-name>[,<cond>...]) <expr>

http-check set-var(<var-name>[,<cond>...]) <expr>
http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>

Cette opération définit le contenu d’une variable. La variable est déclarée en inline.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<var-name>   The name of the variable. Only "proc", "sess" and "check"
             scopes can be used. See section 2.8 about variables for details.

 <cond>      A set of conditions that must all be true for the variable to
             actually be set (such as "ifnotempty", "ifgt" ...). See the
             set-var converter's description for a full list of possible
             conditions.

 <expr>      Is a sample-fetch expression potentially followed by converters.

 <fmt>       This is the value expressed using Custom log format (see Custom
             Log Format in section 8.2.6).

Exemples :

http-check set-var(check.port) int(1234)
http-check set-var-fmt(check.port) "name=%H"

http-check unset-var(<var-name>)

http-check unset-var(<var-name>)

Libère une référence à une variable dans son contexte.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<var-name>   The name of the variable. Only "proc", "sess" and "check"
             scopes can be used. See section 2.8 about variables for details.

Exemples :

http-check unset-var(check.port)

http-error status <code> [content-type <type>]

http-error status <code> [content-type <type>]
           [ { default-errorfiles | errorfile <file> | errorfiles <name> |
           file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
       [ hdr `<name>` `<fmt>` ]*

Définit un message d’erreur personnalisé à utiliser à la place des erreurs générées par HAProxy.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

status <code>        is the HTTP status code. It must be specified.
                     Currently, HAProxy is capable of generating codes
                     200, 400, 401, 403, 404, 405, 407, 408, 410, 413,
                     414, 425, 429, 431, 500, 501, 502, 503, and 504.

content-type <type>  is the response content type, for instance
                     "text/plain". This parameter is ignored and should be
                     omitted when an errorfile is configured or when the
                     payload is empty. Otherwise, it must be defined.

default-errorfiles   Reset the previously defined error message for current
                     proxy for the status <code>. If used on a backend, the
                     frontend error message is used, if defined. If used on
                     a frontend, the default error message is used.

errorfile <file>     designates a file containing the full HTTP response.
                     It is recommended to follow the common practice of
                     appending ".http" to the filename so that people do
                     not confuse the response with HTML error pages, and to
                     use absolute paths, since files are read before any
                     chroot is performed.

errorfiles <name>    designates the http-errors section to use to import
                     the error message with the status code <code>. If no
                     such message is found, the proxy's error messages are
                     considered.

file <file>          specifies the file to use as response payload. If the
                     file is not empty, its content-type must be set as
                     argument to "content-type", otherwise, any
                     "content-type" argument is ignored. <file> is
                     considered as a raw string.

string <str>         specifies the raw string to use as response payload.
                     The content-type must always be set as argument to
                     "content-type".

lf-file <file>       specifies the file to use as response payload. If the
                     file is not empty, its content-type must be set as
                     argument to "content-type", otherwise, any
                     "content-type" argument is ignored. <file> is
                     evaluated as a Custom log format (see section 8.2.6).

lf-string <str>      specifies the log-format string to use as response
                     payload. The content-type must always be set as
                     argument to "content-type".

hdr <name> <fmt>     adds to the response the HTTP header field whose name
                     is specified in <name> and whose value is defined by
                     <fmt>, which follows the Custom log format rules (see
                     section 8.2.6). This parameter is ignored if an
                     errorfile is used.

Ce directive peut être utilisée à la place de « errorfile » pour définir un message d’erreur personnalisé. Comme la directive « errorfile », elle est utilisée pour les erreurs détectées et renvoyées par HAProxy. Si un fichier d’erreur est défini, il est analysé au démarrage de HAProxy et doit être conforme aux normes HTTP. La réponse générée ne doit pas dépasser la taille de tampon configurée (BUFFSIZE), sinon une erreur interne sera renvoyée. Enfin, si vous envisagez d’utiliser des règles http-after-response pour réécrire ces erreurs, l’espace de tampon réservé doit être disponible (voir “tune.maxrewrite”).

Les fichiers sont lus en même temps que la configuration et conservés en mémoire. Pour cette raison, les erreurs sont toujours renvoyées, même lorsque le processus est chrooté, et aucune modification de fichier n’est prise en compte pendant l’exécution du processus.

Note : les erreurs 400/408/500 émises en phase précoce de l’analyse de la requête sont gérées par le multiplexeur à un niveau inférieur. Aucune mise en forme personnalisée n’est prise en charge à ce niveau. Seules les messages d’erreur statiques, définis avec la directive « errorfile », sont prises en charge. Toutefois, cette limitation n’existe que pendant l’analyse des en-têtes de la requête ou entre deux transactions.

Voir aussi : « errorfile », « errorfiles », « errorloc », « errorloc302 », « errorloc303 » et section 12.4 concernant les erreurs HTTP.

http-request <action> [options...] [ { if | unless } <condition> ]

http-request <action> [options...] [ { if | unless } <condition> ]

Contrôle d’accès pour les requêtes au niveau 7

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

L’instruction http-request définit un ensemble de règles applicables au traitement au niveau 7. Ces règles sont évaluées dans l’ordre de leur déclaration lorsqu’elles sont rencontrées dans une section frontend, listen ou backend. Chaque règle peut éventuellement être suivie d’une condition basée sur une ACL, auquel cas elle n’est évaluée que si la condition se traduit par une valeur vraie.

La condition est évaluée juste avant l’exécution de l’action, et celle-ci est exécutée exactement une fois. Il n’y a donc aucun problème si une action modifie un élément vérifié dans le cadre de la condition. Cela signifie également que plusieurs actions peuvent s’appuyer sur la même condition, de sorte que la première action qui modifie l’évaluation de la condition suffit à désactiver implicitement les actions restantes. Cette approche est utilisée, par exemple, lorsqu’il s’agit d’attribuer une valeur à une variable provenant de différentes sources lorsque celle-ci est vide. Il n’y a aucune limite au nombre d’instructions « http-request » par instance.

Le premier mot-clé après « http-request » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour cette action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « HTTP Req »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Exemple :

acl nagios src 192.168.129.3
acl local_net src 192.168.0.0/16
acl auth_ok http_auth(L1)

http-request allow if nagios
http-request allow if local_net auth_ok
http-request auth realm Gimme if local_net auth_ok
http-request deny

Exemple :

acl key req.hdr(X-Add-Acl-Key) -m found
acl add path /addacl
acl del path /delacl

acl myhost hdr(Host) -f myhost.lst

http-request add-acl(myhost.lst) %[req.hdr(X-Add-Acl-Key)] if key add
http-request del-acl(myhost.lst) %[req.hdr(X-Add-Acl-Key)] if key del

Exemple :

acl value  req.hdr(X-Value) -m found
acl setmap path /setmap
acl delmap path /delmap

use_backend bk_appli if { hdr(Host),map_str(map.lst) -m found }

http-request set-map(map.lst) %[src] %[req.hdr(X-Value)] if setmap value
http-request del-map(map.lst) %[src]                     if delmap

Voir aussi : « stats http-request », section 12.2 sur les listes d’utilisateurs et section 7 sur l’utilisation des ACL.

http-response <action> <options...> [ { if | unless } <condition> ]

http-response <action> <options...> [ { if | unless } <condition> ]

Contrôle d’accès pour les réponses au niveau 7

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

L’instruction http-response définit un ensemble de règles applicables au traitement au niveau couche 7. Ces règles sont évaluées dans l’ordre de leur déclaration lorsqu’elles sont rencontrées dans une section frontend, listen ou backend. Comme ces règles s’appliquent aux réponses, les règles du backend sont évaluées en premier, suivies par celles du frontend. Une règle peut éventuellement être suivie d’une condition basée sur une ACL, auquel cas elle n’est évaluée que si la condition est vraie.

La condition est évaluée juste avant l’exécution de l’action, et celle-ci est exécutée exactement une fois. Il n’y a donc aucun problème si une action modifie un élément vérifié dans le cadre de la condition. Cela signifie également que plusieurs actions peuvent s’appuyer sur la même condition, de sorte que la première action qui modifie l’évaluation de la condition suffit à désactiver implicitement les actions restantes. Cette approche est utilisée, par exemple, lorsqu’il s’agit d’attribuer une valeur à une variable provenant de différentes sources lorsque celle-ci est vide. Il n’y a aucune limite au nombre d’instructions « http-response » par instance.

Le premier mot-clé après « http-response » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour cette action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « HTTP Res »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Exemple :

acl key_acl res.hdr(X-Acl-Key) -m found

acl myhost hdr(Host) -f myhost.lst

http-response add-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl
http-response del-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl

Exemple :

acl value  res.hdr(X-Value) -m found

use_backend bk_appli if { hdr(Host),map_str(map.lst) -m found }

http-response set-map(map.lst) %[src] %[res.hdr(X-Value)] if value
http-response del-map(map.lst) %[src]                     if ! value

Voir également : « http-request », section 12.2 sur les listes d’utilisateurs et section 7 sur l’utilisation des ACL.

http-reuse { never | safe | aggressive | always }

http-reuse { never | safe | aggressive | always }

Déclare la manière dont les connexions HTTP inactives peuvent être partagées entre les requêtes

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Afin d’éviter le coût lié à la mise en place de nouvelles connexions vers les serveurs backend pour chaque requête HTTP, HAProxy tente de maintenir ces connexions inactives ouvertes après leur utilisation. Ces connexions sont spécifiques à un serveur et sont stockées dans une liste appelée pool, regroupées selon un ensemble de propriétés clés communes. Les requêtes HTTP ultérieures provoquent une recherche d’une connexion compatible partageant les mêmes propriétés dans le pool associé, ce qui permet de réutiliser cette connexion au lieu d’en établir une nouvelle.

Une limite sur le nombre de connexions inactives à maintenir sur un serveur peut être spécifiée à l’aide du mot-clé de configuration pool-max-conn pour le serveur. Les connexions inutilisées sont purgées périodiquement selon l’intervalle pool-purge-delay.

Les propriétés de connexion suivantes sont utilisées pour déterminer si une connexion inactif est éligible à la réutilisation pour une requête donnée :

  • adresses source et destination
  • protocole proxy
  • options de socket TOS et mark
  • nom de connexion, déterminé soit par le résultat de l’évaluation de l’expression « pool-conn-name » si présente, soit par l’expression « sni », qui par défaut vaut « req.hdr(host),field(1,:) », c’est-à-dire utilise le champ d’en-tête « Host » de la requête entrante sans deux-points ni numéro de port.

Dans certains cas, la recherche ou la réutilisation de connexion n’est pas effectuée en raison de restrictions supplémentaires. Cela est déterminé par la stratégie de réutilisation spécifiée via l’argument mot-clé :

- "never" : les connexions inactives ne sont jamais partagées entre les sessions. Ce mode peut être imposé pour annuler une stratégie différente héritée d'une section defaults ou dans un contexte de dépannage. Par exemple, si une ancienne application erronée considère que plusieurs requêtes effectuées sur la même connexion proviennent du même client, et qu'il n'est pas possible de corriger l'application, il peut être souhaitable de désactiver le partage des connexions pour un seul backend. Un exemple d'une telle application pourrait être une ancienne version d'HAProxy utilisant l'insertion de cookies en mode tunnel sans vérifier aucune requête après la première.

- "safe" : il s'agit de la stratégie par défaut et recommandée. La première requête d'une session est toujours envoyée via sa propre connexion, et seules les requêtes ultérieures peuvent être acheminées par d'autres connexions existantes. Cela garantit que, si le serveur ferme la connexion pendant l'envoi de la requête, le navigateur peut décider de la renvoyer silencieusement. Étant donné qu'il s'agit d'une configuration strictement équivalente à la mise en mémoire tampon régulière, aucune conséquence secondaire n'est à craindre. Une gestion spéciale est également appliquée aux connexions utilisant des protocoles sujets au blocage en tête de file (backend avec h2 ou fcgi). Dans ce cas, dès qu'au moins un flux est traité, la connexion utilisée est réservée pour gérer les flux de la même session. Dès lors que plus aucun flux n'est traité, la connexion est libérée et peut être réutilisée.

- "aggressive" : ce mode peut être utile dans les environnements de services web où tous les serveurs ne sont pas nécessairement connus, et où il serait avantageux de traiter la plupart des premières requêtes sur des connexions existantes. Dans ce cas, les premières requêtes ne sont envoyées que sur des connexions existantes ayant déjà été réutilisées au moins une fois, ce qui prouve que le serveur prend correctement en charge la réutilisation des connexions. Ce mode ne doit être utilisé que lorsque l'on est certain que le client peut réessayer une requête en échec de temps en temps, et où l'avantage de la réutilisation agressive des connexions dépasse nettement les inconvénients liés aux rares échecs de connexion.

- "always" : ce mode est recommandé uniquement lorsque le chemin vers le serveur est connu pour ne jamais interrompre les connexions existantes rapidement après les avoir libérées. Il permet d'envoyer la première requête d'une session vers une connexion existante. Cela peut offrir une amélioration de performance significative par rapport à la stratégie "safe" lorsque le backend est une ferme de cache, car ces composants présentent généralement un comportement constant et bénéficient du partage de connexion. Il est recommandé de maintenir le délai d'expiration "http-keep-alive" faible dans ce mode afin qu'aucune connexion morte ne reste utilisable. Dans la plupart des cas, cela entraîne les mêmes gains de performance que le mode "aggressive", mais avec des risques plus élevés. Ce mode ne doit être utilisé que lorsqu'il améliore la situation par rapport à "aggressive".

Notez également que les connexions utilisant des mécanismes d’authentification frauduleux (reliés à la connexion), tels que NTLM, sont marquées comme privées si possible et jamais partagées. Cela ne s’applique toutefois pas lors de l’utilisation d’un protocole à capacité de multiplexage et d’un mode de réutilisation dont la valeur est supérieure à la stratégie par défaut « sûre », car dans ce cas, rien n’empêche la connexion d’être déjà partagée.

Les règles déterminant si une connexion inactif doit être conservée ou fermée après traitement sont également régies par les paramètres “tune.pool-low-fd-ratio” (valeur par défaut : 20 %) et “tune.pool-high-fd-ratio” (valeur par défaut : 25 %). Ces valeurs correspondent au pourcentage total des descripteurs de fichiers utilisés par des connexions inactives au-delà duquel HAProxy va respectivement éviter de conserver une connexion ouverte après une réponse, et tuer activement les connexions inactives. Certains environnements utilisant un taux très élevé de connexions inactives, soit en raison d’une valeur globale “maxconn” trop faible, soit en raison d’un grand nombre de connexions HTTP/2 ou HTTP/3 sur le frontal (peu de connexions) mais de nombreuses connexions HTTP/1 sur le backend, peuvent observer un taux de réutilisation plus faible car trop peu de connexions sont conservées ouvertes. Dans ce cas, il peut être souhaitable de modifier ces seuils ou simplement d’augmenter la valeur globale de “maxconn”.

Dans certains cas rares, lorsque le nom d’hôte est utilisé pour distinguer les connexions TLS sortantes (par exemple, dans un proxy inverse), où la plupart des requêtes ciblent des hôtes différents, le taux de réutilisation sera très faible, et l’éviction automatique des connexions peu utilisées interviendra avant que les connexions n’aient eu la possibilité d’être réutilisées, car le mécanisme mesure continuellement le nombre moyen de connexions nécessaires pour assurer le service sans épuiser les ressources. Dans de tels cas, définir « pool-low-conn » à une valeur proche du nombre moyen attendu de connexions inactives peut aider à préserver davantage de connexions en incitant les threads à en établir eux-mêmes au lieu de tenter de choisir celles d’autres threads, réduisant ainsi la taille du pool de connexions disponibles.

Si un serveur hébergé localement utilise un seul certificat (avec plusieurs noms d’hôte ou des caractères génériques) et gère plusieurs sites, il peut être plus efficace d’utiliser simplement « no-sni-auto » sur la ligne « server » afin d’éviter de réserver une connexion à un nom d’hôte unique. Cela augmente considérablement le taux de réutilisation. Certains serveurs peuvent toutefois effectuer des vérifications excessives entre le nom d’hôte et le SNI, entraînant le rejet des requêtes ultérieures ; cette option nécessite donc une validation préalable. Le comportement par défaut (“sni-auto”) vise à garantir la sécurité même avec de tels serveurs.

Lorsque les groupes de threads sont activés explicitement, il est important de comprendre que les connexions inactives ne sont utilisables qu’entre les threads d’un même groupe. Il peut donc arriver qu’un déséquilibre de charge entre les groupes entraîne un besoin accru de connexions inactives, réduisant ainsi le taux de réutilisation. La même solution peut alors être appliquée (augmenter la valeur globale de « maxconn » ou augmenter les ratios de pool).

Voir aussi : « option http-keep-alive », « pool-conn-name », « pool-max-conn », « pool-purge-delay », « server maxconn », « sni », « thread-groups », “tune.pool-high-fd-ratio”, “tune.pool-low-fd-ratio”

http-send-name-header [<header>]

http-send-name-header [<header>]

Ajoutez le nom du serveur à une requête. Utilisez la chaîne d’en-tête fournie par <header>

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<header>  The header string to use to send the server name

L’instruction « http-send-name-header » fait que le champ d’en-tête nommé <header> est défini au nom du serveur cible au moment où la requête est sur le point d’être envoyée sur le réseau. Toutes les occurrences existantes de cet en-tête sont supprimées. Lors de réessais ou de redirigements, le champ d’en-tête est mis à jour afin de refléter toujours le serveur auquel une tentative de connexion est effectuée. Étant donné que cet en-tête est modifié très tard dans la phase de configuration de la connexion, il peut avoir des effets imprévus sur des en-têtes déjà modifiés. Par exemple, son utilisation avec des en-têtes au niveau du transport, tels que connection, content-length, transfer-encoding, etc., risque fortement de provoquer l’envoi de requêtes non valides au serveur. C’est pourquoi les noms d’en-tête suivants sont interdits : host, content-length, transfer-encoding et connection.

Voir également : « server »

id <value>

id <value>

Définir un identifiant persistant pour un proxy.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Arguments : aucun

Définir un identifiant persistant pour le proxy. Cet identifiant doit être unique et positif. Un identifiant non utilisé sera automatiquement attribué s’il n’est pas défini. En raison d’un comportement historique, la valeur 1 n’est pas utilisée à moins d’être explicitement définie. Par conséquent, la plus petite valeur automatiquement attribuée sera 2. Cet identifiant est actuellement retourné uniquement dans les statistiques.

ignore-persist { if | unless } <condition>

ignore-persist { if | unless } <condition>

Déclarer une condition pour ignorer la persistance

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Par défaut, lorsque la persistance des cookies est activée, toutes les requêtes contenant le cookie sont persistantes sans condition (à condition que le serveur cible soit en fonctionnement).

L’instruction « ignore-persist » permet de déclarer diverses conditions basées sur des ACL qui, lorsqu’elles sont remplies, entraînent l’ignorance de la persistance pour une requête. Cela peut être utile pour équilibrer la charge des requêtes de fichiers statiques, qui n’ont souvent pas besoin de persistance. Cela peut également servir à désactiver entièrement la persistance pour un User-Agent spécifique (par exemple, certains robots de navigation web).

La persistance est ignorée lorsque la condition « if » est remplie, ou sauf si la condition « unless » est remplie.

Exemple :

acl url_static  path_beg         /static /images /img /css
acl url_static  path_end         .gif .png .jpg .css .js
ignore-persist  if url_static

Voir aussi : « force-persist », « cookie » et section 7 concernant l’utilisation des ACL.

load-server-state-from-file { global | local | none }

load-server-state-from-file { global | local | none }

Permettre le rechargement sans interruption de HAProxy

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Ce directive indique à HAProxy le chemin vers un fichier dans lequel l’état des serveurs du processus précédent a été sauvegardé. Ainsi, au démarrage, avant de traiter le trafic, le nouveau processus peut appliquer les anciens états aux serveurs exactement comme s’il n’y avait pas eu de rechargement. L’objectif de la directive « load-server-state-from-file » est de préciser à HAProxy le fichier à utiliser. Pour l’instant, deux arguments permettent soit d’empêcher le chargement de l’état, soit de charger les états à partir d’un fichier contenant tous les backends et serveurs. Ce fichier d’état peut être généré en exécutant la commande « show servers state » sur le socket de statistiques et en redirigeant la sortie.

Le format du fichier est versionné et très spécifique. Pour le comprendre, veuillez lire la documentation de la commande « show servers state » (chapitre 9.3 du Guide d’administration).

Arguments :

global     load the content of the file pointed by the global directive
           named "server-state-file".

local      load the content of the file pointed by the directive
           "server-state-file-name" if set. If not set, then the backend
           name is used as a file name.

none       don't load any stat for this backend

Notes : - l’adresse IP du serveur est conservée entre les rechargements par défaut, mais son ordre peut être modifié grâce au paramètre « init-addr » du serveur. Cela signifie qu’un changement d’adresse IP effectué en ligne de commande en cours d’exécution sera conservé, et qu’une modification du résolveur local (par exemple /etc/hosts) pourra ne pas avoir d’effet si un fichier d’état est utilisé.

- Le poids du serveur  est appliqué à partir du processus précédent, sauf s'il a changé entre les fichiers de configuration précédent et nouveau.

Exemple : Configuration minimale

  global
   stats socket /tmp/socket
   server-state-file /tmp/server_state

  defaults
   load-server-state-from-file global

  backend bk
   server s1 127.0.0.1:22 check weight 11
   server s2 127.0.0.1:22 check weight 12

Ensuite, on peut exécuter :

socat /tmp/socket - <<< "show servers state" > /tmp/server_state

Contenu du fichier /tmp/server_state serait le suivant :

1
# <field names skipped for the doc example>
1 bk 1 s1 127.0.0.1 2 0 11 11 4 6 3 4 6 0 0
1 bk 2 s2 127.0.0.1 2 0 12 12 4 6 3 4 6 0 0

Exemple : Configuration minimale

global
 stats socket /tmp/socket
 server-state-base /etc/haproxy/states

defaults
 load-server-state-from-file local

backend bk
 server s1 127.0.0.1:22 check weight 11
 server s2 127.0.0.1:22 check weight 12

Ensuite, on peut exécuter :

socat /tmp/socket - <<< "show servers state bk" > /etc/haproxy/states/bk

Contenu du fichier /etc/haproxy/states/bk serait le suivant :

1
# <field names skipped for the doc example>
1 bk 1 s1 127.0.0.1 2 0 11 11 4 6 3 4 6 0 0
1 bk 2 s2 127.0.0.1 2 0 12 12 4 6 3 4 6 0 0

Voir également : « server-state-file », « server-state-file-name » et « show servers state »

log global

log global
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
    [profile <prof>] <facility> [<level> [<minlevel>]]
no log

Activez la journalisation par instance des événements et du trafic.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Préfixe :

no         should be used when the logger list must be flushed. For example,
           if you don't want to inherit from the default logger list. This
           prefix does not allow arguments.

Arguments :

global     should be used when the instance's logging parameters are the
           same as the global ones. This is the most common usage. "global"
           replaces all log arguments with those of the log entries found
           in the "global" section. Only one "log global" statement may be
           used per instance, and this form takes no other parameter.

<target>   indicates where to send the logs. It takes the same format as
           for the "global" section's logs, and can be one of:

           - An IPv4 address optionally followed by a colon (':') and a UDP
             port. If no port is specified, 514 is used by default (the
             standard syslog port).

           - An IPv6 address followed by a colon (':') and optionally a UDP
             port. If no port is specified, 514 is used by default (the
             standard syslog port).

           - A filesystem path to a UNIX domain socket, keeping in mind
             considerations for chroot (be sure the path is accessible
             inside the chroot) and uid/gid (be sure the path is
             appropriately writable).

           - A file descriptor number in the form "fd@<number>", which may
             point to a pipe, terminal, or socket. In this case unbuffered
             logs are used and one writev() call per log is performed. This
             is a bit expensive but acceptable for most workloads. Messages
             sent this way will not be truncated but may be dropped, in
             which case the DroppedLogs counter will be incremented. The
             writev() call is atomic even on pipes for messages up to
             PIPE_BUF size, which POSIX recommends to be at least 512 and
             which is 4096 bytes on most modern operating systems. Any
             larger message may be interleaved with messages from other
             processes.  Exceptionally for debugging purposes the file
             descriptor may also be directed to a file, but doing so will
             significantly slow HAProxy down as non-blocking calls will be
             ignored. Also there will be no way to purge nor rotate this
             file without restarting the process. Note that the configured
             syslog format is preserved, so the output is suitable for use
             with a TCP syslog server. See also the "short" and "raw"
             formats below.

           - "stdout" / "stderr", which are respectively aliases for "fd@1"
             and "fd@2", see above.

           - A ring buffer in the form "ring@<name>", which will correspond
             to an in-memory ring buffer accessible over the CLI using the
             "show events" command, which will also list existing rings and
             their sizes. Such buffers are lost on reload or restart but
             when used as a complement this can help troubleshooting by
             having the logs instantly available. See section 12.5 about
             rings.

           - A log backend in the form "backend@<name>", which will send
             log messages to the corresponding log backend responsible for
             sending the message to the proper server according to the
             backend's lb settings. A log backend is a backend section with
             "mode log" set (see "mode" for more information).

           - An explicit stream address prefix such as "tcp@","tcp6@",
             "tcp4@" or "uxst@" will allocate an implicit ring buffer with
             a stream forward server targeting the given address.

           You may want to reference some environment variables in the
           address parameter, see section 2.3 about environment variables.

<length>   is an optional maximum line length. Log lines larger than this
           value will be truncated before being sent. The reason is that
           syslog servers act differently on log line length. All servers
           support the default value of 1024, but some servers simply drop
           larger lines while others do log them. If a server supports long
           lines, it may make sense to set this value here in order to avoid
           truncating long lines. Similarly, if a server drops long lines,
           it is preferable to truncate them before sending them. Accepted
           values are 80 to 65535 inclusive. The default value of 1024 is
           generally fine for all standard usages. Some specific cases of
           long captures or JSON-formatted logs may require larger values.
           You may also need to increase "tune.http.logurilen" if your
           request URIs are truncated.

<ranges>   A list of comma-separated ranges to identify the logs to sample.
           This is used to balance the load of the logs to send to the log
           server. The limits of the ranges cannot be null. They are numbered
           from 1. The size or period (in number of logs) of the sample must
           be set with <sample_size> parameter.

<sample_size>
           The size of the sample in number of logs to consider when balancing
           their logging loads. It is used to balance the load of the logs to
           send to the syslog server. This size must be greater or equal to the
           maximum of the high limits of the ranges.
           (see also <ranges> parameter).

<format> is the log format used when generating syslog messages. It may be
         one of the following:

  local     Analog to rfc3164 syslog message format except that hostname
            field is stripped. This is the default.
            Note: option "log-send-hostname" switches the default to
            rfc3164.

  rfc3164   The RFC3164 syslog message format.
            (https://tools.ietf.org/html/rfc3164)

  rfc5424   The RFC5424 syslog message format.
            (https://tools.ietf.org/html/rfc5424)

  priority  A message containing only a level plus syslog facility between
            angle brackets such as '<63>', followed by the text. The PID,
            date, time, process name and system name are omitted. This is
            designed to be used with a local log server.

  short     A message containing only a level between angle brackets such as
            '<3>', followed by the text. The PID, date, time, process name
            and system name are omitted. This is designed to be used with a
            local log server. This format is compatible with what the
            systemd logger consumes.

  timed     A message containing only a level between angle brackets such as
            '<3>', followed by ISO date and by the text. The PID, process
            name and system name are omitted. This is designed to be
            used with a local log server.

  iso       A message containing only the ISO date, followed by the text.
            The PID, process name and system name are omitted. This is
            designed to be used with a local log server.

  raw       A message containing only the text. The level, PID, date, time,
            process name and system name are omitted. This is designed to
            be used in containers or during development, where the severity
            only depends on the file descriptor used (stdout/stderr).

<prof>     name of the optional "log-profile" section that will be
           considered during the log building process to override some
           log options. Check out "8.3.5. Log profiles" for more info.

<facility> must be one of the 24 standard syslog facilities:

               kern   user   mail   daemon auth   syslog lpr    news
               uucp   cron   auth2  ftp    ntp    audit  alert  cron2
               local0 local1 local2 local3 local4 local5 local6 local7

           Note that the facility is ignored for the "short" and "raw"
           formats, but still required as a positional field. It is
           recommended to use "daemon" in this case to make it clear that
           it's only supposed to be used locally.

<level>    is optional and can be specified to filter outgoing messages. By
           default, all messages are sent. If a level is specified, only
           messages with a severity at least as important as this level
           will be sent. An optional minimum level can be specified. If it
           is set, logs emitted with a more severe level than this one will
           be capped to this level. This is used to avoid sending "emerg"
           messages on all terminals on some default syslog configurations.
           Eight levels are known:

             emerg  alert  crit   err    warning notice info  debug

Il est important de garder à l’esprit que ce sont les paramètres du frontal qui déterminent ce qui doit être journalisé pour une connexion, et que, en cas de commutation de contenu, les entrées de journal du backend seront ignorées. Les connexions sont journalisées au niveau « info ».

Toutefois, la déclaration de journalisation des backends définit la manière et l’emplacement où les changements d’état des serveurs seront journalisés. Le niveau « notice » sera utilisé pour indiquer un serveur qui passe à l’état actif, le niveau « warning » pour les signaux de terminaison et les arrêts définitifs du service, et le niveau « alert » pour les cas où un serveur tombe.

Note : Selon RFC3164, les messages sont tronqués à 1024 octets avant d’être émis.

Exemple :

log global
log stdout format short daemon          # send log to systemd
log stdout format raw daemon            # send everything to stdout
log stderr format raw daemon notice     # send important events to stderr
log 127.0.0.1:514 local0 notice         # only send important events
log tcp@127.0.0.1:514 local0 notice notice  # same but limit output
                                            # level and send in tcp
log "${LOCAL_SYSLOG}:514" local0 notice   # send to local server

log-format <fmt>

log-format <fmt>

Spécifie la chaîne de format personnalisé à utiliser pour les journaux de trafic

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Ce directive spécifie la chaîne de format de journalisation utilisée pour tous les journaux issus du trafic passant par le frontal utilisant cette ligne. Si la directive est utilisée dans une section defaults, tous les frontaux ultérieurs utiliseront le même format de journalisation. Veuillez consulter section 8.2.6 qui traite en détail la chaîne de format de journalisation personnalisée.

Un format de journal spécifique, utilisé uniquement en cas d’erreur de connexion, peut également être défini, voir l’option « error-log-format ».

La directive « log-format » remplace les directives précédentes « option tcplog », « log-format », « option httplog » et « option httpslog ».

log-format-sd <fmt>

log-format-sd <fmt>

Spécifie la chaîne de format de journal personnalisé utilisée pour produire des données structurées RFC5424

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Cette directive spécifie la chaîne de format de journalisation structurée RFC5424 qui sera utilisée pour tous les journaux issus du trafic passant par le frontal utilisant cette ligne. Si la directive est utilisée dans une section defaults, tous les frontaux ultérieurs utiliseront le même format de journalisation. Voir la section 8.2.6 qui traite en détail la chaîne de format de journalisation.

Consultez https://tools.ietf.org/html/rfc5424#section-6.3 pour en savoir plus sur la partie données structurées de RFC5424.

Note : cette chaîne de format de journal sera utilisée uniquement par les journaux ayant défini le format de journalisation sur « rfc5424 ».

Exemple :

log-format-sd [exampleSDID@1234\ bytes=\"%B\"\ status=\"%ST\"]

log-steps <steps>

log-steps <steps>

Spécifie à quels stades du traitement des transactions les journaux doivent être générés.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Pendant le traitement des transactions tcp/http, HAProxy peut produire des journaux à différentes étapes du traitement (par exemple : accepter, se connecter, requête, réponse, fermer).

Par défaut, HAProxy émet une seule ligne de journal par transaction, une fois que toutes les composantes utilisées dans l’expression logformat ont pu être satisfaites. Cela signifie qu’en pratique, le journal est généralement émis à la fin de la transaction (après la fin de la réponse pour HTTP ou la fin de la connexion pour TCP), sauf si l’option logasap est utilisée.

La directive « log-steps » permet de préciser les instants exacts auxquels les journaux seront émis, et même de générer plusieurs journaux pour une même transaction. La valeur spéciale « all » peut être utilisée pour activer toutes les origines de journalisation disponibles, permettant ainsi de suivre une transaction de l’acceptation à la fermeture. Les origines de journalisation individuelles peuvent également être spécifiées en indiquant leurs noms séparés par des virgules, afin d’activer sélectivement la production des journaux.

Les origines de journalisation courantes sont : accept, connect, request, response, close.

Exemple :

frontend myfront
    option httplog
    log-steps accept,close         #only log accept and close for the txn

Les origines de journalisation spécifiées sous forme de « étapes de journalisation » (comme accept, close) peuvent être utilisées telles quelles dans les profils de journalisation (après la directive « on »). Combiner les « étapes de journalisation » avec les profils de journalisation est particulièrement intéressant pour exercer un contrôle fin sur les journaux générés automatiquement par HAProxy lors du traitement des transactions.

Ce paramètre n’est pertinent que sur les frontaux ; il est ignoré sur les backends.

Voir aussi : « log-profile »

log-tag <string>

log-tag <string>

Spécifie l’étiquette de journalisation à utiliser pour tous les journaux sortants

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Définit le champ tag dans l’en-tête syslog à cette chaîne. La valeur par défaut est le log-tag défini dans la section global, sinon le nom du programme tel qu’il a été lancé depuis la ligne de commande, qui est généralement « HAProxy ». Il peut parfois être utile de distinguer plusieurs processus s’exécutant sur le même hôte, ou de distinguer des instances clientes s’exécutant dans le même processus. Dans le backend, les journaux concernant les serveurs up/down utiliseront cette étiquette. À titre indicatif, il peut être pratique de définir un log-tag lié à un client hébergé dans une section defaults, puis d’ajouter tous les frontaux et backends de ce client, avant de commencer une autre instance cliente dans une nouvelle section defaults. Voir également la directive global « log-tag ».

max-keep-alive-queue <value>

max-keep-alive-queue <value>

Définir la taille maximale de la file d’attente du serveur pour la maintenance des connexions keep-alive

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

La réutilisation de la connexion serveur via HTTP keep-alive tente de réutiliser la même connexion serveur dès que possible, mais cela peut parfois s’avérer contre-productif, par exemple si un serveur possède un grand nombre de connexions tandis que d’autres sont inactives. Cela est particulièrement vrai pour les serveurs statiques.

Ce paramètre permet de définir un seuil sur le nombre de connexions en attente au-delà duquel HAProxy cesse de tenter de réutiliser le même serveur et privilégie la recherche d’un autre. La valeur par défaut, -1, signifie qu’aucune limite n’est appliquée. Une valeur nulle signifie que les requêtes keep-alive ne seront jamais mises en attente. Pour des serveurs très proches, accessibles avec une faible latence et peu sensibles à la rupture des connexions keep-alive, une valeur faible est recommandée (par exemple, un serveur local statique peut utiliser une valeur de 10 ou moins). Pour des serveurs distants souffrant d’une forte latence, des valeurs plus élevées peuvent être nécessaires afin de compenser la latence et/ou le coût associé au choix d’un autre serveur.

Notez que cela n’a aucune incidence sur les réponses qui sont conservées sur le même serveur consécutivement à une réponse 401. Elles continueront à être acheminées vers le même serveur, même si elles doivent être mises en file d’attente.

Voir également : « option http-server-close », « option prefer-last-server », la directive « maxconn » du serveur et la persistance des cookies.

max-session-srv-conns <nb>

max-session-srv-conns <nb>

Définir le nombre maximal de connexions sortantes que l’on peut maintenir en veille pour une session cliente donnée. La valeur par défaut est 5 (elle correspond exactement à MAX_SRV_LIST, définie au moment de la compilation).

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

maxconn <conns>

maxconn <conns>

Corriger le nombre maximum de connexions simultanées sur un frontal

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<conns>   is the maximum number of concurrent connections the frontend will
          accept to serve. Excess connections will be queued by the system
          in the socket's listen queue and will be served once a connection
          closes.

Si le système le permet, il peut être utile, sur de grands sites, d’augmenter fortement cette limite afin que HAProxy gère les files d’attente de connexions, plutôt que de laisser les clients avec des tentatives de connexion non répondues. Cette valeur ne doit pas dépasser maxconn global. Gardez à l’esprit qu’une connexion consomme environ 33 ko de mémoire RAM, incluant deux tampons de taille tune.bufsize (16 ko par défaut) ainsi que d’autres données. Cela signifie qu’un système moyen doté de 1 Go de mémoire vive peut supporter environ 20 000 à 25 000 connexions simultanées, si correctement configuré.

En outre, lorsque <conns> est défini avec des valeurs élevées, il se peut que les serveurs ne soient pas dimensionnés pour supporter de telles charges ; il est donc généralement conseillé de leur attribuer des limites de connexion raisonnables.

Lorsque cette valeur est définie à zéro, ce qui est la valeur par défaut, la valeur globale « maxconn » est utilisée.

Voir également : « server », section « global » et son paramètre « maxconn », « fullconn »

mode { tcp|http|log|spop }

mode { tcp|http|log|spop }

Définir le mode d’exécution ou le protocole de l’instance. Peut être utilisé dans les sections : defaults | frontal | listen | backend. oui | oui | oui | oui

Arguments :

tcp       The instance will work in pure TCP mode. A full-duplex connection
          will be established between clients and servers, and no layer 7
          examination will be performed. This is the default mode. It
          should be used for SSL, SSH, SMTP, ...

http      The instance will work in HTTP mode. The client request will be
          analyzed in depth before connecting to any server. Any request
          which is not RFC-compliant will be rejected. Layer 7 filtering,
          processing and switching will be possible. This is the mode which
          brings HAProxy most of its value.

haterm    The frontend will work in haterm HTTP benchmark mode. This is
          not supported by backends. See doc/haterm.txt for details.

log       When used in a backend section, it will turn the backend into a
          log backend. Such backend can be used as a log destination for
          any "log" directive by using the "backend@<name>" syntax. Log
          messages will be distributed to the servers from the backend
          according to the lb settings which can be configured using the
          "balance" keyword. Log backends support UDP servers by prefixing
          the server's address with the "udp@" prefix. Common backend and
          server features are supported, but not TCP or HTTP specific ones.

spop      When used in a backend section, it will turn the backend into a
          spop backend. This mode is mandatory if the backend contains
          SPOA servers, but when mode is tcp, it will automatically be
          converted to mode spop if such servers are detected.

Lors de la commutation de contenu, il est obligatoire que le frontal et le backend soient dans le même mode (généralement HTTP), faute de quoi la configuration sera refusée.

Exemple :

defaults http_instances
    mode http

monitor fail { if | unless } <condition>

monitor fail { if | unless } <condition>

Ajoutez une condition pour signaler un échec à une requête HTTP de surveillance.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

if <cond>     the monitor request will fail if the condition is satisfied,
              and will succeed otherwise. The condition should describe a
              combined test which must induce a failure if all conditions
              are met, for instance a low number of servers both in a
              backend and its backup.

unless <cond> the monitor request will succeed only if the condition is
              satisfied, and will fail otherwise. Such a condition may be
              based on a test on the presence of a minimum number of active
              servers in a list of backends.

Cette instruction ajoute une condition qui peut forcer la réponse à une requête de surveillance à signaler une erreur. Par défaut, lorsque un composant externe interroge l’URI dédié à la surveillance, une réponse 200 est renvoyée. Lorsqu’une des conditions ci-dessus est remplie, HAProxy renvoie 503 au lieu de 200. Cela est très utile pour signaler une panne du site à un composant externe qui pourrait baser ses annonces de routage entre plusieurs sites sur la disponibilité signalée par HAProxy. Dans ce cas, on s’appuierait sur une ACL impliquant le critère « nbsrv ». Notez que « monitor fail » ne fonctionne qu’en mode HTTP. Les deux messages d’état peuvent être ajustés à l’aide de « errorfile » ou « errorloc » si nécessaire.

Exemple :

frontend www
   mode http
   acl site_dead nbsrv(dynamic) lt 2
   acl site_dead nbsrv(static)  lt 2
   monitor-uri   /site_alive
   monitor fail  if site_dead

Voir aussi : « monitor-uri », « errorfile », « errorloc »

monitor-uri <uri>

monitor-uri <uri>

Intercepte une URI utilisée par les requêtes de surveillance des composants externes

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<uri>     is the exact URI which we want to intercept to return HAProxy's
          health status instead of forwarding the request.

Lorsqu’une requête HTTP faisant référence à <uri> sera reçue sur un frontal, HAProxy ne la transmettra ni ne la journalisera, mais renverra soit “HTTP/1.0 200 OK” soit “HTTP/1.0 503 Service unavailable”, selon les conditions d’échec définies avec “monitor fail”. Cela suffit généralement à toute sonde HTTP frontale pour détecter que le service est actif et en fonctionnement, sans transmettre la requête à un serveur backend. Notez que la méthode HTTP, la version et tous les en-têtes sont ignorés, mais la requête doit être au moins valide au niveau HTTP. Ce mot-clé ne peut être utilisé qu’avec un frontal en mode HTTP.

Les requêtes de surveillance sont traitées très tôt, juste après l’analyse de la requête, et même avant toute directive « http-request ». Seules les règles tcp-request sont appliquées avant celles-ci. Elles ne peuvent pas non plus être journalisées, ce qui est le comportement attendu. Une seule URI peut être configurée pour la surveillance ; lorsque plusieurs directives « monitor-uri » sont présentes, celle qui est définie en dernier détermine l’URI utilisée. Elles ne sont utilisées que pour signaler l’état de santé de HAProxy à un composant supérieur, rien de plus. Toutefois, il est possible d’ajouter un nombre quelconque de conditions à l’aide de « monitor fail » et des ACLs afin d’ajuster le résultat selon n’importe quelle vérification imaginable (le plus souvent, le nombre de serveurs disponibles dans un backend).

Note : si <uri> commence par une barre oblique (’/’), la correspondance est effectuée sur le chemin de la requête plutôt que sur l’URI de la requête. Il s’agit d’un contournement permettant aux requêtes HTTP/2 de correspondre à l’URI de surveillance. En effet, dans HTTP/2, les clients sont encouragés à n’envoyer que des URIs absolus.

Exemple :

# Use /haproxy_test to report HAProxy's status
frontend www
    mode http
    monitor-uri /haproxy_test

Voir aussi : « monitor fail »

option abortonclose

option abortonclose
no option abortonclose

Activer ou désactiver l’abandon anticipé du traitement non démarré lorsque le client se ferme

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

La prise en charge des connexions TCP permet la fermeture indépendante dans chaque direction, et une connexion dont une seule direction est fermée est souvent qualifiée de « demi-fermée ». À l’origine, lorsque l’écosystème HTTP était principalement basé sur le mode « fermeture », avec une seule requête et une seule réponse par connexion avant la fermeture, il était fréquent de voir des clients scriptés envoyer leur requête, fermer le côté envoi, attendre la réponse, recevoir l’indication de fermeture et terminer ainsi la connexion. Mais avec l’arrivée du keep-alive et de protocoles plus avancés, cette pratique a pratiquement disparu, et les seuls cas où un client ferme la connexion avant de recevoir sa réponse sont essentiellement ceux où l’utilisateur souhaite interrompre un transfert, ou lorsque le délai d’expiration est atteint et que la connexion est fermée.

Ces deux situations (demi-fermeture vs interruption) sont indiscernables du côté serveur (ici, l’écouteur HAProxy). Cela pose problème, car laisser la connexion ouverte et continuer à traiter une requête lorsque le client interrompt peut consommer beaucoup de ressources, notamment si la fermeture résulte d’un utilisateur cliquant sur le bouton « actualiser », ce qui signifie que de nouvelles requêtes sont en file d’attente sans que les précédentes soient interrompues. Inversement, interrompre systématiquement en cas de situation de demi-fermeture briserait un certain nombre d’applications TCP, ainsi que certaines applications HTTP sur les réseaux internes interagissant avec des agents hérités.

L’option « abortonclose » permet de choisir le comportement souhaité : - lorsqu’elle est présente dans un frontend, elle empêche le traitement des échanges TLS en attente sur une connexion demi-fermée. Cela peut résulter d’un utilisateur qui clique sur « actualiser » pendant une requête HTTPS sous une charge élevée, par exemple lors d’un basculement VRRP entre un nœud HAProxy actif et son sauvegarde : tous les clients se reconnectent en même temps au nouveau nœud, et chacun doit effectuer une main-handshake TLS coûteuse et complète. Si cette opération prend plus de quelques secondes, il est probable que certains utilisateurs abandonnent, et il est inutile de gaspiller des cycles CPU sur leurs échanges. Étant donné le coût CPU des échanges TLS, il est recommandé de laisser cette option activée sur les frontaux exposés à Internet. C’est le comportement par défaut pour les connexions TLS entrantes.

- quand présent dans un backend, il provoque l'abandon d'une requête qui n'a pas encore été envoyée au serveur (c'est-à-dire lorsqu'elle est en attente dans la file ou lors de la tentative de connexion). Si la requête est déjà en cours de traitement par un serveur, la connexion vers ce serveur est elle-même passée en demi-fermeture pour indiquer la même condition au serveur, qui décidera alors de la suite à donner. Ceci est la valeur par défaut pour les backends en mode HTTP.

Il est recommandé d’activer cette option sur les points de terminaison TLS exposés à Internet et sur les services HTTP, et de la désactiver pour les services TCP purs ainsi que pour les environnements hérités non exposés. Elle est activée par défaut dans les backends HTTP et peut être désactivée de force en préfixant le mot-clé par « no », soit dans la section backend elle-même, soit dans la section « defaults » dont elle hérite. Elle est également activée par défaut pour les écouteurs TLS et peut être désactivée de force en spécifiant « no option abortonclose » dans le frontend ou dans la section « defaults » dont il hérite.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « délai d’expiration de file d’attente » et les paramètres serveur « maxconn » et « maxqueue »

option accept-invalid-http-request (deprecated)

option accept-invalid-http-request     (deprecated)
no option accept-invalid-http-request  (deprecated)

Activer ou désactiver la relaxation de l’analyse des requêtes HTTP

Le mot-clé « accept-invalid-http-request » est obsolète ; utilisez plutôt « option accept-unsafe-violations-in-http-request ».

option accept-invalid-http-response (deprecated)

option accept-invalid-http-response     (deprecated)
no option accept-invalid-http-response  (deprecated)

Activer ou désactiver la relaxation de l’analyse des réponses HTTP

Le mot-clé « accept-invalid-http-response » est obsolète ; utilisez plutôt « option accept-unsafe-violations-in-http-response ».

option accept-unsafe-violations-in-http-request

option accept-unsafe-violations-in-http-request
no option accept-unsafe-violations-in-http-request

Activer ou désactiver la relaxation de l’analyse des requêtes HTTP

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Par défaut, HAProxy respecte les différentes RFC HTTP en matière d’analyse des messages. Cela signifie que l’analyse des messages est assez stricte et provoque une erreur renvoyée au client pour les messages malformés. Ce comportement est souhaité, car de tels messages malformés sont essentiellement utilisés pour construire des attaques exploitant des faiblesses du serveur ou contourner les filtres de sécurité. Parfois, un navigateur défectueux ne respecte pas ces RFCs pour une raison quelconque (configuration, implémentation…) et le problème n’est pas immédiatement corrigé. Dans un tel cas, il est possible de relâcher le parseur HAProxy pour accepter certaines requêtes non valides en spécifiant cette option. La plupart des règles concernent l’analyse H1 pour des raisons historiques. Les versions plus récentes de HTTP ont tendance à être plus propres et les applications suivent plus strictement ces protocoles.

Lorsque cette option est définie, les règles suivantes s’appliquent :

* Dans H1 uniquement, les caractères non valides, y compris le caractère NULL, dans le nom d’en-tête ne seront pas rejetés ; toutefois, l’en-tête sera supprimé.

* Dans H1 uniquement, un caractère NULL dans une valeur d’en-tête sera accepté ;

* Dans H1 uniquement, les caractères dont la valeur est supérieure à 127 dans l'URI seront acceptés. La liste des caractères autorisés dans un URI est strictement définie par RFC3986. Les caractères 0 à 31, 32 (espace), 34 (« " »), 60 (« < »), 62 (« > »), 92 (« &#92; »), 94 (« ^ »), 96 (« ` »), 123 (« { »), 124 (« | »), 125 (« } »), 127 (suppression) et tous ceux dont la valeur est supérieure ne sont normalement pas autorisés. Dans H1, tous les caractères dont la valeur est comprise entre 0 et 32 ainsi que 127 seront systématiquement bloqués. Tous les caractères dont la valeur est supérieure à 127 (exclu) seront également bloqués, sauf lorsque cette option est activée. Les autres caractères (33 à 126) ne seront pas vérifiés du tout.

* Dans H1 et H2, les URL contenant des références de fragment ('#' après le chemin) seront acceptées ;

* En H1 uniquement, aucune vérification n'est effectuée sur l'autorité pour les requêtes CONNECT ;

* Dans H1 uniquement, aucune vérification ne sera effectuée contre la valeur de l'en-tête authority et de l'en-tête Host.

* Dans H1 uniquement, les contrôles de la version HTTP seront assouplis. Les requêtes GET HTTP/0.9 pourront ainsi être transmises sans version spécifiée, tout comme les requêtes utilisant d'autres noms de protocole, par exemple RTSP, ou plusieurs chiffres pour les versions majeure et mineure.

* Dans H1 uniquement, les requêtes WebSocket (RFC6455) ne présentant pas de champ d'en-tête "Sec-Websocket-Key" valide seront acceptées.

Cette option ne doit jamais être activée par défaut, car elle masque les bugs applicatifs et expose des failles de sécurité. Elle ne doit être déployée qu’après confirmation d’un problème.

Lorsque cette option est activée, les requêtes H1 invalides mais acceptées sont capturées afin de permettre une analyse ultérieure à l’aide de la requête « show errors » sur le socket de statistiques UNIX. Cette action permet également de confirmer que le problème a été résolu.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option accept-unsafe-violations-in-http-response » et « show errors » sur la socket de statistiques.

option accept-unsafe-violations-in-http-response

option accept-unsafe-violations-in-http-response
no option accept-unsafe-violations-in-http-response

Activer ou désactiver la relaxation de l’analyse des réponses HTTP

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

De même que « option accept-unsafe-violations-in-http-request », cette option peut être utilisée pour assouplir les règles de parsing des réponses HTTP. Elle ne doit être activée que pour des serveurs hérités de confiance, afin d’accepter certaines réponses non conformes. La plupart de ces règles concernent le parsing H1 pour des raisons historiques. Les versions plus récentes de HTTP ont tendance à être plus rigoureuses, et les applications suivent désormais ces protocoles de manière plus stricte.

Lorsque cette option est définie, les règles suivantes s’appliquent :

* Dans H1 uniquement, les codes d’état de plus de 3 chiffres mais dont la valeur tient dans 16 bits ne sont pas rejetés.

* Dans H1 uniquement, les caractères non valides, y compris le caractère NULL, dans le nom d’en-tête ne seront pas rejetés ; toutefois, l’en-tête sera supprimé.

* Dans H1 uniquement, un caractère NULL dans une valeur d’en-tête sera accepté ;

* Dans H1 uniquement, les valeurs vides ou plusieurs occurrences de valeurs « chunked » pour l’en-tête Transfer-Encoding seront acceptées ;

* Dans H1 uniquement, aucune vérification ne sera effectuée contre la valeur de l'en-tête authority et de l'en-tête Host.

* Dans H1 uniquement, les tests sur la version HTTP seront assouplis. Cela permettra des noms de protocole différents (par exemple RTSP) ainsi que des chiffres multiples pour les versions majeure et mineure.

* Dans H1 uniquement, les réponses WebSocket (RFC6455) qui ne présentent pas un champ d'en-tête "Sec-Websocket-Accept" valide seront acceptées.

Cette option ne doit jamais être activée par défaut, car elle masque les bugs applicatifs et expose des failles de sécurité. Elle ne doit être déployée qu’après confirmation d’un problème.

Lorsque cette option est activée, les noms d’en-tête erronés seront toujours acceptés dans les réponses, mais la réponse complète sera capturée afin de permettre une analyse ultérieure à l’aide de la requête « show errors » sur le socket de statistiques UNIX. Cette action permet également de confirmer que le problème a été résolu.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option accept-unsafe-violations-in-http-request » et « show errors » sur la socket de statistiques.

option allbackups

option allbackups
no option allbackups

Utilisez soit tous les serveurs de sauvegarde en même temps, soit uniquement le premier.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Par défaut, le premier serveur de secours opérationnel reçoit tout le trafic lorsque tous les serveurs normaux sont hors service. Parfois, il peut être préférable d’utiliser plusieurs serveurs de secours simultanément, car un seul ne serait pas suffisant. Lorsque l’option allbackups est activée, la répartition de charge est effectuée entre tous les serveurs de secours lorsque tous les serveurs normaux sont indisponibles. Le même algorithme de répartition de charge est utilisé et les poids des serveurs sont respectés. Ainsi, il n’y a plus d’ordre de priorité entre les serveurs de secours.

Cette option est principalement utilisée avec des fermes de serveurs statiques destinées à renvoyer une page « désolé » lorsque l’application est complètement hors ligne.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

option checkcache

option checkcache
no option checkcache

Analysez toutes les réponses des serveurs et bloquez les réponses comportant des cookies pouvant être mis en cache

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Certains frameworks de haut niveau définissent des cookies d’application partout et ne permettent pas toujours au développeur un contrôle suffisant sur la manière dont les réponses doivent être mises en cache. Lorsqu’un cookie de session est renvoyé pour un objet pouvant être mis en cache, le risque de croisement ou de vol de session entre utilisateurs empruntant les mêmes caches est élevé. Dans certaines situations, il est préférable de bloquer la réponse que de laisser des informations sensibles de session circuler librement.

L’option « checkcache » active une inspection approfondie de toutes les réponses des serveurs afin de garantir une conformité stricte à la spécification HTTP en matière de cacheabilité. Elle vérifie soigneusement les en-têtes « Cache-control », « Pragma » et « Set-cookie » dans la réponse du serveur afin de détecter tout risque de mise en cache d’un cookie par un proxy côté client. Lorsque cette option est activée, les seules réponses pouvant être transmises au client sont : - toutes celles qui ne contiennent pas d’en-tête « Set-Cookie » ; - toutes celles dont le code de retour est différent de 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501, à condition que le serveur n’ait pas défini un champ d’en-tête « Cache-control: public » ; - toutes celles résultant d’une requête utilisant une méthode autre que GET, HEAD, OPTIONS, TRACE, à condition que le serveur n’ait pas défini un champ d’en-tête « Cache-Control: public » ; - celles comportant un en-tête « Pragma: no-cache » ; - celles comportant un en-tête « Cache-control: private » ; - celles comportant un en-tête « Cache-control: no-store » ; - celles comportant un en-tête « Cache-control: max-age=0 » ; - celles comportant un en-tête « Cache-control: s-maxage=0 » ; - celles comportant un en-tête « Cache-control: no-cache » ; - celles comportant un en-tête « Cache-control: no-cache=“set-cookie” » ; - celles comportant un en-tête « Cache-control: no-cache=“set-cookie, » (permettant d’autres champs après « set-cookie »).

Si une réponse ne respecte pas ces exigences, elle sera bloquée comme si elle provenait d’une règle « http-response deny », avec une réponse « HTTP 502 bad gateway ». L’état de session affiche « PH– », ce qui signifie que le proxy a bloqué la réponse durant le traitement des en-têtes. En outre, une alerte sera envoyée dans les journaux afin d’informer les administrateurs qu’une correction est nécessaire.

En raison de l’impact élevé sur l’application, celle-ci doit être testée de manière approfondie avec l’option activée avant de passer en production. Il est également recommandé d’activer toujours cette option lors des tests, même si elle n’est pas utilisée en production, car elle signale les comportements potentiellement dangereux de l’application.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

option clitcpka

option clitcpka
no option clitcpka

Activer ou désactiver l’envoi de paquets TCP keepalive du côté client

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Lorsqu’un pare-feu ou tout composant sensible à la session se trouve entre un client et un serveur, et que le protocole implique des sessions très longues avec des périodes d’inactivité prolongées (par exemple, les bureaux distants), il existe un risque que l’un des composants intermédiaires décide d’expirer une session restée inactif trop longtemps.

Activer les keep-alives TCP au niveau du socket fait que le système envoie régulièrement des paquets à l’autre extrémité de la connexion, la maintenant active. Le délai entre les sondes de keep-alive est contrôlé uniquement par le système et dépend à la fois du système d’exploitation et de ses paramètres de réglage.

Il est important de comprendre que les paquets keep-alive ne sont ni émis ni reçus au niveau de l’application. Seuls les piles réseau les perçoivent. Pour cette raison, même si l’une des extrémités du proxy utilise déjà des keep-alive pour maintenir sa connexion active, ces paquets keep-alive ne seront pas transférés à l’autre extrémité du proxy.

Veuillez noter que cela n’a rien à voir avec le keep-alive HTTP.

L’option « clitcpka » active l’envoi de sondes TCP keep-alive côté client d’une connexion, ce qui devrait aider à détecter les expiration de session entre HAProxy et un client.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option srvtcpka », « option tcpka »

option contstats

option contstats

Activer la mise à jour continue des statistiques de trafic

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Par défaut, les compteurs utilisés pour le calcul des statistiques ne sont incrémentés qu’au moment où un flux se termine. Cela fonctionne assez bien lors de la mise à disposition d’objets de petite taille, mais avec des objets volumineux (par exemple des images ou archives importantes) ou lors du streaming A/V, le graphique généré à partir des compteurs HAProxy ressemble à un hérisson. Lorsque cette option est activée, les compteurs sont incrémentés fréquemment tout au long du flux, généralement toutes les 5 secondes, ce qui est souvent suffisant pour produire des graphiques nets. Le recalcule touche directement un chemin critique, aussi n’est-il pas activé par défaut, car il peut entraîner de nombreux réveils pour un très grand nombre de sessions et provoquer une légère baisse de performance.

option disable-h2-upgrade

option disable-h2-upgrade
no option disable-h2-upgrade

Active ou désactive la mise à jour implicite HTTP/2 à partir d’une connexion client HTTP/1.x.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Par défaut, HAProxy est capable de mettre implicitement à jour une connexion client HTTP/1.x en connexion HTTP/2 si la première requête qu’il reçoit sur une connexion HTTP donnée correspond à l’introduction de connexion HTTP/2 (c’est-à-dire la chaîne « PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n »). Ainsi, il est possible de prendre en charge des clients HTTP/1.x et HTTP/2 sur des connexions non chiffrées. Cette option doit être utilisée pour désactiver la mise à jour implicite. Notez que cette mise à jour implicite n’est prise en charge que pour les proxies HTTP, ce qui s’applique également à cette option. Notez également qu’il est possible de forcer le HTTP/2 sur des connexions claires en spécifiant « proto h2 » dans la directive bind. Enfin, cette option s’applique à toutes les directives bind. Pour désactiver les mises à jour implicites de HTTP/2 pour une directive bind spécifique, il est possible d’utiliser « proto h1 ».

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

option dontlog-normal

option dontlog-normal
no option dontlog-normal

Activer ou désactiver la journalisation des connexions normales et réussies

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Il existe des sites très volumineux traitant plusieurs milliers de connexions par seconde, pour lesquels la journalisation constitue un problème majeur. Certains sont même contraints de désactiver les journaux et ne peuvent pas déboguer les problèmes en production. L’activation de cette option garantit que les connexions normales, celles qui ne rencontrent aucune erreur, aucun délai d’expiration, aucune tentative de reconnexion ni aucun réacheminement, ne seront pas journalisées. Cela libère de l’espace disque pour les anomalies. En mode HTTP, le code d’état de la réponse est vérifié et les codes de retour 5xx seront toujours journalisés.

Il est fortement déconseillé d’utiliser cette option, car la plupart du temps, la clé des problèmes complexes se trouve dans les journaux normaux, qui ne seront pas journalisés ici. Si vous devez séparer les journaux, utilisez plutôt l’option « log-separate-errors ».

Voir aussi : « log », « dontlognull », « log-separate-errors » et section 8 concernant la journalisation.

option dontlognull

option dontlognull
no option dontlognull

Activer ou désactiver la journalisation des connexions nulles

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Dans certains environnements, des composants se connectent régulièrement à divers systèmes afin de vérifier qu’ils sont toujours actifs. Cela peut provenir d’un autre répartiteur de charge ou de systèmes de surveillance. Par défaut, même une simple vérification de port ou un balayage génère une entrée dans les journaux. Si ces connexions polluent trop les journaux, il est possible d’activer l’option « dontlognull » pour indiquer qu’une connexion sur laquelle aucune donnée n’a été transférée ne sera pas journalisée, ce qui correspond généralement à ces sondes. Notez que les erreurs seront toutefois renvoyées au client et prises en compte dans les statistiques. Si ce n’est pas le comportement souhaité, l’option « http-ignore-probes » peut être utilisée à la place.

Il est généralement recommandé de ne pas utiliser cette option dans des environnements non contrôlés (par exemple, Internet), faute de quoi les scans et autres activités malveillantes ne seraient pas journalisés.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « log », « http-ignore-probes », « monitor-uri », et la section 8 concernant la journalisation.

option external-check

option external-check

Utilisez des processus externes pour les contrôles d’état des serveurs

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Il est possible de tester l’état de santé d’un serveur à l’aide d’une commande externe. Cela est réalisé en exécutant l’exécutable défini par la directive « external-check command ».

Exige que l’option globale « external-check » soit définie.

Voir aussi : « external-check », « external-check command », « external-check path »

option forwarded [ proto ]

option forwarded [ proto ]
                 [ host | host-expr <host_expr> ]
                 [ by | by-expr <by_expr> ] [ by_port | by_port-expr <by_port_expr>]
                 [ for | for-expr <for_expr> ] [ for_port | for_port-expr <for_port_expr>]
no option forwarded

Activer l’insertion de l’en-tête forwarded défini par le RFC 7239 dans les requêtes envoyées aux serveurs

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<host_expr>     optional argument to specify a custom sample expression
                those result will be used as 'host' parameter value

<by_expr>       optional argument to specify a custom sample expression
                those result will be used as 'by' parameter nodename value

<for_expr>      optional argument to specify a custom sample expression
                those result will be used as 'for' parameter nodename value

<by_port_expr>  optional argument to specify a custom sample expression
                those result will be used as 'by' parameter nodeport value

<for_port_expr> optional argument to specify a custom sample expression
                those result will be used as 'for' parameter nodeport value

Étant donné que HAProxy fonctionne en mode proxy inverse, les serveurs perdent une partie du contexte de la requête (origine de la requête : adresse IP du client, protocole utilisé…).

Une manière courante de contourner cette limitation consiste à utiliser les en-têtes bien connus x-forward-for et x-forward-* pour exposer une partie de ce contexte au niveau du servers/applications. sous-jacent. Bien que cette approche fonctionnait autrefois et soit largement déployée, elle n’est pas officiellement prise en charge par l’IETF et peut être à l’origine de problèmes d’interopérabilité ainsi que de failles de sécurité.

Pour résoudre ce problème, une nouvelle extension HTTP a été définie par l’IETF : l’en-tête forwarded (RFC7239). Plus d’informations ici : https://www.rfc-editor.org/rfc/rfc7239.html

L’utilisation de cet en-tête unique permet de transmettre de nombreuses informations au sein du même en-tête, et surtout, résout le problème de chaînage de proxy. (La RFC autorise plusieurs proxies en chaîne à ajouter leurs propres valeurs à un en-tête déjà existant).

Cette option peut être spécifiée dans les sections defaults, listen ou backend, mais sera ignorée dans les sections frontend.

Définir l’option forwarded sans argument entraîne l’utilisation du comportement implicite par défaut. Ce comportement par défaut active le paramètre proto et injecte l’adresse IP du client d’origine.

La configuration équivalente explicit/manual serait :

option forwarded proto for

Le mot-clé « by » est utilisé pour activer le paramètre « by » (« nodename ») dans l’en-tête transféré. Il permet d’insérer des informations sur le proxy de la requête. La valeur de « by » sera définie sur l’adresse IP du proxy (adresse de destination) si disponible. Sinon (par exemple, avec un écouteur UNIX), « by » sera définie sur « unknown ».

Le mot-clé « by-expr » est utilisé pour activer le paramètre « by » (“nodename”) dans l’en-tête transféré. Il permet d’incorporer des informations sur le proxy de la requête. La valeur de « by » sera définie par le résultat de l’expression d’échantillonnage <by_expr>, si elle est valide, sinon elle sera définie à « unknown ».

Le mot-clé « for » est utilisé pour activer le paramètre « for » (« nodename ») dans l’en-tête transféré. Il permet d’incorporer des informations sur le client de la requête. La valeur de « for » sera définie sur l’adresse IP du client (adresse source) si disponible. Sinon (par exemple, avec un écouteur UNIX), « for » sera définie sur « unknown ».

Le mot-clé « for-expr » est utilisé pour activer le paramètre « for » (« nodename ») dans l’en-tête transféré. Il permet d’insérer des informations sur le client de la requête. La valeur de « for » sera définie sur le résultat de l’expression d’échantillonnage <for_expr>, si elle est valide, sinon elle sera définie sur « unknown ».

Le mot-clé ‘by_port’ est utilisé pour fournir les informations « nodeport » au paramètre « by ». ‘by_port’ exige que « by » ou « by-expr » soit défini, sinon il sera ignoré. Le champ « nodeport » sera défini sur le port du proxy (destination) s’il est disponible, sinon il sera ignoré.

Le mot-clé ‘by_port-expr’ est utilisé pour fournir les informations « nodeport » au paramètre « by ». ‘by_port-expr’ exige que « by » ou « by-expr » soit défini, sinon il sera ignoré. Le champ « nodeport » sera défini avec le résultat de l’expression d’échantillonnage <by_port_expr>, si celle-ci est valide, sinon il sera ignoré.

Le mot-clé ‘for_port’ est utilisé pour fournir les informations « nodeport » au paramètre « for ». ‘for_port’ exige que « for » ou « for-expr » soit défini, sinon il sera ignoré. Le « nodeport » sera défini sur le port client (source) s’il est disponible, sinon il sera ignoré.

Le mot-clé ‘for_port-expr’ est utilisé pour fournir les informations « nodeport » au paramètre « for ». ‘for_port-expr’ exige que « for » ou « for-expr » soit défini, sinon il sera ignoré. Le champ « nodeport » sera défini avec le résultat de l’expression d’échantillonnage <for_port_expr>, si celle-ci est valide, sinon il sera ignoré.

Exemples :

# Those servers want the ip address and protocol of the client request
# Resulting header would look like this:
#   forwarded: proto=http;for=127.0.0.1
backend www_default
    mode http
    option forwarded
    #equivalent to: option forwarded proto for

# Those servers want the requested host and hashed client ip address
# as well as client source port (you should use seed for xxh32 if ensuring
# ip privacy is a concern)
# Resulting header would look like this:
#   forwarded: host="haproxy.org";for="_000000007F2F367E:60138"
backend www_host
    mode http
    option forwarded host for-expr src,xxh32,hex for_port

# Those servers want custom data in host, for and by parameters
# Resulting header would look like this:
#   forwarded: host="host.com";by=_haproxy;for="[::1]:10"
backend www_custom
    mode http
    option forwarded host-expr str(host.com) by-expr str(_haproxy) for for_port-expr int(10)

# Those servers want random 'for' obfuscated identifiers for request
# tracing purposes while protecting sensitive IP information
# Resulting header would look like this:
#   forwarded: for=_000000002B1F4D63
backend www_for_hide
    mode http
    option forwarded for-expr rand,hex

Voir aussi : « option forwardfor », « option originalto »

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

Activer l’insertion de l’en-tête X-Forwarded-For dans les requêtes envoyées aux serveurs

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<network> is an optional argument used to disable this option for sources
          matching <network>
<name>    an optional argument to specify a different "X-Forwarded-For"
          header name.

Étant donné que HAProxy fonctionne en mode proxy inverse, les serveurs voient son adresse IP comme celle du client. Cela peut parfois être problématique lorsque l’adresse IP du client est attendue dans les journaux du serveur. Pour résoudre ce problème, HAProxy peut ajouter l’en-tête HTTP bien connu « X-Forwarded-For » à toutes les requêtes envoyées au serveur. Cet en-tête contient une valeur représentant l’adresse IP du client. Étant donné que cet en-tête est toujours ajouté à la fin de la liste d’en-têtes existante, le serveur doit être configuré pour ne jamais utiliser que la dernière occurrence de cet en-tête. Consultez le manuel du serveur pour savoir comment activer l’utilisation de cet en-tête standard. Notez que seule la dernière occurrence de l’en-tête doit être utilisée, car il est effectivement possible que le client ait déjà fourni cet en-tête.

Le mot-clé « header » peut être utilisé pour spécifier un nom d’en-tête différent afin de remplacer le nom par défaut « X-Forwarded-For ». Cela peut être utile lorsque vous avez déjà un en-tête « X-Forwarded-For » provenant d’une autre application (par exemple, stunnel) et que vous devez le préserver. De même, si votre backend ne utilise pas l’en-tête « X-Forwarded-For » et nécessite un autre en-tête (par exemple, les serveurs Web Zeus exigent « X-Cluster-Client-IP »).

Parfois, une même instance HAProxy peut être partagée entre un accès direct depuis un client et un accès via un proxy inverse (par exemple, lorsqu’un proxy inverse SSL est utilisé pour déchiffrer le trafic HTTPS). Il est possible de désactiver l’ajout de l’en-tête pour une adresse ou un réseau connu en ajoutant le mot-clé « except » suivi de l’adresse réseau. Dans ce cas, toute adresse IP source correspondant au réseau ne déclenchera pas l’ajout de cet en-tête. Les utilisations les plus courantes concernent les réseaux privés ou 127.0.0.1. Les versions IPv4 et IPv6 sont toutes deux prises en charge.

Autrement, le mot-clé « if-none » indique que l’en-tête ne sera ajouté que s’il est absent. Cela ne doit être utilisé que dans un environnement entièrement fiable, car cela pourrait entraîner une faille de sécurité si les en-têtes parvenant à HAProxy sont contrôlés par l’utilisateur final.

Cette option peut être spécifiée soit dans le frontal, soit dans le backend. Si au moins l’un d’eux l’utilise, l’en-tête sera ajouté. Notez que le paramètre d’en-tête défini dans le backend a priorité sur celui défini dans le frontal si les deux sont configurés. Dans le cas de l’argument « if-none », si au moins l’un du frontal ou du backend ne le précise pas, il impose que l’ajout soit obligatoire, et donc l’emporte.

Exemple :

# Public HTTP address also used by stunnel on the same machine
frontend www
    mode http
    option forwardfor except 127.0.0.1  # stunnel already adds the header

# Those servers want the IP Address in X-Client
backend www
    mode http
    option forwardfor header X-Client

Voir également : « option httpclose », « option http-server-close », « option http-keep-alive »

option h1-case-adjust-bogus-client

option h1-case-adjust-bogus-client
no option h1-case-adjust-bogus-client

Activer ou désactiver le réglage de la casse des en-têtes HTTP/1 envoyés aux clients malveillants

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Il n’existe pas de cas standard pour les noms d’en-têtes, car, comme indiqué dans RFC7230, ils sont insensibles à la casse. Les applications doivent donc les traiter de manière insensible à la casse. Toutefois, certaines applications incorrectes violent les normes et s’appuient erronément sur les cas les plus couramment utilisés par les navigateurs. Ce problème devient critique avec HTTP/2 car tous les noms d’en-têtes doivent être échangés en minuscules, et HAProxy adopte la même convention. Tous les noms d’en-têtes sont envoyés en minuscules aux clients et aux serveurs, indépendamment de la version HTTP.

Lorsqu’HAProxy reçoit une réponse HTTP/1, ses noms d’en-têtes sont convertis en minuscules, manipulés et envoyés ainsi aux clients. Si un client est connu pour violer les normes HTTP et échouer à traiter une réponse provenant d’HAProxy, il est possible de transformer les noms d’en-têtes en minuscules vers un format différent lors de la mise en forme et de l’envoi de la réponse au client, en activant cette option et en précisant la liste des en-têtes à reformater à l’aide des directives globales « h1-case-adjust » ou « h1-case-adjust-file ». Ceci ne doit être qu’une solution de contournement temporaire, le temps que le client soit corrigé, car les clients nécessitant de telles solutions de contournement pourraient être vulnérables aux attaques d’envoi de contenu masqué et doivent être absolument corrigés.

Veuillez noter que cette option n’affecte pas les clients conformes aux normes.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option h1-case-adjust-bogus-server », « h1-case-adjust », « h1-case-adjust-file ».

option h1-case-adjust-bogus-server

option h1-case-adjust-bogus-server
no option h1-case-adjust-bogus-server

Activer ou désactiver le traitement de la casse des en-têtes HTTP/1 envoyés aux serveurs malveillants

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Il n’existe pas de cas standard pour les noms d’en-têtes, car, comme indiqué dans RFC7230, ils sont insensibles à la casse. Les applications doivent donc les traiter de manière insensible à la casse. Toutefois, certaines applications incorrectes violent les normes et s’appuient erronément sur les cas les plus couramment utilisés par les navigateurs. Ce problème devient critique avec HTTP/2 car tous les noms d’en-têtes doivent être échangés en minuscules, et HAProxy adopte la même convention. Tous les noms d’en-têtes sont envoyés en minuscules aux clients et aux serveurs, indépendamment de la version HTTP.

Lorsqu’HAProxy reçoit une requête HTTP/1, les noms d’en-têtes sont convertis en minuscules, manipulés et envoyés de cette manière aux serveurs. Si un serveur est connu pour violer les normes HTTP et échouer à traiter une requête provenant d’HAProxy, il est possible de transformer les noms d’en-têtes en minuscules vers un format différent lors de la mise en forme et de l’envoi de la requête au serveur, en activant cette option et en précisant la liste des en-têtes à reformater à l’aide des directives globales « h1-case-adjust » ou « h1-case-adjust-file ». Ceci ne doit être qu’une solution de contournement temporaire, le temps que le serveur soit corrigé, car les serveurs nécessitant de telles solutions de contournement pourraient être vulnérables aux attaques d’envoi de contenu masqué et doivent absolument être corrigés.

Veuillez noter que cette option n’affecte pas les serveurs conformes aux normes.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option h1-case-adjust-bogus-client », « h1-case-adjust », « h1-case-adjust-file ».

option http-buffer-request

option http-buffer-request
no option http-buffer-request

Activer ou désactiver l’attente de la totalité du corps de la requête HTTP avant de poursuivre

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Il peut parfois être souhaitable d’attendre la réception du corps d’une requête HTTP avant de prendre une décision. C’est précisément ce que fait « balance url_param », par exemple. Le premier cas d’utilisation consiste à tamponner les requêtes provenant de clients lents avant de se connecter au serveur. Un autre cas d’utilisation consiste à prendre la décision de routage en fonction du contenu du corps de la requête. Cette option, placée dans un frontal ou un backend, force le traitement HTTP à attendre jusqu’à réception intégrale du corps ou remplissage complet du tampon de requête. Elle peut entraîner des effets indésirables avec certaines applications qui abuse de HTTP en s’attendant à des transmissions non tamponnées entre le frontal et le backend ; elle ne doit donc certainement pas être utilisée par défaut.

Voir aussi : « option http-no-delay », « timeout http-request », « http-request wait-for-body »

option http-drop-request-trailers

option http-drop-request-trailers
no option http-drop-request-trailers

Supprimer les traînées HTTP de la requête lors de son envoi au serveur

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | non | oui

Arguments : aucun

Lorsque cette option est activée, tous les trailers HTTP trouvés dans une requête sont supprimés avant d’être envoyés au serveur.

RFC9110#section-6.5.1 indique que les champs de bout de message peuvent être fusionnés avec les champs d’en-tête. Cette opération doit être effectuée intentionnellement, mais elle peut poser problème pour certaines applications, notamment si des clients malveillants masquent des champs d’en-tête sensibles dans la partie des champs de bout de message et que certains intermédiaires les fusionnent avec les en-têtes sans vérification spécifique. Dans ce cas, cette option peut être activée sur le backend afin de supprimer tout champ de bout de message détecté dans les requêtes avant leur envoi au serveur.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option http-drop-response-trailers »

option http-drop-response-trailers

option http-drop-response-trailers
no option http-drop-response-trailers

Supprimer les traînées HTTP de la réponse lors de son envoi au client

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Cette option est similaire à « option http-drop-request-trailers », mais elle doit être utilisée pour supprimer les champs de bout de réponse avant de les envoyer aux clients.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option http-drop-request-trailers »

option http-ignore-probes

option http-ignore-probes
no option http-ignore-probes

Activez ou désactivez la journalisation des connexions nulles et des délais d’expiration des requêtes

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Récemment, certains navigateurs ont commencé à implémenter une fonctionnalité de « pré-connexion », consistant à établir une connexion en avance à certains sites web récemment visités, au cas où l’utilisateur souhaiterait les visiter. Cela entraîne la création de nombreuses connexions vers des sites web, qui aboutissent à un code 408 Délai d’expiration de la requête si le délai d’expiration est atteint en premier, ou à un code 400 Requête incorrecte lorsque le navigateur décide de les fermer en premier. Ces événements polluent les journaux et alimentent les compteurs d’erreurs. Une option « option dontlognull » existait déjà, mais elle est insuffisante dans ce cas. À la place, cette option effectue les actions suivantes : - empêche l’envoi de tout message 400/408 au client si rien n’a été reçu sur une connexion avant sa fermeture ; - empêche l’émission de tout message de journalisation dans cette situation ; - empêche l’incrémentation de tout compteur d’erreur

Ainsi, la connexion vide est ignorée silencieusement. Notez qu’il est préférable de ne pas utiliser cette option sauf si son utilité est claire, car elle masque des problèmes réels. La raison la plus courante d’une requête non reçue accompagnée d’un code 408 provient d’une incohérence de MTU entre le client et un élément intermédiaire tel qu’un VPN, qui bloque les paquets trop volumineux. Ces problèmes sont généralement observés avec les requêtes POST ainsi qu’avec les requêtes GET comportant de grandes cookies. Les journaux sont souvent la seule manière de les détecter.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « log », « dontlognull », « errorfile » et la section 8 sur la journalisation.

option http-keep-alive

option http-keep-alive
no option http-keep-alive

Activer ou désactiver la persistance HTTP du client vers le serveur pour les connexions HTTP/1.x

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Par défaut, HAProxy fonctionne en mode keep-alive pour les connexions persistantes HTTP/1.x : pour chaque connexion, il traite chaque requête et réponse, puis laisse la connexion inactif des deux côtés. Ce mode peut être modifié par plusieurs options, telles que « option http-server-close » ou « option httpclose ». Cette option permet de rétablir le mode keep-alive, ce qui peut être utile lorsque un autre mode a été utilisé dans une section « defaults ».

Paramètre « option http-keep-alive » active le mode keep-alive HTTP côté client et côté serveur. Cela permet d’obtenir la latence la plus faible côté client (réseau lent) et la réutilisation de session la plus rapide côté serveur, au prix de la maintenance de connexions inactives vers les serveurs. En général, il est possible, avec cette option, d’atteindre environ le double du débit de requêtes que l’option « http-server-close » permet sur des objets de petite taille. Deux situations principales rendent cette option utile :

- lorsque le serveur n'est pas conforme à HTTP et authentifie la connexion
    au lieu des requêtes (par exemple, authentification NTLM)

- lorsque le coût de l'établissement de la connexion au serveur est important par rapport au coût de récupération de l'objet associé depuis le serveur.

Ce dernier cas peut survenir lorsque le serveur est un serveur statique rapide ou un cache.

Actuellement, les journaux ne préciseront pas si les requêtes proviennent de la même session. La date d’acceptation indiquée dans les journaux correspond à la fin de la requête précédente, et le temps de requête correspond au temps passé en attente d’une nouvelle requête. Le délai d’expiration de la requête keep-alive reste lié au délai d’expiration défini par « timeout http-keep-alive » ou « timeout http-request », si ce dernier n’est pas configuré.

Cette option désactive et remplace toute option précédente « option httpclose » ou « option http-server-close ».

Voir également : « option httpclose », « option http-server-close », « option prefer-last-server » et « option http-pretend-keepalive ».

option http-no-delay

option http-no-delay
no option http-no-delay

Instructez le système à privilégier les délais d’interaction faibles par rapport aux performances en HTTP

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

En HTTP, chaque charge utile est unidirectionnelle et ne comporte aucune notion d’interactivité. Tout agent doit être capable de mettre en file d’attente les données de manière à garantir un délai raisonnablement faible. Certains rares cas d’applications serveur-à-serveur abuse du protocole HTTP et s’attendent à ce que la phase de charge utile soit hautement interactive, avec de nombreuses tranches de données entrelacées dans les deux sens au sein d’une même requête. Cela n’est absolument pas pris en charge par la spécification HTTP et ne fonctionnera pas à travers la plupart des proxies ou serveurs. Lorsque de telles applications tentent de procéder ainsi via HAProxy, cela fonctionne, mais elles subiront des délais élevés dus aux optimisations réseau qui favorisent les performances en incitant le système à attendre que suffisamment de données soient disponibles afin d’envoyer uniquement des paquets complets. Les délais typiques s’élèvent à environ 200 ms par aller-retour. Notez qu’un tel comportement ne se produit qu’en cas d’utilisation anormale. Les utilisations normales, telles que les requêtes CONNECT ou les WebSockets, ne sont pas affectées.

Lorsque l’option http-no-delay est présente dans le frontend ou le backend utilisé par une connexion, toutes ces optimisations sont désactivées afin de rendre les échanges aussi rapides que possible. Bien entendu, cela ne garantit en rien la fonctionnalité, car cela peut provoquer des dysfonctionnements ailleurs. Toutefois, si cela fonctionne via HAProxy, il fonctionnera à la vitesse maximale. Cette option ne doit jamais être utilisée par défaut, et ne doit jamais être utilisée du tout sauf si une application défectueuse est identifiée. L’usage de cette option entraîne une augmentation de la consommation de bande passante et de la charge CPU, ce qui peut réduire significativement les performances dans les environnements à forte latence.

Voir également : « option http-buffer-request »

option http-pretend-keepalive

option http-pretend-keepalive
no option http-pretend-keepalive

Définir si HAProxy doit annoncer keepalive pour la connexion HTTP/1.x au serveur ou non

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsqu’il est exécuté avec l’option « option http-server-close » ou « option httpclose », HAProxy ajoute un en-tête « Connection: close » à la requête HTTP/1.x transmise au serveur. Malheureusement, certains serveurs, lorsqu’ils détectent cet en-tête, renoncent automatiquement à utiliser l’encodage par tronçons pour les réponses de longueur inconnue, ce qui est totalement sans rapport. Le résultat est qu’un client ou un cache pourrait recevoir une réponse incomplète sans s’en rendre compte, et considérer la réponse comme complète.

En définissant « option http-pretend-keepalive », HAProxy fait croire au serveur qu’il maintiendra la connexion ouverte. Le serveur ne basculera alors pas vers le comportement anormal indésirable décrit ci-dessus. Une fois que HAProxy a reçu toute la réponse, il ferme la connexion avec le serveur exactement comme il le ferait avec « option httpclose ». Ainsi, le client reçoit une réponse normale et la connexion est correctement fermée côté serveur.

Il est recommandé de ne pas activer cette option par défaut, car la plupart des serveurs ferment la connexion eux-mêmes de manière plus efficace après le dernier paquet, et libèrent leurs tampons légèrement plus tôt. En outre, le paquet supplémentaire sur le réseau pourrait réduire légèrement les performances maximales globales. Toutefois, il convient de noter qu’en activant cette option, HAProxy aura un travail légèrement moindre à accomplir. Ainsi, si HAProxy constitue le goulot d’étranglement de l’ensemble de l’architecture, l’activation de cette option pourrait économiser quelques cycles CPU.

Cette option peut être définie dans les sections backend et listen. Son utilisation dans une section frontend sera ignorée, et un avertissement sera signalé au démarrage. Il s’agit d’une option liée au backend, aussi n’y a-t-il aucune raison réelle de la définir dans un frontend.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option httpclose », « option http-server-close » et « option http-keep-alive »

option http-restrict-req-hdr-names { preserve | delete | reject }

option http-restrict-req-hdr-names { preserve | delete | reject }

Définir la politique HAProxy concernant les noms d’en-tête de requête HTTP contenant des caractères en dehors de l’ensemble “[a-zA-Z0-9-]”

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

preserve  disable the filtering. It is the default mode for HTTP proxies
          with no FastCGI application configured.

delete    remove request headers with a name containing a character
          outside the "[a-zA-Z0-9-]" charset. It is the default mode for
          HTTP backends with a configured FastCGI application.

reject    reject the request with a 403-Forbidden response if it contains a
          header name with a character outside the "[a-zA-Z0-9-]" charset.

Cette option peut être utilisée pour restreindre les noms d’en-tête de requête aux caractères alphanumériques et au trait d’union ([A-Za-z0-9-]). Cela peut être obligatoire pour assurer l’interopérabilité avec des serveurs non conformes à HTTP qui échouent à traiter certains caractères dans les noms d’en-tête. Elle peut également être obligatoire pour les applications FastCGI, car tous les caractères non alphanumériques dans les noms d’en-tête sont remplacés par un trait de soulignement (’_’). Il devient ainsi facile de confondre des noms d’en-tête et de contourner certaines règles. Par exemple, les en-têtes « X-Forwarded-For » et “X_Forwarded-For” sont tous deux convertis en “HTTP_X_FORWARDED_FOR” en FastCGI.

Notez que cette option est évaluée par proxy et après l’évaluation des règles http-request.

option http-server-close

option http-server-close
no option http-server-close

Activer ou désactiver la fermeture de la connexion HTTP/1.x côté serveur

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Par défaut, HAProxy fonctionne en mode keep-alive pour les connexions persistantes HTTP/1.x : pour chaque connexion, il traite chaque requête et réponse, puis laisse la connexion inactif des deux côtés. Ce mode peut être modifié par plusieurs options, telles que « option http-server-close » ou « option httpclose ». L’activation de « option http-server-close » active le mode de fermeture de connexion HTTP côté serveur tout en conservant la capacité à supporter le keep-alive HTTP et le pipelining côté client. Cela permet d’obtenir la plus faible latence côté client (réseau lent) et la réutilisation de session la plus rapide côté serveur, afin de préserver les ressources serveur, de manière similaire à « option httpclose ». Cela permet également de servir des serveurs non capables de keep-alive en mode keep-alive aux clients, à condition qu’ils respectent les exigences de RFC7230. Veuillez noter que certains serveurs ne respectent pas toujours ces exigences lorsqu’ils reçoivent « Connection: close » dans la requête. Le résultat est qu’aucune connexion keep-alive ne sera utilisée. Une solution de contournement consiste à activer « option http-pretend-keepalive ».

Actuellement, les journaux ne préciseront pas si les requêtes proviennent de la même session. La date d’acceptation indiquée dans les journaux correspond à la fin de la requête précédente, et le temps de requête correspond au temps passé en attente d’une nouvelle requête. Le délai d’expiration de la requête keep-alive reste lié au délai d’expiration défini par « timeout http-keep-alive » ou « timeout http-request », si ce dernier n’est pas configuré.

Cette option peut être définie aussi bien dans un frontend que dans un backend. Elle est activée si au moins l’un des deux — frontend ou backend — qui gère une connexion l’a activée. Elle désactive et remplace toute option précédente « option httpclose » ou « option http-keep-alive ». Veuillez consulter la section 4 (“Proxies”) pour comprendre comment cette option s’combine avec les autres lorsque les options frontend et backend diffèrent.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option httpclose », « option http-pretend-keepalive » et « option http-keep-alive ».

option http-use-proxy-header

option http-use-proxy-header
no option http-use-proxy-header

Utilisez l’en-tête Proxy-Connection non standard à la place de Connection

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Bien que RFC7230 indique explicitement que les agents HTTP/1.1 doivent utiliser l’en-tête Connection pour indiquer leur préférence concernant les connexions persistantes ou non persistantes, les navigateurs et les proxies ignorent cet en-tête pour les connexions proxyées et utilisent à la place l’en-tête Proxy-Connection, non documenté et non standard. Le problème survient lorsqu’on cherche à placer un répartiteur de charge entre les navigateurs et de tels proxies, car il y aura une différence entre ce que HAProxy comprend et ce que le client et le proxy ont convenu.

En définissant cette option dans un frontal, HAProxy peut automatiquement passer à l’utilisation de cet en-tête non standard s’il détecte des requêtes proxyées. Une requête proxyée est définie ici comme une requête dont l’URI ne commence ni par ‘/’ ni par ‘*’. Cette option est incompatible avec le mode tunnel HTTP. Notez que cette option ne peut être spécifiée que dans un frontal et affecte la requête tout au long de sa durée de vie.

En outre, lorsque cette option est définie, une requête nécessitant une authentification passe automatiquement à l’utilisation des en-têtes d’authentification du proxy si elle est elle-même une requête proxyée. Cela permet de vérifier ou d’imposer l’authentification devant un proxy existant.

Cette option doit normalement ne jamais être utilisée, sauf devant un proxy.

Voir également : « option httpclose », et « option http-server-close ».

option httpchk

option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
option httpchk <method> <uri> <version> <host>

Active le protocole HTTP pour vérifier l’état de santé des serveurs

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<method>  is the optional HTTP method used with the requests. When not set,
          the "OPTIONS" method is used, as it generally requires low server
          processing and is easy to filter out from the logs. Any method
          may be used, though it is not recommended to invent non-standard
          ones.

<uri>     is the URI referenced in the HTTP requests. It defaults to " / "
          which is accessible by default on almost any server, but may be
          changed to any other URI. Query strings are permitted.

<version> is the optional HTTP version string. It defaults to "HTTP/1.0"
          but some servers might behave incorrectly in HTTP 1.0, so turning
          it to HTTP/1.1 may sometimes help. Note that the Host field is
          mandatory in HTTP/1.1.

<host>    is the optional HTTP Host header value. It is not set by default.
          It is a log-format string.

Par défaut, les contrôles d’état des serveurs se limitent à la tentative d’établissement d’une connexion TCP. Lorsque l’option « option httpchk » est spécifiée, une requête HTTP complète est envoyée une fois la connexion TCP établie, et les réponses 2xx et 3xx sont considérées comme valides, tandis que toutes les autres indiquent une défaillance du serveur, y compris l’absence de réponse.

Associé aux directives « http-check », il est possible de personnaliser la requête envoyée lors des contrôles d’état HTTP ou les règles de correspondance sur la réponse. Il est également possible de configurer une séquence send/expect, tout comme avec la directive « tcp-check » pour les contrôles d’état TCP.

La configuration du serveur est utilisée par défaut pour ouvrir des connexions afin d’effectuer des contrôles d’état HTTP. Il est également possible de remplacer les paramètres du serveur à l’aide de règles « http-check connect ».

L’option « httpchk » n’exige pas nécessairement un backend HTTP ; elle fonctionne également avec des backends TCP brut. Cela est particulièrement utile pour vérifier des scripts simples liés à des ports dédiés via le démon inetd. Toutefois, elle s’appuie toujours internement sur un multiplexeur HTX. Cela implique que la mise en forme des requêtes et l’analyse des réponses seront strictes.

Exemples :

# Relay HTTPS traffic to Apache instance and check service availability
# using HTTP request "OPTIONS * HTTP/1.1" on port 80.
backend https_relay
    mode tcp
    option httpchk OPTIONS * HTTP/1.1
    http-check send hdr Host www
    server apache1 192.168.1.1:443 check port 80

Voir également : « option ssl-hello-chk », « option smtpchk », « option mysql-check », « option pgsql-check », « http-check » et les options serveur « check », « port » et « inter ».

option httpclose

option httpclose
no option httpclose

Activer ou désactiver la fermeture de la connexion HTTP/1.x

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Par défaut, HAProxy fonctionne en mode keep-alive concernant les connexions persistantes HTTP/1.x : pour chaque connexion, il traite chaque requête et réponse, puis laisse la connexion inactif des deux côtés. Ce mode peut être modifié par plusieurs options, telles que « option http-server-close » ou « option httpclose ».

Si l’option « option httpclose » est définie, HAProxy fermera la connexion client ou serveur, selon l’emplacement où l’option est configurée. Le frontal est considéré pour les connexions client, tandis que le backend est considéré pour les connexions serveur. Si l’option est définie sur un écouteur, elle s’applique aux connexions client et serveur. Elle vérifiera si un en-tête « Connection: close » est déjà présent dans chaque sens, et l’ajoutera si nécessaire.

Cette option peut également être combinée avec « option http-pretend-keepalive », ce qui empêche l’envoi de l’en-tête de requête « Connection: close », mais entraîne tout de même la fermeture de la connexion une fois la réponse entière reçue.

Il désactive et remplace toute option précédente « option http-server-close » ou « option http-keep-alive ».

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option http-server-close ».

option httplog [ clf ]

option httplog [ clf ]

Activer la journalisation des requêtes HTTP, de l’état du flux et des minuteries

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

clf       if the "clf" argument is added, then the output format will be
          the CLF format instead of HAProxy's default HTTP format. You can
          use this when you need to feed HAProxy's logs through a specific
          log analyzer which only support the CLF format and which is not
          extensible.

Par défaut, le format de sortie des journaux est très limité, ne comportant que les adresses source et destination, ainsi que le nom de l’instance. En spécifiant « option httplog », chaque ligne de journalisation adopte un format bien plus riche, incluant, sans s’y limiter, la requête HTTP, les temporisateurs de connexion, l’état du flux, le nombre de connexions, les en-têtes et cookies capturés, le nom du frontal, du backend et du serveur, ainsi que bien entendu l’adresse source et les ports.

Spécifier uniquement « option httplog » efface automatiquement le mode « clf » s’il était défini par défaut.

L’option httplog remplace toute directive log-format précédemment définie.

Voir également : section 8 concernant la journalisation.

option httpslog

option httpslog

Activer la journalisation des requêtes HTTPS, de l’état du flux et des compteurs

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Par défaut, le format de sortie des journaux est très limité, ne comportant que les adresses source et destination, ainsi que le nom de l’instance. En spécifiant « option httpslog », chaque ligne de journalisation adopte un format bien plus riche, incluant, sans s’y limiter, la requête HTTP, les temporisateurs de connexion, l’état du flux, le nombre de connexions, les en-têtes et cookies capturés, le nom du frontal, du backend et du serveur, les états de vérification du certificat SSL et de la négociation SSL, ainsi que bien entendu l’adresse source et les ports.

L’option httpslog remplace toute directive log-format précédemment définie.

Voir également : section 8 concernant la journalisation.

option idle-close-on-response

option idle-close-on-response
no option idle-close-on-response

Éviter de fermer les connexions frontend inactives si une interruption douce est en cours

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Par défaut, les connexions inactives seront fermées lors d’un arrêt doux. Dans certains environnements, un client communiquant avec le proxy peut avoir préparé certaines connexions inactives afin d’envoyer des requêtes ultérieurement. Si aucune tentative de nouvelle tentative en cas d’erreur d’écriture n’est effectuée, cela peut entraîner des erreurs pendant le rechargement de haproxy. Même si une implémentation correcte devrait réessayer en cas d’erreurs connection/write, cette option a été introduite afin de maintenir la compatibilité descendante avec les versions de HAProxy antérieures à la 2.4. En effet, avant la version 2.4, HAProxy attendait une dernière requête et réponse pour ajouter un en-tête « connection: close » avant de fermer la connexion, informant ainsi le client que la connexion ne serait pas réutilisable.

Dans un exemple concret, ce comportement a été observé sur AWS en utilisant un ALB devant un HAProxy. Le résultat final était un code 502 envoyé par l’ALB lors des rechargements du HAProxy.

Les utilisateurs sont avertis qu’utiliser cette option peut augmenter le nombre de processus anciens si les connexions restent inactives trop longtemps. Il se peut qu’il soit nécessaire d’ajuster les délais d’expiration client et/ou le paramètre « hard-stop-after » en cas de rechargements fréquents.

Voir également : « timeout client », « timeout client-fin », « timeout http-request », « hard-stop-after »

option independent-streams

option independent-streams
no option independent-streams

Activer ou désactiver le traitement indépendant des délais d’expiration dans les deux sens

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Par défaut, lorsque des données sont envoyées via une socket, le délai d’expiration d’écriture et le délai d’expiration de lecture de cette socket sont actualisés, car nous considérons qu’il y a une activité sur cette socket, et nous ne disposons d’aucun autre moyen de deviner si nous devrions recevoir des données ou non.

Bien que ce comportement par défaut soit souhaitable pour presque toutes les applications, il existe une situation où il est préférable de le désactiver, et de ne mettre à jour le délai d’expiration de lecture que si des données entrantes sont reçues. Cela se produit dans les flux avec des délais d’expiration élevés et de faibles quantités de données échangées, comme les sessions telnet. Si le serveur disparaît soudainement, les données de sortie s’accumulent dans les tampons de socket du système, les deux délais d’expiration sont correctement mis à jour, et il n’existe aucun moyen de savoir que le serveur ne les reçoit pas, aussi ne déclenchons-nous pas de délai d’expiration. Toutefois, lorsque le protocole sous-jacent échoe toujours les données envoyées, il suffirait à lui seul de détecter le problème en utilisant le délai d’expiration de lecture. Notez que ce problème ne se produit pas avec des protocoles plus verbeux, car les données ne s’accumulent pas longtemps dans les tampons de socket.

Lorsque cette option est définie sur le frontal, elle désactive les mises à jour du délai d’expiration en lecture pour les données envoyées au client. Ce cas est probablement peu utile. Lorsqu’elle est définie sur le backend, elle désactive les mises à jour du délai d’expiration en lecture pour les données envoyées au serveur. Cette action risque généralement de rompre les grandes requêtes HTTP provenant de lignes lentes, utilisez-la donc avec précaution.

Voir également : « timeout client », « timeout server » et « timeout tunnel »

option ldap-check

option ldap-check

Utilisez les contrôles d’état LDAPv3 pour le test des serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Il est possible de vérifier que le serveur communique correctement en LDAPv3, et non seulement de tester qu’il accepte la connexion TCP. Lorsque cette option est activée, un message de liaison simple anonyme LDAPv3 est envoyé au serveur, et la réponse est analysée afin de détecter un message de réponse de liaison LDAPv3.

Le serveur est considéré comme valide uniquement lorsque la réponse LDAP contient un resultCode success (http://tools.ietf.org/html/rfc4511#section-4.1.9 ).

La journalisation des requêtes de liaison dépend du serveur ; consultez la documentation correspondante pour savoir comment la configurer.

Exemple :

option ldap-check

Voir aussi : « option httpchk »

option log-health-checks

option log-health-checks
no option log-health-checks

Activer ou désactiver la journalisation des mises à jour d’état des contrôles d’état

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Par défaut, les échecs de contrôle d’état sont journalisés si le serveur est UP et les contrôles d’état réussis sont journalisés si le serveur est DOWN, de sorte que la quantité d’informations supplémentaires est limitée.

Lorsque cette option est activée, tout changement d’état du contrôle d’état ou de la santé du serveur est journalisé, ce qui permet de savoir qu’un serveur a échoué à des contrôles d’état ponctuels avant de planter, ou précisément quand il a cessé de répondre avec un statut HTTP valide, puis quand le port a commencé à rejeter les connexions, enfin quand le serveur a cessé toute réponse.

Notez que les changements d’état non provoqués par les contrôles d’état (par exemple, enable/disable en ligne de commande) ne sont pas intentionnellement journalisés par cette option.

Voir aussi : « option httpchk », « option ldap-check », « option mysql-check », « option pgsql-check », « option redis-check », « option smtpchk », « option tcp-check », « log » et la section 8 sur la journalisation.

option log-separate-errors

option log-separate-errors
no option log-separate-errors

Modifier le niveau de journalisation pour les connexions non entièrement réussies

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Parfois, il n’est pas facile de repérer les erreurs dans les journaux. Cette option permet à HAProxy d’augmenter le niveau des journaux contenant potentiellement des informations intéressantes, telles que les erreurs, les délais d’expiration, les tentatives de reconnexion, les redirigements, ou les codes d’état HTTP 5xx. Le niveau passe de « info » à « err ». Cela permet de les journaliser séparément dans un fichier différent avec la plupart des démons syslog. Prenez garde à ne pas les supprimer du fichier d’origine, sinon vous perdriez l’ordre des événements, qui fournit des informations très importantes.

Avec cette option, les grands sites traitant plusieurs milliers de connexions par seconde peuvent journaliser le trafic normal dans un tampon tournant et ne sauvegarder que les journaux d’erreurs plus petits.

Voir aussi : « log », « dontlognull », « dontlog-normal » et section 8 concernant la journalisation.

option logasap

option logasap
no option logasap

Active ou désactive la journalisation précoce.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Par défaut, les journaux sont émis lorsque tous les alias de format de journal et les extraits d’échantillon utilisés dans la définition de la chaîne de format de journal renvoient une valeur, ou lorsque le flux est terminé. Cela permet aux chaînes de format de journal intégrées de tenir compte du temps de transfert ou du nombre d’octets dans les messages de journal.

Lors de la gestion de connexions longues, telles que les transferts de fichiers volumineux ou RDP, il peut s’écouler un certain temps avant que la requête ou la connexion n’apparaisse dans les journaux. En utilisant « option logasap », le message de journalisation est généré dès que la connexion au serveur est établie en mode tcp, ou dès que le serveur envoie l’intégralité des en-têtes en mode http. Les informations manquantes dans les journaux seront le nombre total d’octets, qui ne reflétera que la quantité de données transférées avant la création du message, et le temps total, qui ne tiendra pas compte de la durée restante de la connexion ou du temps de transfert. Pour le cas HTTP, il est bon de capturer l’en-tête de réponse Content-Length afin que les journaux indiquent au moins le nombre d’octets attendus lors du transfert.

Exemples :

listen http_proxy 0.0.0.0:80
    mode http
    option httplog
    option logasap
    log 192.168.2.200 local3
    >>> Feb  6 12:14:14 localhost \
          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
          static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \
          "GET /image.iso HTTP/1.0"

Voir également : « option httplog », « capture réponse en-tête » et section 8 concernant la journalisation.

option mysql-check [ user <username> [ { post-41 | pre-41 | post-80 } ] ]

option mysql-check [ user <username> [ { post-41 | pre-41 | post-80 } ] ]

Utilisez les contrôles d’état MySQL pour tester les serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<username> This is the username which will be used when connecting to MySQL
           server.
post-41    Send post v4.1 client compatible checks (the default)
pre-41     Send pre v4.1 client compatible checks
post-80    Send post v8.0 client compatible checks with CLIENT_PLUGIN_AUTH
           capability set and mysql_native_password as the authentication
           plugin. Use this option when connecting to MySQL 8.0+ servers
           where the health check user is created with mysql_native_password
           authentication. Example:
             CREATE USER 'haproxy'@'%' IDENTIFIED WITH mysql_native_password BY '';

Si vous spécifiez un nom d’utilisateur, le test consiste à envoyer deux paquets MySQL : un paquet d’authentification client, puis un paquet QUIT pour fermer correctement la session MySQL. Nous analysons ensuite le paquet d’initialisation d’échange MySQL et/ou le paquet d’erreur. Il s’agit d’un test basique mais utile, qui ne génère ni erreur ni connexion interrompue côté serveur. Toutefois, il nécessite un utilisateur autorisé non verrouillé, sans mot de passe. Pour créer un utilisateur basique limité dans MySQL, avec des limites de ressources facultatives :

CREATE USER '<username>'@'<ip_of_haproxy|network_of_haproxy/netmask>'
/*!50701 WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 */
/*M!100201 MAX_STATEMENT_TIME 0.0001 */;

Si vous ne spécifiez pas de nom d’utilisateur (cela est obsolète et non recommandé), le contrôle se limite à l’analyse du paquet d’initialisation de handshake MySQL ou du paquet d’erreur ; aucun paquet n’est envoyé en ce mode. Il a été signalé qu’il peut provoquer un verrouillage si le contrôle est trop fréquent et/ou s’il y a une trafic insuffisant. En réalité, vous devez, dans ce cas, vérifier la valeur de MySQL “max_connect_errors” comme si une connexion était établie avec succès en moins de “max_connect_errors” tentatives après une interruption précédente de connexion, auquel cas le compteur d’erreurs pour l’hôte est réinitialisé à zéro. Si le serveur HAProxy est bloqué, la commande « FLUSH HOSTS » est la seule manière de le débloquer.

N’oubliez pas que cela ne vérifie ni la présence de la base de données ni sa cohérence. Pour effectuer cette vérification, vous pouvez utiliser une vérification externe avec xinetd, par exemple.

La vérification nécessite MySQL >=3.22 ; pour les versions plus anciennes, utilisez la vérification TCP.

Souvent, un serveur MySQL entrant doit voir l’adresse IP du client pour diverses raisons, notamment le contrôle des privilèges par IP et la journalisation des connexions. Lorsqu’il est possible de le faire, il est souvent judicieux de masquer l’adresse IP du client lors de la connexion au serveur en utilisant l’argument « usesrc » du mot-clé « source », ce qui nécessite que la fonctionnalité de proxy transparent soit compilée, ainsi qu’un serveur MySQL qui achemine le client via la machine hébergeant HAProxy.

Voir aussi : « option httpchk »

option nolinger

option nolinger
no option nolinger

Activer ou désactiver le nettoyage immédiat des ressources de session après fermeture

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Lorsque les clients ou les serveurs interrompent les connexions de manière inappropriée (par exemple, en étant physiquement déconnectés), les délais d’expiration de session sont déclenchés et la session est fermée. Toutefois, elle reste dans l’état FIN_WAIT1 pendant une certaine durée dans le système, consommant des ressources et pouvant limiter la capacité à établir de nouvelles connexions.

Lorsque cela se produit, il est possible d’activer l’option nolinger, qui force le système à supprimer immédiatement les données en attente sur une socket lors de sa fermeture. Ainsi, un paquet TCP RST est émis, les données en attente sont tronquées, et la session est instantanément supprimée des tables du système. L’effet généralement observable par un client est que les réponses sont tronquées si la fermeture intervient avec le dernier bloc de données (par exemple, dans une réponse de redirection ou d’erreur). Du côté serveur, cela peut aider à libérer immédiatement les ports sources lors du transfert quand un client interrompt une connexion en tunnel. Dans les deux cas, des réinitialisations TCP sont émises, et comme la session est détruite instantanément, aucune retransmission ne sera tentée. Sur un réseau bruyant, cela peut aggraver les problèmes, notamment lorsqu’un pare-feu est présent du côté bruyant, car le pare-feu pourrait détecter et traiter la réinitialisation (et supprimer ainsi sa session), puis bloquer tout trafic ultérieur pour cette session, y compris les retransmissions provenant de l’autre côté. Ainsi, si l’autre côté ne reçoit pas cette réinitialisation, il ne recevra jamais de nouveau RST, et le pare-feu pourrait enregistrer de nombreux paquets bloqués.

Pour toutes ces raisons, il est fortement recommandé de ne pas utiliser cette option, sauf si absolument nécessaire en dernier recours. Dans la plupart des cas, l’utilisation des délais « client-fin » ou « server-fin » permet d’obtenir des résultats similaires avec un comportement plus fiable. Sur Linux, il est également possible d’utiliser la configuration bind ou server « tcp-ut ».

Cette option peut être utilisée aussi bien sur les frontaux que sur les backends, selon le côté où elle est requise. Utilisez-la sur le frontal pour les clients, et sur le backend pour les serveurs. Bien que cette option soit techniquement prise en charge dans les sections « defaults », elle ne doit en aucun cas être utilisée là-bas, car elle risque de se propager accidentellement à des sections qui ne doivent pas l’utiliser, provoquant ainsi des problèmes.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « timeout client-fin », « timeout server-fin », mots-clés bind ou server « tcp-ut ».

option originalto [ except <network> ] [ header <name> ]

option originalto [ except <network> ] [ header <name> ]

Activer l’insertion de l’en-tête X-Original-To dans les requêtes envoyées aux serveurs

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<network> is an optional argument used to disable this option for sources
          matching <network>
<name>    an optional argument to specify a different "X-Original-To"
          header name.

Étant donné qu’HAProxy peut fonctionner en mode transparent, chaque requête provenant d’un client peut être redirigée vers le proxy, et HAProxy lui-même peut acheminer chaque requête vers un environnement SQUID complexe, ce qui fait perdre l’hôte de destination provenant de SO_ORIGINAL_DST. Cela est problématique lorsque l’on souhaite appliquer des règles d’accès basées sur les adresses IP de destination. Pour résoudre ce problème, HAProxy peut ajouter un nouvel en-tête HTTP « X-Original-To » à toutes les requêtes envoyées au serveur. Cet en-tête contient une valeur représentant l’adresse IP de destination d’origine. Cette fonctionnalité doit être configurée de manière à ne jamais utiliser que la dernière occurrence de cet en-tête. Notez qu’il ne faut utiliser que la dernière occurrence de cet en-tête, car il est effectivement possible que le client ait déjà fourni un tel en-tête.

Le mot-clé « header » peut être utilisé pour spécifier un nom d’en-tête différent afin de remplacer le nom par défaut « X-Original-To ». Cela peut être utile lorsque vous avez déjà un en-tête « X-Original-To » provenant d’une autre application et que vous devez le préserver. De même, si votre serveur backend ne utilise pas l’en-tête « X-Original-To » et nécessite un autre en-tête.

Parfois, une même instance HAProxy peut être partagée entre un accès direct depuis un client et un accès via un proxy inverse (par exemple lorsqu’un proxy inverse SSL est utilisé pour déchiffrer le trafic HTTPS). Il est possible de désactiver l’ajout de l’en-tête pour une adresse ou un réseau cible connus en ajoutant le mot-clé « except » suivi de l’adresse réseau. Dans ce cas, toute adresse IP de destination correspondant au réseau ne déclenchera pas l’ajout de cet en-tête. Les utilisations les plus courantes concernent les réseaux privés ou 127.0.0.1. Les versions IPv4 et IPv6 sont toutes deux prises en charge.

Cette option peut être spécifiée soit dans le frontal, soit dans le backend. Si au moins l’un d’eux l’utilise, l’en-tête sera ajouté. Notez que le paramètre d’en-tête défini dans le backend a priorité sur celui défini dans le frontal si les deux sont configurés.

Exemples :

# Original Destination address
frontend www
    mode http
    option originalto except 127.0.0.1

# Those servers want the IP Address in X-Client-Dst
backend www
    mode http
    option originalto header X-Client-Dst

Voir également : « option httpclose », « option http-server-close ».

option persist

option persist
no option persist

Activer ou désactiver la persistance forcée sur les serveurs inaccessibles

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsqu’une requête HTTP atteint un backend avec un cookie faisant référence à un serveur inactif, elle est, par défaut, redirigée vers un autre serveur. Il est possible de forcer la requête à être envoyée en premier au serveur inactif en utilisant « option persist », si cela est absolument nécessaire. Un cas d’utilisation courant est lorsque les serveurs sont sous une charge extrême et passent leur temps à basculer. Dans ce cas, les utilisateurs continuent d’être dirigés vers le serveur sur lequel ils ont ouvert la session, dans l’espoir qu’ils soient correctement servis. Il est recommandé d’utiliser « option redispatch » en conjonction avec cette option afin que, dans le cas où il serait impossible de se connecter au serveur (serveur définitivement inactif), le client soit finalement redirigé vers un autre serveur valide.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option redispatch », « retries », « force-persist »

option pgsql-check user <username>

option pgsql-check user <username>

Utilisez les contrôles d’état PostgreSQL pour le test des serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<username> This is the username which will be used when connecting to
           PostgreSQL server.

La vérification envoie un message StartupMessage PostgreSQL et attend soit un message de demande d’authentification, soit un message d’erreur. Il s’agit d’un test basique mais utile qui ne génère ni erreur ni connexion interrompue sur le serveur. Cette vérification est identique à celle de « mysql-check ».

Voir aussi : « option httpchk »

option prefer-last-server

option prefer-last-server
no option prefer-last-server

Permettre à plusieurs requêtes équilibrées de rester sur le même serveur

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsque l’algorithme de répartition de charge utilisé n’est pas déterministe, et qu’une requête précédente a été envoyée à un serveur auquel HAProxy maintient encore une connexion, il peut être souhaitable que les requêtes ultérieures d’une même session soient dirigées vers le même serveur autant que possible. Notez que cela diffère de la persistance, car nous ne faisons qu’indiquer une préférence que HAProxy tente d’appliquer sans aucune garantie. L’utilisation réelle concerne les connexions keep-alive envoyées aux serveurs. Lorsque cette option est utilisée, HAProxy tentera de réutiliser la même connexion attachée au serveur au lieu de répartir la charge vers un autre serveur, ce qui provoquerait la fermeture de la connexion. Cela peut avoir un sens pour les serveurs de fichiers statiques. Il ne convient pas d’utiliser cette option en combinaison avec des algorithmes basés sur le hachage. Notez qu’HAProxy tente déjà automatiquement de rester attaché à un serveur qui renvoie un code 401 ou à un proxy qui renvoie un code 407 (authentification requise), lorsque l’algorithme de répartition de charge n’est pas déterministe. Cette fonctionnalité est obligatoire pour l’utilisation avec le défi d’authentification NTLM défectueux, et aide considérablement au dépannage de certaines applications défaillantes. L’option prefer-last-server peut également être souhaitable dans ces environnements afin d’éviter de redistribuer le trafic après chaque réponse.

Il peut être utile de préciser ici quels algorithmes de répartition de charge sont considérés comme déterministes. Les algorithmes déterministes sélectionnent toujours le même serveur pour des données clientes données, à condition que l’ensemble des serveurs disponibles n’ait pas changé. En général, les algorithmes déterministes impliquent un hachage ou une recherche dans les requêtes entrantes pour choisir le serveur cible. Toutefois, ce n’est pas toujours le cas ; par exemple, « static-rr » peut également être considéré comme déterministe, car le choix du serveur repose sur le poids statique du serveur, rendant la sélection prévisible. L’algorithme « sticky » assure une routage déterministe pour les clients revenant.

En ce qui concerne les algorithmes non déterministes, ces algorithmes choisissent un serveur en fonction de l’état dynamique du serveur ou d’une rotation simple, si bien que deux requêtes consécutives ne sont pas garanties d’être acheminées vers le même serveur. L’option prefer-last-server est spécifiquement conçue pour de tels cas. roundrobin et leastconn en sont des exemples.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option http-keep-alive »

option redispatch

option redispatch
option redispatch <interval>
no option redispatch

Activer ou désactiver la redistribution de session en cas d’échec de connexion

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<interval> The optional integer value that controls how often redispatches
           occur when retrying connections. Positive value P indicates a
           redispatch is desired on every Pth retry, and negative value
           N indicate a redispatch is desired on the Nth retry prior to the
           last retry. For example, the default of -1 preserves the
           historical behavior of redispatching on the last retry, a
           positive value of 1 would indicate a redispatch on every retry,
           and a positive value of 3 would indicate a redispatch on every
           third retry. You can disable redispatches with a value of 0.

En mode HTTP, si un serveur désigné par un cookie est hors service, les clients peuvent effectivement rester attachés à ce serveur, par exemple lors de l’utilisation de « option persist » ou de « force-persist », car ils ne peuvent pas supprimer le cookie, ce qui les empêche de nouveau d’accéder au service.

Spécifier « option redispatch » permet au proxy de rompre la persistance basée sur les cookies ou le hachage constant, et de redistribuer les connexions vers un serveur fonctionnel.

Les serveurs actifs sont sélectionnés à partir d’un sous-ensemble de la liste des serveurs disponibles. Les serveurs actifs qui ne sont ni hors service ni en maintenance (c’est-à-dire dont l’état n’est pas vérifié ou qui ont été vérifiés comme « up ») sont sélectionnés dans l’ordre suivant :

1. Any active, non-backup server, if any, or,

2. If the "allbackups" option is not set, the first backup server in the
   list, or

3. If the "allbackups" option is set, any backup server.

Lorsqu’une nouvelle tentative est effectuée, HAProxy tente de sélectionner un serveur différent du dernier utilisé. Le nouveau serveur est sélectionné à partir de la liste actuelle des serveurs.

Parfois, si la liste est mise à jour entre deux tentatives (par exemple, si un grand nombre de tentatives ont lieu et que la durée est supérieure au temps nécessaire pour vérifier qu’un serveur est hors service, le supprimer de la liste et basculer sur la liste des serveurs de secours), les connexions peuvent être redirigées vers un serveur de secours, toutefois.

Il permet également de réessayer la connexion à un autre serveur en cas d’échecs multiples. Bien entendu, cela nécessite que « retries » soit défini à une valeur non nulle.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option persist », « force-persist », « retries »

option redis-check

option redis-check

Utilisez les contrôles d’état Redis pour tester les serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Il est possible de vérifier que le serveur communique correctement selon le protocole REDIS, et non seulement qu’il accepte la connexion TCP. Lorsque cette option est activée, une commande PING REDIS est envoyée au serveur, et la réponse est analysée afin de détecter le message de réponse “+PONG”.

Exemple :

option redis-check

Voir également : « option httpchk », « option tcp-check », « tcp-check expect »

option smtpchk

option smtpchk
option smtpchk <hello> <domain>

Utilisez les contrôles d’état SMTP pour tester les serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<hello>   is an optional argument. It is the "hello" command to use. It can
          be either "HELO" (for SMTP) or "EHLO" (for ESMTP). All other
          values will be turned into the default command ("HELO").

<domain>  is the domain name to present to the server. It may only be
          specified (and is mandatory) if the hello command has been
          specified. By default, "localhost" is used.

Lorsque l’option smtpchk est activée, les contrôles d’état consistent en une connexion TCP suivie d’une commande SMTP. Par défaut, cette commande est « HELO localhost ». Le code de réponse du serveur est analysé, et seuls les codes de réponse commençant par un « 2 » sont considérés comme valides. Toutes les autres réponses, ainsi qu’une absence de réponse, constituent une erreur et indiquent un serveur hors service.

Ce test est destiné à être utilisé avec des serveurs ou relais SMTP. Selon la requête, il se peut que certains serveurs ne journalisent pas chaque tentative de connexion, vous devrez donc peut-être expérimenter pour améliorer le comportement. Utiliser telnet sur le port 25 est souvent plus simple que de modifier la configuration.

Souvent, un serveur SMTP entrant doit voir l’adresse IP du client pour diverses raisons, notamment le filtrage du spam, la prévention de la falsification d’adresse et la journalisation. Lorsqu’il est possible de le faire, il est souvent judicieux de masquer l’adresse IP du client lors de la connexion au serveur en utilisant l’argument « usesrc » du mot-clé « source », ce qui nécessite que la fonctionnalité de proxy transparent soit compilée.

Exemple :

option smtpchk HELO mydomain.org

Voir aussi : « option httpchk », « source »

option socket-stats non option socket-stats

Activer ou désactiver la collecte et la fourniture de statistiques séparées pour chaque socket.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

option splice-auto

option splice-auto
no option splice-auto

Activer ou désactiver l’accélération matérielle du noyau sur les sockets dans les deux sens

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Lorsque cette option est activée, soit sur un frontal, soit sur un backend, HAProxy évalue automatiquement la possibilité d’utiliser le splice TCP du noyau pour transférer les données entre le client et le serveur, dans les deux sens. HAProxy utilise des heuristiques pour estimer si le splice du noyau pourrait améliorer les performances ou non. Les deux sens sont gérés indépendamment. Notez que les heuristiques utilisées ne sont pas très agressives afin de limiter une utilisation excessive du splice. Cette option nécessite que le splice soit activé au moment de la compilation et peut être désactivée globalement à l’aide de l’option « nosplice ». Étant donné que le splice utilise des tubes, son utilisation suppose qu’il y ait suffisamment de tubes disponibles.

Note importante : la fusion TCP basée sur le noyau est une fonctionnalité spécifique à Linux, apparue pour la première fois dans le noyau 2.6.25. Elle permet d’accélérer le transfert de données entre sockets au niveau du noyau, sans copier ces données en espace utilisateur, offrant ainsi des gains de performance et des économies de cycles CPU significatifs. Étant donné que de nombreuses implémentations anciennes sont défectueuses, susceptibles de corrompre les données ou de fonctionner de manière inefficace, cette fonctionnalité n’est pas activée par défaut et doit être utilisée avec une extrême prudence. Bien qu’il ne soit pas possible de détecter la correction d’une implémentation, la version 2.6.29 est la première à proposer une implémentation correctement fonctionnelle. En cas de doute, la fusion peut être désactivée globalement à l’aide du mot-clé global « nosplice ».

Exemple :

option splice-auto

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option splice-request », « option splice-response » et les options globales « nosplice » et « maxpipes »

option splice-request

option splice-request
no option splice-request

Activer ou désactiver l’accélération automatique du noyau sur les sockets pour les requêtes

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Lorsque cette option est activée, soit sur un frontal, soit sur un backend, HAProxy utilisera le transfert direct du noyau (tcp splicing) chaque fois que possible pour acheminer les données allant du client vers le serveur. Il peut toutefois recourir au schéma recv/send si aucun canal libre n’est disponible. Cette option nécessite que le transfert direct soit activé lors de la compilation et peut être désactivée globalement via l’option « nosplice ». Étant donné que le transfert direct utilise des canaux, son utilisation suppose la disponibilité de suffisamment de canaux libres.

Remarque importante : consultez « option splice-auto » pour les limitations d’utilisation.

Exemple :

option splice-request

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option splice-auto », « option splice-response » et les options globales « nosplice » et « maxpipes »

option splice-response

option splice-response
no option splice-response

Active ou désactive l’accélération automatique du noyau sur les sockets pour les réponses

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Lorsque cette option est activée, soit sur un frontal, soit sur un backend, HAProxy utilisera le transfert direct du noyau (tcp splicing) chaque fois que possible pour acheminer les données allant du serveur vers le client. Il peut toutefois recourir au schéma recv/send si aucun canal libre n’est disponible. Cette option nécessite que le transfert direct soit activé lors de la compilation et peut être désactivée globalement via l’option « nosplice ». Étant donné que le transfert direct utilise des canaux, son utilisation suppose la disponibilité de suffisamment de canaux libres.

Remarque importante : consultez « option splice-auto » pour les limitations d’utilisation.

Exemple :

option splice-response

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir également : « option splice-auto », « option splice-request » et les options globales « nosplice » et « maxpipes »

option spop-check

option spop-check

Utilisez les contrôles d’état SPOP pour tester les serveurs

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Il est possible de vérifier que le serveur communique correctement selon le protocole SPOP, et non seulement qu’il accepte la connexion TCP. Lorsque cette option est activée, une négociation HELLO est établie entre HAProxy et le serveur, et la réponse est analysée afin de vérifier qu’aucune erreur n’est signalée.

Exemple :

option spop-check

Voir aussi : « option httpchk »

option srvtcpka

option srvtcpka
no option srvtcpka

Activer ou désactiver l’envoi de paquets TCP keepalive côté serveur

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsqu’un pare-feu ou tout composant sensible à la session se trouve entre un client et un serveur, et que le protocole implique des sessions très longues avec des périodes d’inactivité prolongées (par exemple, les bureaux distants), il existe un risque que l’un des composants intermédiaires décide d’expirer une session restée inactif trop longtemps.

Activer les keep-alives TCP au niveau du socket fait que le système envoie régulièrement des paquets à l’autre extrémité de la connexion, la maintenant active. Le délai entre les sondes de keep-alive est contrôlé uniquement par le système et dépend à la fois du système d’exploitation et de ses paramètres de réglage.

Il est important de comprendre que les paquets keep-alive ne sont ni émis ni reçus au niveau de l’application. Seuls les piles réseau les perçoivent. Pour cette raison, même si l’une des extrémités du proxy utilise déjà des keep-alive pour maintenir sa connexion active, ces paquets keep-alive ne seront pas transférés à l’autre extrémité du proxy.

Veuillez noter que cela n’a rien à voir avec le keep-alive HTTP.

L’option « srvtcpka » active l’envoi de sondes TCP keep-alive du côté serveur d’une connexion, ce qui devrait aider à détecter les expiration de session entre HAProxy et un serveur.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option clitcpka », « option tcpka »

option ssl-hello-chk

option ssl-hello-chk

Utilisez les contrôles d’état client hello SSLv3 pour tester les serveurs

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Lorsque certains protocoles basés sur SSL sont relayés en mode TCP via HAProxy, il est possible de vérifier que le serveur communique correctement en SSL, et non seulement qu’il accepte la connexion TCP. Lorsque l’option ssl-hello-chk est activée, un message client hello SSLv3 pur est envoyé une fois la connexion établie avec le serveur, puis la réponse est analysée afin de détecter un message server hello SSL. Le serveur est considéré comme valide uniquement si la réponse contient ce message server hello.

Tous les serveurs ont été testés afin de s’assurer qu’ils répondent correctement aux messages de hello SSLv3, et la plupart des serveurs ne journalisent même pas les requêtes ne contenant que des messages hello, ce qui est appréciable.

Notez que ce contrôle fonctionne même lorsque le support SSL n’a pas été inclus dans HAProxy, car il forge le message SSL. Lorsque le support SSL est disponible, il est préférable d’utiliser les contrôles d’état SSL natifs plutôt que celui-ci.

Voir aussi : « option httpchk », « check-ssl »

option tcp-check

option tcp-check

Effectuez les contrôles d’état à l’aide des séquences tcp-check send/expect

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Cette méthode de contrôle d’état est destinée à être combinée avec des listes de commandes « tcp-check » afin de prendre en charge des séquences de contrôle d’état de type send/expect.

Les contrôles TCP prennent actuellement en charge 4 modes de fonctionnement : - absence de directive « tcp-check » : le contrôle d’état se limite à une tentative de connexion, ce qui constitue le mode par défaut.

- « tcp-check send » ou « tcp-check send-binary » est indiqué : cela permet d'envoyer une chaîne lors de l'ouverture d'une connexion. Avec certains protocoles, cela permet d'envoyer un message « QUIT », par exemple, ce qui empêche le serveur de noter une erreur de connexion pour chaque contrôle d'état. Le résultat du contrôle reste fondé uniquement sur la capacité à ouvrir la connexion.

- "tcp-check expect" est uniquement mentionné : il sert à tester une bannière.
    La connexion est établie et HAProxy attend que le serveur présente un contenu qui doit respecter certaines règles. Le résultat de la vérification repose sur la correspondance entre le contenu reçu et les règles définies. Cette fonctionnalité convient aux protocoles POP, IMAP, SMTP, FTP, SSH et TELNET.

- à la fois « tcp-check send » et « tcp-check expect » sont mentionnés : cela permet de tester un protocole de type hello. HAProxy envoie un message, le serveur répond et la réponse est analysée. Le résultat de la vérification repose sur la correspondance entre le contenu de la réponse et les règles définies. Cette approche convient souvent aux protocoles qui nécessitent une liaison ou un request/response modèle.
    LDAP, MySQL, Redis et SSL sont des exemples de tels protocoles, bien qu’ils disposent déjà chacun de leurs vérifications dédiées, qui comprennent une compréhension plus poussée du protocole respectif.
    En ce mode, plusieurs questions peuvent être envoyées et plusieurs réponses peuvent être analysées.

Un cinquième mode peut être utilisé pour insérer des commentaires à différentes étapes du script.

Pour chaque règle tcp-check que vous créez, vous pouvez ajouter une directive « comment », suivie d’une chaîne. Cette chaîne sera rapportée dans les journaux et sur stderr en mode débogage. Elle est utile pour faciliter la génération de rapports d’erreurs conviviaux. La directive « comment » est bien entendu facultative.

Pendant l’exécution d’un contrôle d’état, une portée de variables est mise à disposition pour stocker des échantillons de données, à l’aide de l’opération « tcp-check set-var ». La libération de ces variables est possible à l’aide de « tcp-check unset-var ».

Exemples :

# perform a POP check (analyze only server's banner)
option tcp-check
tcp-check expect string +OK\ POP3\ ready comment POP\ protocol

# perform an IMAP check (analyze only server's banner)
option tcp-check
tcp-check expect string *\ OK\ IMAP4\ ready comment IMAP\ protocol

# look for the redis master server after ensuring it speaks well
# redis protocol, then it exits properly.
# (send a command then analyze the response 3 times)
option tcp-check
tcp-check comment PING\ phase
tcp-check send PING\r\n
tcp-check expect string +PONG
tcp-check comment role\ check
tcp-check send info\ replication\r\n
tcp-check expect string role:master
tcp-check comment QUIT\ phase
tcp-check send QUIT\r\n
tcp-check expect string +OK

forge a HTTP request, then analyze the response
(send many headers before analyzing)
option tcp-check
tcp-check comment forge\ and\ send\ HTTP\ request
tcp-check send HEAD\ /\ HTTP/1.1\r\n
tcp-check send Host:\ www.mydomain.com\r\n
tcp-check send User-Agent:\ HAProxy\ tcpcheck\r\n
tcp-check send \r\n
tcp-check expect rstring HTTP/1\..\ (2..|3..) comment check\ HTTP\ response

Voir également : « tcp-check connect », « tcp-check expect » et « tcp-check send ».

option tcp-smart-accept

option tcp-smart-accept
no option tcp-smart-accept

Activer ou désactiver l’enregistrement d’un paquet ACK pendant la séquence d’acceptation

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments : aucun

Lorsqu’une requête de connexion HTTP arrive, le système l’acquitte en lieu et place de HAProxy, puis le client envoie immédiatement sa requête, que le système acquitte également tout en informant HAProxy de la nouvelle connexion. HAProxy lit ensuite la requête et envoie une réponse. Cela signifie que le système envoie une acknowledgement TCP inutile, car la requête aurait pu être acquittée par HAProxy lorsqu’il envoie sa réponse.

Pour cette raison, en mode HTTP, HAProxy demande automatiquement au système d’éviter d’envoyer cet ACK inutile sur les plates-formes qui le supportent (actuellement au moins Linux). Cela ne devrait causer aucun problème, car le système l’envoie quand même après 40 ms si la réponse met plus de temps que prévu à arriver.

Lors de sessions de dépannage réseau complexes, il peut être souhaitable de désactiver cette optimisation, car les accusés de réception différés peuvent compliquer le dépannage lorsqu’il s’agit d’identifier où les paquets sont retardés. Il est alors possible de revenir au comportement normal en spécifiant « no option tcp-smart-accept ».

Il est également possible de forcer ce comportement pour les proxies non HTTP en spécifiant simplement « option tcp-smart-accept ». Par exemple, cela peut avoir un sens avec certains services tels que SMTP, où le serveur parle en premier.

Il est recommandé d’éviter de forcer cette option dans une section defaults. En cas de doute, envisagez de la réinitialiser aux valeurs automatiques en préfixant l’option par le mot-clé default, ou de la désactiver en utilisant le mot-clé no.

Voir également : « option tcp-smart-connect »

option tcp-smart-connect

option tcp-smart-connect
no option tcp-smart-connect

Activer ou désactiver la sauvegarde d’un paquet ACK pendant la séquence de connexion

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Sur certains systèmes (au moins Linux), HAProxy peut demander au noyau de ne pas envoyer immédiatement une accusé de réception vide lors d’une requête de connexion, mais de transmettre directement la requête de tampon à la place. Cela permet d’économiser un paquet sur le réseau et améliore ainsi les performances. Cette fonctionnalité peut également être utile pour certains serveurs, car ils reçoivent immédiatement la requête accompagnant la connexion entrante.

Cette fonctionnalité est activée lorsque « option tcp-smart-connect » est définie dans un backend. Elle n’est pas activée par défaut car elle complique le dépannage réseau.

Il n’a de sens d’activer cette fonctionnalité que pour les protocoles où le client parle en premier, comme HTTP. Dans les autres cas, si aucune donnée ne peut être envoyée à la place de l’ACK, un ACK normal est transmis.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : « option tcp-smart-accept »

option tcpka

option tcpka

Activer ou désactiver l’envoi de paquets TCP keepalive des deux côtés

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Lorsqu’un pare-feu ou tout composant sensible à la session se trouve entre un client et un serveur, et que le protocole implique des sessions très longues avec des périodes d’inactivité prolongées (par exemple, les bureaux distants), il existe un risque que l’un des composants intermédiaires décide d’expirer une session restée inactif trop longtemps.

Activer les keep-alives TCP au niveau du socket fait que le système envoie régulièrement des paquets à l’autre extrémité de la connexion, la maintenant active. Le délai entre les sondes de keep-alive est contrôlé uniquement par le système et dépend à la fois du système d’exploitation et de ses paramètres de réglage.

Il est important de comprendre que les paquets keep-alive ne sont ni émis ni reçus au niveau de l’application. Seuls les piles réseau les perçoivent. Pour cette raison, même si l’une des extrémités du proxy utilise déjà des keep-alive pour maintenir sa connexion active, ces paquets keep-alive ne seront pas transférés à l’autre extrémité du proxy.

Veuillez noter que cela n’a rien à voir avec le keep-alive HTTP.

L’option « tcpka » active l’envoi de sondes TCP keep-alive côté client et côté serveur d’une connexion. Notez que cette option n’a de sens que dans les sections « defaults » ou « listen ». Si cette option est utilisée dans un frontend, seuls les clients recevront des keep-alives ; si elle est utilisée dans un backend, seuls les serveurs recevront des keep-alives. Pour cette raison, il est fortement recommandé d’utiliser explicitement les options « option clitcpka » et « option srvtcpka » lorsque la configuration est répartie entre frontends et backends.

Voir aussi : « option clitcpka », « option srvtcpka »

option tcplog [clf]

option tcplog [clf]

Activer la journalisation avancée des connexions TCP avec l’état du flux et les compteurs

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

clf       if the "clf" argument is added, then the output format will be
          the CLF format instead of HAProxy's default TCP format. You can
          use this when you need to feed HAProxy's logs through a specific
          log analyzer which only support the CLF format and which is not
          extensible.  Since this expects an HTTP format some of the
          values have been pre set. The http request will show as TCP and
          the response code will show as 000.

Par défaut, le format de sortie des journaux est très pauvre, ne contenant que les adresses source et destination, ainsi que le nom de l’instance. En spécifiant « option tcplog », chaque ligne de journal devient beaucoup plus riche, incluant, sans s’y limiter, les compteurs de connexion, l’état du flux, le nombre de connexions, le nom du frontal, du backend et du serveur, ainsi que l’adresse source et les ports. Cette option est utile pour les proxies TCP purs afin de déterminer si c’est le client ou le serveur qui se déconnecte ou expiré. Pour les proxies HTTP normaux, il est préférable d’utiliser « option httplog », qui est encore plus complet.

L’option tcplog remplace toute directive précédente log-format.

Voir également : « option httplog », et section 8 concernant la journalisation.

option transparent (deprecated)

option transparent        (deprecated)
no option transparent     (deprecated)

Activer le proxy transparent côté client

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Cette option a été introduite afin de permettre une persistance au niveau 7 aux répartiteurs de charge au niveau 3. L’idée consiste à utiliser la capacité du système d’exploitation à rediriger une connexion entrante provenant d’une adresse distante vers un processus local (ici HAProxy), et à faire en sorte que ce processus connaisse l’adresse initialement demandée. Lorsque cette option est utilisée, les sessions sans cookies seront acheminées vers l’adresse IP d’origine de la requête entrante (qui doit correspondre à celle d’un autre équipement), tandis que les requêtes avec cookies seront toujours acheminées vers le serveur approprié.

Notez qu’en dépit d’une croyance répandue, cette option ne fait pas que HAProxy présente l’adresse IP du client au serveur lors de l’établissement de la connexion.

À compter de la version 3.3, cette option est désormais obsolète car elle était sujet à plusieurs limitations techniques internes. Son utilisation génère un avertissement, qui peut être évité si nécessaire via le mot-clé global « expose-deprecated-directives ».

L’approche correcte consiste à déclarer un serveur sur l’adresse 0.0.0.0, qui s’occupera de la connexion à l’adresse cible attendue. Un serveur gérera également correctement les connexions inactives vers les serveurs cibles.

Exemple :

# option transparent  ## before 3.3
server transparent 0.0.0.0

Voir également : l’argument « usesrc » du mot-clé « source », et l’option « transparent » du mot-clé « bind ».

option use-small-buffers [ queue | l7-retries | check ]*

Activer la prise en charge des tampons de petite taille pour les catégories données.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Cette option peut être utilisée pour activer le support des petits tampons à divers emplacements afin de réduire la consommation de mémoire. Par défaut, sans paramètre, les petits tampons sont utilisés autant que possible à tous les emplacements possibles. Sinon, il est possible de les limiter aux emplacements suivants :

  • queue : Lorsqu’il est défini, des tampons de petite taille seront utilisés pour stocker les requêtes, si elles sont suffisamment petites, lorsque la connexion est mise en file d’attente.
  • l7-retries : Lorsqu’il est défini, des tampons de petite taille seront utilisés pour sauvegarder les requêtes lorsque les réessais L7 sont activés.
  • check : Lorsqu’il est défini, des tampons de petite taille seront utilisés pour les requêtes de vérification de santé.

Lorsqu’il est activé, des tampons de petite taille sont utilisés, mais uniquement si cela est possible. Sinon, lorsque les données sont trop grandes, un tampon régulier est automatiquement utilisé. La taille des tampons de petite taille est configurable via le paramètre global “tune.bufsize.small”.

Si cette option a été activée dans une section « defaults », elle peut être désactivée dans une instance spécifique en préfixant son nom par le mot-clé « no ».

Voir aussi : tune.bufsize.small

persist rdp-cookie

persist rdp-cookie
persist rdp-cookie(<name>)

Activer la persistance basée sur les cookies RDP

Peut être utilisé dans les contextes suivants : tcp

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<name>    is the optional name of the RDP cookie to check. If omitted, the
          default cookie name "msts" will be used. There currently is no
          valid reason to change this name.

Cette instruction active la persistance basée sur un cookie RDP. Le cookie RDP contient toutes les informations nécessaires pour identifier le serveur dans la liste des serveurs connus. Ainsi, lorsque cette option est configurée dans le backend, la requête est analysée ; si un cookie RDP est détecté, il est décodé. Si ce cookie correspond à un serveur connu qui est toujours actif (ou si l’option persist est définie), la connexion est acheminée vers ce serveur.

Notez que cela n’a de sens que dans un backend TCP, mais pour que cela fonctionne, le frontal doit avoir attendu suffisamment longtemps pour garantir la présence d’un cookie RDP dans le tampon de la requête. Il s’agit de la même exigence que pour la méthode de répartition de charge « rdp-cookie ». Il est donc fortement recommandé de regrouper toutes les directives dans une seule section « listen ».

En outre, il est important de comprendre que le serveur terminal émettra ce cookie RDP uniquement s’il est configuré en mode « redirection de jeton », ce qui signifie que l’option « redirection de l’adresse IP » est désactivée.

Exemple :

listen tse-farm
    bind:3389
    # wait up to 5s for an RDP cookie in the request
    tcp-request inspect-delay 5s
    tcp-request content accept if RDP_COOKIE
    # apply RDP cookie persistence
    persist rdp-cookie
    # if server is unknown, let's balance on the same cookie.
    # alternatively, "balance leastconn" may be useful too.
    balance rdp-cookie
    server srv1 1.1.1.1:3389
    server srv2 1.1.1.2:3389

Voir également : « balance rdp-cookie », « tcp-request » et l’ACL “req.rdp_cookie”.

quic-initial <action> [ { if | unless } <condition> ]

quic-initial <action> [ { if | unless } <condition> ]

Effectuer une action sur un paquet Initial QUIC entrant. Contrairement à « tcp-request connection », cette directive est exécutée avant toute instanciation d’élément de connexion, avant le démarrage et la finalisation de l’échange SSL, ce qui est plus efficace lorsqu’il s’agit de rejeter des tentatives de connexion.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | non

Arguments :

<action>    defines the action to perform if the condition applies. See
            below.

<condition> is a standard layer4-only ACL-based condition (see section 7).
            However, QUIC initial rules are executed too early even for
            some layer4 sample fetch methods despite no configuration
            warning and may result in unspecified runtime behavior,
            although they will not crash. Consider that only internal
            samples and layer4 "src*" and "dst*" are considered as
            supported for now.

Cette action est exécutée tôt lors de l’analyse des paquets QUIC. En conséquence, seule une liste minimale d’actions est prise en charge : - accept - dgram-drop - reject - send-retry

rate-limit sessions <rate>

rate-limit sessions <rate>

Fixez une limite au nombre de nouvelles sessions acceptées par seconde sur un frontal

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<rate>    The <rate> parameter is an integer designating the maximum number
          of new sessions per second to accept on the frontend.

Lorsque le frontal atteint le nombre spécifié de nouvelles sessions par seconde, il cesse d’accepter de nouvelles connexions jusqu’à ce que le taux redescende en dessous de la limite. Pendant cette période, les sessions en attente seront conservées dans la file d’attente du socket (dans les tampons système), et HAProxy ne sera même pas au courant de l’existence de ces sessions en attente. Lorsqu’on applique une limite très faible sur un service fortement sollicité, il peut être pertinent d’augmenter la taille de la file d’attente du socket en utilisant le mot-clé « backlog ».

Cette fonctionnalité est particulièrement efficace pour bloquer les attaques basées sur les connexions ou l’abus de service sur des serveurs sensibles. Comme le taux de session est mesuré toutes les millisecondes, il est extrêmement précis. De plus, la limite s’applique immédiatement, aucune attente n’est nécessaire pour détecter le seuil.

Exemple : limiter le débit des connexions SMTP à 10 par seconde au maximum écoute smtp mode tcp bind :25 taux-limité sessions 10 serveur smtp1 127.0.0.1:1025

Note : lorsque le débit maximal est atteint, l’état du frontal n’est pas modifié, mais ses sockets apparaissent comme « EN ATTENTE » dans les statistiques si l’option « socket-stats » est activée.

Voir également : le mot-clé « backlog » et le critère ACL “fe_sess_rate”.

redirect location <loc> [code <code>] <option> [{if | unless} <condition>]

redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
redirect prefix   <pfx> [code <code>] <option> [{if | unless} <condition>]
redirect scheme   <sch> [code <code>] <option> [{if | unless} <condition>]

Rediriger HTTP vers if/unless si une condition est remplie

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

If/unless la condition est remplie, la requête HTTP entraîne une réponse de redirection. Si aucune condition n’est spécifiée, la redirection s’applique sans condition.

Arguments :

<loc>     With "redirect location", the exact value in <loc> is placed into
          the HTTP "Location" header. When used in an "http-request" rule,
          <loc> value follows the Custom log format rules and can include
          some dynamic values (see Custom log format in section 8.2.6).

<pfx>     With "redirect prefix", the "Location" header is built from the
          concatenation of <pfx> and the complete URI path, including the
          query string, unless the "drop-query" option is specified (see
          below). As a special case, if <pfx> equals exactly "/", then
          nothing is inserted before the original URI. It allows one to
          redirect to the same URL (for instance, to insert a cookie). When
          used in an "http-request" rule, <pfx> value follows the Custom
          Log Format rules and can include some dynamic values (see Custom
          Log Format in section 8.2.6).

<sch>     With "redirect scheme", then the "Location" header is built by
          concatenating <sch> with "://" then the first occurrence of the
          "Host" header, and then the URI path, including the query string
          unless the "drop-query" option is specified (see below). If no
          path is found or if the path is "*", then "/" is used instead. If
          no "Host" header is found, then an empty host component will be
          returned, which most recent browsers interpret as redirecting to
          the same host. This directive is mostly used to redirect HTTP to
          HTTPS. When used in an "http-request" rule, <sch> value follows
          the Custom log format rules and can include some dynamic values
          (see Custom log format in section 8.2.6).

<code>    The code is optional. It indicates which type of HTTP redirection
          is desired. Only codes 301, 302, 303, 307 and 308 are supported,
          with 302 used by default if no code is specified. 301 means
          "Moved permanently", and a browser may cache the Location. 302
          means "Moved temporarily" and means that the browser should not
          cache the redirection. 303 is equivalent to 302 except that the
          browser will fetch the location with a GET method. 307 is just
          like 302 but makes it clear that the same method must be reused.
          Likewise, 308 replaces 301 if the same method must be used.

<option>  There are several options which can be specified to adjust the
          expected behavior of a redirection:

  - "drop-query"
    When this keyword is used in a prefix-based redirection, then the
    location will be set without any possible query-string, which is useful
    for directing users to a non-secure page for instance. It has no effect
    with a location-type redirect.

  - "append-slash"
    This keyword may be used in conjunction with "drop-query" to redirect
    users who use a URL not ending with a '/' to the same one with the '/'.
    It can be useful to ensure that search engines will only see one URL.
    For this, a return code 301 is preferred.

  - "ignore-empty"
    This keyword only has effect when a location is produced using a log
    format expression (i.e. when used in http-request or http-response).
    It indicates that if the result of the expression is empty, the rule
    should silently be skipped. The main use is to allow mass-redirects
    of known paths using a simple map.

  - "set-cookie NAME[=value]"
    A "Set-Cookie" header will be added with NAME (and optionally "=value")
    to the response. This is sometimes used to indicate that a user has
    been seen, for instance to protect against some types of DoS. No other
    cookie option is added, so the cookie will be a session cookie. Note
    that for a browser, a sole cookie name without an equal sign is
    different from a cookie with an equal sign.

  - "set-cookie-fmt <fmt>"
    It is equivaliant to the option above, except the "Set-Cookie" header
    will be filled with the result of the log-format string <fmt>
    evaluation. Be careful to respect the "NAME[=value]" format because no
    special check are performed during the configuration parsing.

  - "clear-cookie NAME[=]"
    A "Set-Cookie" header will be added with NAME (and optionally "="), but
    with the "Max-Age" attribute set to zero. This will tell the browser to
    delete this cookie. It is useful for instance on logout pages. It is
    important to note that clearing the cookie "NAME" will not remove a
    cookie set with "NAME=value". You have to clear the cookie "NAME=" for
    that, because the browser makes the difference.

  - "keep-query"
    When this keyword is used in a location-based redirection, then the
    query-string of the original URI, if any, will be appended to the
    location. If no query-string is found, nothing is added. If the
    location already contains a query-string, the original one will be
    appended with the '&' delimiter.

Exemple : déplacer uniquement l’URL de connexion vers HTTPS. acl clear dst_port 80 acl secure dst_port 8080 acl login_page url_beg /login acl logout url_beg /logout acl uid_given url_reg /login?userid=[^&]+ acl cookie_set hdr_sub(cookie) SEEN=1

    rediriger préfixe   https://mysite.com set-cookie SEEN=1 si !cookie_set
    rediriger préfixe   https://mysite.com           si page_connexion !secure
    rediriger préfixe   http://mysite.com supprimer-requête si page_connexion !uid_fourni
    rediriger localisation http://mysite.com/           si !page_connexion secure
    rediriger localisation / supprimer-cookie USERID=       si déconnexion

Exemple : envoyer des redirections pour les requêtes vers des articles sans « / ». acl missing_slash path_reg ^/article/[^/]$ redirect code 301 prefix / drop-query append-slash if missing_slash

Exemple : rediriger tout le trafic HTTP vers HTTPS lorsque le chiffrement SSL est géré par HAProxy. redirect scheme https if !{ ssl_fc }

Exemple : ajouter le préfixe ‘www.’ devant tous les hôtes ne le comportant pas http-request redirect code 301 location \ http://www.%[hdr(host)]%[capture.req.uri] \ sauf si { hdr_beg(host) -i www }

Exemple : rediriger définitivement uniquement les anciens URL vers les nouveaux http-request redirect code 301 location \ %[path,map_str(old-blog-articles.map)] ignore-empty

Voir section 7 concernant l’utilisation des ACL.

retries <value>

retries <value>

Définir le nombre de tentatives à effectuer sur un serveur après un échec

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<value>   is the number of times a request or connection attempt should be
          retried on a server after a failure.

Par défaut, les tentatives de nouvelle connexion sont les seules concernées par les réessais. Toutefois, lorsque la directive « retry-on » est utilisée, d’autres conditions peuvent déclencher un réessai (par exemple, une réponse vide, un code d’état indésirable), et chacune d’elles sera comptée comme une tentative. Lorsque le nombre total de tentatives atteint la valeur indiquée ici, une erreur sera renvoyée.

Afin d’éviter une nouvelle connexion immédiate à un serveur qui redémarre, un minuteur de retour de min(“timeout connect”, une seconde) est appliqué avant toute nouvelle tentative sur le même serveur.

Lorsque l’option redispatch est activée, certaines tentatives peuvent être effectuées sur un autre serveur, même si un cookie référence un serveur différent. Par défaut, cela ne concerne que la dernière tentative, sauf si un argument est fourni à l’option redispatch.

Voir également : « option redispatch »

retry-on [space-delimited list of keywords]

retry-on [space-delimited list of keywords]

Spécifiez quand tenter de réessayer automatiquement une requête échouée. Ce paramètre n’est valable que lorsque « mode » est défini sur http et est ignoré silencieusement dans les autres cas.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

 <keywords>  is a space-delimited list of keywords or HTTP status codes, each
             representing a type of failure event on which an attempt to
             retry the request is desired. Please read the notes at the
             bottom before changing this setting. The following keywords are
             supported:

   none              never retry

   conn-failure      retry when the connection or the SSL handshake failed
                     and the request could not be sent. This is the default.

   empty-response    retry when the server connection was closed after part
                     of the request was sent, and nothing was received from
                     the server. This type of failure may be caused by the
                     request timeout on the server side, poor network
                     condition, or a server crash or restart while
                     processing the request.

   junk-response     retry when the server returned something not looking
                     like a complete HTTP response. This includes partial
                     responses headers as well as non-HTTP contents. It
                     usually is a bad idea to retry on such events, which
                     may be caused a configuration issue (wrong server port)
                     or by the request being harmful to the server (buffer
                     overflow attack for example).

   response-timeout  the server timeout stroke while waiting for the server
                     to respond to the request. This may be caused by poor
                     network condition, the reuse of an idle connection
                     which has expired on the path, or by the request being
                     extremely expensive to process. It generally is a bad
                     idea to retry on such events on servers dealing with
                     heavy database processing (full scans, etc) as it may
                     amplify denial of service attacks.

   0rtt-rejected     retry requests which were sent over early data and were
                     rejected by the server. These requests are generally
                     considered to be safe to retry.

   <status>          any HTTP status code among "401" (Unauthorized), "403"
                     (Forbidden), "404" (Not Found), "408" (Request Timeout),
"421" (Misdirected Request), "425" (Too Early),
"429" (Too Many Requests), "500" (Server Error),
"501" (Not Implemented), "502" (Bad Gateway),
"503" (Service Unavailable), "504" (Gateway Timeout).

   all-retryable-errors
                     retry request for any error that are considered
                     retryable. This currently activates "conn-failure",
                     "empty-response", "junk-response", "response-timeout",
                     "0rtt-rejected", "500", "502", "503", and "504".

L’utilisation de cette directive remplace tout paramètre précédent par les nouveaux ; elle n’est pas cumulée.

Veuillez noter qu’utiliser une valeur autre que « none » ou « conn-failure » impose d’allouer un tampon et de copier intégralement la requête dans celui-ci, ce qui a des impacts mémoire et en performance. Les requêtes qui ne tiennent pas dans un seul tampon ne seront jamais réessayées (voir le paramètre global tune.bufsize).

Vous devez vous assurer que l’application dispose d’un mécanisme de protection contre le rebond, tel qu’un identifiant de transaction unique transmis dans les requêtes, ou que le rebond de la même requête n’a aucune conséquence, ou qu’il est très dangereux d’utiliser une valeur de réessai autre que « conn-failure » ou « none ». Les serveurs de fichiers statiques et les caches sont généralement considérés comme sûrs contre tout type de réessai. Utiliser un code d’état peut être utile pour quitter rapidement un serveur présentant un comportement anormal (mémoire insuffisante, problèmes du système de fichiers, etc.), mais dans ce cas, il peut être judicieux de rediriger immédiatement la connexion vers un autre serveur (voir « option redispatch » à ce sujet). Enfin, il est important de comprendre que la plupart des causes d’échecs proviennent des requêtes elles-mêmes, et que réessayer une requête provoquant un comportement anormal du serveur aggrave souvent la situation pour ce serveur, ou pour l’ensemble du service en cas de redirige.

Sauf si vous connaissez exactement la manière dont l’application gère les requêtes répétées, vous ne devez pas utiliser cette directive.

La valeur par défaut est « conn-failure ».

Exemple :

retry-on 503 504

Voir aussi : « retries », « option redispatch », “tune.bufsize”

server <name> <address>[:[port]] [param*]

server <name> <address>[:[port]] [param*]

Déclarer un serveur dans un backend

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<name>    is the internal name assigned to this server. This name will
          appear in logs and alerts. If "http-send-name-header" is
          set, it will be added to the request header sent to the server.
          This name must be unique within the backend section.

<address> is the IPv4 or IPv6 address of the server. Alternatively, a
          resolvable hostname is supported, but this name will be resolved
          during start-up. Address "0.0.0.0" or "*" has a special meaning.
          It indicates that the connection will be forwarded to the same IP
          address as the one from the client connection. This is useful in
          transparent proxy architectures where the client's connection is
          intercepted and HAProxy must forward to the original destination
          address. This is more or less what the "transparent" keyword does
          except that with a server it's possible to limit concurrency and
          to report statistics. Optionally, an address family prefix may be
          used before the address to force the family regardless of the
          address format, which can be useful to specify a path to a unix
          socket with no slash ('/'). Currently supported prefixes are:
                - 'ipv4@'  -> address is always IPv4
                - 'ipv6@'  -> address is always IPv6
                - 'unix@'  -> address is a path to a local unix socket
                - 'abns@'  -> address is in abstract namespace (Linux only)
                - 'abnsz@'  -> address is in abstract namespace (Linux only)
                   but it is explicitly zero-terminated. This means no \0
                   padding is used to complete sun_path. It is useful to
                   interconnect with programs that don't implement the
                   default abns naming logic that haproxy uses.
                - 'sockpair@' -> address is the FD of a connected unix
                  socket or of a socketpair. During a connection, the
                  backend creates a pair of connected sockets, and passes
                  one of them over the FD. The bind part will use the
                  received socket as the client FD. Should be used
                  carefully.
                - 'quic4@' [ EXPERIMENTAL] -> address is resolved as IPv4
                  and protocol UDP is used. QUIC on the backend side is
                  considered experimental mainly because this prevents the
                  server removal at runtime. This requires the global
                  keyword "expose-experimental-directives" to use it.
                - 'quic6@' [ EXPERIMENTAL] -> address is resolved as IPv6
                  and protocol UDP is used. It is considered similarly
                  flagged as experimental.
                - 'rhttp@' [ EXPERIMENTAL ] -> custom address family for a
                  passive server in HTTP reverse context. This is an
                  experimental features which requires
                  "expose-experimental-directives" on a line before this
                  server.
          You may want to reference some environment variables in the
          address parameter, see section 2.3 about environment
          variables. The "init-addr" setting can be used to modify the way
          IP addresses should be resolved upon startup.

<port>    is an optional port specification. If set, all connections will
          be sent to this port. If unset, the same port the client
          connected to will be used. The port may also be prefixed by a "+"
          or a "-". In this case, the server's port will be determined by
          adding this value to the client's port.

<param*>  is a list of parameters for this server. The "server" keywords
          accepts an important number of options and has a complete section
          dedicated to it. Please refer to section 5 for more details.

Exemples :

server first  10.1.1.1:1080 cookie first  check inter 1000
server second 10.1.1.2:1080 cookie second check inter 1000
server transp ipv4@
server backup "${SRV_BACKUP}:1080" backup
server www1_dc1 "${LAN_DC1}.101:80"
server www1_dc2 "${LAN_DC2}.101:80"

Note : En ce qui concerne les sockets de l’espace de noms abstrait sous Linux, les sockets HAProxy « abns » utilisent la longueur entière de sun_path pour la longueur de l’adresse. Certains autres programmes, comme socat, utilisent par défaut uniquement la longueur de chaîne. Passez l’option « ,unix-tightsocklen=0 » à toute définition de socket abstrait dans socat pour la rendre compatible avec celle de HAProxy, ou utilisez à la place la famille de sockets HAProxy « abnsz ».

Voir également : « default-server », « http-send-name-header » et la section 5 à propos des options de serveur

server-state-file-name [ { use-backend-name | <file> } ]

server-state-file-name [ { use-backend-name | <file> } ]

Définissez le fichier d’état du serveur en lecture, chargez-le et appliquez-le aux serveurs disponibles dans ce backend.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Il ne s’applique que lorsque la directive « load-server-state-from-file » est définie sur « local ». Si <file> n’est pas fourni, et si « use-backend-name » est utilisé ou si cette directive n’est pas définie, alors le nom de backend est utilisé. Si <file> commence par une barre oblique « / », il est considéré comme un chemin absolu. Sinon, <file> est concaténé à la directive globale « server-state-base ».

Exemple : la configuration minimale ci-dessous ferait que HAProxy chercherait le fichier d’état serveur ‘/etc/haproxy/states/bk’ :

global
  server-state-file-base /etc/haproxy/states

backend bk
  load-server-state-from-file

Voir également : « server-state-base », « load-server-state-from-file » et « show servers state »

server-template <prefix> <num | range> <fqdn>[:<port>] [params*]

server-template <prefix> <num | range> <fqdn>[:<port>] [params*]

Définissez un modèle pour initialiser les serveurs avec des paramètres partagés. Les noms de ces serveurs sont construits à partir des paramètres <prefix> et <num | range>.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<prefix>  A prefix for the server names to be built.

<num | range>
          If <num> is provided, this template initializes <num> servers
          with 1 up to <num> as server name suffixes. A range of numbers
          <num_low>-<num_high> may also be used to use <num_low> up to
          <num_high> as server name suffixes.

<fqdn>    A FQDN for all the servers this template initializes.

<port>    Same meaning as "server" <port> argument (see "server" keyword).

<params*>
          Remaining server parameters among all those supported by "server"
          keyword.

Exemples :

# Initializes 3 servers with srv1, srv2 and srv3 as names,
# google.com as FQDN, and health-check enabled.
server-template srv 1-3 google.com:80 check

# or
server-template srv 3 google.com:80 check

# would be equivalent to:
server srv1 google.com:80 check
server srv2 google.com:80 check
server srv3 google.com:80 check

source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]

source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
source <addr>[:<port>] [interface <name>]

Définir l’adresse source pour les connexions sortantes

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<addr>    is the IPv4 address HAProxy will bind to before connecting to a
          server. This address is also used as a source for health checks.

          The default value of 0.0.0.0 means that the system will select
          the most appropriate address to reach its destination. Optionally
          an address family prefix may be used before the address to force
          the family regardless of the address format, which can be useful
          to specify a path to a unix socket with no slash ('/'). Currently
          supported prefixes are:
            - 'ipv4@' -> address is always IPv4
            - 'ipv6@' -> address is always IPv6
            - 'unix@' -> address is a path to a local unix socket
            - 'abns@' -> address is in abstract namespace (Linux only)
            - 'abnsz@'  -> address is in zero-terminated abstract namespace
                           (Linux only)

          You may want to reference some environment variables in the
          address parameter, see section 2.3 about environment variables.

<port>    is an optional port. It is normally not needed but may be useful
          in some very specific contexts. The default value of zero means
          the system will select a free port. Note that port ranges are not
          supported in the backend. If you want to force port ranges, you
          have to specify them on each "server" line.

<addr2>   is the IP address to present to the server when connections are
          forwarded in full transparent proxy mode. This is currently only
          supported on some patched Linux kernels. When this address is
          specified, clients connecting to the server will be presented
          with this address, while health checks will still use the address
          <addr>.

<port2>   is the optional port to present to the server when connections
          are forwarded in full transparent proxy mode (see <addr2> above).
          The default value of zero means the system will select a free
          port.

<hdr>     is the name of a HTTP header in which to fetch the IP to bind to.
          This is the name of a comma-separated header list which can
          contain multiple IP addresses. By default, the last occurrence is
          used. This is designed to work with the X-Forwarded-For header
          and to automatically bind to the client's IP address as seen
          by previous proxy, typically Stunnel. In order to use another
          occurrence from the last one, please see the <occ> parameter
          below. When the header (or occurrence) is not found, no binding
          is performed so that the proxy's default IP address is used. Also
          keep in mind that the header name is case insensitive, as for any
          HTTP header.

<occ>     is the occurrence number of a value to be used in a multi-value
          header. This is to be used in conjunction with "hdr_ip(<hdr>)",
          in order to specify which occurrence to use for the source IP
          address. Positive values indicate a position from the first
          occurrence, 1 being the first one. Negative values indicate
          positions relative to the last one, -1 being the last one. This
          is helpful for situations where an X-Forwarded-For header is set
          at the entry point of an infrastructure and must be used several
          proxy layers away. When this value is not specified, -1 is
          assumed. Passing a zero here disables the feature.

<name>    is an optional interface name to which to bind to for outgoing
          traffic. On systems supporting this features (currently, only
          Linux), this allows one to bind all traffic to the server to
          this interface even if it is not the one the system would select
          based on routing tables. This should be used with extreme care.
          Note that using this option requires root privileges.

Le mot-clé « source » est utile dans les environnements complexes où une adresse spécifique est autorisée à se connecter aux serveurs. Il peut être nécessaire lorsqu’une adresse privée doit être utilisée via une passerelle publique, par exemple, et qu’il est connu que le système ne peut pas déterminer par lui-même l’adresse source appropriée.

Une extension disponible sur certains noyaux Linux patchés peut être utilisée via le mot-clé facultatif « usesrc ». Elle permet de se connecter aux serveurs à l’aide d’une adresse IP qui n’appartient pas au système lui-même. Ce mode est appelé « mode de proxy entièrement transparent ». Pour que cela fonctionne, les serveurs de destination doivent acheminer leur trafic de retour vers cette adresse via la machine exécutant HAProxy, et le transfert IP doit généralement être activé sur cette machine.

En mode « proxy transparent complet », il est possible de forcer l’affichage d’une adresse IP spécifique aux serveurs. Cette fonctionnalité est en réalité peu utilisée. Une utilisation plus courante consiste à demander à HAProxy de présenter l’adresse IP du client. Pour cela, deux méthodes sont disponibles :

-  présentent l'adresse IP et le numéro de port du client. Il s'agit du mode le plus transparent, mais il peut poser des problèmes lorsque le suivi des connexions IP est activé sur la machine, car une même connexion peut être vue deux fois avec des états différents. Toutefois, cette solution présente l'avantage majeur de ne pas limiter le système aux 64 000 couples adresse+port sortants, car toutes les plages clientes peuvent être utilisées.

- présente uniquement l'adresse IP du client et sélectionne un port libre. Cette solution reste élégante, mais légèrement moins transparente (les journaux des pare-feu en aval ne correspondront pas à ceux en amont). Elle présente également l'inconvénient de limiter le nombre de connexions simultanées au nombre habituel de ports 64 k. Toutefois, comme les ports en amont et en aval sont différents, le suivi des connexions locales par adresse IP sur la machine ne sera pas perturbé par la réutilisation de la même session.

Cette option définit la source par défaut pour tous les serveurs du backend. Elle peut également être spécifiée dans une section « defaults ». Une spécification plus fine de l’adresse source est possible au niveau du serveur en utilisant l’option de serveur « source ». Pour en savoir plus, reportez-vous à la section 5 .

Pour fonctionner, l’option « usesrc » nécessite des privilèges root, ou, sur les systèmes pris en charge, la capacité “cap_net_raw”. Voir également la directive globale « setcap ».

Exemples :

backend private
    # Connect to the servers using our 192.168.1.200 source address
    source 192.168.1.200

backend transparent_ssl1
    # Connect to the SSL farm from the client's source address
    source 192.168.1.200 usesrc clientip

backend transparent_ssl2
    # Connect to the SSL farm from the client's source address and port
    # not recommended if IP conntrack is present on the local machine.
    source 192.168.1.200 usesrc client

backend transparent_ssl3
    # Connect to the SSL farm from the client's source address. It
    # is more conntrack-friendly.
    source 192.168.1.200 usesrc clientip

backend transparent_smtp
    # Connect to the SMTP farm from the client's source address/port
    # with Tproxy version 4.
    source 0.0.0.0 usesrc clientip

backend transparent_http
    # Connect to the servers using the client's IP as seen by previous
    # proxy.
    source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)

Voir également : l’option de serveur « source » dans la section 5 , les correctifs Tproxy pour le noyau Linux sur www.balabit.com , le mot-clé « bind ».

srvtcpka-cnt <count>

srvtcpka-cnt <count>

Définit le nombre maximal d’enquêtes keepalive TCP qui doivent être envoyées avant de fermer la connexion côté serveur.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<count>   is the maximum number of keepalive probes.

Ce mot-clé correspond à l’option de socket TCP_KEEPCNT. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_probes) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir également : « option srvtcpka », « srvtcpka-idle », « srvtcpka-intvl ».

srvtcpka-idle <timeout>

srvtcpka-idle <timeout>

Définit le délai pendant lequel la connexion doit rester inactif avant que TCP ne commence à envoyer des sondes de maintien de connexion, si activé, l’envoi des paquets de maintien de connexion TCP côté serveur.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the time the connection needs to remain idle before TCP starts
          sending keepalive probes. It is specified in seconds by default,
          but can be in any other unit if the number is suffixed by the
          unit, as explained at the top of this document.

Ce mot-clé correspond à l’option de socket TCP_KEEPIDLE. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_time) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir également : « option srvtcpka », « srvtcpka-cnt », « srvtcpka-intvl ».

srvtcpka-intvl <timeout>

srvtcpka-intvl <timeout>

Définit le délai entre les sondes keepalive individuelles du côté serveur.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the time between individual keepalive probes. It is specified
          in seconds by default, but can be in any other unit if the number
          is suffixed by the unit, as explained at the top of this
          document.

Ce mot-clé correspond à l’option de socket TCP_KEEPINTVL. Si ce mot-clé n’est pas spécifié, le paramètre TCP système (tcp_keepalive_intvl) est utilisé. La disponibilité de ce paramètre dépend du système d’exploitation. Il est connu pour fonctionner sous Linux.

Voir également : « option srvtcpka », « srvtcpka-cnt », « srvtcpka-idle ».

stats admin { if | unless } <cond>

stats admin { if | unless } <cond>

Activer le niveau d’administration des statistiques if/unless si une condition est remplie

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Cette instruction active le niveau d’administration des statistiques if/unless si une condition est remplie.

Le niveau administrateur permet de enable/disable des serveurs depuis l’interface web. Par défaut, la page de statistiques est en lecture seule pour des raisons de sécurité. Si des directives « stats scope » sont définies dans la section, seuls les proxies désignés par ces directives accepteront les modifications d’état ; l’accès aux autres sera refusé.

Actuellement, la requête POST est limitée à la taille de tampon moins l’espace tampon réservé, ce qui signifie qu’en cas de liste de serveurs trop longue, la requête ne sera pas traitée. Il est recommandé de modifier un petit nombre de serveurs à la fois.

Les requêtes POST d’administration sont sujettes aux attaques CSRF. Cet risque est partiellement atténué en vérifiant que l’en-tête Origin (ou Referer si Origin est absent) correspond à l’en-tête Host, mais cette mesure ne suffit pas à empêcher complètement l’attaque. Il n’existe aucun moyen de se protéger entièrement contre ces attaques. Il est recommandé de ne pas exposer cette fonctionnalité sur une interface publique, et de limiter l’accès à ceux qui en ont besoin.

Exemple :

# statistics admin level only for localhost
backend stats_localhost
    stats enable
    stats admin if LOCALHOST

Exemple :

# statistics admin level always enabled because of the authentication
backend stats_auth
    stats enable
    stats auth  admin:AdMiN123
    stats admin if TRUE

Exemple :

# statistics admin level depends on the authenticated user
userlist stats-auth
    group admin    users admin
    user  admin    insecure-password 'AdMiN123'
    group readonly users haproxy
    user  haproxy  insecure-password 'haproxy'

backend stats_auth
    stats enable
    acl AUTH       http_auth(stats-auth)
    acl AUTH_ADMIN http_auth_group(stats-auth) admin
    stats http-request auth unless AUTH
    stats admin if AUTH_ADMIN

Voir aussi : « stats enable », « stats auth », « stats http-request », « stats scope », section 12.2 sur les listes d’utilisateurs et section 7 sur l’utilisation des ACL.

ssl-f-use [<sslbindconf> ...]*

ssl-f-use [<sslbindconf> ...]*

Attribuez un certificat au frontal actuel.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<sslbindconf> supports the following keywords from the bind line
(see Section 5.1. Bind options):

- allow-0rtt
- alpn
- ca-file
- ca-verify-file
- ciphers
- ciphersuites
- client-sigalgs
- crl-file
- curves
- ecdhe
- ktls
- no-alpn
- no-ca-names
- npn
- sigalgs
- ssl-min-ver
- ssl-max-ver
- verify

sslbindconf also supports the following keywords from the crt-store load
keyword (see Section 12.7.1. Load options):

- crt
- key
- ocsp
- issuer
- sctl
- ocsp-update

Attribuez un certificat <crtname> à une liste de certificats créée automatiquement avec le nom du frontal et préfixée par @ (par exemple : ‘@frontend1’).

Cette liste de certificats implicite sera affectée à chaque ligne « ssl » de liaison dans le frontal actuel.

Les commandes crt-list issues de la socket de statistiques sont effectives avec cette liste de certificats, on peut donc la remplacer, supprimer ou ajouter des certificats et des options SSL à celle-ci.

Exemple :

frontend https
    bind:443 ssl
    bind quic4@:443 ssl
    ssl-f-use crt foobar.pem.rsa sigalgs "RSA-PSS+SHA256"
    ssl-f-use crt test.foobar.pem
    ssl-f-use crt test2.foobar.crt key test2.foobar.key ocsp test2.foobar.ocsp ocsp-update on

Voir également : « crt-list » et « crt ».

stats auth <user>:<passwd>

stats auth <user>:<passwd>

Activer les statistiques avec authentification et accorder l’accès à un compte

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<user>    is a user name to grant access to

<passwd>  is the cleartext password associated to this user

Cette instruction active les statistiques avec les paramètres par défaut et restreint l’accès aux utilisateurs déclarés uniquement. Elle peut être répétée autant de fois que nécessaire pour autoriser autant d’utilisateurs que souhaité. Lorsqu’un utilisateur tente d’accéder aux statistiques sans compte valide, une réponse « 401 Forbidden » sera renvoyée, ce qui amène le navigateur à demander un utilisateur et un mot de passe valides. Le domaine affiché au navigateur est configurable à l’aide de « stats realm ».

Étant donné que la méthode d’authentification est l’authentification HTTP Basic, les mots de passe circulent en clair sur le réseau. Il a donc été décidé que le fichier de configuration utiliserait également des mots de passe en clair afin de rappeler aux utilisateurs qu’ils ne doivent pas être sensibles et ne doivent pas être partagés avec d’autres comptes.

Il est également possible de réduire la portée des proxies affichés dans le rapport à l’aide de « stats scope ».

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir aussi : « stats enable », « stats realm », « stats scope », « stats uri »

stats enable

stats enable

Activer le rapport de statistiques avec les paramètres par défaut

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Cette instruction active le rapport de statistiques avec les paramètres par défaut définis au moment de la compilation. Sauf indication contraire, ces paramètres sont utilisés : - uri des statistiques : /haproxy?stats - realm des statistiques : « HAProxy Statistics » - authentification des statistiques : non activée - portée des statistiques : aucune restriction

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir aussi : « stats auth », « stats realm », « stats uri »

stats hide-version

stats hide-version

Activer les statistiques et masquer le rapport de version HAProxy

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

La page de statistiques peut rapporter certaines informations utiles sur l’état, ainsi que les statistiques. Parmi celles-ci figure la version d’HAProxy. Toutefois, il est généralement considéré comme dangereux de divulguer la version précise à quiconque, car cela peut aider à cibler des vulnérabilités connues par des attaques spécifiques. L’instruction « stats hide-version » supprime la version du rapport de statistiques. Cela est recommandé pour les sites publics ou tout site présentant une faiblesse login/password, et constitue la valeur par défaut.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir aussi : « stats auth », « stats enable », « stats realm », « stats uri », « stats show-version »

stats http-request { allow | deny | auth [realm <realm>] }

stats http-request { allow | deny | auth [realm <realm>] }
             [ { if | unless } <condition> ]

Contrôle d’accès aux statistiques

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Comme « http-request », ces options permettent un contrôle fin de l’accès aux statistiques. Chaque option peut être suivie de if/unless et d’une ACL. La première option dont la condition est satisfaite (ou l’option sans condition) détermine le résultat final. Pour « deny », une erreur 403 est renvoyée ; pour « allow », le traitement normal est effectué ; pour « auth », un code d’erreur 401/407 est renvoyé afin que le client soit invité à saisir un nom d’utilisateur et un mot de passe.

Il n’existe aucune limite fixe au nombre d’instructions http-request par instance.

Voir également : « http-request », section 12.2 sur les listes d’utilisateurs et section 7 sur l’utilisation des ACL.

stats realm <realm>

stats realm <realm>

Activer les statistiques et définir le domaine d’authentification

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<realm>   is the name of the HTTP Basic Authentication realm reported to
          the browser. The browser uses it to display it in the pop-up
          inviting the user to enter a valid username and password.

Le domaine est lu comme un mot unique, de sorte que tout espace qu’il contient doit être échappé à l’aide d’une barre oblique inverse (\).

Cette instruction n’est utile que conjointement avec « stats auth », car elle ne concerne que l’authentification.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir également : « stats auth », « stats enable », « stats uri »

stats refresh <delay>

stats refresh <delay>

Activer les statistiques avec actualisation automatique

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<delay>   is the suggested refresh delay, specified in seconds, which will
          be returned to the browser consulting the report page. While the
          browser is free to apply any delay, it will generally respect it
          and refresh the page this every seconds. The refresh interval may
          be specified in any other non-default time unit, by suffixing the
          unit after the value, as explained at the top of this document.

Cette instruction est utile sur les affichages de surveillance dotés d’une page permanente affichant l’activité du répartiteur de charge. Lorsqu’elle est activée, la page de rapport HTML inclura un lien « actualiser » / « arrêter l’actualisation » permettant à l’utilisateur de choisir s’il souhaite ou non l’actualisation automatique de la page.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir aussi : « stats auth », « stats enable », « stats realm », « stats uri »

stats scope { <name> | "." }

stats scope { <name> | "." }

Activer les statistiques et limiter la portée d’accès

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<name>    is the name of a listen, frontend or backend section to be
          reported. The special name "." (a single dot) designates the
          section in which the statement appears.

Lorsque cette instruction est spécifiée, seules les sections énumérées par cette instruction apparaissent dans le rapport. Toutes les autres sont masquées, et toute tentative de modifier leur état en mode administrateur est rejetée. Cette instruction peut être utilisée autant de fois que nécessaire si plusieurs sections doivent être rapportées. Veuillez noter que la vérification des noms se fait par comparaison de chaînes de caractères simple, et qu’il n’est jamais vérifié qu’un nom de section donné existe réellement.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir également : « stats auth », « stats enable », « stats realm », « stats uri » et « stats admin »

stats show-desc [ <desc> ]

stats show-desc [ <desc> ]

Activer le rapport d’une description sur la page de statistiques.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

`<desc>` est une description facultative à rapporter. Si non spécifiée, la description provenant de la section globale est automatiquement utilisée à la place.

Cette instruction est utile pour les utilisateurs qui proposent des services partagés à leurs clients, où le nœud ou la description doit être différent pour chaque client.

Bien que cette instruction seule suffise à activer le rapport des statistiques, il est recommandé de définir toutes les autres options afin d’éviter de dépendre de paramètres par défaut peu évidents. Par défaut, la description n’est pas affichée.

Exemple :

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats show-desc Master node for Europe, Asia, Africa
    stats uri       /admin?stats
    stats refresh   5s

Voir également : « show-node », « stats enable », « stats uri » et « description » dans la section globale.

stats show-legends

stats show-legends

Activer le rapport d’informations supplémentaires sur la page de statistiques

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

Activer le rapport d’informations supplémentaires sur la page de statistiques : - cap : fonctionnalités (proxy) - mode : l’un des suivants : tcp, http ou health (proxy) - id : identifiant SNMP (proxy, socket, serveur) - IP (socket, serveur) - cookie (backend, serveur)

Bien que cette instruction seule suffise à activer le rapport des statistiques, il est recommandé de définir toutes les autres options afin d’éviter de dépendre de paramètres par défaut peu évidents. Le comportement par défaut consiste à ne pas afficher ces informations.

Voir également : « stats enable », « stats uri ».

stats show-modules

stats show-modules

Activer l’affichage du module de statistiques supplémentaires sur la page de statistiques

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

De nouvelles colonnes sont ajoutées à la fin de la ligne contenant les valeurs supplémentaires de statistiques, affichées comme un infobulle.

Bien que cette instruction seule suffise à activer le rapport des statistiques, il est recommandé de définir toutes les autres options afin d’éviter de dépendre de paramètres par défaut peu évidents. Le comportement par défaut consiste à ne pas afficher ces informations.

Voir également : « stats enable », « stats uri ».

stats show-node [ <name> ]

stats show-node [ <name> ]

Activer le rapport du nom d’hôte sur la page de statistiques.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<name>    is an optional name to be reported. If unspecified, the
          node name from global section is automatically used instead.

Cette instruction est utile pour les utilisateurs qui proposent des services partagés à leurs clients, où le nœud ou la description peut varier sur une page de statistiques fournie à chaque client. Le comportement par défaut consiste à ne pas afficher le nom d’hôte.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats show-node Europe-1
    stats uri       /admin?stats
    stats refresh   5s

Voir également : « show-desc », « stats enable », « stats uri » et « node » dans la section globale.

stats show-version

stats show-version

Activer les statistiques et la rapport de version HAProxy

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments : aucun

La page de statistiques peut rapporter certaines informations d’état utiles en plus des statistiques. Parmi celles-ci figure la version d’HAProxy. Toutefois, il est généralement considéré comme dangereux de divulguer la version précise à quiconque, car cela peut aider à cibler des vulnérabilités connues par des attaques spécifiques, et cette fonctionnalité est donc désactivée par défaut. L’option « stats show-version » permet d’activer l’affichage de ces informations. Cette fonctionnalité n’est pas recommandée pour les sites publics ou tout site présentant une faiblesse login/password.

Voir également : « stats auth », « stats enable », « stats realm », « stats uri », « stats hide-version »

stats uri <prefix>

stats uri <prefix>

Activer les statistiques et définir le préfixe d’URI pour y accéder

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<prefix>  is the prefix of any URI which will be redirected to stats. This
          prefix may contain a question mark ('?') to indicate part of a
          query string.

L’URI des statistiques est intercepté dans le trafic relais, de sorte qu’il apparaît comme une page au sein de l’application normale. Il est fortement conseillé de s’assurer que l’URI sélectionné n’apparaîtra jamais dans l’application, faute de quoi il sera impossible de l’atteindre depuis l’application.

L’URI par défaut intégré dans HAProxy est “/haproxy?stats”, mais celui-ci peut être modifié au moment de la compilation, il est donc préférable de toujours le spécifier explicitement ici. Il est généralement recommandé d’inclure un point d’interrogation dans l’URI afin que les proxies intermédiaires évitent de mettre en cache les résultats. En outre, comme toute chaîne commençant par ce préfixe sera acceptée comme une requête de statistiques, le point d’interrogation aide à garantir qu’aucune URI valide ne commence par les mêmes mots.

Il peut parfois être très pratique d’utiliser « / » comme préfixe d’URI, et de placer cette déclaration dans une instance « listen » à part. Cela facilite la dédication d’une adresse ou d’un port aux statistiques uniquement.

Bien que cette instruction seule suffise à activer la génération de statistiques, il est recommandé de définir tous les autres paramètres afin d’éviter de dépendre de paramètres par défaut non évidents.

Exemple :

# public access (limited to this backend only)
backend public_www
    server srv1 192.168.0.1:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /admin?stats
    stats realm   HAProxy\ Statistics
    stats auth    admin1:AdMiN123
    stats auth    admin2:AdMiN321

# internal monitoring access (unlimited)
backend private_monitoring
    stats enable
    stats uri     /admin?stats
    stats refresh 5s

Voir aussi : « stats auth », « stats enable », « stats realm »

stick match <pattern> [table <table>] [{if | unless} <cond>]

stick match <pattern> [table <table>] [{if | unless} <cond>]

Définir une condition de correspondance de modèle de requête pour associer un utilisateur à un serveur

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<pattern>  is a sample expression rule as described in section 7.3. It
           describes what elements of the incoming request or connection
           will be analyzed in the hope to find a matching entry in a
           stickiness table. This rule is mandatory.

<table>    is an optional stickiness table name. If unspecified, the same
           backend's table is used. A stickiness table is declared using
           the "stick-table" statement.

<cond>     is an optional matching condition. It makes it possible to match
           on a certain criterion only when other conditions are met (or
           not met). For instance, it could be used to match on a source IP
           address except when a request passes through a known proxy, in
           which case we'd match on a header containing that IP address.

Certains protocoles ou applications nécessitent des règles de persistance complexes et ne peuvent pas toujours se fier uniquement aux cookies ni au hachage. L’instruction « stick match » décrit une règle permettant d’extraire le critère de persistance à partir d’une requête ou d’une connexion entrante. Consultez section 7 pour obtenir la liste complète des modèles et règles de transformation possibles.

Le tableau doit être déclaré à l’aide de l’instruction « stick-table ». Il doit être de type compatible avec le motif. Par défaut, il s’agit de celui présent dans le même backend. Il est possible de partager un tableau avec d’autres backends en le référençant à l’aide du mot-clé « table ». Si un autre tableau est référencé, les identifiants de serveur présents dans les backends sont utilisés. Par défaut, tous les identifiants de serveur commencent à 1 dans chaque backend, de sorte que l’ordre des serveurs suffit. Toutefois, en cas de doute, il est fortement recommandé de définir explicitement les identifiants de serveur à l’aide de leur paramètre « id ».

Il est possible de restreindre les conditions dans lesquelles une directive « stick match » s’applique, en utilisant « if » ou « unless » suivis d’une condition. Voir section 7 pour des conditions basées sur les listes de contrôle d’accès.

Il n’y a aucune limite au nombre d’instructions « stick match ». La première qui s’applique et correspond entraîne la redirection de la requête vers le même serveur que celui utilisé pour la requête qui a créé l’entrée. Ainsi, plusieurs correspondances peuvent être utilisées comme mécanisme de secours.

Les règles stick sont vérifiées après les cookies de persistance, elles n’ont donc pas d’effet sur la persistance si un cookie a déjà été utilisé pour sélectionner un serveur. Ainsi, il devient très simple d’insérer des cookies et de les associer à des adresses IP afin de maintenir la persistance entre HTTP et HTTPS.

Exemple :

# forward SMTP users to the same server they just used for POP in the
# last 30 minutes
backend pop
    mode tcp
    balance roundrobin
    stick store-request src
    stick-table type ip size 200k expire 30m
    server s1 192.168.1.1:110
    server s2 192.168.1.1:110

backend smtp
    mode tcp
    balance roundrobin
    stick match src table pop
    server s1 192.168.1.1:25
    server s2 192.168.1.1:25

Voir également : « stick-table », « stick on », section 11 sur les tables de persistance, et section 7 sur les listes de contrôle d’accès et la récupération d’échantillons.

stick on <pattern> [table <table>] [{if | unless} <condition>]

stick on <pattern> [table <table>] [{if | unless} <condition>]

Définir un modèle de requête pour associer un utilisateur à un serveur

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Note : Cette forme est exactement équivalente à « stick match » suivie de « stick store-request », avec les mêmes arguments. Veuillez vous référer aux deux mots-clés pour plus de détails. Elle est fournie uniquement à titre de commodité pour écrire des configurations plus maintenables.

Exemples :

# The following form ...
stick on src table pop if !localhost

# ...is strictly equivalent to this one:
stick match src table pop if !localhost
stick store-request src table pop if !localhost


# Use cookie persistence for HTTP, and stick on source address for HTTPS as
# well as HTTP without cookie. Share the same table between both accesses.
backend http
    mode http
    balance roundrobin
    stick on src table https
    cookie SRV insert indirect nocache
    server s1 192.168.1.1:80 cookie s1
    server s2 192.168.1.1:80 cookie s2

backend https
    mode tcp
    balance roundrobin
    stick-table type ip size 200k expire 30m
    stick on src
    server s1 192.168.1.1:443
    server s2 192.168.1.1:443

Voir aussi : « stick match », « stick store-request » et section 11 sur les tables de persistance.

stick store-request <pattern> [table <table>] [{if | unless} <condition>]

stick store-request <pattern> [table <table>] [{if | unless} <condition>]

Définir un modèle de requête utilisé pour créer une entrée dans une table de persistance

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<pattern>  is a sample expression rule as described in section 7.3. It
           describes what elements of the incoming request or connection
           will be analyzed, extracted and stored in the table once a
           server is selected.

<table>    is an optional stickiness table name. If unspecified, the same
           backend's table is used. A stickiness table is declared using
           the "stick-table" statement.

<cond>     is an optional storage condition. It makes it possible to store
           certain criteria only when some conditions are met (or not met).
           For instance, it could be used to store the source IP address
           except when the request passes through a known proxy, in which
           case we'd store a converted form of a header containing that IP
           address.

Certains protocoles ou applications nécessitent des règles de persistance complexes et ne peuvent pas toujours se fier simplement aux cookies ni au hachage. L’instruction « stick store-request » décrit une règle indiquant quoi extraire de la requête et quand le faire, afin de le stocker dans une table de persistance pour permettre à des requêtes ultérieures de la correspondre à l’aide de l’instruction « stick match ». Évidemment, la partie extraite doit avoir un sens et avoir une chance d’être correspondante dans une requête ultérieure. Le stockage de l’adresse IP du client, par exemple, a souvent un sens. Le stockage d’un identifiant trouvé dans un paramètre d’URL a également un sens. Le stockage d’un port source n’a presque jamais de sens, car il sera presque toujours aléatoirement correspondant. Voir section 7 pour la liste complète des modèles possibles et des règles de transformation.

Le tableau doit être déclaré à l’aide de l’instruction « stick-table ». Il doit être de type compatible avec le motif. Par défaut, il s’agit de celui présent dans le même backend. Il est possible de partager un tableau avec d’autres backends en le référençant à l’aide du mot-clé « table ». Si un autre tableau est référencé, les identifiants de serveur présents dans les backends sont utilisés. Par défaut, tous les identifiants de serveur commencent à 1 dans chaque backend, de sorte que l’ordre des serveurs suffit. Toutefois, en cas de doute, il est fortement recommandé de définir explicitement les identifiants de serveur à l’aide de leur paramètre « id ».

Il est possible de restreindre les conditions dans lesquelles une directive « stick store-request » s’applique, en utilisant « if » ou « unless » suivi d’une condition. Cette condition est évaluée lors de l’analyse de la requête, de sorte que toute critère peut être utilisé. Voir section 7 pour des conditions basées sur les ACL.

Il n’y a aucune limite au nombre d’instructions « stick store-request », mais il existe une limite de 8 stockages simultanés par requête ou réponse. Cela permet de stocker jusqu’à 8 critères, extraits indifféremment de la requête ou de la réponse, quelle que soit la quantité de règles. Seuls les 8 premiers critères correspondants seront conservés. Grâce à cela, il est possible de remplir plusieurs tables en même temps dans l’espoir d’améliorer les chances de reconnaître un utilisateur via un autre protocole ou une autre méthode d’accès. Il est possible d’utiliser plusieurs règles store-request sur la même table, ce qui peut servir à déterminer le meilleur critère à privilégier en organisant les règles par ordre de préférence décroissante. Seul le premier critère extrait pour une table donnée sera stocké. Toutes les règles store-request ultérieures faisant référence à la même table seront ignorées, et leurs ACLs ne seront pas évaluées.

Les règles « store-request » sont évaluées une fois la connexion au serveur établie, afin que le tableau contienne le serveur réel ayant traité la requête.

Exemple :

# forward SMTP users to the same server they just used for POP in the
# last 30 minutes
backend pop
    mode tcp
    balance roundrobin
    stick store-request src
    stick-table type ip size 200k expire 30m
    server s1 192.168.1.1:110
    server s2 192.168.1.1:110

backend smtp
    mode tcp
    balance roundrobin
    stick match src table pop
    server s1 192.168.1.1:25
    server s2 192.168.1.1:25

Voir également : « stick-table », « stick on », section 11 sur les tables de persistance, et section 7 sur les listes de contrôle d’accès et l’extraction d’échantillon.

stick store-response <pattern> [table <table>] [{if | unless} <condition>]

stick store-response <pattern> [table <table>] [{if | unless} <condition>]

Définir un modèle de réponse utilisé pour créer une entrée dans une table de persistance

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<pattern>  is a sample expression rule as described in section 7.3. It
           describes what elements of the response or connection will
           be analyzed, extracted and stored in the table once a
           server is selected.

<table>    is an optional stickiness table name. If unspecified, the same
           backend's table is used. A stickiness table is declared using
           the "stick-table" statement.

<cond>     is an optional storage condition. It makes it possible to store
           certain criteria only when some conditions are met (or not met).
           For instance, it could be used to store the SSL session ID only
           when the response is a SSL server hello.

Certains protocoles ou applications nécessitent des règles de persistance complexes et ne peuvent pas toujours se fier simplement aux cookies ni au hachage. L’instruction « stick store-response » décrit une règle indiquant quoi extraire de la réponse et quand le faire, afin de le stocker dans une table de persistance pour permettre à des requêtes ultérieures de la correspondre à l’aide de l’instruction « stick match ». Évidemment, la partie extraite doit avoir un sens et avoir une chance d’être correspondante dans une requête ultérieure. Stocker un identifiant trouvé dans un en-tête de réponse a un sens. Voir section 7 pour la liste complète des modèles et règles de transformation possibles.

Le tableau doit être déclaré à l’aide de l’instruction « stick-table ». Il doit être de type compatible avec le motif. Par défaut, il s’agit de celui présent dans le même backend. Il est possible de partager un tableau avec d’autres backends en le référençant à l’aide du mot-clé « table ». Si un autre tableau est référencé, les identifiants de serveur présents dans les backends sont utilisés. Par défaut, tous les identifiants de serveur commencent à 1 dans chaque backend, de sorte que l’ordre des serveurs suffit. Toutefois, en cas de doute, il est fortement recommandé de définir explicitement les identifiants de serveur à l’aide de leur paramètre « id ».

Il est possible de restreindre les conditions dans lesquelles une directive « stick store-response » s’applique, en utilisant « if » ou « unless » suivi d’une condition. Cette condition est évaluée pendant l’analyse de la réponse, de sorte que toute critère puisse être utilisé. Voir section 7 pour des conditions basées sur des ACL.

Il n’y a aucune limite au nombre d’instructions « stick store-response », mais un plafond de 8 stockages simultanés par requête ou réponse. Cela permet de stocker jusqu’à 8 critères, extraits indifféremment de la requête ou de la réponse, quel que soit le nombre de règles. Seuls les 8 premiers critères correspondants seront conservés. Grâce à cela, il est possible de remplir plusieurs tables en même temps dans l’espoir d’améliorer les chances de reconnaître un utilisateur via un autre protocole ou une autre méthode d’accès. Il est possible d’utiliser plusieurs règles store-response sur la même table, ce qui peut servir à déterminer le meilleur critère à privilégier en classant les règles par ordre de préférence décroissante. Uniquement le premier critère extrait pour une table donnée sera stocké. Toutes les règles store-response ultérieures faisant référence à la même table seront ignorées, et leurs ACLs ne seront pas évaluées. Toutefois, même si une règle store-request fait référence à une table, une règle store-response peut également utiliser la même table. Cela signifie qu’une table peut apprendre exactement un élément provenant de la requête et un élément provenant de la réponse en même temps.

La table contiendra le serveur réel ayant traité la requête.

Exemple :

# Learn SSL session ID from both request and response and create affinity.
backend https
    mode tcp
    balance roundrobin
    # maximum SSL session ID length is 32 bytes.
    stick-table type binary len 32 size 30k expire 30m

    acl clienthello req.ssl_hello_type 1
    acl serverhello res.ssl_hello_type 2

    # use tcp content accepts to detects ssl client and server hello.
    tcp-request inspect-delay 5s
    tcp-request content accept if clienthello

    # no timeout on response inspect delay by default.
    tcp-response content accept if serverhello

    # SSL session ID (SSLID) may be present on a client or server hello.
    # Its length is coded on 1 byte at offset 43 and its value starts
    # at offset 44.

    # Match and learn on request if client hello.
    stick on req.payload_lv(43,1) if clienthello

    # Learn on response if server hello.
    stick store-response resp.payload_lv(43,1) if serverhello

    server s1 192.168.1.1:443
    server s2 192.168.1.1:443

Voir également : « stick-table », « stick on », section 11 sur les tables de persistance, et section 7 sur les listes de contrôle d’accès et l’extraction de modèles.

stick-table type <type> size <size> [expire <expire>] [args...]

stick-table type <type> size <size> [expire <expire>] [args...]

Configurez le tableau de persistance pour la section courante

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | oui

Cela sert à déclarer et configurer une table de persistance. Veuillez vous référer à la section 11.1 pour obtenir tous les détails et la liste des arguments pris en charge. Seuls le type et la taille sont obligatoires.

tcp-check comment <string>

tcp-check comment <string>

Définit un commentaire pour la règle tcp-check suivante, signalé dans les journaux en cas d’échec.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<string>  is the comment message to add in logs if the following tcp-check
          rule fails.

Il ne fonctionne qu’avec les règles connect, send et expect. Il est utile pour produire des rapports d’erreurs conviviaux.

Voir également : « option tcp-check », « tcp-check connect », « tcp-check send » et « tcp-check expect ».

tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]

tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
                  [ssl] [sni <sni>] [alpn <alpn>] [linger]
                  [proto <name>] [comment <msg>]

Ouvre une nouvelle connexion

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

default      Use default options of the server line to do the health
             checks. The server options are used only if not redefined.

port <expr>  if not set, check port or server port is used.
             It tells HAProxy where to open the connection to.
             <port> must be a valid TCP port source integer, from 1 to
             65535 or an sample-fetch expression.

addr <ip>    defines the IP address to do the health check.

send-proxy   send a PROXY protocol string

via-socks4   enables outgoing health checks using upstream socks4 proxy.

ssl          opens a ciphered connection

sni <sni>    specifies the SNI to use to do health checks over SSL.

alpn <alpn>  defines which protocols to advertise with ALPN. The protocol
             list consists in a comma-delimited list of protocol names,
             for instance: "http/1.1,http/1.0" (without quotes).
             If it is not set, the server ALPN is used.

proto <name> forces the multiplexer's protocol to use for this connection.
             It must be a TCP mux protocol and it must be usable on the
             backend side. The list of available protocols is reported in
             haproxy -vv.

linger       cleanly close the connection instead of using a single RST.

Lorsqu’une application est hébergée sur plusieurs ports TCP ou lorsqu’HAProxy effectue la répartition de charge de plusieurs services au sein d’un même backend, il est pertinent de vérifier chaque service individuellement avant de considérer un serveur comme opérationnel.

Lorsqu’aucun port TCP n’est configuré dans la ligne server ni dans la directive server port, alors la commande ’tcp-check connect port <port>’ doit être la première étape de la séquence.

Dans un ensemble de règles tcp-check, une règle « connect » est obligatoire ; il est également obligatoire de commencer l’ensemble de règles par une règle « connect ». Cette exigence vise à garantir que l’administrateur sait exactement ce qu’il fait.

Lorsqu’une connexion doit démarrer le jeu de règles, elle peut encore être précédée par des règles set-var, unset-var ou comment.

Exemples :

# check HTTP and HTTPs services on a server.
# first open port 80 thanks to server line port directive, then
# tcp-check opens port 443, ciphered and run a request on it:
option tcp-check
tcp-check connect
tcp-check send GET\ /\ HTTP/1.0\r\n
tcp-check send Host:\ haproxy.1wt.eu\r\n
tcp-check send \r\n
tcp-check expect rstring (2..|3..)
tcp-check connect port 443 ssl
tcp-check send GET\ /\ HTTP/1.0\r\n
tcp-check send Host:\ haproxy.1wt.eu\r\n
tcp-check send \r\n
tcp-check expect rstring (2..|3..)
server www 10.0.0.1 check port 80

# check both POP and IMAP from a single server:
option tcp-check
tcp-check connect port 110 linger
tcp-check expect string +OK\ POP3\ ready
tcp-check connect port 143
tcp-check expect string *\ OK\ IMAP4\ ready
server mail 10.0.0.1 check

Voir aussi : « option tcp-check », « tcp-check send », « tcp-check expect »

tcp-check expect [min-recv <int>] [comment <msg>]

tcp-check expect [min-recv <int>] [comment <msg>]
                 [ok-status <st>] [error-status <st>] [tout-status <st>]
                 [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                 [!] <match> <pattern>

Spécifiez les données à collecter et à analyser lors d’un contrôle d’état générique

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

min-recv  is optional and can define the minimum amount of data required to
          evaluate the current expect rule. If the number of received bytes
          is under this limit, the check will wait for more data. This
          option can be used to resolve some ambiguous matching rules or to
          avoid executing costly regex matches on content known to be still
          incomplete. If an exact string (string or binary) is used, the
          minimum between the string length and this parameter is used.
          This parameter is ignored if it is set to -1. If the expect rule
          does not match, the check will wait for more data. If set to 0,
          the evaluation result is always conclusive.

ok-status <st>     is optional and can be used to set the check status if
                   the expect rule is successfully evaluated and if it is
                   the last rule in the tcp-check ruleset. "L7OK", "L7OKC",
                   "L6OK" and "L4OK" are supported:
                     - L7OK : check passed on layer 7
                     - L7OKC: check conditionally passed on layer 7, set
                               server to NOLB state.
                     - L6OK : check passed on layer 6
                     - L4OK : check passed on layer 4
                    By default "L7OK" is used.

error-status <st>  is optional and can be used to set the check status if
                   an error occurred during the expect rule evaluation.
                   "L7OKC", "L7RSP", "L7STS", "L6RSP" and "L4CON" are
                   supported:
                     - L7OKC: check conditionally passed on layer 7, set
                               server to NOLB state.
                     - L7RSP: layer 7 invalid response - protocol error
                     - L7STS: layer 7 response error, for example HTTP 5xx
                     - L6RSP: layer 6 invalid response - protocol error
                     - L4CON: layer 1-4 connection problem
                   By default "L7RSP" is used.

tout-status <st>   is optional and can be used to set the check status if
                   a timeout occurred during the expect rule evaluation.
                   "L7TOUT", "L6TOUT", and "L4TOUT" are supported:
                     - L7TOUT: layer 7 (HTTP/SMTP) timeout
                     - L6TOUT: layer 6 (SSL) timeout
                     - L4TOUT: layer 1-4 timeout
                   By default "L7TOUT" is used.

on-success <fmt>   is optional and can be used to customize the
                   informational message reported in logs if the expect
                   rule is successfully evaluated and if it is the last rule
                   in the tcp-check ruleset. <fmt> is a Custom log format
                   (see section 8.2.6).

on-error <fmt>     is optional and can be used to customize the
                   informational message reported in logs if an error
                   occurred during the expect rule evaluation. <fmt> is a
                   Custom log format (see section 8.2.6).

status-code <expr> is optional and can be used to set the check status code
                   reported in logs, on success or on error. <expr> is a
                   standard HAProxy expression formed by a sample-fetch
                   followed by some converters.

<match>   is a keyword indicating how to look for a specific pattern in the
          response. The keyword may be one of "string", "rstring", "binary" or
          "rbinary".
          The keyword may be preceded by an exclamation mark ("!") to negate
          the match. Spaces are allowed between the exclamation mark and the
          keyword. See below for more details on the supported keywords.

<pattern> is the pattern to look for. It may be a string or a regular
          expression. If the pattern contains spaces, they must be escaped
          with the usual backslash ('\').
          If the match is set to binary, then the pattern must be passed as
          a series of hexadecimal digits in an even number. Each sequence of
          two digits will represent a byte. The hexadecimal digits may be
          used upper or lower case.

Les correspondances disponibles sont intentionnellement similaires à celles de leurs homologues http-check :

string <string>: test the exact string matches in the response buffer.
                  A health check response will be considered valid if the
                  response's buffer contains this exact string. If the
                  "string" keyword is prefixed with "!", then the response
                  will be considered invalid if the body contains this
                  string. This can be used to look for a mandatory pattern
                  in a protocol response, or to detect a failure when a
                  specific error appears in a protocol banner.

rstring <regex>: test a regular expression on the response buffer.
                  A health check response will be considered valid if the
                  response's buffer matches this expression. If the
                  "rstring" keyword is prefixed with "!", then the response
                  will be considered invalid if the body matches the
                  expression.

string-lf <fmt>: test a Custom log format match in the response's buffer.
                  A health check response will be considered valid if the
                  response's buffer contains the  string resulting of the
                  evaluation of <fmt>, which follows the Custom log format
                  rules described in section 8.2.6. If prefixed with "!",
                  then the response will be considered invalid if the
                  buffer contains the string.

binary <hexstring>: test the exact string in its hexadecimal form matches
                     in the response buffer. A health check response will
                     be considered valid if the response's buffer contains
                     this exact hexadecimal string.
                     Purpose is to match data on binary protocols.

rbinary <regex>: test a regular expression on the response buffer, like
                  "rstring". However, the response buffer is transformed
                  into its hexadecimal form, including NUL-bytes. This
                  allows using all regex engines to match any binary
                  content.  The hexadecimal transformation takes twice the
                  size of the original response. As such, the expected
                  pattern should work on at-most half the response buffer
                  size.

binary-lf <hexfmt>: test a Custom log format in its hexadecimal form match
                     in the response's buffer. A health check response will
                     be considered valid if the response's buffer contains
                     the hexadecimal string resulting of the evaluation of
                     <fmt>, which follows the Custom log format rules (see
                     section 8.2.6). If prefixed with "!", then the
                     response will be considered invalid if the buffer
                     contains the hexadecimal string. The hexadecimal
                     string is converted in a binary string before matching
                     the response's buffer.

Il est important de noter que les réponses seront limitées à une taille définie par l’option globale “tune.bufsize”, qui vaut par défaut 16384 octets. Ainsi, les réponses trop grandes peuvent ne pas contenir le motif obligatoire lors de l’utilisation de « string », « rstring » ou binaire. Si une réponse de grande taille est absolument nécessaire, il est possible de modifier la taille maximale par défaut en définissant la variable globale. Toutefois, il convient de garder à l’esprit que l’analyse de réponses très grandes peut consommer des cycles CPU, notamment lors de l’utilisation d’expressions régulières, et qu’il est toujours préférable de cibler les vérifications sur des ressources plus petites. En outre, dans son état actuel, la vérification ne détectera aucun texte ni expression régulière au-delà d’un caractère nul dans la réponse. De même, il n’est pas possible de demander une correspondance avec le caractère nul.

Exemples :

# perform a POP check
option tcp-check
tcp-check expect string +OK\ POP3\ ready

# perform an IMAP check
option tcp-check
tcp-check expect string *\ OK\ IMAP4\ ready

# look for the redis master server
option tcp-check
tcp-check send PING\r\n
tcp-check expect string +PONG
tcp-check send info\ replication\r\n
tcp-check expect string role:master
tcp-check send QUIT\r\n
tcp-check expect string +OK

Voir aussi : « option tcp-check », « tcp-check connect », « tcp-check send », « tcp-check send-binary », « http-check expect », tune.bufsize

tcp-check send <data> [comment <msg>]

tcp-check send <data> [comment <msg>]
tcp-check send-lf <fmt> [comment <msg>]

Spécifiez une chaîne ou un format de journal personnalisé à envoyer en tant que question lors d’un contrôle d’état générique

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

<data>         is the string that will be sent during a generic health
               check session.

<fmt>          is the Custom log format that will be sent, once evaluated,
               during a generic health check session (see section 8.2.6).

Exemples :

# look for the redis master server
option tcp-check
tcp-check send info\ replication\r\n
tcp-check expect string role:master

Voir aussi : « option tcp-check », « tcp-check connect », « tcp-check expect », « tcp-check send-binary », tune.bufsize

tcp-check send-binary <hexstring> [comment <msg>]

tcp-check send-binary <hexstring> [comment <msg>]
tcp-check send-binary-lf <hexfmt> [comment <msg>]

Spécifiez une chaîne de chiffres hexadécimaux ou un format de journal personnalisé en hexadécimal à envoyer sous forme de question binaire lors d’un contrôle d’état TCP brut

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

comment <msg>  defines a message to report if the rule evaluation fails.

<hexstring>    is the hexadecimal string that will be send, once converted
               to binary, during a generic health check session.

<hexfmt>       is the hexadecimal Custom log format that will be send, once
               evaluated and converted to binary, during a generic health
               check session (see section 8.2.6).

Exemples :

# redis check in binary
option tcp-check
tcp-check send-binary 50494e470d0a # PING\r\n
tcp-check expect binary 2b504F4e47 # +PONG

Voir aussi : « option tcp-check », « tcp-check connect », « tcp-check expect », « tcp-check send », tune.bufsize

tcp-check set-var(<var-name>[,<cond>...]) <expr>

tcp-check set-var(<var-name>[,<cond>...]) <expr>
tcp-check set-var-fmt(<var-name>[,<cond>...]) <fmt>

Cette opération définit le contenu d’une variable. La variable est déclarée en inline.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<var-name>   The name of the variable. Only "proc", "sess" and "check"
             scopes can be used. See section 2.8 about variables for details.

 <cond>      A set of conditions that must all be true for the variable to
             actually be set (such as "ifnotempty", "ifgt" ...). See the
             set-var converter's description for a full list of possible
             conditions.

 <expr>      Is a sample-fetch expression potentially followed by converters.

 <fmt>       This is the value expressed using Custom log format rules (see
             Custom log format in section 8.2.6).

Exemples :

tcp-check set-var(check.port) int(1234)
tcp-check set-var-fmt(check.name) "%H"

tcp-check unset-var(<var-name>)

tcp-check unset-var(<var-name>)

Libère une référence à une variable dans son contexte.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<var-name>   The name of the variable. Only "proc", "sess" and "check"
             scopes can be used. See section 2.8 about variables for details.

Exemples :

tcp-check unset-var(check.port)

tcp-request connection <action> <options...> [ { if | unless } <condition> ]

tcp-request connection <action> <options...> [ { if | unless } <condition> ]

Effectuer une action sur une connexion entrante en fonction d’une condition au niveau couche 4

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | non

Arguments :

<action>    defines the action to perform if the condition applies. See
            below.

<condition> is a standard layer4-only ACL-based condition (see section 7).

Immédiatement après l’acceptation d’une nouvelle connexion entrante, il est possible d’évaluer certaines conditions afin de décider si cette connexion doit être acceptée, rejetée ou si ses compteurs doivent être suivis. Ces conditions ne peuvent pas utiliser les contenus de données, car la connexion n’a pas encore été lue, et les tampons ne sont pas encore alloués. Cette fonctionnalité permet d’accepter ou de rejeter sélectivement et très rapidement des connexions provenant de diverses sources, avec une surcharge minimale. Si des contenus doivent être inspectés pour prendre la décision, il faut utiliser à la place les instructions « tcp-request content ».

Les règles « tcp-request connection » sont évaluées dans l’ordre exact de leur déclaration. Si aucune règle ne correspond ou s’il n’y a aucune règle, l’action par défaut consiste à accepter la connexion entrante. Il n’existe aucune limite spécifique au nombre de règles pouvant être insérées. Une règle peut éventuellement être suivie d’une condition basée sur une ACL, auquel cas elle n’est évaluée que si la condition est vraie.

La condition est évaluée juste avant l’exécution de l’action, et celle-ci est exécutée exactement une fois. Il n’y a donc aucun problème si une action modifie un élément vérifié dans le cadre de la condition. Cela signifie également que plusieurs actions peuvent dépendre de la même condition, de sorte que la première action qui modifie l’évaluation de la condition suffit à désactiver implicitement les actions restantes. Cette approche est utilisée, par exemple, lorsqu’il s’agit d’attribuer une valeur à une variable à partir de différentes sources lorsque celle-ci est vide.

Le premier mot-clé après « tcp-request connection » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour l’action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « TCP RqCon »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Notez que la condition “if/unless” est facultative. Si aucune condition n’est définie sur l’action, celle-ci est simplement exécutée sans condition. Cela peut être utile pour les actions “track-sc*” ainsi que pour modifier l’action par défaut en rejet.

Exemple : accepter toutes les connexions provenant d’hôtes listés blancs, rejeter les connexions trop rapides sans les compter, et suivre les connexions acceptées. Cela permet de limiter le débit des connexions provenant de sources abusives.

    tcp-request connection accepte si { src -f /etc/haproxy/whitelist.lst }
    tcp-request connection rejette si { src_conn_rate gt 10 }
    tcp-request connection track-sc0 src

Exemple : accepter toutes les connexions provenant d’hôtes autorisés, compter toutes les autres connexions et rejeter celles qui sont trop rapides. Cela entraîne le blocage des connexions abusives tant qu’elles ne ralentissent pas.

    tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
    tcp-request connection track-sc0 src
    tcp-request connection reject if { sc0_conn_rate gt 10 }

Exemple : activer le protocole PROXY pour le trafic provenant de tous les proxies connus.

    tcp-request connection expect-proxy layer4 if { src -f proxies.lst }

Voir section 7 concernant l’utilisation des ACL.

Voir aussi : « tcp-request session », « tcp-request content », « stick-table »

tcp-request content <action> [{if | unless} <condition>]

tcp-request content <action> [{if | unless} <condition>]

Effectuer une action sur une nouvelle session en fonction d’une condition au niveau couche 4 à 7

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

Arguments :

<action>    defines the action to perform if the condition applies. See
            below.

<condition> is a standard layer 4-7 ACL-based condition (see section 7).

Le contenu d’une requête peut être analysé à un stade précoce du traitement des requêtes appelé « inspection du contenu TCP ». Pendant ce stade, les règles basées sur les ACL sont évaluées à chaque mise à jour du contenu de la requête, jusqu’à ce qu’une règle « accept », « reject » ou « switch-mode » corresponde, ou que le délai d’inspection de la requête TCP expire sans règle correspondante.

La première différence entre ces règles et les règles « tcp-request connection » est que les règles « tcp-request content » peuvent utiliser le contenu pour prendre une décision. Le plus souvent, ces décisions portent sur une reconnaissance ou une validité de protocole. La deuxième différence est que les règles basées sur le contenu peuvent être utilisées aussi bien dans les frontaux que dans les backends. En cas de maintien de connexion HTTP avec le client, toutes les règles « tcp-request content » sont réévaluées, de sorte qu’HAProxy conserve une trace des compteurs persistants attribués par une règle « tcp-request connection » par rapport à une règle « tcp-request content », et vide tous les compteurs liés au contenu après le traitement d’une requête, afin qu’ils puissent être réévalués par les règles lors de la prochaine requête. Ceci est particulièrement important lorsque la règle suit certaines informations L7 ou lorsqu’elle est conditionnée par une ACL basée sur L7, car le suivi peut varier entre les requêtes.

Les règles basées sur le contenu sont évaluées dans l’ordre exact de leur déclaration. Si aucune règle ne correspond ou s’il n’y a aucune règle, l’action par défaut consiste à accepter les contenus. Aucune limite spécifique n’est imposée au nombre de règles pouvant être insérées.

Bien qu’il ne soit pas obligatoire, il est recommandé d’utiliser track-sc0 dans les règles « tcp-request connection », track-sc1 pour les règles « tcp-request content » dans le frontal, et track-sc2 pour les règles « tcp-request content » dans le backend, car cela rend la configuration plus lisible et plus facile à dépanner, mais il s’agit simplement d’une recommandation et tous les compteurs peuvent être utilisés partout.

Le premier mot-clé après « tcp-request content » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour l’action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « TCP RqCnt »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Notez que la condition “if/unless” est facultative. Si aucune condition n’est définie sur l’action, celle-ci est simplement exécutée sans condition. Cela peut être utile pour les actions “track-sc*” ainsi que pour modifier l’action par défaut en rejet.

Notez également qu’il est recommandé d’utiliser une règle « tcp-request session » pour suivre les informations qui ne dépendent pas du contenu au niveau 7, en particulier pour les frontaux HTTP. Certaines opérations HTTP sont effectuées au niveau de la session et peuvent entraîner un rejet prématuré des requêtes. Le suivi au niveau du contenu peut alors être perturbé dans de tels cas. Un avertissement est émis au démarrage afin, dans la mesure du possible, d’éviter une utilisation défaillante.

Il est tout à fait possible de correspondre au contenu au niveau 7 à l’aide de règles « tcp-request content » depuis un proxy TCP, car les correspondances ACL spécifiques à HTTP sont capables de parser préalablement le contenu d’un tampon avant d’extraire les données requises. Si le contenu tamponné ne se parse pas comme un message HTTP valide, alors l’ACL ne correspond pas. Le parseur utilisé à cet effet est exactement le même que celui utilisé pour tout autre traitement HTTP, si bien qu’il n’y a aucun risque de parser différemment. Dans un frontend HTTP ou un backend HTTP, il est garanti que le contenu HTTP sera toujours immédiatement disponible au moment de l’évaluation de la règle, car l’analyse HTTP est effectuée en phase précoce du traitement de la connexion, au niveau de la session. Toutefois, pour de tels proxies, l’utilisation de règles « http-request » est bien plus naturelle et recommandée.

Le suivi des informations layer7 est également possible, à condition que ces informations soient disponibles au moment du traitement de la règle. Le moteur de traitement des règles est capable d’attendre jusqu’à l’expiration du délai d’inspection lorsque les données à suivre ne sont pas encore disponibles.

Exemple :

tcp-request content use-service lua.deny if { src -f /etc/haproxy/blacklist.lst }

Exemple :

tcp-request content set-var(sess.my_var) src
tcp-request content set-var-fmt(sess.from) %[src]:%[src_port]
tcp-request content unset-var(sess.my_var2)

Exemple :

# Accept HTTP requests containing a Host header saying "example.com"
# and reject everything else. (Only works for HTTP/1 connections)
acl is_host_com hdr(Host) -i example.com
tcp-request inspect-delay 30s
tcp-request content accept if is_host_com
tcp-request content reject

# Accept HTTP requests containing a Host header saying "example.com"
# and reject everything else. (works for HTTP/1 and HTTP/2 connections)
acl is_host_com hdr(Host) -i example.com
tcp-request inspect-delay 5s
tcp-request content switch-mode http if HTTP
tcp-request content reject   # non-HTTP traffic is implicit here
...
http-request reject unless is_host_com

Exemple :

# reject SMTP connection if client speaks first
tcp-request inspect-delay 30s
acl content_present req.len gt 0
tcp-request content reject if content_present

# Forward HTTPS connection only if client speaks
tcp-request inspect-delay 30s
acl content_present req.len gt 0
tcp-request content accept if content_present
tcp-request content reject

Exemple :

# Track the last IP(stick-table type string) from X-Forwarded-For
tcp-request inspect-delay 10s
tcp-request content track-sc0 hdr(x-forwarded-for,-1)
# Or track the last IP(stick-table type ip|ipv6) from X-Forwarded-For
tcp-request content track-sc0 req.hdr_ip(x-forwarded-for,-1)

Exemple :

# track request counts per "base" (concatenation of Host+URL)
tcp-request inspect-delay 10s
tcp-request content track-sc0 base table req-rate

Exemple : suivre les compteurs par frontal et par backend, bloquer les abusateurs au niveau du frontal lorsque le backend détecte un abus (et signale GPC0).

    frontend http
        # Utiliser le compteur généralisé 0 dans SC0 comme compteur global d'abus
        # protégeant tous nos sites
        stick-table type ip size 1m expire 5m store gpc0
        tcp-request connection track-sc0 src
        tcp-request connection reject if { sc0_get_gpc0 gt 0 }
        ...
        use_backend http_dynamic if { path_end .php }

    backend http_dynamic
        # si une source effectue trop de requêtes trop rapidement vers ce site dynamique (suivi par SC1), bloquer cette source globalement au niveau du frontal.
        stick-table type ip size 1m expire 5m store http_req_rate(10s)
        acl click_too_fast sc1_http_req_rate gt 10
        acl mark_as_abuser sc0_inc_gpc0(http) gt 0
        tcp-request content track-sc1 src
        tcp-request content reject if click_too_fast mark_as_abuser

Voir section 7 concernant l’utilisation des ACL.

Voir également : « tcp-request connection », « tcp-request session », « tcp-request inspect-delay » et « http-request ».

tcp-request inspect-delay <timeout>

tcp-request inspect-delay <timeout>

Définir le délai maximal autorisé d’attente des données lors de l’inspection du contenu

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Les utilisateurs qui utilisent principalement HAProxy comme relais TCP s’inquiètent souvent du risque de transmettre tout type de protocole à un serveur sans analyse. Pour pouvoir analyser le contenu des requêtes, il est nécessaire de retarder temporairement les données, puis de les analyser. Cette directive permet simplement de retarder les données pendant au plus la durée spécifiée.

L’inspection du contenu TCP s’applique très tôt, lorsque la connexion atteint un frontal, puis très tôt lorsque la connexion est acheminée vers un backend. Cela signifie qu’une connexion peut subir un premier délai au niveau du frontal et un second délai au niveau du backend si les deux disposent de règles tcp-request.

Notez que, lors de l’inspection du contenu, HAProxy évaluera toutes les règles pour chaque nouveau morceau entrant, en tenant compte du fait que ces données sont partielles. Si aucune règle ne correspond avant le délai mentionné, une dernière vérification est effectuée à l’expiration, cette fois-ci en considérant que les contenus sont définitifs. Si aucun délai n’est défini, HAProxy ne patientera pas du tout et appliquera immédiatement un jugement fondé sur les informations disponibles. Évidemment, cela est peu susceptible d’être très utile et pourrait même être sujet à des conditions de course, aussi de telles configurations ne sont pas recommandées.

Notez que le délai d’inspection est raccourci en cas d’erreur de connexion ou d’arrêt, ou si le tampon de requête semble plein.

Dès qu’une règle correspond, la requête est libérée et poursuit son cours normalement. Si le délai d’expiration est atteint et qu’aucune règle ne correspond, la politique par défaut consiste à la laisser passer sans modification.

Pour la plupart des protocoles, il suffit de le définir à quelques secondes, car la plupart des clients envoient intégralement leur requête immédiatement après la connexion. Ajoutez 3 secondes ou plus pour couvrir les retransmissions TCP, mais pas davantage. Pour certains protocoles, il peut être pertinent d’utiliser des valeurs élevées, par exemple pour garantir que le client ne communique jamais avant le serveur (par exemple, SMTP), ou pour attendre que le client émette une communication avant de transmettre des données au serveur (par exemple, SSL). Notez que le délai d’expiration du client doit couvrir au moins le délai d’inspection, sinon il expirera en premier. Si le client ferme la connexion ou si la mémoire tampon est pleine, le délai expire immédiatement, car les contenus ne pourront plus évoluer.

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les proxies héritent cette valeur de leur section defaults.

Voir aussi : « tcp-request content accept », « tcp-request content reject », « timeout client ».

tcp-request session <action> [{if | unless} <condition>]

tcp-request session <action> [{if | unless} <condition>]

Effectuer une action sur une session validée en fonction d’une condition au niveau 5

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | oui | oui | non

Arguments :

<action>    defines the action to perform if the condition applies. See
            below.

<condition> is a standard layer5-only ACL-based condition (see section 7).

Une fois une session validée (c’est-à-dire après la fin de toutes les négociations), il est possible d’évaluer certaines conditions afin de décider si cette session doit être acceptée, rejetée ou si ses compteurs doivent être suivis. Ces conditions ne peuvent pas utiliser les contenus de données, car aucun tampon n’a encore été alloué et le traitement ne peut pas attendre à ce stade. Le cas d’usage principal consiste à copier certaines informations précoces dans des variables (puisqu’il est possible d’accéder aux variables au niveau de la session), ou à suivre certaines informations collectées après la négociation, telles que des éléments au niveau SSL (SNI, chiffres, CN du certificat client) ou des informations provenant de l’en-tête du protocole PROXY (par exemple, suivre une source transmise de cette manière). Les informations extraites peuvent ainsi être copiées dans une variable ou suivies à l’aide de règles « track-sc ». Bien entendu, il est également possible de décider de accept/reject comme pour les autres jeux de règles. La plupart des opérations effectuées ici pourraient également être réalisées dans des règles « tcp-request content », à ceci près que, en HTTP, ces règles sont évaluées pour chaque nouvelle requête, ce qui n’est pas toujours acceptable. Par exemple, une règle pourrait incrémenter un compteur à chaque évaluation. Il serait également possible qu’un pays soit déterminé par géolocalisation à partir de l’adresse IP source, affecté à une variable au niveau de la session, puis que l’adresse source soit réécrite à partir d’un en-tête HTTP pour toutes les requêtes. Si certaines données doivent être inspectées afin de prendre la décision, il convient alors d’utiliser les instructions « tcp-request content » à la place.

Les règles « tcp-request session » sont évaluées dans l’ordre exact de leur déclaration. Si aucune règle ne correspond ou s’il n’y a aucune règle, l’action par défaut consiste à accepter la session entrante. Il n’existe aucune limite spécifique au nombre de règles pouvant être insérées.

Le premier mot-clé après « tcp-request session » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour l’action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées de « TCP RqSes »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Notez que la condition “if/unless” est facultative. Si aucune condition n’est définie sur l’action, celle-ci est simplement exécutée sans condition. Cela peut être utile pour les actions “track-sc*” ainsi que pour modifier l’action par défaut en rejet.

Exemple : suivre l’adresse source d’origine par défaut, ou celle annoncée dans l’en-tête PROXY pour les connexions provenant des proxies locaux. La première règle au niveau de la connexion permet la réception du protocole PROXY pour ces dernières, la deuxième règle suit l’adresse que nous décidons de conserver après décodage éventuel.

    tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
    tcp-request session track-sc0 src

Exemple : accepter toutes les sessions provenant d’hôtes listés blancs, rejeter les sessions trop rapides sans les compter, et suivre les sessions acceptées. Cela permet de limiter le débit des sessions provenant de sources abusives.

    tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
    tcp-request session reject if { src_sess_rate gt 10 }
    tcp-request session track-sc0 src

Exemple : accepter toutes les sessions provenant d’hôtes listés blancs, compter toutes les autres sessions et rejeter celles qui sont trop rapides. Cela entraîne le blocage des connexions abusives tant qu’elles ne ralentissent pas.

    tcp-request session accept if { src -f /etc/haproxy/whitelist.lst }
    tcp-request session track-sc0 src
    tcp-request session reject if { sc0_sess_rate gt 10 }

Voir section 7 concernant l’utilisation des ACL.

Voir aussi : « tcp-request connection », « tcp-request content », « stick-table »

tcp-response content <action> [{if | unless} <condition>]

tcp-response content <action> [{if | unless} <condition>]

Effectuer une action sur une réponse de session en fonction d’une condition au niveau couche 4-7

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | non | oui | oui

Arguments :

<action>    defines the action to perform if the condition applies. See
            below.

<condition> is a standard layer 4-7 ACL-based condition (see section 7).

Le contenu de la réponse peut être analysé à un stade précoce du traitement de la réponse, appelé « inspection du contenu TCP ». Pendant cette phase, les règles basées sur les ACL sont évaluées à chaque mise à jour du contenu de la réponse, jusqu’à ce qu’une règle finale corresponde, ou qu’une durée d’attente pour l’inspection du contenu TCP soit définie et expire sans qu’aucune règle ne corresponde.

Souvent, ces décisions tiennent compte de la reconnaissance ou de la validité d’un protocole.

Les règles basées sur le contenu sont évaluées dans l’ordre exact de leur déclaration. Si aucune règle ne correspond ou s’il n’y a aucune règle, l’action par défaut consiste à accepter les contenus. Aucune limite spécifique n’est imposée au nombre de règles pouvant être insérées.

Le premier mot-clé après « tcp-response content » dans la syntaxe est l’action de la règle, éventuellement suivi d’un nombre variable d’arguments pour cette action. Les actions prises en charge ainsi que leurs syntaxes respectives sont énumérées dans section 4.3 « Actions » (rechercher les actions marquées par « TCP RsCnt »).

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les règles définies dans la section defaults sont évaluées avant celles de la section proxy associée. Pour éviter les ambigüités, dans ce cas, une même section defaults ne peut pas être utilisée par des proxies possédant la capacité frontend et par des proxies possédant la capacité backend. Cela signifie qu’une section listen ne peut pas utiliser une section defaults définissant de telles règles.

Notez que la condition “if/unless” est facultative. Si aucune condition n’est définie sur l’action, celle-ci est simplement exécutée sans condition. Cela peut être utile pour modifier l’action par défaut en rejet.

Plusieurs types d’actions sont pris en charge :

Il est tout à fait possible de correspondre au contenu au niveau 7 à l’aide des règles « tcp-response content », mais il est alors essentiel de s’assurer qu’une réponse complète a été mise en mémoire tampon, faute de quoi aucun contenu ne correspondra. Pour y parvenir, la meilleure solution consiste à détecter le protocole HTTP pendant la période d’inspection.

Voir section 7 concernant l’utilisation des ACL.

Voir également : « tcp-request content », « tcp-response inspect-delay »

tcp-response inspect-delay <timeout>

tcp-response inspect-delay <timeout>

Définir le délai maximal autorisé d’attente d’une réponse lors de l’inspection du contenu

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui(!) | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Cette directive n’est disponible que dans les sections defaults nommées, et non dans les sections anonymes. Les proxies héritent cette valeur de leur section defaults.

Voir également : « tcp-response content », « tcp-request inspect-delay ».

timeout check <timeout>

timeout check <timeout>

Définir un délai d’expiration supplémentaire pour la vérification, mais uniquement après qu’une connexion a déjà été établie.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Si défini, HAProxy utilise min(“délai d’expiration connect”, “inter”) comme délai d’expiration de connexion pour les vérifications et “délai d’expiration vérification” comme délai d’expiration de lecture supplémentaire. La fonction min est utilisée afin que les utilisateurs configurés avec des délais d’expiration de connexion très longs (par exemple, ceux qui en avaient besoin en raison de la file d’attente ou du tarpit) ne ralentissent pas leurs vérifications. (Veuillez noter qu’il n’existe aucune raison valable de définir des délais d’expiration de connexion aussi longs, car “délai d’expiration file d’attente” et “délai d’expiration tarpit” peuvent toujours être utilisés pour éviter cela).

Si « timeout check » n’est pas défini, HAProxy utilise « inter » pour le délai d’expiration complet de la vérification (connexion + lecture), exactement comme toutes les versions <1.3.15.

Dans la plupart des cas, le traitement de la requête de vérification est bien plus simple et rapide que celui des requêtes normales, et les utilisateurs souhaitent souvent éliminer les serveurs en retard ; ce délai d’expiration doit donc être inférieur à « timeout server ».

Ce paramètre est spécifique aux backends, mais peut être défini une fois pour tous dans les sections « defaults ». Il s’agit en réalité l’une des solutions les plus simples pour ne pas l’oublier.

Voir également : « timeout connect », « timeout queue », « timeout server », « timeout tarpit ».

timeout client <timeout>

timeout client <timeout>

Définir le délai maximal d’inactivité du côté client.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Le délai d’expiration inactif s’applique lorsque le client est censé confirmer ou envoyer des données. En mode HTTP, ce délai est particulièrement important à prendre en compte pendant la première phase, lorsque le client envoie la requête, ainsi que pendant la réponse, lorsqu’il lit les données envoyées par le serveur. Toutefois, pour la première phase, il est préférable de définir « timeout http-request » afin de mieux protéger HAProxy contre les attaques du type Slowloris. La valeur est spécifiée en millisecondes par défaut, mais peut être exprimée dans toute autre unité si le nombre est suivi de l’unité, comme indiqué en haut de ce document. En mode TCP (et dans une moindre mesure en mode HTTP), il est fortement recommandé que le délai d’expiration client reste égal au délai d’expiration serveur afin d’éviter des situations complexes à déboguer. Il est bon de prévoir une couverture d’une ou plusieurs pertes de paquets TCP en définissant des délais légèrement supérieurs à des multiples de 3 secondes (par exemple 4 ou 5 secondes). Si des flux longs coexistent avec des flux courts (par exemple WebSocket et HTTP), il peut être pertinent de considérer « timeout tunnel », qui remplace « timeout client » et « timeout server » pour les tunnels, ainsi que « timeout client-fin » pour les connexions demi-fermées.

Ce paramètre est spécifique aux frontaux, mais peut être défini une fois pour tous dans les sections « defaults ». Il s’agit en réalité l’une des solutions les plus simples pour ne pas l’oublier. Un délai d’expiration non spécifié entraîne un délai d’expiration infini, ce qui n’est pas recommandé. Une telle utilisation est acceptée et fonctionne, mais provoque un avertissement au démarrage, car elle peut entraîner un accumulation de sessions expirées dans le système si les délais d’expiration du système ne sont pas configurés non plus.

Voir également : « timeout server », « timeout tunnel », « timeout http-request ».

timeout client-fin <timeout>

timeout client-fin <timeout>

Définir le délai d’expiration d’inactivité du côté client pour les connexions demi-fermées.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Le délai d’expiration d’inactivité s’applique lorsque le client est censé confirmer ou envoyer des données alors qu’une direction est déjà fermée. Ce délai diffère de « timeout client » car il ne s’applique qu’aux connexions dont une direction est fermée. Cette fonction est particulièrement utile pour éviter de maintenir les connexions dans l’état FIN_WAIT trop longtemps lorsque les clients ne se déconnectent pas correctement. Ce problème est particulièrement fréquent avec des connexions longues, telles que RDP ou WebSocket. Notez que ce délai peut remplacer « timeout tunnel » lorsque la connexion est fermée dans une seule direction. Il s’applique aux connexions HTTP/2 inactives une fois qu’un cadre GOAWAY a été envoyé, ce qui indique souvent une attente de fermeture rapide de la connexion.

Ce paramètre est spécifique aux frontaux, mais peut être défini une fois pour tous dans les sections « defaults ». Par défaut, il n’est pas défini, de sorte que les connexions demi-ouvertes utilisent les autres délais d’expiration (timeout.client ou timeout.tunnel).

Voir également : « timeout client », « timeout server-fin » et « timeout tunnel ».

timeout client-hs <timeout>

timeout client-hs <timeout>

Définir le délai maximal d’attente pour la finalisation de la négociation TLS du client. Cette option est utilisable pour les connexions TCP et QUIC.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Si ce délai d’expiration de handshake n’est pas défini, il s’agit du délai d’expiration client utilisé à la place.

timeout connect <timeout>

timeout connect <timeout>

Définir le temps maximal d’attente pour qu’une tentative de connexion à un serveur aboutisse.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Si le serveur est situé sur le même LAN que HAProxy, la connexion doit être immédiate (moins de quelques millisecondes). En tout état de cause, il est recommandé de prévoir un délai d’expiration légèrement supérieur à un ou plusieurs multiples de 3 secondes (par exemple 4 ou 5 secondes) afin de couvrir une ou plusieurs pertes de paquets TCP. Par défaut, le délai d’expiration de connexion préconfigure également les délais d’expiration de file d’attente et de tarpit à la même valeur, si ces derniers n’ont pas été spécifiés.

Ce paramètre est spécifique aux backends, mais peut être défini une fois pour tous dans les sections « defaults ». Il s’agit en réalité l’une des solutions les plus simples pour ne pas l’oublier. Un délai d’expiration non spécifié entraîne un délai d’expiration infini, ce qui n’est pas recommandé. Une telle utilisation est acceptée et fonctionne, mais provoque un avertissement au démarrage, car elle peut entraîner un accumulation de sessions défaillantes dans le système si les délais d’expiration du système ne sont pas configurés non plus.

Voir également : « timeout check », « timeout queue », « timeout server », « timeout tarpit ».

timeout http-keep-alive <timeout>

timeout http-keep-alive <timeout>

Définir le délai maximal autorisé d’attente pour la venue d’une nouvelle requête HTTP

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Par défaut, le délai d’expiration d’attente d’une nouvelle requête en cas de maintien de la connexion (keep-alive) est défini par « timeout http-request ». Toutefois, cela n’est pas toujours pratique, car certaines personnes souhaitent des délais d’expiration très courts pour libérer les connexions plus rapidement, tandis que d’autres préfèrent des délais plus longs, mais souhaitent tout de même des délais courts une fois la requête en cours.

Le délai d’expiration « http-keep-alive » répond à ces besoins. Il détermine la durée d’attente d’une nouvelle requête HTTP après l’envoi d’une réponse. Dès que le premier octet de la requête est détecté, le délai d’expiration « http-request » est utilisé pour attendre la réception complète de la requête. Notez que les lignes vides précédant une nouvelle requête ne réinitialisent pas le délai d’expiration et ne sont pas comptées comme une nouvelle requête.

Il existe également une autre différence entre les deux délais d’expiration : lorsque la connexion expire pendant le délai d’expiration http-keep-alive, aucune erreur n’est renvoyée, la connexion se ferme simplement. Si la connexion expire pendant le délai d’expiration “http-request” en attendant la fin d’une requête, une erreur HTTP 408 est renvoyée au client avant la fermeture de la connexion, sauf si l’option “option http-ignore-probes” est définie dans le frontal.

En général, « timeout http-keep-alive » doit être utilisé pour empêcher les clients de maintenir une connexion inactif trop longtemps sur des sites recevant un grand nombre de connexions courtes. Cela peut être réalisé en définissant la valeur à quelques dizaines à plusieurs centaines de millisecondes dans HTTP/1.1.. Cela fermera la connexion après que le client ait demandé une page, sans avoir à la maintenir ouverte pour attendre une nouvelle activité du client. Dans ce scénario, une nouvelle activité du navigateur entraînera une nouvelle négociation au niveau TCP et/ou SSL. Un cas d’utilisation courant est celui des sites HTTP qui ne servent qu’une redirection vers la page HTTPS. Ces connexions ne doivent pas rester inactives trop longtemps, car elles ne seront pas réutilisées, sauf peut-être pour télécharger une favicon.

Un autre cas d’utilisation est l’exact opposé : certaines sites souhaitent autoriser les clients à réutiliser des connexions inactives pendant une longue durée (par exemple 30 secondes à une minute), mais ne veulent pas attendre aussi longtemps pour la première requête, afin d’éviter une vector d’attaque très peu coûteux. Dans ce cas, le délai d’expiration http-keep-alive serait défini sur une valeur élevée, mais le délai d’expiration http-request resterait faible (quelques secondes).

Lorsqu’il est défini à une valeur très faible, les requêtes supplémentaires qui ne sont pas en pipeline risquent d’être traitées sur une autre connexion, sauf si les requêtes sont véritablement en pipeline, ce qui est très rare avec HTTP/1.1 (les requêtes envoyées bout à bout sans attendre de réponse). La plupart des implémentations de HTTP/1.1 envoient une requête, attendent la réponse, puis envoient une autre requête. Une valeur faible ici pour HTTP/1.1 peut être avantageuse pour réduire l’utilisation de mémoire et de sockets sur des sites comptant des centaines de milliers de clients, au prix d’une augmentation des coûts de calcul liés à l’établissement de connexion.

Une attention particulière doit être portée aux valeurs faibles lors de la gestion de HTTP/2.. La nature de HTTP/2 consiste à multiplexer les requêtes sur une connexion afin de réduire les surcoûts liés à la reconnexion au niveau des couches TCP et/ou SSL. Le protocole utilise également des trames de contrôle qui réagissent mal à la fermeture prématurée des connexions TCP, situation extrêmement rare pouvant entraîner des réponses tronquées lorsque les données sont perdues en transit après avoir quitté HAProxy (ce qui empêche même la journalisation d’une erreur). Une valeur basse suggérée pour HTTP/2 serait d’environ 4 secondes. Cela empêche la plupart des implémentations modernes de keep-alive de maintenir inutilement des connexions obsolètes, tout en permettant aux requêtes ultérieures de réutiliser la connexion. Toutefois, cette valeur doit être ajustée selon les besoins et ne constitue qu’un point de départ.

Si ce paramètre n’est pas défini, le délai d’expiration « http-request » s’applique ; si les deux ne sont pas définis, le délai d’expiration « timeout client » s’applique tout de même au niveau inférieur. Il doit être défini dans le frontal pour prendre effet, sauf si le frontal est en mode TCP, auquel cas le délai d’expiration du backend HTTP sera utilisé.

Voir également : « timeout http-request », « timeout client ».

timeout http-request <timeout>

timeout http-request <timeout>

Définir le délai maximal autorisé d’attente pour une requête HTTP complète

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Afin d’offrir une protection contre les attaques DoS, il peut être nécessaire de réduire le délai d’expiration maximal accepté pour recevoir une requête HTTP complète, sans affecter le délai d’expiration client. Cela permet de se protéger contre les connexions établies sur lesquelles aucune donnée n’est transmise. Le délai d’expiration client ne peut offrir une protection efficace contre ce type d’abus, car il s’agit d’un délai d’inactivité, ce qui signifie qu’une attaque consistant à envoyer un caractère de temps à autre ne déclenchera pas le délai. Grâce au délai d’expiration de requête HTTP, quelle que soit la vitesse à laquelle le client tape, la requête sera interrompue si elle n’est pas complète dans les délais. Lorsque le délai expire, une réponse HTTP 408 est envoyée au client pour l’informer du problème, puis la connexion est fermée. Les journaux rapporteront des codes de terminaison « cR ». Certains navigateurs récents rencontrent des problèmes avec ce comportement standard et bien documenté, il peut donc être nécessaire de masquer le code 408 en utilisant « option http-ignore-probes » ou « errorfile 408 /dev/null ». Pour plus de détails, consulter les explications concernant le code de terminaison « cR » dans la section 8.5 de .

Par défaut, ce délai d’expiration s’applique uniquement à la partie en-tête de la requête, et non aux données. Dès que la ligne vide est reçue, ce délai d’expiration n’est plus utilisé. Lorsqu’il est combiné avec « option http-buffer-request », ce délai d’expiration s’applique également au corps de la requête. Il est réutilisé sur les connexions keep-alive pour attendre une deuxième requête si « timeout http-keep-alive » n’est pas défini.

En général, il suffit de le définir à quelques secondes, car la plupart des clients envoient entièrement la requête immédiatement après la connexion. Ajoutez 3 secondes ou plus pour couvrir les retransmissions TCP, mais pas davantage. Une valeur très faible (par exemple 50 ms) fonctionne généralement sur les réseaux locaux, à condition qu’il n’y ait pas de perte de paquets. Cela empêche les utilisateurs d’envoyer des requêtes HTTP brutes via telnet.

Si ce paramètre n’est pas défini, le délai d’expiration client s’applique toujours entre chaque tranche de la requête entrante. Il doit être configuré dans le frontal pour prendre effet, sauf si le frontal est en mode TCP, auquel cas le délai d’expiration du backend HTTP sera utilisé.

Voir également : « errorfile », « http-ignore-probes », « timeout http-keep-alive » et « timeout client », « option http-buffer-request ».

timeout queue <timeout>

timeout queue <timeout>

Définir le temps maximal d’attente dans la file d’attente pour qu’un slot de connexion devienne disponible

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Lorsque la limite maxconn d’un serveur est atteinte, les connexions sont placées en attente dans une file d’attente, qui peut être spécifique au serveur ou globale au backend. Afin de ne pas attendre indéfiniment, un délai d’expiration est appliqué aux requêtes en attente dans la file. Si ce délai d’expiration est atteint, la requête est considérée comme quasi impossible à traiter, elle est donc abandonnée et un code d’erreur 503 est renvoyé au client.

L’instruction « timeout queue » permet de définir le délai d’expiration maximal autorisé pour une requête en attente dans une file d’attente. Si non spécifié, la même valeur que le délai d’expiration de connexion du backend (« timeout connect ») est utilisée, afin de maintenir la compatibilité descendante avec les versions antérieures ne disposant pas de paramètre « timeout queue ».

Voir également : « timeout connect ».

timeout server <timeout>

timeout server <timeout>

Définir le délai maximal d’inactivité du côté serveur.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Le délai d’expiration d’inactivité s’applique lorsque le serveur est censé reconnaître une requête ou envoyer des données. En mode HTTP, ce délai est particulièrement important à prendre en compte pendant la première phase de la réponse du serveur, lorsqu’il doit envoyer les en-têtes, car il représente directement le temps de traitement du serveur pour la requête. Pour déterminer quelle valeur utiliser, il est souvent pertinent de commencer par définir les délais de réponse jugés inacceptables, puis de consulter les journaux pour observer la répartition des temps de réponse, et d’ajuster la valeur en conséquence.

La valeur est spécifiée en millisecondes par défaut, mais peut être exprimée dans toute autre unité si le nombre est suivi de l’unité, comme indiqué en haut de ce document. En mode TCP (et, dans une moindre mesure, en mode HTTP), il est fortement recommandé que le délai d’expiration client reste égal au délai d’expiration serveur afin d’éviter des situations complexes à déboguer. Quelle que soit la durée de réponse attendue du serveur, il est bon de prévoir au moins une ou plusieurs pertes de paquets TCP en définissant des délais d’expiration légèrement supérieurs à des multiples de 3 secondes (par exemple, au moins 4 ou 5 secondes). Si des flux longs coexistent avec des flux courts (par exemple, WebSocket et HTTP), il peut être pertinent de considérer « timeout tunnel », qui remplace « timeout client » et « timeout server » pour les tunnels.

Ce paramètre est spécifique aux backends, mais peut être défini une fois pour tous dans les sections « defaults ». Il s’agit en réalité l’une des solutions les plus simples pour ne pas l’oublier. Un délai d’expiration non spécifié entraîne un délai d’expiration infini, ce qui n’est pas recommandé. Une telle utilisation est acceptée et fonctionne, mais provoque un avertissement au démarrage, car elle peut entraîner un accumulation de sessions expirées dans le système si les délais d’expiration du système ne sont pas configurés non plus.

Voir également : « timeout client » et « timeout tunnel ».

timeout server-fin <timeout>

timeout server-fin <timeout>

Définir le délai d’expiration d’inactivité du côté serveur pour les connexions demi-fermées.

Peut être utilisé dans les contextes suivants : tcp, http, log

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Le délai d’expiration d’inactivité s’applique lorsque le serveur est censé reconnaître ou envoyer des données alors qu’une direction de la connexion est déjà fermée. Ce délai diffère de « timeout server » car il ne s’applique qu’aux connexions dont une direction est fermée. Cette fonction est particulièrement utile pour éviter de maintenir les connexions dans l’état FIN_WAIT trop longtemps lorsque le serveur distant ne se déconnecte pas correctement. Ce problème est particulièrement fréquent avec des connexions longues telles que RDP ou WebSocket. Notez que ce délai peut remplacer « timeout tunnel » lorsque la connexion se ferme dans une seule direction. Ce paramètre a été ajouté pour complétude, mais dans la plupart des cas, il ne devrait pas être nécessaire.

Ce paramètre est spécifique aux backends, mais peut être défini une fois pour tous dans les sections « defaults ». Par défaut, il n’est pas configuré, de sorte que les connexions demi-ouvertes utilisent les autres délais d’expiration (timeout.server ou timeout.tunnel).

Voir également : « timeout client-fin », « timeout server » et « timeout tunnel ».

timeout tarpit <timeout>

timeout tarpit <timeout>

Définir la durée pendant laquelle les connexions tarpittées seront maintenues

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<timeout> is the tarpit duration specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Lorsqu’une connexion est soumise à un tarpit via la directive « http-request tarpit », elle reste ouverte sans activité pendant une durée déterminée, puis est fermée. La directive « timeout tarpit » définit la durée pendant laquelle elle reste ouverte.

La valeur est spécifiée en millisecondes par défaut, mais peut être exprimée dans toute autre unité si le nombre est suivi de l’unité, comme indiqué en haut du présent document. Si non spécifiée, la même valeur que le délai d’expiration de connexion du backend (“timeout connect”) est utilisée, pour assurer la compatibilité descendante avec les versions antérieures ne disposant pas du paramètre “timeout tarpit”.

Voir également : « timeout connect ».

timeout tunnel <timeout>

timeout tunnel <timeout>

Définir le délai maximal d’inactivité côté client et côté serveur pour les tunnels.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Le délai d’expiration du tunnel s’applique lorsque une connexion bidirectionnelle est établie entre un client et un serveur, et que la connexion reste inactive dans les deux sens. Ce délai d’expiration remplace les délais d’expiration du client et du serveur une fois que la connexion devient un tunnel. En TCP, ce délai d’expiration est utilisé dès qu’aucun analyseur n’est attaché à l’une des connexions (par exemple, lorsque des règles de contenu TCP sont acceptées). En HTTP, ce délai d’expiration est utilisé lorsque la connexion est mise à niveau (par exemple, lors du passage au protocole WebSocket, ou lors du transfert d’une requête CONNECT vers un proxy), ou après la première réponse lorsque l’option keepalive/close n’est pas spécifiée.

Étant donné que ce délai d’expiration est généralement utilisé en conjonction avec des connexions longues, il est généralement recommandé de définir également « timeout client-fin » afin de gérer le cas où un client disparaît soudainement du réseau sans reconnaître la fermeture, ou en envoyant une fermeture sans reconnaître les données en attente. Cela peut survenir dans des réseaux bruyants où des pare-feu sont présents, et est détecté par la présence d’un grand nombre de sessions en état FIN_WAIT.

La valeur est spécifiée en millisecondes par défaut, mais peut être exprimée dans toute autre unité si le nombre est suivi de l’unité, comme indiqué en haut de ce document. Quel que soit le délai d’inactivité normal attendu, il est recommandé de prévoir au moins une ou plusieurs pertes de paquets TCP en définissant des délais d’expiration légèrement supérieurs à des multiples de 3 secondes (par exemple, au moins 4 ou 5 secondes).

Ce paramètre est spécifique aux backends, mais peut être défini une fois pour tous dans les sections « defaults ». Il s’agit en réalité l’une des solutions les plus simples pour ne pas l’oublier.

Exemple :

defaults http
    option http-server-close
    timeout connect 5s
    timeout client 30s
    timeout client-fin 30s
    timeout server 30s
    timeout tunnel  1h    # timeout to use with WebSocket and CONNECT

Voir aussi : « timeout client », « timeout client-fin », « timeout server ».

transparent (deprecated)

transparent (deprecated)

Activer le proxy transparent côté client

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | non | oui | oui

Arguments : aucun

Ce mot-clé a été introduit afin de permettre une persistance au niveau 7 aux répartiteurs de charge au niveau 3. L’idée consiste à exploiter la capacité du système d’exploitation à rediriger une connexion entrante provenant d’une adresse distante vers un processus local (ici HAProxy), et à faire en sorte que ce processus connaisse l’adresse initialement demandée. Lorsque cette option est utilisée, les sessions sans cookies seront acheminées vers l’adresse IP d’origine de la requête entrante (qui doit correspondre à celle d’un autre équipement), tandis que les requêtes avec cookies seront toujours acheminées vers le serveur approprié.

Le mot-clé « transparent » est obsolète ; utilisez plutôt « option transparent ».

Notez qu’en dépit d’une croyance répandue, cette option ne fait pas que HAProxy présente l’adresse IP du client au serveur lors de l’établissement de la connexion.

Voir également : « option transparent »

unique-id-format <fmt>

unique-id-format <fmt>

Générez un identifiant unique pour chaque requête.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | oui

Arguments :

<fmt>   is a Custom log format string (see section 8.2.6).

Ce mot-clé crée un identifiant pour chaque requête en utilisant le format de journalisation personnalisé. Un identifiant unique est utile pour suivre une requête traversant plusieurs composants d’une infrastructure complexe. L’identifiant nouvellement créé peut également être journalisé à l’aide de l’alias %ID dans la chaîne de format de journalisation personnalisé.

Le format doit être composé d’éléments garantissant l’unicité lorsqu’ils sont combinés. Par exemple, si plusieurs instances HAProxy sont impliquées, il peut être important d’inclure le nom du nœud. Il est souvent nécessaire de journaliser les adresses et ports source et destination de la connexion entrante. Notez qu’étant donné qu’une même connexion peut être utilisée pour plusieurs requêtes, inclure un compteur de requêtes peut aider à les distinguer. De même, une horodatage peut protéger contre un dépassement du compteur. Journaliser l’identifiant du processus évite les conflits après une redémarrage du service.

Il est recommandé d’utiliser la notation hexadécimale pour de nombreux champs, car elle les rend plus compacts et économise de l’espace dans les journaux.

Pour les connexions régulières, le format configuré dans le frontal est utilisé pour générer l’ID unique. Pour les contrôles d’état, le format du backend est utilisé lors de l’utilisation de la directive « unique-id » au sein d’une règle tcp-check ou http-check.

Exemple :

unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid

will generate:

       7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A

Voir également : « unique-id-header »

unique-id-header <name>

unique-id-header <name>

Ajoutez un en-tête d’ID unique dans la requête HTTP.

Peut être utilisé dans les contextes suivants : http

Peut être utilisé dans les sections : defaults | frontal | listen | backend oui | oui | oui | non

Arguments :

<name>   is the name of the header.

Ajoutez un en-tête unique-id à la requête HTTP envoyée au serveur, en utilisant le format unique-id-format. Cela ne peut pas fonctionner si le format unique-id-format n’existe pas.

Exemple :

    unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
    unique-id-header X-Unique-ID

    will generate:

       X-Unique-ID: 7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A

See also: "unique-id-format"

use_backend <backend> [{if | unless} <condition>]

use_backend <backend> [{if | unless} <condition>]

Passez à un backend spécifique if/unless lorsque une condition basée sur une ACL est remplie.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | oui | oui | non

Arguments :

<backend>   is the name of a valid backend or "listen" section, or a
            Custom log format resolving to a backend name (see Custom
            Log Format in section 8.2.6).

<condition> is a condition composed of ACLs, as described in section 7. If
            it is omitted, the rule is unconditionally applied.

Lors du commutateur de contenu, les connexions arrivent sur un frontal et sont ensuite acheminées vers divers backends selon un ensemble de conditions. La relation entre ces conditions et les backends est décrite à l’aide du mot-clé “use_backend”. Bien qu’il soit normalement utilisé avec le traitement HTTP, il peut également être utilisé en TCP pur, soit sans contenu en utilisant des ACLs sans état (par exemple, validation de l’adresse source), soit combiné avec une règle « tcp-request » pour attendre une partie du contenu.

Il peut y avoir autant de règles “use_backend” que souhaité. Toutes ces règles sont évaluées dans l’ordre de déclaration, et la première qui correspond attribue le backend. Cela reste valable même si le backend est considéré comme hors service. Toutefois, si une règle correspondante cible un backend désactivé ou non publié, elle est ignorée et l’évaluation des règles se poursuit.

Dans la première forme, le backend sera utilisé si la condition est remplie. Dans la deuxième forme, le backend sera utilisé si la condition n’est pas remplie. Si aucune condition n’est valide, le backend défini avec “default_backend” sera utilisé, à moins qu’il ne soit désactivé ou non publié. Si aucun backend par défaut n’est disponible, les serveurs de la même section sont utilisés (dans le cas d’une section « listen ») ou, dans le cas d’un frontal, aucun serveur n’est utilisé et une réponse 503 service unavailable est renvoyée.

Notez qu’il est possible de passer d’un frontend TCP à un backend HTTP. Dans ce cas, soit le frontend a déjà vérifié que le protocole est HTTP, auquel cas le traitement du backend suit immédiatement, soit le backend attend qu’une requête HTTP complète soit reçue. Cette fonctionnalité est utile lorsque un frontend doit déchiffrer plusieurs protocoles sur un même port, dont l’un est HTTP.

Lorsque <backend> est un nom simple, il est résolu au moment de la configuration, et une erreur est signalée si le backend spécifié n’existe pas. Si <backend> est un format d’enregistrement personnalisé, aucune vérification ne peut être effectuée au moment de la configuration, de sorte que le nom du backend est résolu dynamiquement à l’exécution. Si le nom de backend résultant ne correspond à aucun backend valide, aucune autre règle n’est évaluée, et la directive default_backend est appliquée à la place. Notez qu’en cas d’utilisation de noms de backend dynamiques, il est fortement recommandé d’utiliser un préfixe que aucun autre backend n’utilise afin d’assurer qu’un backend non autorisé ne puisse pas être imposé par la requête.

Il est à noter que les règles “use_backend” portant un nom explicite sont utilisées pour détecter l’association entre les frontaux et les backends afin de calculer le paramètre “fullconn” du backend. Cette opération ne peut pas être réalisée pour les noms dynamiques.

Voir également : “default_backend”, « tcp-request », « fullconn », « log-format » et section 7 concernant les ACL.

use-fcgi-app <name>

use-fcgi-app <name>

Définit l’application FastCGI à utiliser pour le backend.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<name>    is the name of the FastCGI application to use.

Consultez section 10.1 pour plus de détails sur la configuration de l’application FastCGI.

use-server <server> if <condition>

use-server <server> if <condition>
use-server <server> unless <condition>

Utilisez uniquement un serveur spécifique if/unless lorsque une condition basée sur une ACL est remplie.

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

Arguments :

<server>    is the name of a valid server in the same backend section
            or a Custom log format string resolving to a server name
            (see section 8.2.6).

<condition> is a condition composed of ACLs, as described in section 7.

Par défaut, les connexions qui arrivent à un backend sont réparties en charge entre les serveurs disponibles selon l’algorithme configuré, sauf si un mécanisme de persistance, tel qu’un cookie, est utilisé et détecté dans la requête.

Parfois, il est utile de rediriger une requête particulière vers un serveur spécifique sans devoir déclarer un backend dédié pour ce serveur. Cela peut être réalisé à l’aide des règles « use-server ». Ces règles sont évaluées après les règles « redirect » et avant l’évaluation des cookies, et elles ont une priorité sur celles-ci. Il peut y avoir autant de règles « use-server » que souhaité. Toutes ces règles sont évaluées dans l’ordre de leur déclaration, et la première qui correspond attribue le serveur.

Si une règle désigne un serveur hors service, et que « option persist » n’est pas utilisée et qu’aucune règle « force-persist » n’a été validée, la règle est ignorée et l’évaluation continue avec les règles suivantes jusqu’à ce qu’une correspondance soit trouvée.

Dans la première forme, le serveur sera utilisé si la condition est remplie. Dans la deuxième forme, le serveur sera utilisé si la condition n’est pas remplie. Si aucune condition n’est valide, le traitement continue et le serveur sera affecté selon d’autres mécanismes de persistance.

Notez qu’un cookie est toujours traité, même si une règle est correspondante, mais aucun serveur n’est alors attribué. Cela permet de supprimer le préfixe des cookies préfixés.

L’instruction « use-server » fonctionne aussi bien en mode HTTP qu’en mode TCP. Cela la rend adaptée à une inspection basée sur le contenu. Par exemple, un serveur peut être sélectionné dans une ferme en fonction du champ TLS SNI lors de l’utilisation de protocoles avec TLS implicite (voir également “req.ssl_sni”). Et si le poids de ces serveurs est défini à zéro, ils ne seront pas utilisés pour le trafic autre que celui pour lequel ils ont été sélectionnés.

Exemple :

# intercept incoming TLS requests based on the SNI field
use-server www if { req.ssl_sni -i www.example.com }
server     www 192.168.0.1:443 weight 0
use-server mail if { req.ssl_sni -i mail.example.com }
server     mail 192.168.0.1:465 weight 0
use-server imap if { req.ssl_sni -i imap.example.com }
server     imap 192.168.0.1:993 weight 0
# all the rest is forwarded to this server
server  default 192.168.0.2:443 check

Lorsque <server> est un nom simple, il est vérifié par rapport aux serveurs existants dans la configuration, et une erreur est signalée si le serveur spécifié n’existe pas. Si c’est un format de journal personnalisé, aucune vérification n’est effectuée lors de l’analyse de la configuration, et si un nom de serveur valide ne peut pas être résolu à l’exécution, mais que la règle use-server est conditionnée par une ACL renvoyant true, aucune autre règle use-server n’est appliquée et on passe à la répartition de charge.

Voir également : “use_backend”, section 5 concernant le serveur et section 7 concernant les listes de contrôle d’accès.

4.3. Mots-clés de gestion des actions

Plusieurs jeux de règles sont évalués à divers stades du traitement de la requête ou de la réponse, et pour chaque règle trouvée dans ces jeux de règles, une action peut être exécutée si la condition facultative est remplie.

Un grand nombre d’actions sont fournies par défaut ; elles peuvent modifier les contenus, accept/block le traitement, modifier les états internes, etc. Il est également possible de définir de nouvelles actions en Lua (dans ce cas, leurs noms seront toujours préfixés par “lua.”).

Bien que certaines actions aient historiquement existé uniquement dans des jeux de règles spécifiques, de nombreuses actions sont désormais utilisables avec plusieurs jeux de règles. La liste présentée dans cette section indique pour quel(s) jeu(x) de règles pris en charge une action peut être utilisée, en cochant les noms abrégés correspondants parmi les jeux de règles suivants :

  • QUIC Ini : l’action est valide pour les règles « quic-initial »
  • TCP RqCon : l’action est valide pour les règles « tcp-request connection »
  • TCP RqSes : l’action est valide pour les règles « tcp-request session »
  • TCP RqCnt : l’action est valide pour les règles « tcp-request content »
  • TCP RsCnt : l’action est valide pour les règles « tcp-response content »
  • HTTP Req : l’action est valide pour les règles « http-request »
  • HTTP Res : l’action est valide pour les règles « http-response »
  • HTTP Aft : l’action est valide pour les règles « http-after-response »

Les mêmes abréviations sont utilisées dans la référence section 4.4 ci-dessous.

 keyword                QUIC: Ini   TCP: RqCon RqSes RqCnt RsCnt   HTTP: Req Res Aft
----------------------+-----------+-----------+-----+-----+------+----------+---+----
accept                         X           X     X     X     X            -   -   -
add-acl                        -           -     -     -     -            X   X   -
add-header                     -           -     -     -     -            X   X   X
add-headers-bin                -           -     -     -     -            X   X   X
allow                          -           -     -     -     -            X   X   X
attach-srv                     -           -     X     -     -            -   -   -
auth                           -           -     -     -     -            X   -   -
cache-store                    -           -     -     -     -            -   X   -
cache-use                      -           -     -     -     -            X   -   -
capture                        -           -     -     X     -            X   X   X
close                          -           -     -     -     X            -   -   -
del-acl                        -           -     -     -     -            X   X   -
del-header                     -           -     -     -     -            X   X   X
del-headers-bin                -           -     -     -     -            X   X   X
del-map                        -           -     -     -     -            X   X   X
deny                           -           -     -     -     -            X   X   -
dgram-drop                     X           -     -     -     -            -   -   -
disable-l7-retry               -           -     -     -     -            X   -   -
do-log                         X           X     X     X     X            X   X   X
do-resolve                     -           -     -     X     -            X   -   -
early-hint                     -           -     -     -     -            X   -   -
expect-netscaler-cip           -           X     -     -     -            -   -   -
expect-proxy layer4            -           X     -     -     -            -   -   -
normalize-uri                  -           -     -     -     -            X   -   -
pause                          -           -     -     -     -            X   X   -
redirect                       -           -     -     -     -            X   X   -
reject                         X           X     X     X     X            X   -   -
replace-header                 -           -     -     -     -            X   X   X
replace-path                   -           -     -     -     -            X   -   -
replace-pathq                  -           -     -     -     -            X   -   -
replace-uri                    -           -     -     -     -            X   -   -
replace-value                  -           -     -     -     -            X   X   X
return                         -           -     -     -     -            X   X   -
sc-add-gpc                     -           X     X     X     X            X   X   X
--keyword---------------QUIC--Ini---TCP--RqCon-RqSes-RqCnt-RsCnt---HTTP--Req-Res-Aft-sc-inc-gpc                     -           X     X     X     X            X   X   X
sc-inc-gpc0                    -           X     X     X     X            X   X   X
sc-inc-gpc1                    -           X     X     X     X            X   X   X
sc-set-gpt                     -           X     X     X     X            X   X   X
sc-set-gpt0                    -           X     X     X     X            X   X   X
send-retry                     X           -     -     -     -            -   -   -
send-spoe-group                -           -     -     X     X            X   X   -
set-bandwidth-limit            -           -     -     X     X            X   X   -
set-bc-mark                    -           -     -     X     -            X   -   -
set-bc-tos                     -           -     -     X     -            X   -   -
set-dst                        -           X     X     X     -            X   -   -
set-dst-port                   -           X     X     X     -            X   -   -
set-fc-mark                    -           X     X     X     X            X   X   -
set-fc-tos                     -           X     X     X     X            X   X   -
set-header                     -           -     -     -     -            X   X   X
set-headers-bin                -           -     -     -     -            X   X   X
set-log-level                  -           -     -     X     X            X   X   X
set-map                        -           -     -     -     -            X   X   X
set-mark (deprecated)          -           X     X     X     X            X   X   -
set-method                     -           -     -     -     -            X   -   -
set-nice                       -           -     -     X     X            X   X   -
set-path                       -           -     -     -     -            X   -   -
set-pathq                      -           -     -     -     -            X   -   -
set-priority-class             -           -     -     X     -            X   -   -
set-priority-offset            -           -     -     X     -            X   -   -
--keyword---------------QUIC--Ini---TCP--RqCon-RqSes-RqCnt-RsCnt---HTTP--Req-Res-Aft-set-query                      -           -     -     -     -            X   -   -
set-retries                    -           -     -     X     -            X   -   -
set-src                        -           X     X     X     -            X   -   -
set-src-port                   -           X     X     X     -            X   -   -
set-status                     -           -     -     -     -            -   X   X
set-timeout                    -           -     -     -     -            X   X   -
set-tos (deprecated)           -           X     X     X     X            X   X   -
set-uri                        -           -     -     -     -            X   -   -
set-var                        -           X     X     X     X            X   X   X
set-var-fmt                    -           X     X     X     X            X   X   X
silent-drop                    -           X     X     X     X            X   X   -
strict-mode                    -           -     -     -     -            X   X   X
switch-mode                    -           -     -     X     -            -   -   -
tarpit                         -           -     -     -     -            X   -   -
track-sc0                      -           X     X     X     -            X   X   -
track-sc1                      -           X     X     X     -            X   X   -
track-sc2                      -           X     X     X     -            X   X   -
unset-var                      -           X     X     X     X            X   X   X
use-service                    -           -     -     X     -            X   -   -
wait-for-body                  -           -     -     -     -            X   X   -
wait-for-handshake             -           -     -     -     -            X   -   -
--keyword---------------QUIC--Ini---TCP--RqCon-RqSes-RqCnt-RsCnt---HTTP--Req-Res-Aft-

4.4. Référence des actions triées par ordre alphabétique

Cette section décrit en détail chaque action et son utilisation, en appliquant les mêmes règles de terminologie et de marquage que celles décrites dans section 4.3 ci-dessus.

accept

accept

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | - | - | -

Cela arrête l’évaluation des règles et permet à la requête ou à la réponse de passer le contrôle. Cette action est définitive, c’est-à-dire qu’aucune règle supplémentaire du même jeu de règles n’est évaluée pour la section courante. Il n’existe aucune différence entre cette action et l’action « allow », à l’exception du fait que, pour des raisons de compatibilité historique, « accept » est utilisé pour les règles TCP et QUIC, tandis que « allow » est utilisé pour les règles HTTP. Voir également l’action « allow » ci-dessous.

add-acl(<file-name>) <key fmt>

add-acl(<file-name>) <key fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela permet d’ajouter une nouvelle entrée à une liste de contrôle d’accès (ACL). L’ACL doit être chargée à partir d’un fichier (même un fichier vide dummy). Le nom du fichier ACL à mettre à jour est passé entre parenthèses. Il prend un argument : <key fmt>, qui suit les règles de format de journalisation personnalisée décrites dans la section 8.2.6 , afin de collecter le contenu de la nouvelle entrée. Une recherche est effectuée dans l’ACL avant l’insertion, afin d’éviter les valeurs en double (ou supplémentaires). Il équivaut à la commande « add acl » du socket de statistiques, mais peut être déclenché par une requête HTTP.

add-header <name> <fmt>

add-header <name> <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela ajoute un champ d’en-tête HTTP dont le nom est spécifié dans <name> et dont la valeur est définie par <fmt>, selon les règles du format de journalisation personnalisé (voir Format de journalisation personnalisé dans la section 8.2.6 ). Cela est particulièrement utile pour transmettre des informations spécifiques à la connexion au serveur (par exemple, le certificat SSL du client), ou pour combiner plusieurs en-têtes en un seul. Cette règle n’est pas définitive, il est donc possible d’ajouter d’autres règles similaires. Notez que l’ajout d’en-tête est effectué immédiatement, de sorte qu’une règle peut réutiliser l’en-tête résultant d’une règle précédente.

add-headers-bin <expr> [ prefix <str> ]

add-headers-bin <expr> [ prefix <str> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Il s’agit d’une variante de l’action « add-header » où les noms et les valeurs des en-têtes sont transmis sous forme de chaîne binaire encodée en varint. Consultez l’extraction d’échantillon “req.hdrs_bin” pour en savoir plus sur le format varint. Cette fonctionnalité est utile lorsque vous souhaitez définir plusieurs en-têtes en une seule fois, sans avoir besoin de connaître à l’avance les noms des en-têtes. Notez que ces en-têtes n’ont pas été validés par le parseur HTTP et pourraient entraîner l’émission de messages non valides, voire, dans les cas les plus graves, des attaques par camouflage de requête. Le nombre d’en-têtes insérés est également important, car il est limité par tune.http.maxhdr. Un préfixe facultatif n’appliquera les en-têtes provenant de la chaîne encodée que s’ils commencent par <str>.

Exemple :

# This would reset the Accept/UA/Host headers to their initial values
http-request set-var(txn.oldheaders) req.hdrs_bin
http-request del-header Accept
http-request del-header User-Agent
http-request del-header Host
http-request add-headers-bin var(txn.oldheaders)

allow

allow

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela arrête l’évaluation des règles et permet à la requête de passer le contrôle. Cette action est définitive, c’est-à-dire qu’aucune règle supplémentaire du même jeu de règles n’est évaluée pour la section courante. Il n’y a aucune différence entre cette action et l’action « accept » sauf que, pour des raisons de compatibilité historique, « accept » est utilisé pour les règles TCP et « allow » pour les règles HTTP. Voir également l’action « accept » ci-dessus.

attach-srv <srv> [name <expr>] [ EXPERIMENTAL ]

attach-srv <srv> [name <expr>] [ EXPERIMENTAL ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | X | - | - | - | - | -

Cela permet d’intercepter la connexion après établissement correct de HTTP/2. La connexion est inversée du côté backend et insérée dans le pool inactif du serveur <srv>. Cette fonctionnalité ne peut être utilisée qu’avec des serveurs disposant d’une adresse ‘rhttp@’.

La connexion est insérée dans le pool de connexions inactives du serveur avec un nom défini par le résultat de l’évaluation de <expr>. Ce nom est celui qui sera utilisé pour la correspondance par les requêtes soumises aux paramètres “pool-conn-name” ou “sni”. Voir “http-reuse” pour plus de détails.

Le proxy HTTP inverse est actuellement toujours en développement actif. Le mécanisme de configuration peut évoluer à l’avenir. Pour cette raison, il est marqué internement comme expérimental, ce qui signifie que la directive « expose-experimental-directives » doit apparaître sur une ligne précédant cette directive.

Notez qu’un protocole très similaire mais indépendant est en cours de développement. Voir https://www.ietf.org/archive/id/draft-bt-httpbis-reverse-http-00.html .

auth [realm <realm>]

auth [realm <realm>]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela arrête l’évaluation des règles et renvoie immédiatement un code d’erreur HTTP 401 ou 407 pour inviter l’utilisateur à fournir un nom d’utilisateur et un mot de passe valides. Aucune autre règle “http-request” n’est évaluée. Un paramètre facultatif “realm” est pris en charge ; il définit le domaine d’authentification renvoyé dans la réponse (généralement le nom de l’application).

Le message d’erreur du proxy correspondant est utilisé. Il peut être personnalisé à l’aide d’une directive « errorfile » ou « http-error ». Pour les réponses 401, toutes les occurrences de l’en-tête WWW-Authenticate sont supprimées et remplacées par un nouvel en-tête comportant un défi d’authentification basique pour le domaine “<realm>”. Pour les réponses 407, l’opération est identique sur l’en-tête Proxy-Authenticate. Si le message d’erreur ne doit pas être modifié, envisagez d’utiliser une règle « http-request return » à la place.

Exemple :

acl auth_ok http_auth_group(L1) G1
http-request auth unless auth_ok

cache-store <name>

cache-store <name>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | -

Stocke une réponse HTTP dans le cache. Le stockage des en-têtes de réponse s’effectue à cette étape, ce qui signifie que vous pouvez utiliser d’autres actions de réponse HTTP pour modifier les en-têtes avant ou après le stockage de la réponse. Cette action est responsable de la configuration du filtre de stockage du cache.

Voir section 6.2 concernant la configuration du cache.

cache-use <name>

cache-use <name>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Essayer de livrer un objet mis en cache depuis le cache <name>. Cette directive est également obligatoire pour stocker le cache, car elle calcule le hachage du cache. Si vous souhaitez utiliser une condition à la fois pour le stockage et la livraison, il est recommandé de la placer après celle-ci.

Voir section 6.2 concernant la configuration du cache.

capture <sample> [ len <length> | id <id> ]

capture <sample> [ len <length> | id <id> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | X | X

Cela capture l’expression d’échantillon <sample> dans le tampon de requête ou de réponse, et la convertit en chaîne de maximum <len> caractères. La chaîne résultante est stockée dans la prochaine case de capture (requête ou réponse), où elle apparaîtra éventuellement à côté d’autres en-têtes HTTP capturés. Elle apparaîtra ensuite automatiquement dans les journaux, et il sera possible de l’extraire à l’aide des méthodes d’extraction d’échantillon afin de la transmettre à des en-têtes ou à tout autre élément. La longueur doit être limitée, car cette taille sera allouée pour chaque capture pendant toute la durée du flux. Notez que cette longueur n’est utilisable qu’avec les règles “http-request”. Veuillez consulter la section 7.3 (Extraction d’échantillon), “capture en-tête de requête” et “capture en-tête de réponse” pour plus d’informations.

Si le mot-clé « id » est utilisé à la place de « len », l’action tente de stocker la chaîne capturée dans une plage de capture prédéfinie. Cela est utile pour exécuter des captures dans les backends. L’identifiant de plage peut être déclaré par une directive précédente « http-request capture » ou avec le mot-clé « declare capture ».

Lorsque vous utilisez cette action dans un backend, vérifiez soigneusement que le ou les frontaux concernés disposent des emplacements de capture nécessaires, faute de quoi cette règle sera ignorée à l’exécution. Cette vérification ne peut pas être effectuée au moment de l’analyse de la configuration en raison de la capacité d’HAProxy à résoudre dynamiquement le nom du backend à l’exécution.

close

close

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | X | - | - | -

Cette action est utilisée pour fermer immédiatement la connexion avec le serveur. Aucune règle ultérieure de type « tcp-response content » n’est évaluée. Son usage principal consiste à forcer la fermeture d’une connexion entre un client et un serveur après un échange, lorsque le protocole applicatif prévoit des délais d’attente importants avant de pouvoir terminer. L’objectif est d’éliminer les connexions inactives qui consomment des ressources significatives sur les serveurs avec certains protocoles.

del-acl(<file-name>) <key fmt>

del-acl(<file-name>) <key fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela permet de supprimer une entrée d’une liste de contrôle d’accès (ACL). L’ACL doit être chargée à partir d’un fichier (même un fichier vide factice). Le nom du fichier ACL à mettre à jour est passé entre parenthèses. Il prend un argument : <key fmt>, qui suit les règles du format de journalisation personnalisé de la section 8.2.6 , afin de collecter le contenu de l’entrée à supprimer. Il équivaut à la commande « del acl » du socket de statistiques, mais peut être déclenché par une requête ou une réponse HTTP.

del-header <name> [ -m <meth> ]

del-header <name> [ -m <meth> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela supprime tous les champs d’en-tête HTTP dont le nom est spécifié dans <name>. <meth> est la méthode de correspondance appliquée au nom de l’en-tête. Les méthodes de correspondance prises en charge sont « str » (correspondance exacte), « beg » (correspondance par préfixe), « end » (correspondance par suffixe), « sub » (correspondance par sous-chaîne) et « reg » (correspondance par expression régulière). Si non spécifiée, la méthode de correspondance exacte est utilisée.

del-headers-bin <expr> [ -m <meth> ]

del-headers-bin <expr> [ -m <meth> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela supprime tous les champs d’en-tête HTTP dont les noms sont spécifiés dans <expr>. <expr> doit renvoyer une chaîne binaire encodée en varint contenant tous les noms d’en-tête à supprimer. Voir « add-headers-bin » et « set-headers-bin » pour la description de l’encodage et des exemples. <meth> est la méthode de correspondance appliquée à tous les noms d’en-tête. Les méthodes de correspondance prises en charge sont « str » (correspondance exacte), « beg » (correspondance par préfixe), « end » (correspondance par suffixe) et « sub » (correspondance par sous-chaîne). La méthode « reg » (correspondance par expression régulière) n’est pas prise en charge en raison de performances imprévisibles en temps d’exécution. Si non spécifiée, la méthode de correspondance exacte est utilisée.

del-map(<map-name>) <key fmt>

del-map(<map-name>) <key fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cette commande est utilisée pour supprimer une entrée d’une MAP. <map-name> doit suivre le format décrit dans 2.7. Concernant le format du nom des MAPs et des ACLs. Le nom de la MAP à mettre à jour est passé entre parenthèses. Elle prend un argument : <key fmt>, qui suit les règles du format personnalisé de journalisation de la section 8.2.6 , afin de collecter le contenu de l’entrée à supprimer. Elle prend un argument : « nom de fichier ». Elle équivaut à la commande « del map » depuis la socket de statistiques, mais peut être déclenchée par une requête ou une réponse HTTP.

deny [ { status | deny_status } <code> ] [ content-type <type> ]

deny [ { status | deny_status } <code> ] [ content-type <type> ]
     [ { default-errorfiles | errorfile <file> | errorfiles <name> |
   file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
 [ hdr `<name>` `<fmt>` ]*

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela arrête l’évaluation des règles et rejette immédiatement la requête ou la réponse. Par défaut, une erreur HTTP 403 est renvoyée pour les requêtes, et 502 pour les réponses, mais la réponse renvoyée peut être personnalisée en utilisant la même syntaxe que pour l’action « return ». Voir « return » ci-dessous pour les détails. À des fins de compatibilité, lorsque aucun argument n’est défini, ou uniquement “deny_status”, l’argument « default-errorfiles » est implicite. Cela signifie que « deny [deny_status <status>] » est un alias de « deny [status <status>] default-errorfiles ». Cette action est définitive, c’est-à-dire qu’aucune règle supplémentaire du même jeu de règles n’est évaluée pour la section courante. Voir également l’action « return » pour la syntaxe avancée.

dgram-drop

dgram-drop

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -

Ignore silencieusement la réception d’un paquet initial QUIC qui aurait sinon entraîné l’instanciation d’une nouvelle connexion QUIC et l’exécution de son échange SSL.

disable-l7-retry

disable-l7-retry

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela désactive toute tentative de réessai de la requête en cas d’échec pour toute autre raison qu’une erreur de connexion. Cela peut être utile, par exemple, pour s’assurer que les requêtes POST ne sont pas réessayées en cas d’échec.

do-log [profile <log_profile>]

do-log [profile <log_profile>]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | X | X

Cette action déclenche manuellement l’émission d’un journal sur le proxy. Cela signifie que les options de journalisation du proxy seront prises en compte (y compris les options de formatage telles que « log-format »), mais qu’elle n’interférera pas avec les journaux générés automatiquement par le proxy pendant le traitement des transactions.

En utilisant « log-profile », il est possible de décrire précisément la manière dont le journal doit être émis pour chacun des contextes disponibles où l’action peut être utilisée. Autrement dit, le mot-clé « on » suivi des valeurs suivantes : « quic-init », « tcp-req-conn », « tcp-req-sess », « tcp-req-cont », « tcp-res-cont », « http-req », « http-res », « http-after-res ».

En outre, ils seront correctement signalés lors de l’utilisation de l’alias de format de journalisation “%OG”.

Argument facultatif « profile » peut être utilisé pour spécifier le nom d’une section log-profile à utiliser pour cette action do-log en particulier, plutôt que celle associée au logger actuel, qui s’applique par défaut.

Exemple :

log-profile my-dft-prof
  on tcp-req-conn format "Connect: %ci"

log-profile my-local-prof
  on tcp-req-conn format "Local Connect: %ci"

frontend myfront
  log stdout format rfc5424 profile my-dft-prof local0
  log-format "log generated using proxy logformat, from '%OG'"
  acl local src 127.0.0.1
  # on connection use either log-profile from the logger (my-dft-prof) or
  # explicit my-local-prof if source ip is localhost
  tcp-request connection do-log if !local
  tcp-request connection do-log profile my-local-prof if local
  # on content use proxy logformat, since no override was specified
  # in my-dft-prof
  tcp-request content do-log

do-resolve(<var>,<resolvers>[,ipv4|ipv6]) <expr>

do-resolve(<var>,<resolvers>[,ipv4|ipv6]) <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cette action effectue une résolution DNS de la sortie de <expr> et stocke le résultat dans la variable <var>. Elle utilise la section des résolveurs DNS pointée par <resolvers>. Il est possible de choisir une préférence de résolution à l’aide des arguments facultatifs « ipv4 » ou « ipv6 ». Voir également le mot-clé global « dns-accept-family » pour imposer une utilisation stricte d’une famille spécifique.

Lors de la résolution DNS, la connexion côté client est mise en pause en attendant la fin de la résolution. Si une adresse IP est trouvée, elle est stockée dans <var>. Si une erreur de quelque nature que ce soit survient, <var> n’est pas définie. On peut utiliser cette action pour découvrir l’adresse IP d’un serveur en temps réel, en se basant sur des informations présentes dans la requête (par exemple, un en-tête Host). Si cette action est utilisée pour déterminer l’adresse IP du serveur (en utilisant l’action « set-dst »), l’adresse IP du serveur dans le backend doit être définie sur 0.0.0.0. L’action do-resolve prend un paramètre uniquement composé de l’hôte ; toute port doit être supprimée de la chaîne.

Exemple :

resolvers mydns
  nameserver local 127.0.0.53:53
  nameserver google 8.8.8.8:53
  timeout retry   1s
  hold valid 10s
  hold nx 3s
  hold other 3s
  hold obsolete 0s
  accepted_payload_size 8192

frontend fe
  bind 10.42.0.1:80
  http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),host_only
  http-request capture var(txn.myip) len 40

  # return 503 when the variable is not set,
  # which mean DNS resolution error
  use_backend b_503 unless { var(txn.myip) -m found }

  default_backend be

backend b_503
  # dummy backend used to return 503.
  # one can use the errorfile directive to send a nice
  # 503 error page to end users

backend be
  # rule to prevent HAProxy from reconnecting to services
  # on the local network (forged DNS name used to scan the network)
  http-request deny if { var(txn.myip) -m ip 127.0.0.0/8 10.0.0.0/8 }
  http-request set-dst var(txn.myip)
  server clear 0.0.0.0:0

NOTE : N’oubliez pas de définir les règles de « protection » afin d’assurer que HAProxy ne sera pas utilisé pour scanner le réseau, ni pire, entrer en boucle sur lui-même…

early-hint <name> <fmt>

early-hint <name> <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela permet de générer une réponse HTTP 103 Early Hints avant toute autre réponse. Cela ajoute un champ d’en-tête HTTP à cette réponse dont le nom est spécifié dans <name> et dont la valeur est définie par <fmt>, selon les règles du format de journalisation personnalisé (voir Format de journalisation personnalisé dans la section 8.2.6 ). Cela est particulièrement utile pour transmettre au client des en-têtes Link afin de précharger des ressources nécessaires à l’affichage des documents HTML.

Consultez le RFC 8297 pour plus d’informations.

expect-netscaler-cip layer4

expect-netscaler-cip layer4

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -

Cela configure la connexion orientée client pour recevoir un en-tête de protocole d’insertion de l’adresse IP client NetScaler avant toute lecture de données depuis la socket. Cela équivaut à utiliser le mot-clé « accept-netscaler-cip » dans la ligne « bind », à ceci près que l’utilisation d’une règle TCP permet d’accepter le protocole PROXY uniquement pour des plages d’adresses IP spécifiques, grâce à une ACL. Cette configuration est pratique lorsque le trafic provenant d’hôtes publics traverse plusieurs couches de répartiteurs de charge.

expect-proxy layer4

expect-proxy layer4

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | - | - | - | - | - | -

Cela configure la connexion côté client pour recevoir une en-tête PROXY avant toute lecture sur la socket. Cela équivaut à placer le mot-clé « accept-proxy » dans la ligne « bind », sauf que l’utilisation d’une règle TCP permet d’accepter le protocole PROXY uniquement pour certaines plages d’adresses IP en utilisant une ACL. Cela est pratique lorsque le trafic provenant d’hôtes publics traverse plusieurs couches de répartiteurs de charge.

normalize-uri <normalizer>

normalize-uri <normalizer>
normalize-uri fragment-encode
normalize-uri fragment-strip
normalize-uri path-merge-slashes
normalize-uri path-strip-dot
normalize-uri path-strip-dotdot [ full ]
normalize-uri percent-decode-unreserved [ strict ]
normalize-uri percent-to-uppercase [ strict ]
normalize-uri query-sort-by-name

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Effectue la normalisation de l’URI de la requête.

La normalisation des URI dans HAProxy 2.4 est actuellement disponible en tant que préversion technique expérimentale. En tant que tel, elle nécessite que la directive globale « expose-experimental-directives » soit définie afin de pouvoir l’utiliser. Vous devez vous préparer au fait que le comportement des normalisateurs pourrait évoluer pour corriger des éventuels problèmes, ce qui pourrait entraîner une interruption du traitement correct des requêtes dans votre infrastructure.

Chaque normalisateur gère un seul type de normalisation afin de permettre une sélection fine du niveau de normalisation adapté au backend pris en charge.

Par exemple, le normaliseur « path-strip-dotdot » peut être utile pour un serveur de fichiers statiques qui mappe directement l’URI demandé à un chemin dans le système de fichiers local. Toutefois, il peut perturber le routage d’une API qui attend un nombre spécifique de segments dans le chemin.

Il est important de noter que certains normalisateurs peuvent entraîner des transformations non sécurisées pour des URI corrompues. Il se peut également qu’une combinaison de normalisateurs qui sont sûrs individuellement entraîne des transformations non sécurisées lorsqu’ils sont combinés de manière incorrecte.

Par exemple, le normalisateur « percent-decode-unreserved » peut produire des résultats inattendus lorsqu’une URI corrompue contient des caractères pourcent nus. Une telle URI corrompue est « /%%36%36 », qui serait décodée en « /%66 », ce qui équivaut à « /f ». En spécifiant l’option « strict », les requêtes adressées à une telle URI corrompue seront rejetées de manière sécurisée.

Les normalisateurs suivants sont disponibles :

  • fragment-encode : Encodé “#” sous la forme “%23”.

Le normalisateur « fragment-strip » doit être privilégié, sauf si l’on sait que les clients défectueux ne codent pas correctement ‘#’ dans le composant de chemin.

Exemple :

  • /#foo -> /%23foo

  • fragment-strip : Supprime le composant « fragment » de l’URI.

Selon la RFC 3986#3.5, le composant « fragment » d’une URI ne doit pas être transmis, mais géré par l’agent utilisateur après avoir récupéré une ressource.

Ce normalisateur doit être appliqué en premier afin de s’assurer que le fragment n’est pas interprété comme faisant partie du composant de chemin de la requête.

Exemple :

  • /#foo -> /

  • path-strip-dot : Supprime les segments “/./” dans le composant “path” (RFC 3986#6.2.2.3).

Les segments contenant des points codés en pourcentage ("%2E”) ne seront pas détectés. Utilisez d’abord le normaliseur « percent-decode-unreserved » si ce comportement est indésirable.

Exemple :

  • /. -> /

  • /./bar/ -> /bar/

  • /a/./a -> /a/a

  • /.well-known/ -> /.well-known/ (aucun changement)

  • path-strip-dotdot : Normalise les segments “/../” dans le composant “path” (RFC 3986#6.2.2.3).

Cela fusionne les segments qui tentent d’accéder au répertoire parent avec leur segment précédent.

Les segments vides ne reçoivent aucune traitement particulier. Utilisez d’abord le normaliseur « merge-slashes » si ce comportement n’est pas souhaité.

Les segments contenant des points codés en pourcentage ("%2E") ne seront pas détectés. Utilisez d’abord le normaliseur « percent-decode-unreserved » si ce comportement est indésirable.

Exemple :

  • /foo/../ -> /
  • /foo/../bar/ -> /bar/
  • /foo/bar/../ -> /foo/
  • /../bar/ -> /../bar/
  • /bar/../../ -> /../
  • /foo//../ -> /foo/
  • /foo/%2E%2E/ -> /foo/%2E%2E/

Si l’option « full » est spécifiée, alors « ../ » au début sera également supprimé :

Exemple :

  • /../bar/ -> /bar/

  • /bar/../../ -> /

  • path-merge-slashes : Fusionne les barres obliques adjacentes dans le composant “path” en une seule barre oblique.

Exemple :

  • // -> /

  • /foo//bar -> /foo/bar

  • percent-decode-unreserved : Décode les caractères encodés en pourcentage non réservés en leur représentation sous forme de caractère régulier (RFC 3986#6.2.2.2).

L’ensemble des caractères non réservés comprend toutes les lettres, tous les chiffres, “-”, “.”, “_”, et “~”.

Exemple :

  • /%61dmin -> /admin
  • /foo%3Fbar=baz -> /foo%3Fbar=baz (no change)
  • /%%36%36 -> /%66 (unsafe)
  • /%ZZ -> /%ZZ

Si l’option « strict » est spécifiée, les séquences non valides entraîneront la renvoi d’une réponse HTTP 400 Bad Request.

Exemple :

  • /%%36%36 -> HTTP 400

  • /%ZZ -> HTTP 400

  • percent-to-uppercase : Met en majuscule les lettres au sein des séquences encodées en pourcentage (RFC 3986#6.2.2.1).

Exemple :

  • /%6f -> /%6F
  • /%zz -> /%zz

Si l’option « strict » est spécifiée, les séquences non valides entraîneront la renvoi d’une réponse HTTP 400 Bad Request.

Exemple :

  • /%zz -> HTTP 400

  • query-sort-by-name : Trie les paramètres de chaîne de requête par nom de paramètre. Les paramètres sont supposés être séparés par ‘&’. Les noms plus courts sont placés avant les noms plus longs, et les noms de paramètre identiques conservent leur ordre relatif.

Exemple :

  • /?c=3&a=1&b=2 -> /?a=1&b=2&c=3
  • /?aaa=3&a=1&aa=2 -> /?a=1&aa=2&aaa=3
  • /?a=3&b=4&a=1&b=5&a=2 -> /?a=3&a=1&a=2&b=4&b=5

pause { <timeout> | <expr> }

pause { <timeout> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela suspend l’analyse du message pendant le nombre de millisecondes spécifié. Le délai d’expiration peut être précisé en millisecondes ou avec toute autre unité si le nombre est suivi de l’unité, comme expliqué en haut de ce document. Il est également possible d’écrire une expression qui doit renvoyer un nombre interprété comme un délai d’expiration en millisecondes. Si l’évaluation de l’expression échoue ou si elle renvoie une valeur non valide, l’action est ignorée et l’évaluation se poursuit.

Cette action peut être utilisée à des fins de débogage. Elle peut également servir à ralentir certains clients selon des critères spécifiques. Par exemple, il est possible de ralentir les clients dont le taux de requêtes est trop élevé, en les suivant à l’aide d’une règle « track-sc ».

redirect <rule>

redirect <rule>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela effectue une redirection HTTP basée sur une règle de redirection. Il s’agit exactement de la même chose que l’instruction « redirect », sauf qu’elle insère une règle de redirection traitée au milieu des autres règles « http-request » ou « http-response », et que ces règles utilisent le format de journalisation personnalisé. Pour les réponses, seule le type de redirection « location » est autorisé. En outre, lorsqu’une redirection est effectuée pendant une réponse, la transmission depuis le serveur vers HAProxy est interrompue, de sorte qu’aucun contenu ne peut être transféré au client. Cela peut entraîner la fermeture de certaines connexions sur HTTP/1.. Cette action est définitive, c’est-à-dire qu’aucune règle supplémentaire du même jeu de règles n’est évaluée pour la section courante. Voir le mot-clé « redirect » pour la syntaxe de la règle.

reject

reject

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | X | X | X | X | X | - | -

Cela arrête l’évaluation des règles et ferme immédiatement la connexion sans envoyer de réponse. Pour les règles HTTP, cela se comporte de manière similaire aux règles « tcp-request content reject ». Cela peut être utile pour forcer la fermeture immédiate d’une connexion sur les connexions HTTP/2.

Dans les règles « tcp-request connection », les connexions rejetées ne deviennent pas une session, ce qui explique qu’elles soient comptabilisées séparément dans les statistiques, sous le libellé « connexions refusées ». Elles ne sont pas prises en compte pour la limitation du débit de sessions et ne sont pas non plus journalisées. La raison en est que ces règles doivent uniquement être utilisées pour filtrer des taux de connexion extrêmement élevés, tels que ceux observés lors d’une attaque DDoS massive. Dans de telles conditions extrêmes, l’action simple de journaliser chaque événement ferait rapidement planter le système et réduirait considérablement la capacité de filtrage. Si la journalisation est absolument nécessaire, il convient alors d’utiliser des règles « tcp-request content » à la place, car les règles « tcp-request session » ne journalisent pas non plus.

Lorsqu’il est utilisé dans les règles « tcp-response content », la connexion serveur sera fermée et la réponse interrompue. Cela est généralement utilisé pour empêcher la fuite d’informations sensibles, typiquement après l’inspection du contenu en conjonction avec l’action « wait-for-body ».

Cette action peut également être utilisée dans les règles « quic-initial ». La connexion QUIC nouvellement ouverte est immédiatement fermée sans traitement de handshake SSL, et le client est notifié via un code d’erreur CONNECTION_REFUSED.

replace-header <name> <match-regex> <replace-fmt>

replace-header <name> <match-regex> <replace-fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela correspond à la valeur de toutes les occurrences du champ d’en-tête <name> contre <match-regex>. La correspondance est effectuée de manière sensible à la casse. Les valeurs correspondantes sont entièrement remplacées par <replace-fmt>. Les caractères de format sont autorisés dans <replace-fmt> et fonctionnent comme les arguments <fmt> dans « http-request add-header ». Les références arrière standard utilisant une barre oblique inversée (’\’) suivie d’un nombre sont prises en charge.

Cette action agit sur des lignes entières d’en-têtes, quelle que soit la quantité de valeurs qu’elles contiennent. Elle est donc particulièrement adaptée au traitement des en-têtes contenant naturellement des virgules dans leurs valeurs, tels que If-Modified-Since ou Set-Cookie. Les en-têtes contenant une liste séparée par des virgules de valeurs, tels qu’Accept ou Cache-Control, doivent être traités à l’aide de l’action « replace-value » à la place. Voir également l’action « replace-value ».

Exemple :

http-request replace-header Cookie foo=([^;]*);(.*) foo=\1;ip=%bi;\2

# applied to:
Cookie: foo=foobar; expires=Tue, 14-Jun-2016 01:40:45 GMT;

# outputs:
Cookie: foo=foobar;ip=192.168.1.20; expires=Tue, 14-Jun-2016 01:40:45 GMT;

# assuming the backend IP is 192.168.1.20

http-request replace-header User-Agent curl foo

# applied to:
User-Agent: curl/7.47.0

# outputs:
User-Agent: foo

Exemple :

http-response replace-header Set-Cookie (C=[^;]*);(.*) \1;ip=%bi;\2

# applied to:
Set-Cookie: C=1; expires=Tue, 14-Jun-2016 01:40:45 GMT

# outputs:
Set-Cookie: C=1;ip=192.168.1.20; expires=Tue, 14-Jun-2016 01:40:45 GMT

# assuming the backend IP is 192.168.1.20.

replace-path <match-regex> <replace-fmt>

replace-path <match-regex> <replace-fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela fonctionne comme « replace-header », sauf qu’il s’applique à la composante chemin de la requête plutôt qu’à un en-tête. La composante chemin commence au premier « / » après un schéma et une autorité éventuels et se termine avant le point d’interrogation. Ainsi, le remplacement n’affecte pas le schéma, l’autorité ni la chaîne de requête.

Il convient de noter que les expressions régulières peuvent être plus coûteuses à évaluer que certaines ACL, si bien qu’une substitution rare peut bénéficier d’une condition afin d’éviter toute évaluation si elle ne correspond pas.

Exemple :

# prefix /foo: turn /bar?q=1 into /foo/bar?q=1:
http-request replace-path (.*) /foo\1

# strip /foo: turn /foo/bar?q=1 into /bar?q=1
http-request replace-path /foo/(.*) /\1
# or more efficient if only some requests match:
http-request replace-path /foo/(.*) /\1 if { url_beg /foo/ }

replace-pathq <match-regex> <replace-fmt>

replace-pathq <match-regex> <replace-fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela a le même effet que « http-request replace-path », sauf que le chemin inclut la chaîne de requête si une telle chaîne est présente. Ainsi, le chemin et la chaîne de requête sont remplacés.

Exemple :

# suffix /foo: turn /bar?q=1 into /bar/foo?q=1:
http-request replace-pathq ([^?]*)(\?(.*))? \1/foo\2

replace-uri <match-regex> <replace-fmt>

replace-uri <match-regex> <replace-fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela fonctionne comme « replace-header », sauf qu’il s’applique à la partie URI de la requête au lieu d’un en-tête. La partie URI peut contenir un schéma, une autorité ou une chaîne de requête facultatifs. Ces éléments sont considérés comme faisant partie de la valeur qui est comparée.

Il convient de noter que les expressions régulières peuvent être plus coûteuses à évaluer que certaines ACL, si bien qu’une substitution rare peut bénéficier d’une condition afin d’éviter toute évaluation si elle ne correspond pas.

NOTE IMPORTANTE : historiquement, dans HTTP/1.x, la grande majorité des requêtes envoyées par les navigateurs utilisent la « forme origin », qui diffère de la « forme absolue » en ce qu’elles ne contiennent ni schéma ni autorité dans la partie URI. La forme absolue est principalement utilisée pour les requêtes envoyées aux proxies, celles créées manuellement et certaines émises par des applications spécifiques. En conséquence, « replace-uri » fonctionne généralement correctement dans HTTP/1.x avec des règles commençant par un « / ». Toutefois, dans HTTP/2, les clients sont encouragés à envoyer uniquement des URI absolus, similaires à ceux utilisés par les clients HTTP/1 pour communiquer avec les proxies. Dans ce cas, des règles partielles de « replace-uri » peuvent échouer dans HTTP/2 alors qu’elles fonctionnent dans HTTP/1.. Soit les règles doivent être adaptées pour éventuellement correspondre à un schéma et une autorité, soit il faut utiliser « replace-path ».

Exemple :

# rewrite all "http" absolute requests to "https":
http-request replace-uri ^http://(.*) https://\1

# prefix /foo: turn /bar?q=1 into /foo/bar?q=1:
http-request replace-uri ([^/:]*://[^/]*)?(.*) \1/foo\2

replace-value <name> <match-regex> <replace-fmt>

replace-value <name> <match-regex> <replace-fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela fonctionne comme « replace-header », sauf qu’il effectue la correspondance de l’expression régulière contre chaque valeur délimitée par une virgule du champ d’en-tête <name> au lieu de l’intégralité de l’en-tête. Cette directive convient à tous les en-têtes autorisés à contenir plusieurs valeurs. Un exemple pourrait être l’en-tête de requête Accept, ou Cache-Control pour les requêtes ou les réponses.

Exemple :

http-request replace-value X-Forwarded-For ^192\.168\.(.*)$ 172.16.\1

# applied to:
X-Forwarded-For: 192.168.10.1, 192.168.13.24, 10.0.0.37

# outputs:
X-Forwarded-For: 172.16.10.1, 172.16.13.24, 10.0.0.37

Exemple :

http-after-response replace-value Cache-control ^public$ private

# applied to:
Cache-Control: max-age=3600, public

# outputs:
Cache-Control: max-age=3600, private

return [ status <code> ] [ content-type <type> ]

return [ status <code> ] [ content-type <type> ]
       [ { default-errorfiles | errorfile <file> | errorfiles <name> |
     file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
   [ hdr `<name>` `<fmt>` ]*

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela arrête l’évaluation des règles et renvoie immédiatement une réponse. Le code d’état par défaut utilisé pour la réponse est 200. Il peut être spécifié de manière optionnelle en tant qu’argument à « status ». Le type de contenu de la réponse peut également être précisé en tant qu’argument à « content-type ». Enfin, la réponse elle-même peut être définie. Elle peut être une réponse HTTP complète spécifiant le fichier d’erreur à utiliser, ou le corps de la réponse spécifiant le fichier ou la chaîne à utiliser. Les règles suivantes sont appliquées pour créer la réponse :

  • Si ni le fichier d’erreur ni la charge utile à utiliser ne sont définis, une réponse factice est renvoyée. Seul l’argument « status » est pris en compte. Il peut être n’importe quel code compris dans la plage [200, 599]. L’argument « content-type », le cas échéant, est ignoré.

  • Si l’argument « default-errorfiles » est défini, les fichiers d’erreur du proxy sont pris en compte. Si l’argument « status » est défini, il doit être l’un des codes d’état gérés par HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 ou 504). L’argument « content-type », le cas échéant, est ignoré.

  • Si un fichier d’erreur spécifique est défini, via l’argument « errorfile », le fichier correspondant, contenant une réponse HTTP complète, est renvoyé. Seul l’argument « status » est pris en compte. Il doit être l’un des codes d’état gérés par HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 ou 504). L’argument « content-type », le cas échéant, est ignoré.

  • Si une section http-errors est définie, avec un argument “errorfiles”, le fichier correspondant dans la section http-errors spécifiée, contenant une réponse HTTP complète, est renvoyé. Seul l’argument “status” est pris en compte. Il doit être l’un des codes d’état gérés par HAProxy (200, 400, 403, 404, 405, 408, 410, 413, 414, 425, 429, 431, 500, 501, 502, 503 ou 504). L’argument “content-type”, le cas échéant, est ignoré.

  • Si un argument « file » ou « lf-file » est spécifié, le contenu du fichier est utilisé comme charge utile de la réponse. Si le fichier n’est pas vide, son type de contenu doit être précisé en tant qu’argument à « content-type ». Sinon, tout argument « content-type » est ignoré. Avec un argument « lf-file », le contenu du fichier est évalué comme un format de journal personnalisé (voir section 8.2.6 ). Avec un argument « file », il est considéré comme un contenu brut.

  • Si un argument « string » ou « lf-string » est spécifié, la chaîne définie est utilisée comme charge utile de la réponse. Le type de contenu doit toujours être défini en tant qu’argument à « content-type ». Avec un argument « lf-string », la chaîne est évaluée comme un format de journalisation personnalisé (voir section 8.2.6 ). Avec un argument « string », il est considéré comme une chaîne brute.

Lorsque la réponse n’est pas basée sur un fichier d’erreur, il est possible d’ajouter des champs d’en-tête HTTP à la réponse à l’aide des arguments « hdr ». Dans le cas contraire, tous les arguments « hdr » sont ignorés. Pour chacun d’eux, le nom de l’en-tête est spécifié dans <name> et sa valeur est définie par <fmt>, selon les règles du format de journalisation personnalisé décrites dans la section 8.2.6 .

Notez que la réponse générée doit être plus petite qu’une mémoire tampon. Pour éviter tout avertissement, lorsque un fichier d’erreur ou un fichier brut est chargé, l’espace mémoire réservé pour la réécriture des en-têtes doit également être libre.

Cette action est définitive, c’est-à-dire que aucune règle supplémentaire du même jeu de règles n’est évaluée pour la section courante.

Exemple :

http-request return errorfile /etc/haproxy/errorfiles/200.http \
    if { path /ping }

http-request return content-type image/x-icon file /var/www/favicon.ico  \
    if { path /favicon.ico }

http-request return status 403 content-type text/plain    \
    lf-string "Access denied. IP %[src] is blacklisted."  \
    if { src -f /etc/haproxy/blacklist.lst }

sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }

sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cette action incrémente le compteur généralisé à l’index <idx> du tableau associé au compteur collant désigné par <sc-id> de la valeur de l’entier <int> ou de l’évaluation entière de l’expression <expr>. Les entiers et les expressions sont limités aux valeurs 32 bits non signées. En cas d’erreur, cette action échoue silencieusement et l’évaluation des actions se poursuit. <idx> est un entier compris entre 0 et 99 et <sc-id> est un entier compris entre 0 et 2. L’action échoue également silencieusement si aucun compteur généralisé n’est stocké à cet index. L’entrée dans la table est actualisée même si la valeur est nulle. Le ‘gpc_rate’ est automatiquement ajusté pour refléter le taux moyen de croissance de la valeur du compteur généralisé.

Cette action s’applique uniquement aux types de données ‘gpc’ et ‘gpc_rate’ (et non aux types de données hérités ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ ni ‘gpc1_rate’). Il n’existe aucune fonction équivalente pour les types de données hérités, mais si la valeur est toujours 1, veuillez consulter ‘sc-inc-gpc()’, ‘sc-inc-gpc0()’ et ‘sc-inc-gpc1()’. Il n’existe aucun moyen de décrémenter la valeur, mais il est possible de stocker des valeurs exactes dans une étiquette à usage général à l’aide de ‘sc-set-gpt()’.

L’utilisation principale de cette action consiste à compter des scores ou des volumes totaux (par exemple, le danger estimé par adresse IP source signalé par le serveur ou un WAF, les octets téléchargés au total, etc.).

sc-inc-gpc(<idx>,<sc-id>)

sc-inc-gpc(<idx>,<sc-id>)

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cette action incrémente le compteur généralisé à l’index <idx> du tableau associé au compteur collant désigné par <sc-id>. En cas d’erreur, cette action échoue silencieusement et l’évaluation des actions continue. <idx> est un entier compris entre 0 et 99 et <sc-id> est un entier compris entre 0 et 2. L’action échoue également silencieusement si aucun compteur généralisé n’est stocké à cet index. Cette action s’applique uniquement aux types de données ‘gpc’ et ‘gpc_rate’ (et non aux types de données hérités ‘gpc0’, ‘gpc1’, ‘gpc0_rate’ ni ‘gpc1_rate’).

sc-inc-gpc0(<sc-id>)

sc-inc-gpc0(<sc-id>)
sc-inc-gpc1(<sc-id>)

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cette action incrémente le compteur GPC0 ou GPC1 selon le compteur de persistance désigné par <sc-id>. En cas d’erreur, cette action échoue silencieusement et l’évaluation des actions se poursuit.

sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }

sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cette action définit le GPT 32 bits non signé à l’index <idx> du tableau associé au compteur collant désigné par <sc-id> à la valeur de <int>/<expr>.. Le résultat attendu est un booléen.

En cas d’erreur, cette action échoue silencieusement et l’évaluation des actions se poursuit. <idx> est un entier compris entre 0 et 99 et <sc-id> est un entier compris entre 0 et 2. L’action échoue également silencieusement si aucun GPT n’est stocké à cet index.

Cette action s’applique uniquement au type de données ‘gpt’ (et non au type de données hérité ‘gpt0’).

sc-set-gpt0(<sc-id>) { <int> | <expr> }

sc-set-gpt0(<sc-id>) { <int> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cette action définit l’étiquette 32 bits non signée GPT0 selon le compteur collant désigné par <sc-id> et la valeur de <int>/<expr>.. Le résultat attendu est une valeur booléenne. En cas d’erreur, cette action échoue silencieusement et l’évaluation des actions se poursuit. Cette action est un alias de « sc-set-gpt(0,<sc-id>) ». Voir également l’action « sc-set-gpt ».

send-retry

send-retry

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft X | - | - | - | - | - | - | -

Cette action force l’émission d’un paquet Retry en réponse à un paquet Initial client sans jeton. Cela permet de s’assurer que l’adresse client est validée avant d’instancier tout élément de connexion et de commencer l’échange.

send-spoe-group <engine-name> <group-name>

send-spoe-group <engine-name> <group-name>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -

Cette action est utilisée pour déclencher l’envoi d’un groupe de messages SPOE. Pour cela, le moteur SPOE utilisé pour envoyer les messages doit être défini, ainsi que le groupe SPOE à envoyer. Bien entendu, le moteur SPOE doit faire référence à un filtre SPOE existant. Si aucun nom de moteur n’est fourni sur la ligne du filtre SPOE, le nom de l’agent SPOE doit être utilisé.

Arguments :

<engine-name>  The SPOE engine name.

<group-name>   The SPOE group name as specified in the engine
               configuration.

set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]

set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -

Cette action permet d’activer le filtre de limitation de débit <name>, soit dans le sens montant, soit dans le sens descendant, selon le type de filtre. Une limite et une période personnalisées peuvent être définies, mais uniquement si <name> fait référence à un filtre de limitation de débit par flux. Lorsqu’une règle set-bandwidth-limit est exécutée, elle réinitialise d’abord toutes les paramètres du filtre à leurs valeurs par défaut avant de l’activer. En conséquence, si plusieurs actions set-bandwidth-limit sont exécutées pour le même filtre, seule la dernière est prise en compte. Plusieurs filtres de limitation de débit peuvent être activés sur un même flux.

Notez que cette action ne peut pas être utilisée dans une section defaults, car les filtres de limitation de bande passante ne peuvent pas être définis dans des sections defaults. En outre, seule la transmission du corps HTTP est limitée. Les en-têtes HTTP ne sont pas pris en compte.

Arguments :

<expr>  Is a standard HAProxy expression formed by a sample-fetch followed
        by some converters. The result is converted to an integer. It is
        interpreted as a size in bytes for the "limit" parameter and as a
        duration in milliseconds for the "period" parameter.

<size>  Is a number. It follows the HAProxy size format and is expressed in
        bytes.

<time>  Is a number. It follows the HAProxy time format and is expressed in
        milliseconds.

Exemple :

http-request set-bandwidth-limit global-limit
http-request set-bandwidth-limit my-limit limit 1m period 10s

Voir section 9.7 pour la configuration du filtre de limitation de bande passante.

set-bc-mark { <mark> | <expr> }

set-bc-mark { <mark> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cela permet de définir la marque Netfilter/IPFW sur la connexion backend (tous les paquets envoyés au serveur) à la valeur passée dans <mark> ou <expr> sur les plates-formes qui le supportent. Cette valeur est un entier non signé sur 32 bits pouvant être associée à netfilter/ipfw ainsi qu’aux tables de routage ou à la surveillance des paquets via DTrace. <mark> peut être exprimée en notation décimale ou hexadécimale (précédée de « 0x »). En alternative, <expr> peut être utilisé : il s’agit d’une expression standard HAProxy composée d’une récupération d’échantillon suivie de convertisseurs qui doivent aboutir à un type entier. Cette action peut être utile pour forcer certains paquets à emprunter un chemin différent (par exemple, un chemin réseau moins coûteux pour les téléchargements massifs). Cette fonctionnalité est disponible sur les noyaux Linux 2.6.32 et versions ultérieures, nécessite des privilèges d’administrateur, ainsi que sur FreeBSD et OpenBSD. La marque est définie pour toute la durée de la connexion backend/server (de la connexion à la fermeture).

set-bc-tos { <tos> | <expr> }

set-bc-tos { <tos> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cela permet de définir la valeur du champ TOS ou DSCP sur la connexion au backend (tous les paquets envoyés au serveur) à la valeur passée dans <tos> ou <expr> sur les plates-formes qui le supportent. Cette valeur représente les 8 bits entiers du champ TOS IP. Notez que seuls les 6 bits supérieurs sont utilisés en DSCP ou TOS, tandis que les deux bits inférieurs sont toujours à 0. En alternative, <expr> peut être utilisé : il s’agit d’une expression standard HAProxy composée d’un extrait de données suivi de convertisseurs, qui doit aboutir à un type entier. Cette action peut être utilisée pour ajuster certains comportements de routage sur les routeurs internes en fonction d’informations provenant de la requête. Le champ TOS sera défini pour toute la durée de la connexion backend/server (de la connexion à la fermeture).

Voir les RFC 2474, 2597, 3260 et 4594 pour plus d’informations.

set-dst <expr>

set-dst <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -

Cela permet de définir l’adresse IP de destination avec la valeur de l’expression spécifiée. Utile lorsque un proxy placé devant HAProxy modifie l’adresse IP de destination, mais fournit l’IP correcte dans un en-tête HTTP ; ou lorsque vous souhaitez masquer l’IP pour des raisons de confidentialité. Si vous souhaitez vous connecter au nouvel address/port, utilisez « 0.0.0.0:0 » comme adresse de serveur dans le backend.

Arguments :

<expr>  Is a standard HAProxy expression formed by a sample-fetch followed
        by some converters.

Exemple :

http-request set-dst hdr(x-dst)
http-request set-dst dst,ipmask(24)

Lorsqu’il est possible, set-dst conserve le port de destination d’origine tant que la famille d’adresses le permet ; sinon, le port de destination est défini à 0.

set-dst-port <expr>

set-dst-port <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -

Cela permet de définir le port de destination selon la valeur de l’expression spécifiée. Si vous souhaitez vous connecter au nouveau address/port, utilisez ‘0.0.0.0:0’ comme adresse serveur dans le backend.

Arguments :

<expr>  Is a standard HAProxy expression formed by a sample-fetch
        followed by some converters.

Exemple :

http-request set-dst-port hdr(x-port)
http-request set-dst-port int(4000)

Lorsqu’il est possible, set-dst-port préserve l’adresse de destination d’origine tant que la famille d’adresse prend en charge un port ; sinon, il force l’adresse de destination à IPv4 “0.0.0.0” avant de réécrire le port.

set-fc-mark { <mark> | <expr> }

set-fc-mark { <mark> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -

Cela permet de définir la marque Netfilter/IPFW sur tous les paquets envoyés au client avec la valeur transmise dans <mark> ou <expr> sur les plates-formes qui le supportent. Cette valeur est un entier non signé sur 32 bits pouvant être associée à netfilter/ipfw ainsi qu’à la table de routage ou surveillée via DTrace. <mark> peut être exprimé en notation décimale ou hexadécimale (précédée de « 0x »). En alternative, <expr> peut être utilisé : il s’agit d’une expression standard HAProxy composée d’une récupération d’échantillon suivie de convertisseurs, qui doit aboutir à un type entier. Cette action peut être utile pour forcer certains paquets à emprunter un chemin différent (par exemple, un chemin réseau moins coûteux pour les téléchargements massifs). Cette fonctionnalité est disponible sur les noyaux Linux 2.6.32 et ultérieurs, nécessite des privilèges d’administrateur, ainsi que sur FreeBSD et OpenBSD.

set-fc-tos { <tos | <expr> }

set-fc-tos { <tos | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -

Cela permet de définir la valeur du champ TOS ou DSCP des paquets envoyés au client à la valeur transmise via <tos> ou <expr> sur les plates-formes qui le supportent. Cette valeur représente les 8 bits entiers du champ TOS IP. Notez que seuls les 6 bits supérieurs sont utilisés en DSCP ou TOS, tandis que les deux bits inférieurs sont toujours à 0. En alternative, <expr> peut être utilisé : il s’agit d’une expression standard HAProxy composée d’un échantillonnage suivi de convertisseurs, qui doit se résoudre en un type entier. Cette action peut être utilisée pour ajuster certains comportements de routage sur les routeurs frontières en fonction d’informations provenant de la requête.

Voir les RFC 2474, 2597, 3260 et 4594 pour plus d’informations.

set-header <name> <fmt>

set-header <name> <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela a le même effet que l’action « add-header », sauf que l’en-tête est d’abord supprimé s’il existait déjà. Cela est utile lors du passage d’informations de sécurité au serveur, où l’en-tête ne doit pas être manipulé par des utilisateurs externes, ou pour forcer certains en-têtes de réponse tels que « Server » afin de masquer des informations externes. Notez que la nouvelle valeur est calculée avant la suppression, ce qui permet de concaténer une valeur à un en-tête existant.

Exemple :

http-request set-header X-Haproxy-Current-Date %T
http-request set-header X-SSL                  %[ssl_fc]
http-request set-header X-SSL-Session_ID       %[ssl_fc_session_id,hex]
http-request set-header X-SSL-Client-Verify    %[ssl_c_verify]
http-request set-header X-SSL-Client-DN        %{+Q}[ssl_c_s_dn]
http-request set-header X-SSL-Client-CN        %{+Q}[ssl_c_s_dn(cn)]
http-request set-header X-SSL-Issuer           %{+Q}[ssl_c_i_dn]
http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
http-request set-header X-SSL-Client-NotAfter  %{+Q}[ssl_c_notafter]

set-headers-bin <expr> [ prefix <str> ]

set-headers-bin <expr> [ prefix <str> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Il s’agit d’une variante de l’action « set-header » où les noms et les valeurs des en-têtes sont transmis sous forme de chaîne binaire encodée en varint. Consultez l’extraction d’échantillon “req.hdrs_bin” pour en savoir plus sur le format varint. Cette fonctionnalité est utile lorsque vous souhaitez définir plusieurs en-têtes à la fois, sans avoir besoin de connaître à l’avance les noms des en-têtes. Notez que ces en-têtes n’ont pas été validés par le parseur HTTP et pourraient entraîner l’émission de messages non valides, voire, dans les cas les plus graves, des attaques par camouflage de requête. Le nombre d’en-têtes insérés est également important, car il est limité par tune.http.maxhdr. Un préfixe facultatif ne définira que les en-têtes provenant de la chaîne encodée qui commencent par <str>.

Exemple :

# This would reset the Accept/UA/Host headers to their initial values
http-request set-var(txn.oldheaders) req.hdrs_bin
http-request del-header Accept
http-request del-header User-Agent
http-request del-header Host
http-request set-headers-bin var(txn.oldheaders)

set-log-level <level>

set-log-level <level>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | X

Cela permet de modifier le niveau de journalisation de la requête en cours lorsque certaine condition est remplie. Les niveaux valides sont les 8 niveaux syslog (voir le mot-clé « log ») ainsi que le niveau spécial « silent », qui désactive la journalisation pour cette requête. Cette règle n’est pas définitive, aussi la dernière règle correspondante l’emporte. Cette règle peut être utile pour désactiver les contrôles d’état provenant d’un autre équipement.

set-map(<map-name>) <key fmt> <value fmt>

set-map(<map-name>) <key fmt> <value fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela permet d’ajouter une nouvelle entrée dans une carte. <map-name> doit suivre le format décrit dans 2.7. Concernant le format du nom des cartes et des listes ACL. Le nom de la MAP à mettre à jour est passé entre parenthèses. Elle prend 2 arguments : <key fmt>, qui suit les règles du format de journal personnalisé décrites dans section 8.2.6 , utilisé pour collecter la clé de la carte, et <value fmt>, qui suit les règles du format de journal personnalisé, utilisé pour collecter le contenu de la nouvelle entrée. Elle effectue une recherche dans la carte avant l’insertion, afin d’éviter les valeurs en double (ou supplémentaires). Elle équivaut à la commande « set map » depuis le socket de statistiques, mais peut être déclenchée par une requête HTTP.

set-mark <mark> (deprecated)

set-mark <mark> (deprecated)

Ceci est un alias de « set-fc-mark » (à utiliser à la place).

set-method <fmt>

set-method <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cette directive réécrit la méthode de la requête avec le résultat de l’évaluation de la chaîne de format <fmt>. Il devrait y avoir très peu de raisons valables pour le faire, car cela risque davantage de briser quelque chose que de le corriger.

set-nice <nice>

set-nice <nice>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | X | X | X | -

Cela définit le facteur « nice » de la request/response en cours de traitement. Il n’a d’effet que sur les autres requêtes traitées en même temps. La valeur par défaut est 0, sauf si elle est modifiée par le paramètre « nice » dans la ligne « bind ». La plage acceptée est -1024..1024.. Plus la valeur est élevée, plus la requête est « gentille ». Les valeurs plus faibles rendent la requête plus prioritaire que les autres. Cette option peut être utile pour accélérer certaines requêtes ou réduire la priorité des requêtes non importantes. Son utilisation sans expérimentation préalable peut entraîner des ralentissements importants.

set-path <fmt>

set-path <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cette directive réécrit le chemin de la requête avec le résultat de l'évaluation de la chaîne de format `<fmt>`. La chaîne de requête, le cas échéant, est conservée telle quelle. Si un schéma et une autorité sont présents avant le chemin, ils sont également conservés. Si la requête ne contient pas de chemin ("*"), celui-ci est remplacé par la chaîne de format. Cette fonctionnalité peut être utilisée, par exemple, pour ajouter un composant de répertoire au début d'un chemin. Voir également « http-request set-query » et « http-request set-uri ».

Exemple :

# prepend the host name before the path
http-request set-path /%[hdr(host)]%[path]

set-pathq <fmt>

set-pathq <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela a le même effet que « http-request set-path », sauf que la chaîne de requête est également réécrite. Il peut être utilisé pour supprimer la chaîne de requête, y compris le point d’interrogation (ce qui n’est pas possible avec « http-request set-query »).

set-priority-class <expr>

set-priority-class <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cela permet de définir la classe de priorité de la file d’attente de la requête courante. La valeur doit être une expression échantillonnée qui se convertit en entier dans la plage -2047..2047.. Les valeurs en dehors de cette plage seront tronquées. La classe de priorité détermine l’ordre dans lequel les requêtes en file d’attente sont traitées. Les valeurs plus faibles ont une priorité plus élevée.

set-priority-offset <expr>

set-priority-offset <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cela permet de définir le décalage d’horodatage de priorité de la requête courante. La valeur doit être une expression d’échantillonnage qui se convertit en un entier compris dans la plage -524287..524287.. Les valeurs situées en dehors de cette plage seront tronquées. Lorsqu’une requête est mise en file d’attente, elle est triée d’abord par classe de priorité, puis par l’horodatage actuel ajusté selon le décalage indiqué, en millisecondes. Les valeurs plus faibles ont une priorité plus élevée. Notez que l’horodatage résultant n’est suivi qu’avec une précision suffisante pour 524 287 ms (8 min 44 s 287 ms). Si la requête est en file d’attente assez longtemps pour que l’horodatage ajusté dépasse cette valeur, elle sera mal identifiée comme ayant la priorité la plus élevée. Il est donc important de définir « timeout queue » avec une valeur telle que, combinée au décalage, elle ne dépasse pas cette limite.

set-query <fmt>

set-query <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela réécrit la chaîne de requête de la requête, située après le premier point d’interrogation ("?"), par le résultat de l’évaluation de la chaîne de format <fmt>. La partie située avant le point d’interrogation est conservée intacte. Si la requête ne contient pas de point d’interrogation et que la nouvelle valeur n’est pas vide, un point d’interrogation est ajouté à la fin de l’URI, suivi de la nouvelle valeur. Si un point d’interrogation était présent, il ne sera jamais supprimé, même si la valeur est vide. Cette fonctionnalité peut être utilisée pour ajouter ou supprimer des paramètres de la chaîne de requête.

Voir également « http-request set-query » et « http-request set-uri ».

Exemple :

# replace "%3D" with "=" in the query string
http-request set-query %[query,regsub(%3D,=,g)]

set-retries <int> | <epxr>

set-retries <int> | <epxr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cette action remplace la valeur « retries » spécifiée pour le flux actuel uniquement. Elle peut être une valeur entière comprise dans la plage [0, 100], ou une expression qui doit renvoyer un entier compris dans la plage [0, 100].

Notez que cette action n’est pertinente que du côté du backend et n’est donc disponible que pour les proxies disposant d’une capacité backend. Elle n’est pas autorisée dans les sections « defaults ». Lorsqu’elle est utilisée pour un écouteur, elle est évaluée dans le contexte du frontal. Ainsi, la valeur de réessais est conservée uniquement si le flux n’est pas acheminé vers un backend différent, par exemple via une règle use-backend. Dans le cas contraire, la valeur par défaut de réessais du backend sélectionné s’applique.

Exemple :

tcp-request content set-retries 3
http-request set-retries var(txn.retries)

set-src <expr>

set-src <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -

Cela permet de définir l’adresse IP source à la valeur de l’expression spécifiée. Utile lorsque un proxy placé devant HAProxy modifie l’adresse IP source, mais fournit l’IP correcte dans un en-tête HTTP ; ou lorsque vous souhaitez masquer l’adresse IP source pour des raisons de confidentialité. Toutes les appels ultérieurs à « src » récupéreront cette valeur (voir l’exemple).

Arguments :

<expr>  Is a standard HAProxy expression formed by a sample-fetch followed
        by some converters.

Voir également « option forwardfor ».

Exemple :

http-request set-src hdr(x-forwarded-for)
http-request set-src src,ipmask(24)

# After the masking this will track connections
# based on the IP address with the last byte zeroed out.
http-request track-sc0 src

Lorsqu’il est possible, l’option set-src conserve le port source d’origine tant que la famille d’adresses le permet ; sinon, le port source est défini à 0.

set-src-port <expr>

set-src-port <expr>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | - | -

Cela permet de définir l’adresse du port source à la valeur de l’expression spécifiée.

Arguments :

<expr>  Is a standard HAProxy expression formed by a sample-fetch followed
        by some converters.

Exemple :

http-request set-src-port hdr(x-port)
http-request set-src-port int(4000)

Lorsqu’il est possible, l’option set-src-port conserve l’adresse source d’origine tant que la famille d’adresses prend en charge un port ; sinon, elle force l’adresse source à IPv4 “0.0.0.0” avant de réécrire le port.

set-status <status> [reason <str>]

set-status <status> [reason <str>]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | - | X | X

Cela remplace le code d’état de la réponse par <status>, qui doit être un entier compris entre 100 et 999. Optionnellement, un texte de raison personnalisé peut être fourni, défini par <str>, ou la raison par défaut correspondant au code spécifié sera utilisée comme valeur de secours. Notez que la chaîne de raison n’existe que dans HTTP/1.x et est ignorée par les autres versions du protocole.

Exemple :

# return "431 Request Header Fields Too Large"
http-response set-status 431
# return "503 Slow Down", custom reason
http-response set-status 503 reason "Slow Down".

set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout> | <expr> }

set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout> | <expr> }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cette action remplace le délai d’expiration spécifié pour « client », « connect », « queue », « serveur », « tarpit » ou « tunnel » uniquement pour le flux courant. Modifier un délai d’expiration n’affecte aucun autre délai, même s’ils sont hérités les uns des autres lors de l’analyse de la configuration (voir le dernier exemple). Le délai d’expiration peut être spécifié en millisecondes ou avec toute autre unité si le nombre est suivi de l’unité, comme expliqué en haut de ce document. Il est également possible d’écrire une expression qui doit renvoyer un nombre interprété comme un délai d’expiration en millisecondes.

Notez que les délais d’expiration connect, queue, server et tunnel ne sont pertinents que du côté backend, et ce règle n’est donc disponible que pour les proxies disposant de capacités backend. De même, le délai d’expiration client n’est pertinent que du côté frontal. Le délai d’expiration tarpit est disponible des deux côtés. La valeur du délai d’expiration doit être non nulle pour obtenir les résultats attendus. Lorsque l’action est utilisée pour un écouteur, elle est évaluée dans le contexte frontal. Ainsi, les valeurs personnalisées pour les délais d’expiration côté backend sont conservées uniquement si le flux n’est pas acheminé vers un autre backend, par exemple via une règle use-backend. Sinon, les valeurs par défaut du backend sélectionné seront appliquées.

Exemple :

http-request set-timeout tunnel 5s
http-request set-timeout server req.hdr(host),map_int(host.lst)

Exemple :

http-response set-timeout tunnel 5s
http-response set-timeout server res.hdr(X-Refresh-Seconds),mul(1000)

Exemple :

defaults
  # This will set both tarpit and queue timeout to 5s as they are not
  # defined
  timeout connect 5s
  timeout client 30s
  timeout server 30s

listen foo
  # This will only change the connect timeout to 10s without affecting
  # queue or tarpit timeouts
  http-request set-timeout connect 10s

set-tos <tos> (deprecated)

set-tos <tos> (deprecated)

Ceci est un alias de « set-fc-tos » (à utiliser à la place).

set-uri <fmt>

set-uri <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela réécrit l’URI de la requête avec le résultat de l’évaluation de la chaîne de format <fmt>. Le schéma, l’autorité, le chemin et la chaîne de requête sont tous remplacés en même temps. Cela peut être utilisé pour réécrire des hôtes devant des proxies, ou pour effectuer des modifications complexes de l’URI, telles que le déplacement de parties entre le chemin et la chaîne de requête. Si une URI absolue est définie, elle sera envoyée telle quelle aux serveurs HTTP/1.1. Si ce n’est pas le comportement souhaité, l’hôte, le chemin et/ou la chaîne de requête doivent être définis séparément. Voir également « http-request set-path » et « http-request set-query ».

set-var(<var-name>[,<cond>...]) <expr>

set-var(<var-name>[,<cond>...]) <expr>
set-var-fmt(<var-name>[,<cond>...]) <fmt>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cela sert à définir le contenu d’une variable. La variable est déclarée en inline.

Arguments :

<var-name>   The name of the variable. Variable of the parent stream cannot
             be set. See section 2.8 about variables for details.

 <cond>      A set of conditions that must all be true for the variable to
             actually be set (such as "ifnotempty", "ifgt" ...). See the
             set-var converter's description for a full list of possible
             conditions.

 <expr>      Is a standard HAProxy expression formed by a sample-fetch
             followed by some converters.

 <fmt>       This is the value expressed using Custom log format rules (see
             Custom log format in section 8.2.6).

Toutes les portées sont utilisables pour les règles HTTP, mais seules les portées « proc » et « sess » sont disponibles dans les jeux de règles qui n’ont pas accès aux contenus tels que « tcp-request connection » et « tcp-request session ».

Exemple :

http-request set-var(req.my_var) req.fhdr(user-agent),lower
http-request set-var-fmt(txn.from) %[src]:%[src_port]

silent-drop [ rst-ttl <ttl> ]

silent-drop [ rst-ttl <ttl> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | -

Cela arrête l’évaluation des règles et fait disparaître soudainement la connexion côté client selon une méthode dépendante du système, visant à empêcher la notification du client. Lorsqu’il est appelé sans l’argument rst-ttl, nous tentons d’éviter l’envoi de tout paquet FIN ou RST au client en utilisant TCP_REPAIR. Si cette tentative échoue (notamment en raison d’un manque de privilèges), nous passons à l’envoi d’un paquet RST avec un TTL de 1.

L’effet est que le client perçoit toujours une connexion établie, alors qu’aucune connexion n’existe côté HAProxy, ce qui permet d’économiser des ressources. Toutefois, tout équipement étatique placé entre HAProxy et le client (pare-feux, proxies, répartiteurs de charge) conservera également la connexion établie dans ses tables de session.

Le paramètre facultatif rst-ttl modifie ce comportement : TCP_REPAIR n’est pas utilisé, et un paquet RST avec un TTL configurable est envoyé. Lorsqu’il est défini à une valeur raisonnable, le paquet RST traverse l’infrastructure locale, supprimant la connexion dans les pare-feu et d’autres systèmes, mais disparaît avant d’atteindre le client. Les paquets ultérieurs provenant du client seront alors rejetés directement par l’équipement frontal. Ces RST locaux protègent les ressources locales, mais non le client. Cette fonctionnalité ne doit pas être utilisée à moins que les conséquences de son utilisation soient entièrement comprises.

strict-mode { on | off }

strict-mode { on | off }

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | X

Cela active ou désactive le mode de réécriture stricte pour les règles suivantes. Il n’affecte pas les règles déclarées auparavant et n’est applicable qu’aux règles effectuant une réécriture sur les requêtes. Lorsque le mode strict est activé, toute erreur de réécriture déclenche une erreur interne. Sinon, de telles erreurs sont ignorées silencieusement. Le but du mode de réécriture stricte est de rendre certaines réécritures facultatives tout en rendant obligatoires d’autres réécritures pour poursuivre le traitement des requêtes.

Par défaut, le mode de réécriture strict est activé. Sa valeur est également réinitialisée lorsque l’évaluation d’un jeu de règles se termine. Ainsi, par exemple, si vous modifiez le mode sur le frontal, le mode par défaut est restauré lorsque HAProxy commence l’évaluation des règles du backend.

switch-mode http [ proto <name> ]

switch-mode http [ proto <name> ]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | - | - | -

Cette action est utilisée pour effectuer une mise à niveau de connexion. Seules les mises à niveau HTTP sont actuellement prises en charge. Le protocole peut éventuellement être précisé. Cette action n’est disponible que pour un proxy disposant de la capacité frontal. La mise à niveau de connexion est immédiatement effectuée ; les règles définies par “tcp-request content” ne sont pas évaluées. Cette méthode de mise à niveau doit être privilégiée à la méthode implicite consistant à s’appuyer sur le mode backend. Lorsqu’elle est utilisée, il est possible de définir des directives HTTP dans un frontal sans avertissement. Ces directives seront évaluées de manière conditionnelle si la mise à niveau HTTP est effectuée. Toutefois, un backend HTTP doit toujours être sélectionné. Il reste impossible de router une connexion HTTP (mise à niveau ou non) vers un serveur TCP.

Consultez section 4 pour en savoir plus sur les mises à jour HTTP.

tarpit [ { status | deny_status } <code>] [content-type <type>]

tarpit [ { status | deny_status } <code>] [content-type <type>]
       [ { default-errorfiles | errorfile <file> | errorfiles <name> |
       file `<file>` | lf-file `<file>` | string `<str>` | lf-string `<fmt>` } ]
   [ hdr `<name>` `<fmt>` ]*

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela arrête l’évaluation des règles et bloque immédiatement la requête sans réponse pendant un délai spécifié par « timeout tarpit » ou « timeout connect » si le premier n’est pas défini. Après ce délai, si le client reste connecté, une réponse est renvoyée afin que le client ne soupçonne pas avoir été tarpité. Les journaux signaleront les indicateurs « PT ». Le but de la règle tarpit est de ralentir les robots pendant une attaque, lorsque ceux-ci sont limités en nombre de requêtes simultanées. Elle peut être très efficace contre des robots très rudimentaires, et réduire considérablement la charge sur les pare-feu par rapport à une règle « deny ». Toutefois, face à des robots correctement conçus, elle peut aggraver la situation en obligeant HAProxy et le pare-feu frontal à gérer un nombre insensé de connexions simultanées. Par défaut, une erreur HTTP 500 est renvoyée. Toutefois, la réponse peut être personnalisée en utilisant la même syntaxe que les règles « http-request return ». Voir « http-request return » pour les détails.

Pour des raisons de compatibilité, lorsque aucun argument n’est défini, ou uniquement “deny_status”, l’argument « default-errorfiles » est implicite. Cela signifie que « http-request tarpit [deny_status <status>] » est un alias de « http-request tarpit [status <status>] default-errorfiles ». Aucune règle supplémentaire « http-request » n’est évaluée. Voir également « http-request return » et « http-request silent-drop ».

track-sc0 <key> [table <table>]

track-sc0 <key> [table <table>]
track-sc1 <key> [table <table>]
track-sc2 <key> [table <table>]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | - | X | X | -

Cela active le suivi des compteurs de persistance à partir de la requête en cours. Ces règles n’interrompent pas l’évaluation ni ne modifient l’action par défaut. Le nombre de compteurs pouvant être suivis simultanément par la même connexion est défini par le paramètre global “tune.stick-counters”, qui vaut MAX_SESS_STKCTR s’il est défini au moment de la compilation (il est indiqué dans HAProxy -vv) et qui vaut 3 par défaut, de sorte que le nombre de suivi de compteurs (track-sc) est compris entre 0 et (tune.stick-counters-1). La première règle « track-sc0 » exécutée active le suivi des compteurs du tableau spécifié comme premier ensemble. La première règle « track-sc1 » exécutée active le suivi des compteurs du tableau spécifié comme deuxième ensemble. La première règle « track-sc2 » exécutée active le suivi des compteurs du tableau spécifié comme troisième ensemble. Il est recommandé d’utiliser le premier ensemble de compteurs pour les compteurs par frontal et le second ensemble pour les compteurs par backend. Mais il s’agit simplement d’une orientation ; tous les ensembles peuvent être utilisés partout.

Arguments :

<key>   is mandatory, and is a sample expression rule as described in
        section 7.3. It describes what elements of the incoming connection,
        request or response will be analyzed, extracted, combined, and used
        to select which table entry to update the counters.

<table> is an optional table to be used instead of the default one, which
        is the stick-table declared in the current proxy. All the counters
        for the matches and updates for the key will then be performed in
        that table until the session ends.

Une fois qu’une règle « track-sc* » a été exécutée, la clé est recherchée dans la table. Si elle n’est pas trouvée, une entrée lui est attribuée. Ensuite, un pointeur vers cette entrée est conservé pendant toute la durée de la session, et les compteurs de cette entrée sont mis à jour aussi fréquemment que possible, à chaque mise à jour des compteurs de la session, ainsi qu’au moment systématique de la fin de la session. Les compteurs ne sont mis à jour que pour les événements survenus après le démarrage du suivi. À titre d’exception, les compteurs de connexion et les compteurs de requête sont systématiquement mis à jour afin de refléter des informations utiles.

Si l’entrée suit les compteurs de connexions simultanées, une connexion est comptabilisée tant que l’entrée est suivie, et l’entrée ne peut pas expirer pendant cette période. Le suivi des compteurs offre également un avantage de performance par rapport à la simple vérification des clés, car une seule recherche dans la table est effectuée pour toutes les vérifications ACL qui en font usage.

unset-var(<var-name>)

unset-var(<var-name>)

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | X | X | X | X | X | X | X

Cela sert à supprimer une variable. Consultez l’action « set-var » pour plus de détails sur <var-name>.

Exemple :

http-request unset-var(req.my_var)

use-service <service-name>

use-service <service-name>

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | X | - | X | - | -

Cette action exécute le service TCP ou HTTP configuré pour répondre à la requête, selon la règle dans laquelle elle est utilisée. La règle est finale, c’est-à-dire qu’aucune autre règle n’est évaluée dans le même ensemble de règles.

Un service peut choisir de répondre en envoyant une réponse valide ou de fermer immédiatement la connexion sans envoyer de réponse. Pour les services HTTP, une réponse valide nécessite une réponse HTTP valide. En dehors des services natifs, par exemple l’exportateur Prometheus pour les services HTTP, il est possible d’écrire des services TCP et HTTP personnalisés en Lua.

Arguments :

<service-name>  is mandatory. It is the service to call

Exemple :

http-request use-service prometheus-exporter if { path /metrics }

wait-for-body time <time> [ at-least <bytes> ] [use-large-buffer]

wait-for-body time <time> [ at-least <bytes> ] [use-large-buffer]

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | X | -

Cela retardera le traitement de la requête ou de la réponse jusqu’à ce qu’une des conditions suivantes se produise :

  • Le corps complet de la requête a été reçu, auquel cas le traitement s’effectue normalement.
  • <bytes> octets ont été reçus, lorsque l’argument « at-least » est fourni et que <bytes> est non nul, auquel cas le traitement s’effectue normalement.
  • Le tampon de requête est plein, auquel cas le traitement s’effectue normalement. La taille de ce tampon est déterminée par l’option “tune.bufsize”.
  • La requête attend depuis plus de <time> millisecondes. Dans ce cas, HAProxy répondra à la client avec une erreur 408 « Request Timeout » et interrompra le traitement de la requête. Notez qu’en cas de survenance d’une autre condition en premier, ce délai d’expiration ne sera pas déclenché, même si le corps complet n’a pas encore été reçu.

L’option « use-large-buffer » peut être définie pour allouer un tampon volumineux si le tampon régulier est trop petit pour stocker le corps du message. Pour être utilisée, l’option globale “tune.bufsize.large” doit être définie.

Cette action peut être utilisée comme remplacement de « option http-buffer-request ».

Arguments :

<time>    is mandatory. It is the maximum time to wait for the body. It
          follows the HAProxy time format and is expressed in milliseconds.

<bytes>   is optional. It is the minimum payload size to receive to stop to
          wait. It follows the HAProxy size format and is expressed in
          bytes. A value of 0 (the default) means no limit.

Exemple :

http-request wait-for-body time 1s at-least 1k if METH_POST

Voir également : « option http-buffer-request » et “tune.bufsize.large”

wait-for-handshake

wait-for-handshake

Utilisable dans : QUIC Ini| TCP RqCon| RqSes| RqCnt| RsCnt| HTTP Req| Res| Aft - | - | - | - | - | X | - | -

Cela retardera le traitement de la requête jusqu’à l’achèvement de la négociation SSL. Cela est principalement utile pour retarder le traitement des données préliminaires jusqu’à ce que nous soyons certains de leur validité.

14 - 5. Options de liaison et de serveur

Options d’écouteur, de serveur, par défaut et de résolution DNS

Les mots-clés « bind », « server » et « default-server » prennent en charge un certain nombre de paramètres, selon certains options de compilation et le système sur lequel HAProxy a été compilé. Ces paramètres sont généralement composés d’un mot, parfois suivi d’une valeur, écrits sur la même ligne que la directive « bind » ou « server ». Tous ces paramètres sont décrits dans cette section.

5.1. Options de liaison

Le mot-clé « bind » prend en charge un certain nombre de paramètres, tous transmis sous forme d’arguments sur la même ligne. L’ordre dans lequel ces arguments apparaissent n’a aucune importance, à condition qu’ils figurent après l’adresse bind. Tous ces paramètres sont facultatifs. Certains sont des mots simples (valeurs booléennes), tandis que d’autres exigent une valeur immédiatement après leur nom. Dans ce cas, la valeur doit être fournie sans interruption après le nom du paramètre.

Les paramètres actuellement pris en charge sont les suivants.

accept-netscaler-cip <magic number>

accept-netscaler-cip <magic number>

Force l’utilisation du protocole d’insertion de l’adresse IP client NetScaler sur toutes les connexions acceptées par l’un des sockets TCP déclarés sur la même ligne. Le protocole d’insertion de l’adresse IP client NetScaler indique les adresses couche 3/4 de la connexion entrante à utiliser partout où une adresse est utilisée, à l’exception des règles « tcp-request connection » qui ne verront que l’adresse réelle de la connexion. Les journaux reflètent les adresses indiquées dans le protocole, sauf en cas de violation, auquel cas l’adresse réelle est toujours utilisée. Ce mot-clé, combiné à un support provenant de composants externes, peut servir de solution alternative efficace et fiable au mécanisme X-Forwarded-For, qui n’est pas toujours fiable et même parfois inutilisable. Voir également « tcp-request connection expect-netscaler-cip » pour une configuration plus fine indiquant quels clients sont autorisés à utiliser le protocole.

accept-proxy

accept-proxy

Force l’utilisation du protocole PROXY sur toutes les connexions acceptées par l’un des sockets déclarés sur la même ligne. Les versions 1 et 2 du protocole PROXY sont prises en charge et détectées correctement. Le protocole PROXY indique les adresses couche 3/4 de la connexion entrante, qui seront utilisées partout où une adresse est requise, à l’exception des règles « tcp-request connection » qui ne verront que l’adresse réelle de la connexion. Les journaux reflètent les adresses indiquées dans le protocole, sauf en cas de violation, auquel cas l’adresse réelle sera utilisée. Ce mot-clé, combiné à la prise en charge par des composants externes, peut servir d’alternative efficace et fiable au mécanisme X-Forwarded-For, qui n’est pas toujours fiable et même parfois inutilisable. Voir également « tcp-request connection expect-proxy » pour une configuration plus fine de quels clients sont autorisés à utiliser le protocole.

allow-0rtt

allow-0rtt

Autoriser la réception de données anticipées lors de l’utilisation de TLSv1.3. Cette fonctionnalité est désactivée par défaut, en raison de considérations de sécurité. Étant donné qu’elle est vulnérable aux attaques par répétition, vous ne devez l’autoriser que pour les requêtes qui sont sans danger en cas de répétition, c’est-à-dire les requêtes idempotentes. Vous pouvez utiliser l’action « wait-for-handshake » pour toute requête qui ne serait pas sûre avec des données anticipées. Avec QUIC, le 0rtt est pris en charge avec QuicTLS, OpenSSL >= 3.5.2 et AWS-LC. Avec TCP/TLS, le 0rtt n’est pris en charge qu’avec OpenSSL, et nécessite que le client envoie un ALPN, sinon les données anticipées ne seront pas prises en compte avant la fin de l’établissement de la connexion.

alpn <protocols>

alpn <protocols>

Cela active l’extension TLS ALPN et annonce la liste de protocoles spécifiée comme prise en charge au-dessus d’ALPN. La liste de protocoles est constituée d’une liste séparée par des virgules de noms de protocoles, par exemple : “http/1.1,http/1.0” (sans guillemets). Cela nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifiez avec haproxy -vv). L’extension ALPN remplace l’extension NPN initiale. Au niveau du protocole, ALPN est obligatoire pour activer HTTP/2 sur un frontal HTTPS et HTTP/3 sur un frontal QUIC. Toutefois, lorsque ces frontaux n’ont aucun des paramètres “npn”, “alpn” ou “no-alpn” définis, une valeur par défaut de “h2,http/1.1” sera utilisée pour un frontal HTTPS régulier, et “h3” pour un frontal QUIC. Les versions d’OpenSSL antérieures à 1.0.2 ne prennent pas en charge ALPN et ne supportaient que l’extension NPN obsolète. Au moment de la rédaction de ce document, la plupart des navigateurs prennent encore en charge à la fois ALPN et NPN pour HTTP/2, de sorte qu’une bascule vers NPN peut encore fonctionner pendant un certain temps. Mais ALPN doit être utilisé chaque fois que possible. Les protocoles non annoncés ne sont pas négociés. Par exemple, il est possible d’accepter uniquement les connexions HTTP/2 avec ceci :

bind:443 ssl crt pub.pem alpn h2  # explicitly disable HTTP/1.1

QUIC ne prend en charge que h3 et hq-interop comme ALPN. h3 est utilisé pour HTTP/3, tandis que hq-interop est utilisé pour http/0.9 et pour le test d’interopérabilité QUIC (voir https://interop.seemann.io ). Chaque instruction « alpn » remplace la précédente. Pour les supprimer, utilisez « no-alpn ».

Notez que certains anciens navigateurs, comme Firefox 88, ont pu rencontrer des problèmes avec WebSocket sur H2, et dans un tel cas, il peut être nécessaire de désactiver explicitement HTTP/2 dans la chaîne “alpn” en la forçant à “http/1.1” ou “no-alpn”, ou d’activer globalement l’option “h2-workaround-bogus-websocket-clients”.

backlog <backlog>

backlog <backlog>

Définit la file d’attente du socket à cette valeur. Si non spécifié ou égal à 0, la file d’attente du frontal est utilisée à la place, qui est généralement définie par la valeur maxconn.

ca-file <cafile>

ca-file <cafile>

Ce paramètre n’est disponible que si le support OpenSSL a été inclus. Il indique un fichier PEM à partir duquel charger les certificats CA utilisés pour vérifier le certificat du client. Il est possible de charger un répertoire contenant plusieurs CA ; dans ce cas, HAProxy tentera de charger chaque “.pem”, “.crt”, “.cer”, ainsi que chaque fichier .crl présent dans le répertoire. Les fichiers commençant par un point sont ignorés.

Avertissement : Le paramètre “@system-ca” peut être utilisé à la place de cafile afin d’utiliser les certificats CA fiables de votre système, comme cela est fait avec la directive server. Toutefois, vous ne devez pas l’utiliser à moins de savoir ce que vous faites. Configurer cela signifie essentiellement que la liaison acceptera tout certificat client généré à partir d’une des autorités de certification présentes sur votre système, ce qui est extrêmement dangereux.

ca-ignore-err [all|<errorID>,...]

ca-ignore-err [all|<errorID>,...]

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Définit une liste séparée par des virgules d’identifiants d’erreur à ignorer lors de la vérification à une profondeur supérieure à 0. Il peut s’agir d’un identifiant numérique ou du nom de constante (X509_V_ERR), disponible dans la documentation OpenSSL : https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES . Il est recommandé d’utiliser le nom de constante, car la valeur numérique peut évoluer dans les nouvelles versions d’OpenSSL. Si cette option est définie sur « all », toutes les erreurs sont ignorées. La négociation SSL n’est pas interrompue si une erreur est ignorée.

ca-sign-file <cafile>

ca-sign-file <cafile>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il indique un fichier PEM contenant à la fois le certificat de l’autorité de certification (CA) et la clé privée de la CA utilisées pour créer et signer les certificats serveur. Il s’agit d’un paramètre obligatoire lorsque la génération dynamique des certificats est activée. Voir « generate-certificates » pour plus de détails.

ca-sign-pass <passphrase>

ca-sign-pass <passphrase>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il correspond à la phrase secrète de la clé privée de l’autorité de certification. Ce paramètre est facultatif et n’est utilisé que lorsque la génération dynamique des certificats est activée. Voir « generate-certificates » pour plus de détails.

ca-verify-file <cafile>

ca-verify-file <cafile>

Ce paramètre indique un fichier PEM à partir duquel charger les certificats CA utilisés pour vérifier le certificat du client. Il désigne les certificats CA qui ne doivent pas être inclus dans les noms de CA envoyés dans le message de salutation du serveur. En général, « ca-file » doit être défini avec les certificats intermédiaires, et « ca-verify-file » avec les certificats finalisant la chaîne, comme la CA racine.

cc <algo>

cc <algo>

Ce paramètre n’est disponible que sur les systèmes définissant TCP_CONGESTION, et a été validé sur Linux et FreeBSD. Il prend le nom d’un algorithme de contrôle de congestion TCP et configure l’écouteur pour qu’il utilise cet algorithme sur toutes les connexions acceptées par cet écouteur. Les noms courants incluent « reno », « cubic », et dépendent de l’ système. Sur certains systèmes, des autorisations spéciales peuvent être nécessaires pour configurer certains algorithmes. Sur Linux, la liste des algorithmes disponibles se trouve dans le sysctl “net.ipv4.tcp_available_congestion_control”, et la liste de ceux autorisés sans privilèges se trouve dans “net.ipv4.tcp_allowed_congestion_control”. Pour accéder aux algorithmes nécessitant des autorisations supplémentaires, la capacité “cap_net_admin” peut être requise (voir « setcap » dans la section globale). En cas d’échec de configuration d’un algorithme de contrôle de congestion spécifique, l’algorithme par défaut reste inchangé et un avertissement est émis pour signaler le problème. Voir également : le mot-clé serveur « cc » (section 5.2 ). Exemple :

frontend public
    bind:443 cc bbr   # use the BBR algorithm for high bandwidths

ciphers <ciphers>

ciphers <ciphers>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de chiffrement (“cipher suite”) négociés lors de l’établissement de la connexion SSL/TLS jusqu’à TLSv1.2. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL. Pour des informations complémentaires et des recommandations, consulter par exemple (https://wiki.mozilla.org/Security/Server_Side_TLS ) et (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Pour la configuration des chiffrements TLSv1.3, se référer à la directive « ciphersuites ».

ciphersuites <ciphersuites>

ciphersuites <ciphersuites>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré et si OpenSSL 1.1.1 ou une version ultérieure a été utilisée pour compiler HAProxy. Il définit la chaîne décrivant la liste des algorithmes de chiffrement (“cipher suite”) négociés lors de la négociation TLSv1.3. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL, dans la section « ciphersuites ». Pour la configuration des chiffrements TLSv1.2 et versions antérieures, veuillez consulter le mot-clé « ciphers ». Ce paramètre peut accepter des suites de chiffrement TLSv1.2, mais cette fonctionnalité n’est pas documentée et n’est pas recommandée, car elle pourrait être incohérente ou défaillante. Les suites de chiffrement TLSv1.3 par défaut d’OpenSSL sont : “TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256”

TLSv1.3 ne prend en charge que 5 suites de chiffrement :

  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_AES_128_CCM_8_SHA256

Exemple :

ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256
ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

client-sigalgs <sigalgs>

client-sigalgs <sigalgs>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de signature liés à l’authentification cliente qui sont négociés. Le format de la chaîne est défini dans « man 3 SSL_CTX_set1_client_sigalgs » des pages de documentation OpenSSL. Il est déconseillé d’utiliser ce paramètre si aucun cas d’utilisation spécifique n’a été identifié.

crl-file <crlfile>

crl-file <crlfile>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il indique un fichier PEM à partir duquel charger la liste de révocation de certificats utilisée pour vérifier le certificat du client. Vous devez fournir une liste de révocation de certificats pour chaque certificat de votre chaîne d’autorité de certification.

crt <cert>

crt <cert>

Ce paramètre n’est disponible que lorsque le support d’OpenSSL a été intégré.

HAProxy utilise un système de mise en cache : les fichiers sont chargés une seule fois dans le stockage des certificats, et chaque mot-clé « crt » suivant utilise cette version mise en cache. Lorsqu’un certificat est déclaré dans un « crt-store », le stockage des certificats est peuplé à partir de ce dernier et ne tente pas de charger des fichiers supplémentaires en détectant les extensions de fichier.

Il désigne un fichier PEM contenant à la fois les certificats requis et les clés privées associées. Ce fichier peut être construit en concaténant plusieurs fichiers PEM en un seul (par exemple : cat cert.pem key.pem > combined.pem). Si votre autorité de certification exige un certificat intermédiaire, celui-ci peut également être concaténé dans ce fichier. Le certificat intermédiaire peut également être partagé via le répertoire indiqué par la directive « issuers-chain-path ».

Si le fichier ne contient pas de clé privée, HAProxy tentera de charger la clé au même chemin, suffixé par un “.key”.

Si l’OpenSSL utilisé prend en charge le Diffie-Hellman, les paramètres présents dans ce fichier sont chargés.

Si un nom de répertoire est utilisé au lieu d’un fichier PEM, tous les fichiers trouvés dans ce répertoire seront chargés dans l’ordre alphabétique, sauf ceux dont le nom se termine par ‘.key’, ‘.issuer’, ‘.ocsp’ ou ‘.sctl’ (extensions réservées). Les fichiers commençant par un point sont également ignorés. Cette directive peut être spécifiée plusieurs fois afin de charger des certificats depuis plusieurs fichiers ou répertoires. Les certificats seront présentés aux clients qui fournissent un champ TLS Server Name Indication valide correspondant à l’un de leurs CN ou sujets alternatifs. Les caractères génériques sont pris en charge, où un caractère générique ‘*’ remplace le premier composant du nom d’hôte (par exemple, *.example.org correspond à www.example.org mais pas à www.sub.example.org ). Si un répertoire vide est utilisé, HAProxy ne démarrera pas à moins que le mot-clé “strict-sni” soit utilisé.

Si aucun SNI n’est fourni par le client ou si la bibliothèque SSL ne prend pas en charge les extensions TLS, ou si le client fournit un nom d’hôte SNI ne correspondant à aucun certificat, alors le premier certificat chargé sera présenté. Cela signifie qu’en chargeant des certificats à partir d’un répertoire, il est fortement recommandé de charger en premier le certificat par défaut, soit sous forme de fichier, soit en veillant à ce qu’il soit toujours le premier dans le répertoire. Pour choisir plusieurs certificats par défaut (1 RSA et 1 ECDSA), il existe 3 options :

  • Un bundle de certificats multiple peut être configuré comme le premier certificat (crt foobar.pem dans la configuration où les fichiers existants sont foobar.pem.ecdsa et foobar.pem.rsa).
  • Ou un filtre ‘*’ pour chaque certificat dans une ligne crt-list.
  • Le mot-clé ‘default-crt’ peut être utilisé.

Notez que le même certificat peut être chargé plusieurs fois sans effet secondaire.

Certains autorités de certification (comme GoDaddy) proposent une liste déroulante de types de serveurs qui ne comprend pas HAProxy lors de l’obtention d’un certificat. Si cela se produit, veillez à sélectionner un serveur web que l’autorité de certification considère comme nécessitant une autorité de certification intermédiaire (pour GoDaddy, le choix d’Apache Tomcat permet d’obtenir le bundle correct, mais de nombreux autres, par exemple NGINX, entraînent un bundle erroné qui ne fonctionnera pas pour certains clients).

Pour chaque fichier PEM, HAProxy vérifie la présence d’un fichier au même chemin, suffixé par “.ocsp”. Si un tel fichier est trouvé, le support de l’extension « Certificate Status Request » TLS (également appelée « OCSP stapling ») est activé automatiquement. Le contenu de ce fichier est facultatif. S’il n’est pas vide, il doit contenir une réponse OCSP valide au format DER. Pour être valide, une réponse OCSP doit respecter les règles suivantes : indiquer un statut « bon », être une réponse unique pour le certificat du fichier PEM, et être valide au moment de son ajout. Si ces règles ne sont pas respectées, la réponse OCSP est ignorée et un avertissement est émis. Pour identifier le certificat auquel une réponse OCSP s’applique, le certificat de l’émetteur est nécessaire. Si le certificat de l’émetteur n’est pas présent dans le fichier PEM, il sera chargé à partir d’un fichier situé au même chemin que le fichier PEM, suffixé par “.issuer”. Si ce fichier n’existe pas, l’opération échoue avec une erreur.

Pour chaque fichier PEM, HAProxy vérifie également la présence d’un fichier au même chemin, suffixé par “.sctl”. Si un tel fichier est trouvé, le support de l’extension TLS Certificate Transparency (RFC6962) est activé. Le fichier doit contenir une liste valide de timestamps de certificat signés, comme décrit dans le RFC. Le fichier est analysé pour vérifier sa syntaxe de base, mais aucune signature n’est vérifiée.

Il existe des cas où il est souhaitable de prendre en charge plusieurs types de clés, par exemple RSA et ECDSA dans les suites de chiffrement proposées aux clients. Cela permet aux clients prenant en charge les certificats EC d’utiliser des chiffrements EC, tout en continuant à supporter les clients plus anciens ne prenant en charge que RSA.

Pour y parvenir, OpenSSL 1.1.1 est requis. Vous pouvez configurer ce comportement en indiquant une entrée crt par type de certificat, ou en configurant un « bundle de certificats » comme cela était exigé auparavant avec HAProxy 1.8. Voir « ssl-load-extra-files ».

crt-ignore-err <errors>

crt-ignore-err <errors>

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Définit une liste séparée par des virgules d’identifiants d’erreur à ignorer lors de la vérification au niveau == 0. Il peut s’agir d’un identifiant numérique ou du nom de constante (X509_V_ERR), disponible dans la documentation OpenSSL : https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES . Il est recommandé d’utiliser le nom de constante, car la valeur numérique peut évoluer dans les nouvelles versions d’OpenSSL. Si cette option est définie sur « all », toutes les erreurs sont ignorées. La négociation SSL n’est pas interrompue si une erreur est ignorée.

crt-list <file>

crt-list <file>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il désigne une liste de fichiers PEM, chacun pouvant inclure une configuration SSL optionnelle et un filtre SNI par certificat, selon le format suivant pour chaque ligne :

<crtfile> [\[<sslbindconf> ...\]] [[!]<snifilter> ...]

Les lignes vides ainsi que les lignes commençant par un dièse (’#’) seront ignorées.

La liste de certificats peut être modifiée dynamiquement via la socket de statistiques. (Voir « add ssl crt-list », « del ssl crt-list », « show ssl crt-list » dans le guide d’administration).

Les listes de certificats (crt-list) sont généralement des fichiers dédiés, mais un répertoire chargé avec la directive « crt » est représenté internement comme une crt-list. La directive « ssl-f-use » dans un frontal déclare également une crt-list liée à ce frontal.

crtfile:

This is the filename of the certificate, or an identifier if it was declared
elsewhere (over the CLI or in a crt-store with an alias for example).

It is possible to use the same <crtfile> on multiple lines with different
options and filters.

Multi-cert bundling (see "ssl-load-extra-files") is supported in a
crt-list, as long as only the base name is given in <crtfile>. HAProxy
will duplicate the crt-list line internally, adding an algorithm extension
(.rsa, .ecdsa, .dsa) when loading the file.

sslbindconf:

 <sslbindconf> supports the following keywords from the bind line (see
 Section 5.1. Bind options):

 - allow-0rtt
 - alpn
 - ca-file
 - ca-verify-file
 - ciphers
 - ciphersuites
 - client-sigalgs
 - crl-file
 - curves
 - ecdhe
 - no-alpn
 - no-ca-names
 - npn
 - sigalgs
 - ssl-min-ver
 - ssl-max-ver
 - verify

 <sslbindconf> also supports the following keywords from the crt-store load
 keyword (see Section 12.7.1. Load options):

 - crt
 - key
 - ocsp
 - issuer
 - sctl
 - ocsp-update

Parameters from the bind line are inherited in <sslbindconf>, if none were
specified, the default options are inherited, the parameters specified in
<sslbindconf> overwrite those inherited settings.

snifilter :

When the <snifilter> parameter is used on a crt-list line, the CN and SAN
are not used anymore to select the certificate on this line during the
handshake but the <snifilter> is used instead.

<snifilter> is a list of entries separated by spaces. This list can contain
domains, or wildcards. The wildcards are in wildcard DNS format, using a
single asterisk as the first character of the entry. It is possible to
exclude a domain from a wildcard with a negative filter by specifying a '!'
in front of a single domain. Having a ! in front of a * is ignored. Having
negative filters without a wildcard on the same line is not supported as
well. The special entry '*' is used to specify default certificates, which
are used as fallback when no domain matched.

The certificates will be presented to clients who provide a valid TLS
Server Name Indication field matching one of the SNI filters, or the CN and
SAN of a <crtfile>. The matching algorithm first looks for a positive domain
entry in the list, if not found it will try to look for a wildcard in the
list. If a wildcard match, haproxy checks for a negative filter from the
same line and unmatch if necessary. In case of multiple key algorithms
(RSA,ECDSA,DSA), HAProxy will try to match one certificate per type and
chose the right one depending on what is supported by the client.

If no SNI is presented by the client or if no certificate matched, this
will fallback to one of the default certificate. To disable the default
certificate fallback, the 'strict-sni' option may be used.
When multiple default certificates are defined, HAProxy is able to chose
the right ECDSA or RSA one depending on what the client supports.

The first declared certificate of a bind line is used as a default
certificate, either from crt or crt-list option.
It is also possible to declare a '*' filter, which will add this
certificate to the list of default certificates. To clarify the
configuration, the default certificates could be explicit (with a '*'
filter) at the beginning of the list, so an implicit default is not added
before.
Due to multi-cert bundles being duplicated for each algorithm in the
crt-list, only one algorithm will occupy the first line in the crt-list and
be considered as default. Either specify the entire bundle as default by
declaring '*' as the filter or setting it on the bind line.

The "show ssl sni" command on the stats socket could be used to debug your
configuration. (See "show ssl sni" in the management guide)

Exemple :

# comment
default.pem.rsa *
default.pem.ecdsa *
cert2.pem [alpn h2,http/1.1]
certW.pem *.domain.tld !secure.domain.tld
certS.pem [curves X25519:P-256 ciphers ECDHE-ECDSA-AES256-GCM-SHA384] secure.domain.tld
foo.crt [key bar.pem ocsp foo.ocsp ocsp-update on] foo.bar.com

default-crt <cert>

default-crt <cert>

Cette option a le même effet que l’option « crt », à la différence que ce certificat sera également utilisé comme certificat par défaut. Il est possible d’ajouter plusieurs certificats par défaut afin d’avoir un certificat ECDSA et un certificat RSA ; en ajouter davantage n’est pas réellement utile.

Cette option ne désactive pas les certificats par défaut implicites. Si un certificat « crt » est déclaré en premier, avant tout « default-crt » ou tout autre « crt », il sera toujours utilisé comme certificat par défaut.

Un certificat par défaut est utilisé lorsque l’option « strict-sni » n’est pas spécifiée dans la ligne bind. Un certificat par défaut est fourni lorsque l’extension servername n’a pas été utilisée par le client, ou lorsque le nom de serveur ne correspond à aucun certificat configuré.

Exemple :

# this bind line has 2 default certificates
bind *:443 default-crt foobar.pem.rsa default-crt foobar.pem.ecdsa crt website.pem.rsa

# this bind line has 3 default certificates
bind *:443 crt website.pem.rsa default-crt foobar.pem.rsa default-crt foobar.pem.ecdsa

Voir également le mot-clé « crt ».

curves <curves>

curves <curves>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de courbes elliptiques (“suite de courbes”) négociés lors de l’échange SSL/TLS avec ECDHE. Le format de la chaîne est une liste séparée par des deux-points de noms de courbes. Exemple : “X25519:P-256” (sans guillemets). Lorsque « curves » est défini, le paramètre « ecdhe » est ignoré.

defer-accept

defer-accept

Est un mot-clé facultatif pris en charge uniquement sur certains noyaux Linux. Il indique qu’une connexion ne sera acceptée qu’après la réception de données, ou au pire après la première retransmission. Cette option doit être utilisée uniquement avec des protocoles pour lesquels le client parle en premier (par exemple, HTTP). Elle peut légèrement améliorer les performances en garantissant que la majeure partie de la requête est déjà disponible au moment de l’acceptation de la connexion. En revanche, elle ne permet pas de détecter les connexions qui ne transmettent aucune donnée. Il est important de noter que cette option est défectueuse sur tous les noyaux jusqu’à la version 2.6.31, car la connexion n’est jamais acceptée tant que le client ne parle pas. Cela peut entraîner des problèmes avec les pare-feu frontaux, qui perçoivent une connexion établie alors que le proxy ne la voit qu’en SYN_RECV. Cette option n’est prise en charge que sur les sockets TCPv4/TCPv6 et ignorée par les autres.

ecdhe <named curve>

ecdhe <named curve>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la courbe nommée (RFC 4492) utilisée pour générer les clés temporaires ECDH. Par défaut, la courbe nommée utilisée est prime256v1.

ech <dir> [ EXPERIMENTAL ]

ech <dir> [ EXPERIMENTAL ]

Appliquez toutes les clés ECH provenant de <dir> à la ligne bind. Les fichiers doivent avoir l’extension .ech et utiliser le format de fichier PEM pour ECH. ( https://datatracker.ietf.org/doc/draft-farrell-tls-pemesni/ )

Ce mot-clé active ECH en mode partagé, HAProxy agissant à la fois en tant que terminaison TLS et en tant que terminaison ECH. Voir https://datatracker.ietf.org/doc/draft-ietf-tls-esni/

Il s’agit d’une fonctionnalité expérimentale, qui nécessite l’option « expose-experimental-directives » dans la section globale. Elle exige également une version d’OpenSSL prenant en charge l’ECH ( https://github.com/openssl/openssl/tree/feature/ech ), ainsi qu’une compilation de HAProxy avec USE_ECH=1. L’API ECH d’AWS-LC n’est pas prise en charge.

Exemple :

$ openssl ech -public_name foobar.com -out /etc/haproxy/echkeydir/foobar.com.ech

$ cat haproxy.cfg
[...]
bind:443 ech /etc/haproxy/echkeydir/ ssl crt example.com.pem

// Use the ECHCONFIG section of your .ech file
$ openssl s_client -tls1_3 -connect example.com:443 -servername example.com \
-ech_config_list AD3+DQA5cwAgACB6ybtgtFYoM5r8nJSotus4c7K0EG..9vYmFyLmNvbQAA

expose-fd listeners

expose-fd listeners

Cette option n’est utilisable qu’avec le socket de statistiques. Elle permet au socket de statistiques de transmettre le descripteur d’écouteur (FD) à un autre processus HAProxy. En mode maître-worker, cette fonctionnalité n’est plus nécessaire, les écouteurs étant transmis via les socketpairs internes entre le maître et les workers. Voir également “-x” dans le guide de gestion.

force-sslv3

force-sslv3

Cette option impose l’utilisation de SSLv3 uniquement sur les connexions SSL instanciées à partir de cet écouteur. SSLv3 est généralement moins coûteux que ses homologues TLS pour des débits de connexion élevés. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv10

force-tlsv10

Cette option impose l’utilisation de TLSv1.0 uniquement sur les connexions SSL instanciées à partir de cet écouteur. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv11

force-tlsv11

Cette option impose l’utilisation de TLSv1.1 uniquement sur les connexions SSL instanciées par cet écouteur. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv12

force-tlsv12

Cette option impose l’utilisation de TLSv1.2 uniquement sur les connexions SSL instanciées par cet écouteur. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv13

force-tlsv13

Cette option impose l’utilisation de TLSv1.3 uniquement sur les connexions SSL instanciées à partir de cet écouteur. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

generate-certificates

generate-certificates

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il active la génération dynamique des certificats SSL. Un certificat de l’autorité de certification (CA) et sa clé privée sont nécessaires (voir « ca-sign-file »). Lorsqu’HAProxy est configuré en tant que proxy forward transparent, les requêtes SSL génèrent des erreurs en raison d’un désaccord sur le nom commun du certificat présenté au client. Avec cette option activée, HAProxy tentera de générer un certificat en utilisant le nom d’hôte SNI indiqué par le client. Cette opération n’est effectuée que si aucun certificat ne correspond au nom d’hôte SNI (voir « crt-list »).

En cas d’erreur de génération de certificat, la connexion bascule vers le certificat par défaut. Lorsque strict-sni est utilisé, le certificat par défaut n’est pas utilisé et la connexion entraîne un échec de négociation.

Il peut également être utilisé lorsque HAProxy est configuré en tant que proxy inverse pour faciliter le déploiement d’une architecture comprenant de nombreux backends.

La création d’un certificat SSL est une opération coûteuse, aussi un cache LRU est utilisé pour stocker des certificats falsifiés (voir ’tune.ssl.ssl-ctx-cache-size’). Cela augmente la consommation mémoire de HAProxy afin de réduire la latence lorsque le même certificat est utilisé plusieurs fois.

gid <gid>

gid <gid>

Définit le groupe des sockets UNIX sur le GID système indiqué. Ce paramètre peut également être défini par défaut dans l’instruction « unix-bind » de la section globale. Notez que certaines plates-formes ignorent simplement ce paramètre. Ce réglage est équivalent à l’option « group », à ceci près que l’identifiant de groupe est utilisé à la place de son nom. Ce paramètre est ignoré pour les sockets non UNIX.

group <group>

group <group>

Définit le groupe des sockets UNIX sur le groupe système indiqué. Ce paramètre peut également être défini par défaut dans l’instruction « unix-bind » de la section globale. Notez que certaines plates-formes ignorent simplement ce paramètre. Ce paramètre est équivalent à l’option « gid », à ceci près que le nom du groupe est utilisé au lieu de son identifiant gid. Ce paramètre est ignoré pour les sockets non UNIX.

guid-prefix <string>

guid-prefix <string>

Génère des identifiants uniques globaux sensibles à la casse pour chaque socket d’écoute allouée sur cette ligne de liaison. Le préfixe sera concaténé à l’indice de position de l’écouteur sur la ligne de liaison courante, en utilisant le caractère ‘-’ comme séparateur. Voir la description de la mot-clé proxy « guid » pour plus d’informations sur son format. Voir également « shm-stats-file ».

id <id>

id <id>

Fixe l’identifiant de socket. Par défaut, les identifiants de socket sont attribués automatiquement, mais il peut parfois être plus pratique de les fixer pour faciliter la surveillance. Cette valeur doit être strictement positive et unique au sein de l’écouteur/ frontal. Cette option ne peut être utilisée que lors de la définition d’une seule socket.

idle-ping <delay>

idle-ping <delay>

Peut être utilisé dans les contextes suivants : tcp, http, log

Définir un intervalle pour le test de vivacité périodique sur les connexions frontales inactives. Si la partie distante ne parvient pas à répondre avant le prochain test planifié, la connexion est fermée. Sinon, le délai d’expiration client est actualisé et la connexion est maintenue. Notez que les temporisateurs http-request/http-keep-alive s’exécutent en parallèle et ne sont pas actualisés par idle-ping.

Cette fonctionnalité dépend d’un support spécifique du protocole sous-jacent. Pour l’instant, seul H2 mux l’implémente. Le ping inactif est simplement ignoré par les autres protocoles.

Cette option est particulièrement utile lors de l’utilisation d’un proxy inverse HTTP. La définir sur la ligne bind est utile pour le pair chargé d’établir activement les connexions et qui recevra ensuite le trafic entrant à travers celles-ci.

interface <interface>

interface <interface>

Restreint la socket à une interface spécifique. Lorsqu’elle est spécifiée, seule la trame reçue depuis cette interface particulière est traitée par la socket. Cette fonctionnalité n’est actuellement prise en charge que sous Linux. L’interface doit être une interface système primaire, et non une interface aliasée. Il est également possible de lier plusieurs frontaux à la même adresse si ceux-ci sont liés à des interfaces différentes. Notez que le lien à une interface réseau nécessite des privilèges root. Ce paramètre n’est compatible qu’avec les sockets TCPv4/TCPv6. Lorsqu’il est spécifié, le trafic de retour utilise la même interface que le trafic entrant, ainsi que sa table de routage associée, même si des routes explicites via des interfaces différentes sont configurées. Cela peut s’avérer utile pour résoudre les problèmes de routage asymétrique lorsque les mêmes adresses IP clientes doivent pouvoir atteindre des frontaux hébergés sur des interfaces différentes.

ktls <on|off> [ EXPERIMENTAL ]

ktls <on|off> [ EXPERIMENTAL ]

Active ou désactive kTLS pour ces sockets. Si activé, kTLS sera utilisé si le noyau le prend en charge et si le chiffrement est compatible. Cette fonctionnalité n’est disponible qu’avec le noyau Linux 4.17 et versions ultérieures. Veuillez noter que certains pilotes réseau et/ou piles TLS peuvent limiter l’utilisation de kTLS à TLS v1.2 uniquement. Voir également « force-tlsv12 ».

label <label>

label <label>

Définit une étiquette facultative pour ces sockets. Elle peut servir à regrouper les sockets par étiquette, indépendamment de l’emplacement où les lignes bind ont été déclarées.

level <level>

level <level>

Ce paramètre est utilisé uniquement avec les sockets de statistiques pour restreindre la nature des commandes pouvant être émises sur le socket. Il est ignoré par les autres sockets. <level> peut prendre l’une des valeurs suivantes :

  • « user » est le niveau de privilège le plus faible ; seules les statistiques non sensibles peuvent être lues, et aucune modification n’est autorisée. Ce niveau est pertinent sur les systèmes où il n’est pas facile de restreindre l’accès à la socket.
  • « operator » est le niveau par défaut et convient à la plupart des utilisations courantes. Toutes les données peuvent être lues, et seules les modifications non sensibles sont autorisées (par exemple, réinitialiser les compteurs max).
  • « admin » doit être utilisé avec précaution, car toutes les actions sont autorisées (par exemple, réinitialiser tous les compteurs).

maxconn <maxconn>

maxconn <maxconn>

Limite les sockets à ce nombre de connexions simultanées. Les connexions supplémentaires resteront dans la file d’attente du système jusqu’à ce qu’une connexion soit libérée. Si non spécifié, la limite sera identique à celle du frontal maxconn. Notez que, dans le cas de plages de ports ou d’adresses multiples, la même valeur sera appliquée à chaque socket. Ce paramètre permet d’imposer des limites différentes sur les sockets coûteux, par exemple les entrées SSL qui peuvent facilement consommer toute la mémoire.

mode <mode>

mode <mode>

Définit le mode octal utilisé pour définir les permissions d’accès sur le socket UNIX. Ce paramètre peut également être défini par défaut dans l’instruction « unix-bind » de la section globale. Notez que certaines plates-formes ignorent simplement ce paramètre. Ce paramètre est ignoré pour les sockets non UNIX.

mss <maxseg>

mss <maxseg>

Définit la valeur de la taille maximale du segment TCP (MSS) à annoncer sur les connexions entrantes. Cela peut être utilisé pour imposer une MSS plus faible pour des ports spécifiques, par exemple pour les connexions passant par un VPN. Notez que cette fonctionnalité repose sur une fonctionnalité du noyau qui est théoriquement prise en charge sous Linux, mais était défectueuse dans toutes les versions antérieures à 2.6.28. Elle peut ou non fonctionner sur d’autres systèmes d’exploitation. Elle peut également ne pas modifier la valeur annoncée, mais modifier la taille effective des segments sortants. La valeur couramment annoncée pour TCPv4 sur les réseaux Ethernet est 1460 = 1500 (MTU) - 40 (IP+TCP). Si cette valeur est positive, elle sera utilisée comme MSS annoncé. Si elle est négative, elle indiquera de combien réduire le MSS annoncé par la connexion entrante pour les segments sortants. Ce paramètre n’est compatible qu’avec les sockets TCP v4/v6.

name <name>

name <name>

Définit un nom facultatif pour ces sockets, qui sera indiqué sur la page de statistiques.

namespace <name>

namespace <name>

Sous Linux, il est possible de spécifier l’espace d’adressage réseau auquel un socket appartient. Cette directive permet de lier explicitement un écouteur à un espace d’adressage différent de celui par défaut. Veuillez vous référer à la documentation de votre système d’exploitation pour obtenir davantage de détails sur les espaces d’adressage réseau.

nbconn <nbconn> [ EXPERIMENTAL ]

nbconn <nbconn> [ EXPERIMENTAL ]

Ce paramètre n’est valable que pour les instances d’écouteur utilisant HTTP inverse. Il définit le nombre de connexions à monter en parallèle. Si non spécifié, une valeur par défaut de 1 est utilisée.

Le proxy HTTP inverse est actuellement toujours en développement actif. Le mécanisme de configuration peut évoluer à l’avenir. Pour cette raison, il est marqué internement comme expérimental, ce qui signifie que la directive « expose-experimental-directives » doit apparaître sur une ligne précédant cette directive.

nice <nice>

nice <nice>

Définit la « gentillesse » des connexions initiées depuis la socket. La valeur doit être comprise dans la plage -1024..1024 inclusive, et vaut zéro par défaut. Les valeurs positives signifient que ces connexions sont plus favorables aux autres et cèdent facilement leur place au planificateur. À l’inverse, les valeurs négatives signifient que les connexions souhaitent s’exécuter avec une priorité plus élevée que les autres. La différence n’apparaît que sous de fortes charges, lorsque le système est proche de saturation. Les valeurs négatives conviennent aux services à faible latence ou aux services d’administration, tandis que des valeurs élevées sont généralement recommandées pour les tâches intensives en CPU, comme le traitement SSL ou les transferts en masse, qui sont moins sensibles à la latence. Par exemple, il peut être pertinent d’utiliser une valeur positive pour une socket SMTP et une valeur négative pour une socket RDP.

no-alpn

no-alpn

Désactive le traitement ALPN (en pratique, cela définit la chaîne ALPN sur une chaîne vide qui ne sera pas annoncée). Permet d’annuler une occurrence précédente de la directive « alpn » et de désactiver la négociation de protocole d’application. Peut également être utilisé pour empêcher un écouteur de négocier ALPN avec un client sur un écouteur HTTPS ou QUIC ; par défaut, les écouteurs HTTPS annoncent « h2,http/1.1 » et les écouteurs QUIC annoncent « h3 ». Voir également « alpn » ci-dessus. Notez qu’en utilisant « crt-list », un certificat peut remplacer le paramètre « alpn » et réactiver son traitement.

no-ca-names

no-ca-names

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il empêche l’envoi des noms de certificat autorité de certification dans le message Server Hello lorsque ca-file est utilisé. Utilisez ca-verify-file à la place de ca-file avec no-ca-names.

no-sslv3

no-sslv3

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive le support de SSLv3 sur tous les sockets instanciés à partir de l’écouteur lorsque le chiffrement SSL est activé. Notez que SSLv2 est forcé désactivé dans le code et ne peut pas être activé via aucune option de configuration. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

no-strict-sni

no-strict-sni

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive l’imposition stricte du SNI provenant d’une directive précédente « strict-sni ». Il peut être nécessaire pour désactiver sélectivement l’utilisation du SNI strict sur une ligne « bind » lorsque celle-ci était déjà imposée globalement via « ssl-default-bind-options ». Voir également l’option de liaison « strict-sni ».

no-tls-tickets

no-tls-tickets

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive la reprise de session sans état (extension TLS Ticket RFC 5077) et force l’utilisation de la reprise de session avec état. La reprise de session sans état est plus coûteuse en utilisation du processeur. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Le mécanisme des tickets TLS n’est utilisé qu’avec TLS 1.2 au maximum. La confidentialité progressive est compromise avec les tickets TLS, sauf si les clés de ticket sont régulièrement renouvelées (par rechargement ou en utilisant « tls-ticket-keys »).

no-tlsv10

no-tlsv10

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive le support de TLSv1.0 sur tous les sockets instanciés à partir de l’écouteur lorsque le support SSL est actif. Notez que SSLv2 est forcé désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

no-tlsv11

no-tlsv11

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive le support de TLSv1.1 sur tous les sockets instanciés à partir de l’écouteur lorsque le support SSL est activé. Notez que SSLv2 est forcé désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

no-tlsv12

no-tlsv12

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive le support de TLSv1.2 sur tous les sockets instanciés à partir de l’écouteur lorsque le support SSL est activé. Notez que SSLv2 est forcé désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

no-tlsv13

no-tlsv13

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il désactive le support de TLSv1.3 sur tous les sockets instanciés à partir de l’écouteur lorsque le support SSL est actif. Notez que SSLv2 est forcé désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

npn <protocols>

npn <protocols>

Cela active l’extension TLS NPN et annonce la liste de protocoles spécifiée comme prise en charge au-dessus de NPN. La liste de protocoles est constituée d’une liste séparée par des virgules de noms de protocoles, par exemple : “http/1.1,http/1.0” (sans guillemets). Cela nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifiez avec HAProxy -vv). Notez que l’extension NPN a été remplacée par l’extension ALPN (voir le mot-clé « alpn »), bien que celle-ci ne soit disponible qu’à partir d’OpenSSL 1.0.2. Si HTTP/2 est requis sur une version plus ancienne d’OpenSSL, NPN peut encore être utilisé, la plupart des clients le supportant encore au moment de la rédaction de ce document. Il est possible d’activer à la fois NPN et ALPN, bien que cela n’ait probablement pas de sens en dehors d’un contexte de test.

prefer-client-ciphers

prefer-client-ciphers

Utilisez la préférence du client lors du choix de la suite de chiffrement, la préférence du serveur étant appliquée par défaut. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ».

Notez qu’avec OpenSSL >= 1.1.1, le chiffrement ChaCha20-Poly1305 est automatiquement priorisé (même sans définir cette option), si un chiffrement ChaCha20-Poly1305 figure en tête de la liste des chiffrements du client.

Lorsqu’un ensemble à algorithmes doubles (RSA + ECDSA) est utilisé, l’algorithme de sélection choisit entre RSA et ECDSA, en privilégiant toujours ECDSA. Une fois le certificat approprié sélectionné, c’est la bibliothèque SSL qui détermine la priorité des chiffres, des courbes, etc. Par conséquent, cette option ne peut pas être utilisée pour privilégier un certificat RSA au détriment d’un certificat ECDSA.

proto <name>

proto <name>

Force le protocole du multiplexeur à utiliser pour les connexions entrantes. Il doit être compatible avec le mode du frontal (TCP ou HTTP). Il doit également être utilisable du côté du frontal. La liste des protocoles disponibles est indiquée dans HAProxy -vv.. Les propriétés des protocoles sont les suivantes : le mode (TCP/HTTP), le côté (FE/BE), le nom du multiplexeur et ses drapeaux.

Certains protocoles sont sujets au blocage par tête de file côté serveur (drapeau=HOL_RISK). Enfin, certains protocoles ne prennent pas en charge les mises à jour (drapeau=NO_UPG). La compatibilité HTX est également indiquée (drapeau=HTX).

Voici les protocoles pouvant être utilisés en tant qu’argument de la directive « proto » dans une ligne bind :

quic: mode=HTTP  side=FE|BE  mux=QUIC  flags=HTX|NO_UPG|FRAMED
 qmux: mode=HTTP  side=FE|BE  mux=QMUX  flags=HTX|NO_UPG
 h2  : mode=HTTP  side=FE|BE  mux=H2    flags=HTX|HOL_RISK|NO_UPG
 h1  : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
 none: mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG

L’idée derrière cette option est de contourner le choix du protocole du multiplexeur optimal pour toutes les connexions instanciées à partir de ce socket d’écoute. Par exemple, il est possible de forcer l’utilisation du protocole http/2 sur un TCP non chiffré en spécifiant « proto h2 » dans la ligne bind.

Si les paramètres ALPN ou NPN sont configurés, les protocoles spécifiés doivent être compatibles avec le protocole du multiplexeur afin d’éviter tout problème. Par exemple, si « proto h1 » est défini, l’ALPN ne doit pas être configuré sur « h2 ».

QMux est un sous-ensemble de QUIC qui s’exécute sur TCP. Il correspond au protocole proposé dans le brouillon suivant : https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html . Il est actuellement considéré comme expérimental dans HAProxy.

quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]

quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]

Il s’agit d’un paramètre spécifique à QUIC permettant de sélectionner l’algorithme de contrôle de congestion pour toute tentative de connexion aux écouteurs QUIC configurés. Ils sont similaires à ceux utilisés par TCP.

Le pacing est activé au-dessus de l’algorithme de congestion afin de réduire les pertes et améliorer le débit. Il peut être désactivé via le mot-clé global “tune.quic.fe.tx.pacing”. Dans la plupart des cas, le pacing doit rester activé, notamment lors de l’utilisation de BBR, qui en dépend pour fonctionner comme prévu. Utiliser BBR sans pacing peut entraîner des ralentissements ou des taux élevés de pertes pendant les transferts.

Valeur par défaut : cubic

Pour une personnalisation supplémentaire, une liste de paramètres peut être spécifiée après le jeton d’algorithme. Elle doit être écrite entre parenthèses, séparée par des virgules. Chaque argument est facultatif et peut être vide si nécessaire. Voici l’ordre obligatoire de chaque paramètre :

  • taille maximale de fenêtre en octets. Elle doit être supérieure à 10 ko et inférieure à 4 Go. La valeur par défaut est utilisée si aucun paramètre n’est fourni. “tune.quic.fe.cc.max-win-size”

Exemple :

# newreno congestion control algorithm
quic-cc-algo newreno
# cubic congestion control algorithm with one megabytes as window
quic-cc-algo cubic(1m)

Une valeur spéciale « nocc » peut être utilisée pour forcer une fenêtre de congestion fixe, toujours réglée à sa taille maximale. Elle est réservée aux scénarios de débogage afin d’éliminer tout effet secondaire causé par le contrôleur de congestion. Elle ne doit pas être utilisée en production, car elle peut rapidement entraîner des problèmes réseau tels qu’un taux élevé de perte de paquets.

quic-force-retry

quic-force-retry

Il s’agit d’un paramètre spécifique à QUIC qui force l’utilisation de la fonctionnalité de réessai QUIC pour toutes les tentatives de connexion aux écouteurs QUIC configurés. Cette fonctionnalité consiste à vérifier que les pairs sont capables de recevoir des paquets à l’adresse de transport qu’ils ont utilisée pour initier une nouvelle connexion, en leur envoyant un paquet Retry contenant un jeton. Ce jeton doit être renvoyé au destinataire du paquet Retry, qui est le seul à pouvoir valider le jeton. Notez que le réessai QUIC sera toujours utilisé, même si une limite de réessai a été définie (voir le paramètre “tune.quic.fe.sec.retry-threshold”).

Ce paramètre nécessite que le secret du cluster soit défini, faute de quoi une erreur sera signalée au démarrage (voir « cluster-secret »).

Consultez https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2 pour plus d’informations sur la réessai QUIC.

quic-socket [ connection | listener ]

quic-socket [ connection | listener ]

Ce paramètre spécifique à QUIC permet de définir le mode d’allocation de socket pour les écouteurs spécifiques. Voir “tune.quic.fe.sock-per-conn” pour une description complète des avantages et inconvénients de chaque mode.

Ce paramètre s’applique conjointement avec l’option globale “tune.quic.fe.sock-per-conn”. Si le mode « default-on » est activé au niveau du réglage global (valeur par défaut), chaque connexion QUIC utilisera son propre socket, sauf pour les écouteurs ayant pour configuration « quic-socket listener ». Toutefois, si le mode global est défini sur « force-off », la configuration individuelle de l’écouteur sera ignorée.

severity-output <format>

severity-output <format>

Ce paramètre est utilisé uniquement avec les sockets de statistiques pour configurer le niveau de sévérité inséré en préfixe des messages de retour informatifs. Le niveau de sévérité des messages peut varier entre 0 et 7, conformément au RFC 5424 syslog. Les commandes socket valides et réussies demandant des données (par exemple, « show map », « get acl foo » etc.) ne comporteront jamais de niveau de sévérité en préfixe. Il est ignoré par les autres sockets. <format> peut être l’un des éléments suivants :

  • « none » (par défaut) aucun niveau de gravité n’est ajouté aux messages de retour.
  • « number » le niveau de gravité est ajouté sous forme de nombre.
  • « string » le niveau de gravité est ajouté sous forme de chaîne, conformément à la convention rfc5424.

shards { <number> | by-thread | by-group }

shards { <number> | by-thread | by-group }

En mode multithreadé, sur les systèmes d’exploitation prenant en charge plusieurs écouteurs sur la même adresse IP:port, cela crée automatiquement ce nombre d’écouteurs identiques pour la même ligne, chacun lié à une part équitable du nombre de threads attachés à cet écouteur. Cela peut parfois être utile lors de l’utilisation de très grands nombres de threads, où le verrouillage en noyau sur une seule socket commence à entraîner une surcharge significative. Dans ce cas, le trafic entrant est réparti sur plusieurs sockets, réduisant ainsi la contention. Notez que cette opération peut facilement augmenter la consommation CPU en faisant travailler davantage de threads, même légèrement.

Si le nombre de shards est supérieur au nombre de threads disponibles, il sera automatiquement réduit au nombre de threads (c’est-à-dire un shard par thread). La valeur spéciale « by-thread » crée également autant de shards qu’il y a de threads dans la ligne « bind ». Étant donné que le système répartit uniformément le trafic entrant entre tous ces shards, il est important que ce nombre soit un diviseur entier du nombre de threads. En alternance, la valeur spéciale « by-group » crée un shard par groupe de threads. Cette option peut être utile lorsqu’il y a beaucoup de threads sans souhaiter créer trop de sockets. La répartition de la charge sera un peu moins optimale, mais la contention (notamment au niveau du système) restera inférieure à celle observée avec un seul socket.

Sur les systèmes d’exploitation qui ne prennent pas en charge plusieurs sockets liés à la même adresse, les modes « by-thread » et « by-group » basculent automatiquement vers un seul shard. Pour le mode « by-group », ce basculement s’effectue sans avertissement, car cela n’a aucune incidence sur un seul groupe, et les sockets seront dupliquées de toute façon pour chaque groupe. En revanche, pour le mode « by-thread », un avertissement diagnostique est émis si ce basculement se produit, car le nombre de listeners résultant ne correspondra pas à l’attente.

sigalgs <sigalgs>

sigalgs <sigalgs>

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de signature négociés pendant l’échange TLSv1.2 et TLSv1.3. Le format de la chaîne est défini dans « man 3 SSL_CTX_set1_sigalgs » des pages de documentation OpenSSL. Il est déconseillé d’utiliser ce paramètre sauf si une compatibilité avec un middlebox est requise.

ssl

ssl

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Il active le déchiffrement SSL sur les connexions instanciées à partir de cet écouteur. Une certificat est nécessaire (voir « crt » ci-dessus). Tous les contenus présents dans les tampons apparaîtront en clair, de sorte que les ACLs et le traitement HTTP n’auront accès qu’aux données déchiffrées. SSLv3 est désactivé par défaut ; utilisez « ssl-min-ver SSLv3 » pour l’activer.

ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

Cette option impose l’utilisation de <version> ou d’une version inférieure sur les connexions SSL instanciées à partir de cet écouteur. Utiliser ce paramètre sans « ssl-min-ver » peut prêter à ambiguïté, car la valeur par défaut de « ssl-min-ver » pourrait évoluer dans les versions futures de HAProxy. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-min-ver ».

ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

Cette option impose l’utilisation de <version> ou d’une version supérieure sur les connexions SSL instanciées à partir de cet écouteur. La valeur par défaut est “TLSv1.2”. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options ». Voir également « ssl-max-ver ».

strict-sni

strict-sni

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. La négociation SSL/TLS est autorisée uniquement si le client fournit un SNI correspondant à un certificat. Le certificat par défaut n’est pas utilisé. Cette option permet également de démarrer sans aucun certificat sur une ligne bind, de sorte qu’un répertoire vide puisse être utilisé et rempli ultérieurement via la socket de statistiques. Cette option est également disponible dans l’instruction globale « ssl-default-bind-options », et peut être désactivée sélectivement sur une ligne bind en utilisant « no-strict-sni ». Voir l’option « crt » pour plus d’informations. Voir la commande « add ssl crt-list » dans le guide d’administration.

tcp-md5sig <password>

tcp-md5sig <password>

Active la signature TCP MD5 (Protection des sessions BGP via l’option de signature TCP MD5) pour toutes les connexions entrantes instanciées à partir de ce socket d’écoute. Cette option n’est disponible que sous Linux. Lorsqu’elle est activée, la chaîne <password> est utilisée pour signer chaque segment TCP à l’aide d’un hachage de 16 octets MD5. Cela protège la connexion TCP contre les attaques par falsification. Le cas d’utilisation principal de cette option est de permettre à BGP de se protéger contre l’introduction de segments TCP falsifiés dans le flux de connexion. Elle peut toutefois être utile pour toute connexion TCP très longue.

tcp-ss <mode>

tcp-ss <mode>

Active l’option TCP Save SYN pour toutes les connexions entrantes instanciées à partir de cette socket d’écoute. Cette option est disponible sur Linux depuis la version 4.3. Elle demande au noyau de conserver une copie du paquet IP entrant contenant le drapeau TCP SYN, pour une inspection ultérieure via la fonction d’extraction d’échantillon “fc_saved_syn”. L’option dispose de 3 modes : - 0 l’extraction du paquet SYN est désactivée, c’est le comportement par défaut - 1 l’extraction du paquet SYN est activée, et inclut les en-têtes IP et TCP - 2 l’extraction du paquet SYN est activée, et inclut les en-têtes ETH, IP et TCP

Cela ne fonctionne que pour les connexions TCP régulières, et est ignoré pour les autres protocoles (par exemple, les sockets UNIX). Voir également “fc_saved_syn”.

tcp-ut <delay>

tcp-ut <delay>

Définit le délai d’expiration utilisateur TCP pour toutes les connexions entrantes instanciées à partir de ce socket d’écoute. Cette option est disponible sur Linux depuis la version 2.6.37. Elle permet à HAProxy de configurer un délai d’expiration pour les sockets contenant des données n’ayant pas reçu d’accusé de réception après le délai configuré. Cela est particulièrement utile pour les connexions longues souffrant de longues périodes d’inactivité, telles que les terminaux distants ou les pools de connexions bases de données, où les délais d’expiration du client et du serveur doivent rester élevés afin de permettre une longue période d’inactivité, mais où il est important de détecter que le client a disparu afin de libérer toutes les ressources associées à sa connexion (et à la session du serveur). L’argument est un délai exprimé en millisecondes par défaut. Cette fonctionnalité ne s’applique qu’aux connexions TCP régulières et est ignorée pour les autres protocoles.

tfo

tfo

Est un mot-clé facultatif pris en charge uniquement sur les noyaux Linux >= 3.7. Il active le Fast Open TCP sur le socket d’écoute, ce qui signifie que les clients prenant en charge cette fonctionnalité pourront envoyer une requête et recevoir une réponse durant la négociation en trois étapes à partir de la deuxième connexion, économisant ainsi un aller-retour après la première connexion. Cela n’a de sens que pour les protocoles utilisant des taux de connexion élevés et où chaque aller-retour compte. Cette option peut entraîner des problèmes avec de nombreux pare-feu qui n’acceptent pas de données dans les paquets SYN, elle ne doit donc être activée qu’après tests approfondis. Cette option n’est prise en charge que sur les sockets TCPv4/TCPv6 et ignorée par les autres. Vous devrez peut-être compiler HAProxy avec USE_TFO=1 si votre libc ne définit pas TCP_FASTOPEN.

thread [<thread-group>/]<thread-set>[,...]

thread [<thread-group>/]<thread-set>[,...]

Cela restreint la liste des threads sur lesquels cet écouteur est autorisé à s’exécuter. Il n’impose aucun de ces threads, mais élimine ceux qui ne correspondent pas. Il limite les threads autorisés à traiter les connexions entrantes pour cet écouteur.

Il existe deux schémas de numérotation. Par défaut, les numéros de thread sont absolus dans le processus, compris entre 1 et la valeur spécifiée dans global.nbthread. Il est également possible de désigner un numéro de thread en utilisant son numéro relatif au sein de son groupe de threads, en spécifiant d’abord le numéro du groupe de threads, puis un slash (’/’) et le numéro de thread relatif. Dans ce cas, les numéros de thread commencent également à 1 et s’arrêtent à 32 ou 64, selon la plateforme. Lorsque des numéros de thread absolus sont spécifiés, ils sont automatiquement traduits en numéros relatifs une fois les groupes de threads connus. En général, les numéros absolus sont préférés pour les configurations simples, tandis que les numéros relatifs sont préférés pour les configurations complexes où l’organisation des processeurs a une importance pour les performances.

Après le numéro de groupe de threads facultatif, la spécification « thread-set » doit utiliser le format suivant :

"all" | "odd" | "even" | [number][-[number]]

Comme leurs noms l’indiquent, « all » valide tous les threads du jeu (tous ceux du groupe, s’il est spécifié, ou tous ceux du processus), « odd » valide tous les threads dont le numéro est impair (chaque deuxième thread à partir du numéro 1), que ce soit pour le processus ou le groupe, et « even » valide tous les threads dont le numéro est pair (chaque deuxième thread à partir du numéro 2). Si au contraire des plages de numéros de thread sont utilisées, alors tous les threads compris entre le premier et le dernier numéro de thread sont validés. Les numéros sont soit relatifs au groupe, soit absolus, selon la présence ou non d’un numéro de groupe. Si le premier numéro de thread est omis, la valeur « 1 » est utilisée, représentant soit le premier thread du groupe, soit le premier thread du processus. Si le dernier numéro de thread est omis, on utilise soit le dernier numéro de thread du groupe (32 ou 64), soit le dernier numéro de thread du processus (global.nbthread).

Ces plages peuvent être répétées et séparées par une virgule, afin de spécifier des ensembles de threads non contigus, et le groupe, s’il est présent, doit être indiqué à nouveau pour chaque nouvelle plage. Notez qu’il n’est pas autorisé de mélanger des spécifications relatives au groupe et des spécifications absolues, car toute la ligne « bind » doit utiliser soit une notation absolue, soit une notation relative, les éléments non définis étant résolus à la fin de l’analyse.

Il est important de savoir qu’un écouteur décrit par une ligne « bind » crée au moins une socket représentée par au moins un descripteur de fichier. Comme les descripteurs de fichier ne peuvent pas s’étendre sur plusieurs groupes de threads, si une ligne « bind » spécifie une plage de threads couvrant plus d’un groupe, plusieurs descripteurs de fichier seront automatiquement créés afin d’en avoir au moins un par groupe. Techniquement, ils font tous référence à la même socket dans le noyau, mais ils obtiendront un identifiant distinct dans HAProxy et même une entrée dédiée dans les statistiques si l’option « option socket-stats » est utilisée.

Le but principal est de permettre à plusieurs lignes bind de partager la même adresse IP:port, mais pas le même thread dans un écouteur, afin que le système puisse répartir les connexions entrantes sur plusieurs files d’attente, contournant ainsi la répartition de charge interne de HAProxy. Ce fonctionnement est actuellement connu pour être pris en charge par Linux 3.9 et versions ultérieures. Voir également le mot-clé « shards » ci-dessus, qui automatiser la duplication des lignes bind et leur affectation à plusieurs groupes de threads.

Ce mot-clé est compatible avec les liaisons HTTP inversées. Toutefois, il est interdit de spécifier un jeu de threads qui s’étend sur plusieurs groupes de threads pour un tel écouteur, car cela pourrait empêcher nbconn de fonctionner comme prévu.

tls-tickets

tls-tickets

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il active la reprise de session sans état (extension TLS Ticket RFC 5077). Il est défini par défaut, mais peut être nécessaire pour réactiver sélectivement cette fonctionnalité sur une ligne « bind » si elle a été désactivée globalement via « no-tls-tickets », comme indiqué dans « ssl-default-bind-options ». Voir également le mot-clé « no-tls-tickets » pour « bind ».

tls-ticket-keys <keyfile>

tls-ticket-keys <keyfile>

Définit le fichier contenant les clés de billet TLS à charger. Les clés doivent avoir une longueur de 48 ou 80 octets, selon que aes128 ou aes256 est utilisé, encodées en base64 avec une clé par ligne (par exemple : OpenSSL rand 80 | OpenSSL base64 -A | xargs echo). La première clé détermine la longueur des clés suivantes : il n’est pas possible de mélanger des clés aes128 et aes256. Le nombre de clés est spécifié par l’option de compilation TLS_TICKETS_NO (valeur par défaut : 3) et au moins autant de clés doivent être présentes dans le fichier. Les TLS_TICKETS_NO dernières clés seront utilisées pour le déchiffrement et l’avant-dernière pour le chiffrement. Cela permet une rotation facile des clés en ajoutant simplement une nouvelle clé au fichier et en rechargant le processus. Les clés doivent être régulièrement rotées (par exemple toutes les 12 h) ou la confidentialité parfaite sera compromise. Il est également recommandé de ne pas stocker les clés sur un support permanent tel qu’un disque dur (indice : utiliser tmpfs et ne pas échanger ces fichiers). Le délai d’expiration peut être modifié à l’aide de tune.ssl.timeout.

transparent

transparent

Est un mot-clé facultatif pris en charge uniquement sur certains noyaux Linux. Il indique que les adresses seront liées même si elles n’appartiennent pas à la machine locale, et que les paquets ciblant l’une de ces adresses seront interceptés comme si elles étaient configurées localement. Cela nécessite généralement que le transfert IP soit activé. Attention ! N’utilisez pas ce mot-clé avec l’adresse par défaut ‘*’, car cela redirigerait tout le trafic destiné au port spécifié. Ce mot-clé n’est disponible que si HAProxy est compilé avec USE_LINUX_TPROXY=1. Ce paramètre n’est compatible qu’avec les sockets TCPv4 et TCPv6, selon la version du noyau. Certains noyaux de distribution incluent des correctifs de cette fonctionnalité, vérifiez donc la prise en charge auprès de votre fournisseur.

uid <uid>

uid <uid>

Définit le propriétaire des sockets UNIX selon l’identifiant système UID spécifié. Ce paramètre peut également être défini par défaut dans l’instruction « unix-bind » de la section globale. Notez que certaines plates-formes ignorent simplement ce paramètre. Ce paramètre est équivalent à l’option « user », à ceci près qu’il utilise l’identifiant numérique de l’utilisateur au lieu de son nom. Ce paramètre est ignoré pour les sockets non UNIX.

user <user>

user <user>

Définit le propriétaire des sockets UNIX sur l’utilisateur système indiqué. Ce paramètre peut également être défini par défaut dans l’instruction « unix-bind » de la section globale. Notez que certaines plates-formes l’ignorent simplement. Ce paramètre est équivalent à l’option « uid », sauf qu’il utilise le nom d’utilisateur au lieu de son identifiant uid. Ce paramètre est ignoré pour les sockets non UNIX.

v4v6

v4v6

Est un mot-clé facultatif pris en charge uniquement sur les systèmes les plus récents, y compris les noyaux Linux ≥ 2.4.21. Il permet de lier une socket à la fois à IPv4 et à IPv6 lorsqu’elle utilise l’adresse par défaut. Cette option est parfois nécessaire sur les systèmes qui, par défaut, ne lient qu’à IPv6. Elle n’a aucun effet sur les sockets non IPv6 et est annulée par l’option « v6only ».

v6only

v6only

Est un mot-clé facultatif pris en charge uniquement sur les systèmes les plus récents, y compris les noyaux Linux ≥ 2.4.21. Il est utilisé pour lier une socket à IPv6 uniquement lorsqu’elle utilise l’adresse par défaut. Cette approche est parfois préférée à une configuration système entière, car elle est spécifique à chaque écouteur. Il n’a aucun effet sur les sockets non IPv6 et a une priorité sur l’option « v4v6 ».

verify [none|optional|required]

verify [none|optional|required]

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Si sa valeur est définie sur « none », aucune certificat client n’est demandé. C’est la valeur par défaut. Dans les autres cas, un certificat client est demandé. Si le client ne fournit pas de certificat après la demande et que « verify » est défini sur « required », la négociation est interrompue, alors qu’elle aurait abouti si la valeur était « optional ». Le certificat fourni par le client est toujours vérifié à l’aide des autorités de certification (CA) du fichier « ca-file » et des listes de révocation de certificats (CRL) facultatives du fichier « crl-file ». En cas d’échec de vérification, la négociation est interrompue, indépendamment de la valeur de l’option « verify », sauf si le code d’erreur correspond exactement à l’un des codes listés dans « ca-ignore-err » ou « crt-ignore-err ».

5.2. Options serveur et options par défaut pour serveur

Les mots-clés « server » et « default-server » prennent en charge un certain nombre de paramètres, tous transmis sous forme d’arguments sur la ligne du serveur. L’ordre d’apparition de ces arguments n’a pas d’importance, et tous sont facultatifs. Certains de ces paramètres sont des mots simples (valeurs booléennes), tandis que d’autres attendent une ou plusieurs valeurs après eux. Dans ce cas, les valeurs doivent immédiatement suivre le nom du paramètre. À l’exception de « default-server », tous ces paramètres doivent être spécifiés après l’adresse du serveur s’ils sont utilisés :

server <name> <address>[:port] [settings ...]
default-server [settings ...]

Remarque : toutes ces options sont prises en charge par les mots-clés « server » et « default-server », sauf l’« id », qui n’est pris en charge que par « server ».

Les paramètres actuellement pris en charge sont les suivants.

addr <ipv4|ipv6>

addr <ipv4|ipv6>

Peut être utilisé dans les contextes suivants : tcp, http, log

En utilisant le paramètre « addr », il devient possible d’utiliser une adresse IP différente pour envoyer les vérifications de santé ou pour interroger l’agent de vérification. Sur certains serveurs, il peut être souhaitable de réserver une adresse IP à un composant spécifique capable d’effectuer des tests complexes, plus adaptés aux vérifications de santé qu’application elle-même. Ce paramètre est ignoré si le paramètre « check » n’est pas défini. Voir également le paramètre « port ».

agent-check

agent-check

Peut être utilisé dans les contextes suivants : tcp, http, log

Activez un contrôle d’état d’agent auxiliaire exécuté indépendamment d’un contrôle d’état régulier. Un contrôle d’état d’agent est effectué en établissant une connexion TCP sur le port défini par le paramètre « agent-port » et en lisant une chaîne ASCII terminée par le premier ‘\r’ ou ‘\n’ rencontré. La chaîne est composée d’une série de mots séparés par des espaces, des tabulations ou des virgules, dans n’importe quel ordre, chacun composé de :

  • Représentation ASCII d’un pourcentage entier positif, par exemple « 75% ». Les valeurs au format, définissent le poids proportionnellement au poids initial d’un serveur, tel qu’il est configuré au démarrage de HAProxy. Notez qu’un poids nul est affiché sur la page de statistiques sous la forme « DRAIN », car cela a le même effet sur le serveur (il est retiré de la ferme de chargement). Il s’agit de la méthode héritée pour définir le poids d’un serveur. Il est préférable de le définir en utilisant le préfixe « weight: ».

  • La chaîne « weight: » suivie d’un entier positif ou d’un pourcentage entier positif, sans espace. Si la valeur se termine par le signe « % », le nouveau poids sera proportionnel au poids initial du serveur. Sinon, la valeur est considérée comme un poids absolu et doit être comprise entre 0 et 256. Les serveurs faisant partie d’une ferme utilisant un algorithme de répartition de charge statique ont des limitations plus strictes, car le poids ne peut pas être modifié une fois défini. Pour ces serveurs, les seules valeurs acceptées sont 0 et 100 % (ou 0 et le poids initial). Les modifications prennent effet immédiatement, bien que certains algorithmes de répartition de charge nécessitent un certain nombre de requêtes pour prendre en compte les changements. Notez qu’un poids nul est indiqué sur la page de statistiques comme « DRAIN », car il a le même effet sur le serveur (il est retiré de la ferme de répartition de charge).

  • La chaîne « maxconn: » suivie d’un entier (aucun espace entre). Les valeurs de ce format définissent la valeur maxconn d’un backend. Le nombre maximal de connexions annoncé doit être multiplié par le nombre de répartiteurs de charge et de backends différents utilisant ce contrôle d’état afin d’obtenir le nombre total de connexions que le backend pourrait recevoir. Exemple : maxconn:30

  • Le mot « ready ». Cela met l’état administratif du serveur en mode READY, annulant ainsi tout état DRAIN ou MAINT

  • Le mot « drain ». Cela mettra l’état administratif du serveur en mode DRAIN, de sorte qu’il n’acceptera aucune nouvelle connexion, à l’exception de celles qui sont acceptées via la persistance.

  • Le mot « maint ». Cela placera l’état administratif du serveur en mode MAINT, ce qui empêchera toute nouvelle connexion et arrêtera les contrôles d’état.

  • Les mots « down », « fail » ou « stopped », suivis éventuellement d’une chaîne de description après un trait dièse (’#’). Tous ces mots marquent l’état d’exploitation du serveur comme DOWN, mais comme le mot lui-même est rapporté sur la page de statistiques, la différence permet à un administrateur de savoir si la situation était prévue ou non : le service peut être arrêté intentionnellement, peut apparaître comme actif mais échouer à certaines vérifications de validité, ou peut être perçu comme hors service (par exemple, processus manquant ou port non réactif).

  • Le mot « up » rétablit l’état opérationnel du serveur à UP si les contrôles d’état indiquent également que le service est accessible.

Les paramètres non annoncés par l’agent ne sont pas modifiés. Par exemple, un agent peut être conçu pour surveiller l’utilisation du CPU et ne rapporter qu’un poids relatif, sans jamais interagir avec l’état d’exploitation. De même, un agent pourrait être conçu comme une interface utilisateur finale avec trois boutons radio permettant à un administrateur de modifier uniquement l’état administratif. Toutefois, il est important de noter que seul l’agent peut annuler ses propres actions ; ainsi, si un serveur est mis en mode DRAIN ou en état DOWN à l’aide de l’agent, l’agent doit implémenter les actions équivalentes correspondantes pour ramener le service en exploitation.

La défaillance de connexion à l’agent n’est pas considérée comme une erreur, car la connectivité est vérifiée par le contrôle d’état régulier, activé par le paramètre « check ». Attention toutefois : il n’est pas recommandé d’arrêter un agent après qu’il a signalé « down », car seul un agent signalant « up » pourra réactiver le serveur. Notez que l’interface CLI sur le socket Unix de statistiques est également capable de forcer le résultat d’un agent afin de contourner un agent défaillant si nécessaire.

Exige que le paramètre « agent-port » soit défini. Voir également les paramètres « agent-inter » et « no-agent-check ».

agent-send <string>

agent-send <string>

Peut être utilisé dans les contextes suivants : tcp, http, log

Si cette option est spécifiée, HAProxy enverra la chaîne donnée (telle quelle) au serveur agent lors de la connexion. Vous pourriez, par exemple, encoder le nom du backend dans cette chaîne, ce qui permettrait à votre agent de renvoyer des réponses différentes selon le backend. Veillez à inclure un ‘\n’ si vous souhaitez terminer votre requête par une nouvelle ligne.

agent-inter <delay>

agent-inter <delay>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « agent-inter » définit l’intervalle entre deux vérifications de l’agent en <delay> millisecondes. Si non spécifié, le délai par défaut est de 2000 ms.

Tout comme pour tout autre paramètre basé sur le temps, il peut être spécifié dans n’importe quelle unité explicite parmi {us, ms, s, m, h, d}. Le paramètre « agent-inter » sert également de délai d’expiration pour les contrôles d’état lorsque « timeout check » n’est pas défini. Afin de réduire les effets de « résonance » lorsque plusieurs serveurs sont hébergés sur le même matériel, les agents et les contrôles d’état de tous les serveurs sont lancés avec un léger décalage temporel entre eux. Il est également possible d’ajouter un bruit aléatoire à l’intervalle des agents et des contrôles d’état en utilisant le mot-clé global « spread-checks ». Cela a un sens, par exemple, lorsque de nombreux backends utilisent les mêmes serveurs.

Voir également les paramètres « agent-check » et « agent-port ».

agent-addr <addr>

agent-addr <addr>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « agent-addr » définit l’adresse de vérification de l’agent.

Vous pouvez déléguer le contrôle d’état de l’agent à une cible différente, afin de centraliser la gestion de l’état et des poids des serveurs définis dans HAProxy, en cas d’impossibilité de mettre en œuvre des services auto-conscients et auto-gérés. Vous pouvez spécifier une adresse IP ou un nom d’hôte ; celle-ci sera résolue.

agent-port <port>

agent-port <port>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « agent-port » définit le port TCP utilisé pour les vérifications des agents.

Voir également les paramètres « agent-check » et « agent-inter ».

allow-0rtt

allow-0rtt

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Autorise l’envoi de données anticipées au serveur lors de l’utilisation de TLS 1.3. Notez que les données anticipées ne seront envoyées que si le client les a utilisées, ou si le backend utilise « retry-on » avec le mot-clé « 0rtt-rejected ». Avec QUIC, le 0rtt est pris en charge avec QuicTLS, OpenSSL >= 3.5.2 et AWS-LC. Avec TCP/TLS, le 0rtt n’est pris en charge que avec OpenSSL.

alpn <protocols>

alpn <protocols>

Peut être utilisé dans les contextes suivants : tcp, http

Cela active l’extension TLS ALPN et annonce la liste de protocoles spécifiée comme prise en charge au-dessus d’ALPN. La liste de protocoles est constituée d’une liste séparée par des virgules de noms de protocoles, par exemple : « http/1.1,http/1.0 » (sans guillemets). Cela nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifiez avec haproxy -vv). L’extension ALPN remplace l’extension NPN initiale. ALPN est obligatoire pour se connecter à des serveurs HTTP/2. Il est également obligatoire pour pouvoir utiliser HTTP/3 via un serveur QUIC ; « h3 » sert de valeur par défaut pour les serveurs QUIC sans paramètre « alpn ». Les versions d’OpenSSL antérieures à 1.0.2 ne prennent pas en charge ALPN et ne supportaient que l’extension NPN obsolète. Si HTTP/2 et HTTP/1.1 sont attendus comme étant pris en charge, les deux versions peuvent être annoncées, dans l’ordre de préférence, comme ci-dessous :

server 127.0.0.1:443 ssl crt pub.pem alpn h2,http/1.1

Voir également « ws » pour utiliser un ALPN alternatif pour les flux WebSocket.

backup

backup

Peut être utilisé dans les contextes suivants : tcp, http, log

Lorsque « backup » est présent sur une ligne de serveur, ce dernier n’est utilisé en répartition de charge que lorsque tous les autres serveurs non réservés sont indisponibles. Les requêtes portant un cookie de persistance faisant référence à ce serveur sont toutefois toujours servies. Par défaut, seul le premier serveur de secours opérationnel est utilisé, sauf si l’option « allbackups » est définie dans le backend. Voir également les options « no-backup » et « allbackups ».

ca-file <cafile>

ca-file <cafile>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support OpenSSL a été inclus. Il indique un fichier PEM à partir duquel charger les certificats CA utilisés pour vérifier le certificat du serveur. Il est possible de charger un répertoire contenant plusieurs CA ; dans ce cas, HAProxy tentera de charger chaque “.pem”, “.crt”, “.cer”, ainsi que tous les fichiers .crl présents dans le répertoire. Les fichiers commençant par un point sont ignorés.

Afin d’utiliser les autorités de certification fiables de votre système, le paramètre “@system-ca” peut être utilisé à la place de cafile. Le chemin de ce répertoire peut être remplacé en définissant la variable d’environnement SSL_CERT_DIR.

cc <algo>

cc <algo>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que sur les systèmes définissant TCP_CONGESTION, et a été validé sur Linux et FreeBSD. Il prend le nom d’un algorithme de contrôle de congestion TCP et configure les connexions sortantes pour utiliser cet algorithme. Les noms courants incluent « reno » ou « cubic », qui dépendent de l’exploitation. Sur certains systèmes, des permissions spéciales peuvent être nécessaires pour configurer certains algorithmes. Sur Linux, les algorithmes disponibles sont listés dans sysctl “net.ipv4.tcp_available_congestion_control”, et ceux autorisés sans privilèges se trouvent dans “net.ipv4.tcp_allowed_congestion_control”. Pour accéder aux algorithmes nécessitant des permissions supplémentaires, la capacité “cap_net_admin” peut être requise (voir « setcap » dans la section globale). En cas d’échec de configuration d’un algorithme de congestion spécifique, celui par défaut reste inchangé. Voir également : le mot-clé bind « cc » (section 5.1 ).

check

check

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option active les contrôles d’état sur un serveur : - lorsqu’elle n’est pas définie, aucun contrôle d’état n’est effectué, et le serveur est toujours considéré comme disponible. - lorsqu’elle est définie et qu’aucune autre méthode de contrôle n’est configurée, le serveur est considéré comme disponible lorsque la connexion peut être établie au niveau du transport le plus élevé configuré. Cela signifie TCP par défaut, ou SSL/TLS lorsque « ssl » ou « check-ssl » sont définis, pouvant éventuellement être combiné avec des préfixes de connexion tels qu’un en-tête de protocole PROXY lorsque « send-proxy » ou « check-send-proxy » sont définis. Ce comportement diffère légèrement pour les serveurs dynamiques ; consultez les paragraphes suivants pour plus de détails. - lorsqu’elle est définie et qu’un contrôle d’état au niveau applicatif est défini, les échanges au niveau applicatif sont effectués au-dessus du niveau de transport configuré, et le serveur est considéré comme disponible si tous les échanges réussissent.

Par défaut, les contrôles d’état sont effectués sur la même adresse et le même port que ceux configurés sur le serveur, en utilisant les mêmes paramètres d’encapsulation (SSL/TLS, en-tête proxy-protocol, etc.). Il est possible de modifier l’adresse de destination à l’aide de « addr » et le port à l’aide de « port ». Lorsque cela est fait, il est supposé que le serveur n’est pas contrôlé sur le port de service, et les paramètres d’encapsulation configurés ne sont pas réutilisés. Il faut définir explicitement « check-send-proxy » pour envoyer les en-têtes de connexion, et « check-ssl » pour utiliser SSL/TLS.

Notez que la configuration implicite du protocole SSL et du protocole PROXY n’est pas appliquée aux serveurs dynamiques. Dans ce cas, il est nécessaire d’utiliser explicitement les options « check-ssl » et « check-send-proxy » lorsqu’elles sont requises, même si le port de vérification n’est pas redéfini.

Lorsque « sni » ou « alpn » sont définis sur la ligne server, leur valeur n’est pas utilisée pour les contrôles d’état et il faut alors utiliser « check-sni » ou « check-alpn ».

L’adresse source par défaut pour le trafic de contrôle d’état est la même que celle définie dans le backend. Elle peut être modifiée à l’aide du mot-clé « source ».

L’intervalle entre les contrôles d’état peut être défini à l’aide du mot-clé « inter », et les mots-clés « rise » et « fall » peuvent être utilisés pour préciser le nombre de contrôles d’état réussis ou échoués requis pour marquer un serveur comme disponible ou indisponible.

Des contrôles d’état au niveau applicatif optionnels peuvent être configurés à l’aide de « option httpchk », « option mysql-check », « option smtpchk », « option pgsql-check », « option ldap-check » ou « option redis-check ».

Exemple :

# simple tcp check
backend foo
  server s1 192.168.0.1:80 check
# this does a tcp connect + tls handshake
backend foo
  server s1 192.168.0.1:443 ssl check
# simple tcp check is enough for check success
backend foo
  option tcp-check
  tcp-check connect
  server s1 192.168.0.1:443 ssl check

check-reuse-pool

check-reuse-pool

Peut être utilisé dans les contextes suivants : tcp, http

Cette option permet aux vérifications de réutiliser les connexions inactives disponibles au lieu d’en ouvrir une dédiée. La connexion est réinsérée dans le pool une fois la vérification terminée. L’objectif principal est de limiter le nombre d’ouvertures et de fermetures de connexions sur un serveur spécifique. Cette fonctionnalité n’est compatible qu’avec les règlessets de vérification http-check. Elle est ignorée silencieusement pour les autres types de vérification. En outre, la politique de réutilisation doit être définie sur agressive sur le backend, car chaque tentative de vérification est effectuée sur une session dédiée.

Pour simplifier la configuration, cette option est ignorée silencieusement si une option de connexion spécifique de vérification est définie, qu’elle soit définie sur la ligne du serveur ou via une règle personnalisée tcp-check connect.

Cette option est automatiquement activée pour les serveurs agissant en tant que passerelle HTTP inverse passive, ainsi que pour ceux dont la connexion est uniquement prise en charge par réutilisation.

Voir également : « check-pool-conn-name »

check-send-proxy

check-send-proxy

Peut être utilisé dans les contextes suivants : tcp, http

Cette option force l’émission d’une ligne PROXY protocol dans les contrôles d’état sortants, quelle que soit l’utilisation ou non de send-proxy par le serveur pour le trafic normal. Par défaut, le protocole PROXY est activé pour les contrôles d’état si celui-ci est déjà activé pour le trafic normal et si aucune directive « port » ni « addr » n’est présente. Toutefois, si une telle directive est présente, l’option « check-send-proxy » doit être utilisée pour forcer l’utilisation du protocole. Voir également l’option « send-proxy » pour plus d’informations.

check-alpn <protocols>

check-alpn <protocols>

Peut être utilisé dans les contextes suivants : tcp, http

Définit les protocoles à annoncer via ALPN. La liste des protocoles est une liste séparée par des virgules de noms de protocoles, par exemple : « http/1.1,http/1.0 » (sans guillemets). Si ce paramètre n’est pas défini, le serveur ALPN est utilisé.

check-pool-conn-name <name>

check-pool-conn-name <name>

Peut être utilisé dans les contextes suivants : tcp, http

Lorsque la réutilisation de connexion est effectuée pour les vérifications, utilise <name> s’il est défini comme identifiant de connexion afin de correspondre à une connexion correspondante dans la pool. Cela équivaut à la directive serveur « pool-conn-name ». « check-sni » sera également utilisé comme option de secours si l’option actuelle n’est pas utilisée.

Voir aussi : « check-reuse-pool »

check-proto <name>

check-proto <name>

Peut être utilisé dans les contextes suivants : tcp, http

Force le protocole du multiplexeur à utiliser pour les connexions de vérification de santé du serveur. Il doit être compatible avec le type de vérification de santé (TCP ou HTTP). Il doit également être utilisable du côté du backend. La liste des protocoles disponibles est indiquée dans HAProxy -vv.. Les propriétés des protocoles sont les suivantes : le mode (TCP/HTTP), le côté (FE/BE), le nom du multiplexeur et ses indicateurs.

Certains protocoles sont sujets au blocage par tête de file côté serveur (drapeau=HOL_RISK). Enfin, certains protocoles ne prennent pas en charge les mises à jour (drapeau=NO_UPG). La compatibilité HTX est également indiquée (drapeau=HTX).

Voici les protocoles pouvant être utilisés en tant qu’argument de la directive « check-proto » sur une ligne de serveur :

h2  : mode=HTTP  side=FE|BE  mux=H2    flags=HTX|HOL_RISK|NO_UPG
fcgi: mode=HTTP  side=BE     mux=FCGI  flags=HTX|HOL_RISK|NO_UPG
h1  : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
none: mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG
quic: mode=HTTP  side=FE|BE  mux=QUIC  flags=HTX|NO_UPG|FRAMED
spop: mode=SPOP  side=BE     mux=SPOP  flags=HOL_RISK|NO_UPG

L’idée de cette option est de contourner le choix du protocole du multiplexeur optimal pour les connexions de vérification de santé établies vers ce serveur. Si elle n’est pas définie, le protocole du serveur sera utilisé, le cas échéant.

Si les paramètres ALPN ou NPN sont configurés, les protocoles spécifiés doivent être compatibles avec le protocole du multiplexeur afin d’éviter tout problème. Par exemple, si « proto h1 » est défini, l’ALPN ne doit pas être configuré sur « h2 ».

La configuration des vérifications QUIC n’est pas entièrement implémentée pour l’instant. Premièrement, les vérifications QUIC ne peuvent être effectuées que pour les serveurs QUIC. Deuxièmement, si un ou plusieurs paramètres de connexion spécifiques sont définis sur un serveur QUIC, le protocole de vérification passera à une utilisation TCP.

check-sni-auto

check-sni-auto

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option active la sélection automatique du SNI lors des contrôles d’état SSL, si aucune valeur n’a déjà été définie. Elle est activée par défaut, mais ce paramètre peut être utilisé en tant que paramètre « server » pour réinitialiser toute configuration « no-check-sni-auto » héritée de la directive « default-server » en tant que valeur par défaut. Il peut également être utilisé en tant que paramètre « default-server » pour réinitialiser toute configuration précédente « no-check-sni-auto » définie sur « default-server ».

Pour les connexions HTTPS, le SNI est automatiquement sélectionné, mais uniquement s’il n’existe pas de règle « http-check connect ». Dans ce cas, le SNI sélectionné est déterminé par la valeur de l’en-tête host, spécifiée via la directive « option httpchk » ou une règle « http-check send ». Aucune sélection automatique n’est appliquée pour les règles « http-check connect ». Pour les autres protocoles, cette option est ignorée.

Si la sélection automatique du SNI est utilisée pour les vérifications de santé, la valeur est affectée au nom de la connexion si l’option « check-reuse-pool » est activée, sauf si elle est remplacée par le mot-clé serveur « check-pool-conn-name ».

Voir l’option « sni-auto » pour activer la sélection automatique du SNI pour le trafic proxyé.

check-sni <sni>

check-sni <sni>

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option permet de spécifier le SNI à utiliser lors des contrôles d’état sur SSL. Il est uniquement possible d’utiliser une chaîne pour définir <sni>. Si vous souhaitez définir un SNI pour le trafic proxy, consultez « sni ».

check-ssl

check-ssl

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option force le chiffrement de tous les contrôles d’état via SSL, indépendamment du fait que le serveur utilise ou non SSL pour le trafic normal. Elle est généralement utilisée lorsque la directive « port » ou « addr » est explicitement définie et que les contrôles d’état SSL ne sont pas hérités. Il est important de comprendre que cette option insère une couche de transport SSL sous les contrôles, de sorte qu’un contrôle de connexion TCP simple devient une connexion SSL, remplaçant ainsi l’ancienne directive « ssl-hello-chk ». L’usage le plus courant consiste à envoyer des contrôles HTTPS en combinant « httpchk » avec des contrôles SSL. Toutes les paramètres SSL sont communs aux contrôles d’état et au trafic (par exemple, les chiffres). Pour plus d’informations, consultez l’option « ssl » et « no-check-ssl » pour désactiver cette option.

check-via-socks4

check-via-socks4

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option active les contrôles d’état sortants via un proxy socks4 en amont. Par défaut, les contrôles d’état ne passent pas par le tunnel socks, même s’il est activé pour le trafic normal.

ciphers <ciphers>

ciphers <ciphers>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Cette option définit la chaîne décrivant la liste des algorithmes de chiffrement négociés lors de l’établissement de la mainshaking SSL/TLS avec le serveur. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL. Pour des informations complémentaires et des recommandations, consulter par exemple (https://wiki.mozilla.org/Security/Server_Side_TLS ) et (https://mozilla.github.io/server-side-tls/ssl-config-generator/ ). Pour la configuration des cipher suites TLSv1.3, se référer à la directive « ciphersuites ».

ciphersuites <ciphersuites>

ciphersuites <ciphersuites>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré au moment de la compilation et si OpenSSL 1.1.1 ou une version ultérieure a été utilisé pour compiler HAProxy. Cette option définit la chaîne décrivant la liste des algorithmes de chiffrement négociés lors de l’échange TLS 1.3 avec le serveur. Le format de la chaîne est défini dans « man 1 ciphers » des pages de documentation OpenSSL, dans la section « ciphersuites ». Pour la configuration des chiffres TLSv1.2 et versions antérieures, veuillez consulter le mot-clé « ciphers ».

client-sigalgs <sigalgs>

client-sigalgs <sigalgs>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de signature liés à l’authentification cliente qui sont négociés. Le format de la chaîne est défini dans « man 3 SSL_CTX_set1_client_sigalgs » des pages de documentation OpenSSL. Il est déconseillé d’utiliser ce paramètre si aucun cas d’utilisation spécifique n’a été identifié.

cookie <value>

cookie <value>

Peut être utilisé dans les contextes suivants : http

Le paramètre « cookie » définit la valeur de cookie attribuée au serveur pour <value>. Cette valeur sera vérifiée dans les requêtes entrantes, et le premier backend opérationnel possédant la même valeur sera sélectionné. En retour, en mode insertion ou réécriture de cookie, cette valeur sera attribuée au cookie envoyé au client. Il n’y a rien de répréhensible à ce que plusieurs serveurs partagent la même valeur de cookie, ce qui est d’ailleurs courant entre serveurs normaux et serveurs de secours. Voir également le mot-clé « cookie » dans la section backend.

crl-file <crlfile>

crl-file <crlfile>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il indique un fichier PEM à partir duquel charger la liste de révocation de certificats utilisée pour vérifier le certificat du serveur.

crt <cert>

crt <cert>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il indique un fichier PEM à partir duquel charger à la fois un certificat et sa clé privée associée. Ce fichier peut être créé en concaténant deux fichiers PEM. Ce certificat sera envoyé si le serveur demande un certificat client.

Si le fichier ne contient pas de clé privée, HAProxy tentera de charger la clé au même chemin, suffixé par un “.key” (à condition que l’option “ssl-load-extra-files” soit configurée en conséquence).

curves <curves>

curves <curves>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de courbes elliptiques (“suite de courbes”) négociés lors de l’échange SSL/TLS avec ECDHE. Le format de la chaîne est une liste séparée par des deux-points de noms de courbes. Exemple : “X25519:P-256” (sans guillemets)

disabled

disabled

Peut être utilisé dans les contextes suivants : tcp, http, log

Le mot-clé « disabled » place le serveur en état « disabled ». Cela signifie qu’il est marqué comme hors service en mode maintenance, et aucune connexion, hormis celles autorisées par le mode persist, ne pourra le rejoindre. Il convient particulièrement bien pour configurer de nouveaux serveurs, car le trafic normal n’y parviendra jamais, tout en permettant encore de tester le service grâce au mécanisme force-persist. Voir également le paramètre « enabled ».

enabled

enabled

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « disabled » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « disabled » précédent défini sur « default-server ».

error-limit <count>

error-limit <count>

Peut être utilisé dans les contextes suivants : tcp, http, log

Si l’observation de la santé est activée, le paramètre « error-limit » spécifie le nombre d’erreurs consécutives qui déclenchent l’événement sélectionné par l’option « on-error ». Par défaut, il est défini à 10 erreurs consécutives.

Voir également les options « check », « error-limit » et « on-error ».

fall <count>

fall <count>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « fall » indique qu’un serveur est considéré comme défaillant après <count> contrôles d’état consécutifs échoués. Cette valeur vaut 3 par défaut si non spécifiée. Voir également les paramètres « check », « inter » et « rise ».

force-sslv3

force-sslv3

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de SSLv3 uniquement lorsque le protocole SSL est utilisé pour communiquer avec le serveur. SSLv3 est généralement moins coûteux que ses homologues TLS pour des débits de connexion élevés. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv10

force-tlsv10

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de TLSv1.0 uniquement lorsque SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv11

force-tlsv11

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de TLSv1.1 uniquement lorsque SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv12

force-tlsv12

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de TLSv1.2 uniquement lorsque le protocole SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

force-tlsv13

force-tlsv13

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de TLSv1.3 uniquement lorsque SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver » et « ssl-max-ver ».

guid <string>

guid <string>

Peut être utilisé dans les contextes suivants : tcp, http, log

Spécifiez un identifiant global sensible à la casse pour ce serveur. Celui-ci doit être unique sur l’ensemble de la configuration haproxy, pour tous les types d’objets. Consultez la description du mot-clé proxy « guid » pour plus d’informations sur son format. Voir également « shm-stats-file ».

hash-key <key>

hash-key <key>

Peut être utilisé dans les contextes suivants : tcp, http, log

Spécifiez la manière dont les clés de nœud « hash-type consistent » sont calculées

Arguments :

<key>   <key> may be one of the following:

  id         The node keys will be derived from the server's numeric
             identifier as set from "id" or which defaults to its position
             in the server list. This is the default. Note that only the 28
             lowest bits of the ID will be used (i.e. (id % 268435456)), so
             better only use values comprised between 1 and this value to
             avoid overlap.

  id32       The node keys will be derived from the server's numeric
             identifier as set from "id" or which defaults to its position
             in the server list, but the full 32 bits of the ID will be
             used so that there is no collision. This one is not scaled
             like "id" is, so it is recommended to either always use it
             with a hash function (see "hash-key") or with explicitly
             assigned ID values that are evenly distributed over the 32-bit
             space.

  guid       The node keys will be derived from the server's guid, when
             available, otherwise they will fall back on "id". The benefit
             is that it does not depend on ordering at all, only on an
             internal stable identifier that can be replicated across many
             load balancers.

  addr       The node keys will be derived from the server's address, when
             available, or else fall back on "id".

  addr-port  The node keys will be derived from the server's address and
             port, when available, or else fall back on "id".

Les options « addr » et « addr-port » peuvent être utiles dans les scénarios où plusieurs processus HAProxy répartissent le trafic vers le même ensemble de serveurs. Si l’ordre des serveurs est différent pour chaque processus (par exemple, en raison d’une résolution DNS effectuée dans un ordre différent), cela permet à chaque processus HAProxy indépendant de s’accorder sur les décisions de routage. Remarque : « balance random » utilise également « hash-type consistent », et la qualité de la répartition dépendra de la qualité des clés.

healthcheck <name>

healthcheck <name>

Peut être utilisé dans les contextes suivants : tcp, http

Spécifiez la section de vérification de santé à utiliser pour effectuer le contrôle sur le serveur.

Argument :

<name>    is the health-check section name.

Grâce à cette option, il est possible d’utiliser une configuration de vérification de santé du serveur préalable au lieu d’utiliser la configuration du proxy. Voir également la section « healthcheck ».

id <value>

id <value>

Peut être utilisé dans les contextes suivants : tcp, http, log

Définir un identifiant persistant pour le serveur. Cet identifiant doit être un nombre positif sur 32 bits et unique pour le proxy. Un identifiant non utilisé sera automatiquement attribué si ce paramètre n’est pas défini. La première valeur attribuée sera 1. Cet identifiant est actuellement renvoyé uniquement dans les statistiques, et est utilisé pour positionner les nœuds de répartition de charge lors de l’utilisation d’algorithmes de hachage cohérents lorsque « hash-key » est défini sur « id » (valeur par défaut). Dans ce cas, seuls les 28 bits les plus bas de la valeur sont utilisés (c’est-à-dire (id % 268435356)), il est donc préférable d’utiliser uniquement des valeurs comprises entre 1 et cette valeur afin d’éviter les chevauchements.

idle-ping <delay>

idle-ping <delay>

Peut être utilisé dans les contextes suivants : tcp, http, log

Définir une intervalle pour le contrôle périodique de la disponibilité des connexions backend inactives. Si la partie distante ne parvient pas à répondre avant le prochain test planifié, la connexion est fermée. Ce mot-clé fait référence au côté backend, ce qui est utile pour vérifier que les connexions inactives restent utilisables. Notez que cela n’empêche pas la destruction de la connexion lors du vidage du pool d’attente inactif.

Cette fonctionnalité dépend d’un support spécifique du protocole sous-jacent. Pour l’instant, seul H2 mux l’implémente. Le ping inactif est simplement ignoré par les autres protocoles.

Cette option est particulièrement utile lors de l’utilisation d’un proxy inverse HTTP. La définir sur la ligne serveur est utile pour le pair qui écoute les connexions entrantes et les associe à un serveur correspondant afin de pouvoir réutiliser ultérieurement le transfert de trafic.

init-addr {last | libc | none | <ip>},[...]*

init-addr {last | libc | none | <ip>},[...]*

Peut être utilisé dans les contextes suivants : tcp, http, log

Indiquez dans quel ordre l’adresse du serveur doit être résolue au démarrage s’il utilise un nom complet (FQDN). Des tentatives sont effectuées pour résoudre l’adresse en appliquant successivement chacune des méthodes mentionnées dans la liste séparée par des virgules. La première méthode réussie est utilisée. Si la fin de la liste est atteinte sans trouver de méthode fonctionnelle, une erreur est levée. La méthode « last » indique de choisir l’adresse figurant dans le fichier d’état (voir « server-state-file »). La méthode « libc » utilise le résolveur interne de libc (gethostbyname() ou getaddrinfo() selon le système d’exploitation et les options de compilation). La méthode « none » indique spécifiquement que le serveur doit démarrer sans adresse IP valide, dans un état down. Cela peut être utile pour ignorer certains problèmes DNS au démarrage, en attendant que la situation soit corrigée ultérieurement. Enfin, une adresse IP (IPv4 ou IPv6) peut être fournie. Elle peut être l’adresse actuellement connue du serveur (par exemple, renseignée par un générateur de configuration), ou l’adresse d’un serveur factice utilisé pour capter les sessions anciennes et leur présenter un message d’erreur approprié. Lorsque l’algorithme de répartition de charge « first » est utilisé, cette adresse IP peut pointer vers un serveur factice utilisé pour déclencher la création d’instances nouvelles en temps réel. Cette option est par défaut définie sur « last,libc », ce qui signifie que l’adresse précédemment trouvée dans le fichier d’état (le cas échéant) est utilisée en priorité, sinon le résolveur libc est utilisé. Cela garantit une compatibilité continue avec le comportement historique. Lors de l’utilisation de résolveurs internes, il est généralement recommandé de désactiver la résolution basée sur libc, ou de la rendre explicite (voir section 5.3 pour plus de détails).

Exemple 1 :

defaults
    # never fail on address resolution
    default-server init-addr last,libc,none

Exemple 2 :

defaults
    # disable libc resolution in combination with resolvers
    default-server init-addr last,none

inter <delay>

inter <delay>
fastinter <delay>
downinter <delay>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « inter » définit l’intervalle entre deux contrôles d’état consécutifs en <delay> millisecondes. Si non spécifié, le délai par défaut est de 2000 ms. Il est également possible d’utiliser « fastinter » et « downinter » afin d’optimiser les délais entre les contrôles en fonction de l’état du serveur :

             Server state                   |         Interval used
    ----------------------------------------+----------------------------------
     UP 100% (non-transitional)             | "inter"
    ----------------------------------------+----------------------------------
     Transitionally UP (going down "fall"), | "fastinter" if set,
     Transitionally DOWN (going up "rise"), | "inter" otherwise.
     or yet unchecked.                      |
    ----------------------------------------+----------------------------------
     DOWN 100% (non-transitional)           | "downinter" if set,
                                            | "inter" otherwise.
    ----------------------------------------+----------------------------------

Tout comme pour tout autre paramètre basé sur le temps, ils peuvent être entrés dans n’importe quelle autre unité explicite parmi { us, ms, s, m, h, d }. Le paramètre « inter » sert également de délai d’expiration pour les contrôles d’état envoyés aux serveurs si « timeout check » n’est pas défini. Afin de réduire les effets de « résonance » lorsque plusieurs serveurs sont hébergés sur le même matériel, l’agent et les contrôles d’état de tous les serveurs sont lancés avec un petit décalage temporel entre eux. Il est également possible d’ajouter un bruit aléatoire dans l’intervalle des agents et des contrôles d’état en utilisant le mot-clé global « spread-checks ». Cela a un sens, par exemple, lorsque de nombreux backends utilisent les mêmes serveurs. Le paramètre global “tune.max-checks-per-thread”, s’il est défini à une valeur non nulle, limitera le nombre de contrôles simultanés effectués en même temps sur un thread donné. Pour y parvenir, HAProxy mettra en file d’attente les contrôles qui devaient démarrer sur un thread ayant atteint cette limite, jusqu’à ce qu’un autre contrôle se termine. Cela aura pour effet d’élargir l’intervalle de contrôle effectif. Dans ce cas, réduire la valeur du paramètre « inter » aura un effet très limité, car elle ne pourra pas réduire le temps passé en file d’attente.

init-state { fully-up | up | down | fully-down | none }

init-state { fully-up | up | down | fully-down | none }

Peut être utilisé dans les contextes suivants : tcp, http

Peut être utilisé dans les sections : defaults | frontal | listen | backend non | non | oui | oui

L’option « init-state » définit l’état initial du serveur : - lorsqu’elle est définie sur « fully-up », le serveur est considéré comme immédiatement disponible, et, si les contrôles d’état sont activés pour ce serveur, il passera à l’état DOWN lorsque TOUS les contrôles d’état échouent. - lorsqu’elle est définie sur « up », le serveur est considéré comme immédiatement disponible, et, si les contrôles d’état sont activés pour ce serveur, il passera immédiatement à l’état DOWN si le prochain contrôle d’état échoue. - lorsqu’elle est définie sur « down », le serveur est initialement considéré comme indisponible, et, si les contrôles d’état sont activés pour ce serveur, il peut passer à l’état UP si le prochain contrôle d’état réussit. - lorsqu’elle est définie sur « fully-down », le serveur est initialement considéré comme indisponible, et, si les contrôles d’état sont activés pour ce serveur, il passera à l’état UP lorsque TOUS les contrôles d’état réussissent. - lorsqu’elle est définie sur « none » (valeur par défaut), la gestion de l’état initial est désactivée. Elle peut être utilisée pour restaurer le comportement par défaut lorsque ce paramètre était hérité d’une directive « default-server ».

L’état initial du serveur est pris en compte lors du démarrage (ou redémarrage) de l’instance HAProxy, lorsqu’un nouveau serveur est détecté (par exemple via la découverte de services ou la résolution DNS), lorsqu’un serveur dynamique devient actif, lorsqu’un serveur quitte le mode maintenance, etc. Cette directive ne peut pas être utilisée lorsque le serveur suit un autre serveur.

Exemples :

# pass client traffic ONLY to Redis "master" node
backend redis-master
  mode tcp
  balance first
  option tcp-check
  tcp-check send role\r\n
  tcp-check expect string master
  server-template redis 3 _redis._tcp.redis-headless-service.sandbox.svc.cluster.local:6379 check ... init-state down

# pass traffic to the server only after 3 successful health checks
backend google-backend
  mode http
  server srv1 google.com:80 check init-state fully-down rise 3
  server srv2 google.com:80 check init-state fully-down rise 3

Voir également : « option tcp-check », « option httpchk »

ktls <on|off> [ EXPERIMENTAL ]

ktls <on|off> [ EXPERIMENTAL ]

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Active ou désactive kTLS pour ces sockets. Si activé, kTLS sera utilisé si le noyau le prend en charge et si le chiffrement est compatible. Cette fonctionnalité n’est disponible qu’avec Linux 4.17 et versions ultérieures. Veuillez noter que certains pilotes réseau et/ou piles TLS peuvent limiter l’utilisation de kTLS à TLS v1.2 uniquement. Voir également « force-tlsv12 ».

log-bufsize <bufsize>

log-bufsize <bufsize>

Peut être utilisé dans les contextes suivants : log

Le paramètre « log-bufsize » spécifie la taille de la mémoire tampon anneau à utiliser pour l’anneau implicite associé au serveur de journalisation dans un backend de journalisation. En l’absence de spécification, cette valeur par défaut est BUFSIZE. Une valeur plus élevée augmente l’utilisation de la mémoire, mais peut aider à éviter la perte de messages de journalisation avec des serveurs lents, car la mémoire tampon pourra contenir davantage de messages en attente. Ce mot-clé ne peut être utilisé que dans les sections de backend de journalisation (avec « mode log »).

log-proto <logproto>

log-proto <logproto>

Peut être utilisé dans les contextes suivants : log, ring

Le paramètre « log-proto » spécifie le protocole utilisé pour acheminer les messages d’événement vers un serveur configuré dans une section log ou ring. Les valeurs possibles sont « legacy » et « octet-count », correspondant respectivement à « Non-transparent-framing » et « Octet counting » dans le rfc6587. La valeur par défaut est « legacy ».

maxconn <maxconn>

maxconn <maxconn>

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « maxconn » spécifie le nombre maximal de connexions simultanées qui seront envoyées à ce serveur. Si le nombre de connexions entrantes simultanées dépasse cette valeur, celles-ci seront placées en file d’attente, en attendant qu’une place soit libérée. Ce paramètre est très important car il peut empêcher des serveurs fragiles de tomber sous des charges extrêmes. Si un paramètre « minconn » est spécifié, la limite devient dynamique. La valeur par défaut est « 0 », ce qui signifie sans limite. Voir également les paramètres « minconn » et « maxqueue », ainsi que le mot-clé « fullconn » du backend.

En mode HTTP, ce paramètre limite le nombre de requêtes simultanées au lieu du nombre de connexions. Plusieurs requêtes peuvent être multiplexées sur une seule connexion TCP vers le serveur. Par exemple, si vous spécifiez une valeur maxconn de 50, vous pouvez observer entre 1 et 50 connexions réelles vers le serveur, mais jamais plus de 50 requêtes simultanées.

maxqueue <maxqueue>

maxqueue <maxqueue>

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « maxqueue » spécifie le nombre maximal de connexions pouvant attendre dans la file d’attente pour ce serveur. Si cette limite est atteinte, les requêtes suivantes seront redirigées vers d’autres serveurs au lieu de rester indéfiniment en attente. Cela rompt la persistance, mais peut permettre à des utilisateurs de se reconnecter rapidement lorsque le serveur vers lequel ils tentent de se connecter est en panne. Certains algorithmes de répartition de charge, comme « leastconn », tiennent compte de cette valeur et acceptent d’ajouter des requêtes à la file d’attente d’un serveur jusqu’à cette limite, à condition qu’elle soit explicitement définie à une valeur strictement supérieure à zéro, ce qui permet souvent de mieux lisser la charge lorsqu’on utilise des valeurs de « maxconn » à un chiffre. La valeur par défaut est « 0 », ce qui signifie que la file d’attente est illimitée. Voir également les paramètres « maxconn » et « minconn », ainsi que « balance leastconn ».

max-reuse <count>

max-reuse <count>

Peut être utilisé dans les contextes suivants : http, ring

Lorsqu’il est utilisé dans un contexte http :

L’argument « max-reuse » indique aux processeurs de connexions HTTP de ne pas réutiliser une connexion serveur plus de ce nombre de fois pour envoyer de nouvelles requêtes. Les valeurs autorisées sont -1 (valeur par défaut), qui désactive cette limite, ou toute valeur positive. La valeur zéro désactive effectivement keep-alive. Cette option est uniquement destinée à contourner certaines erreurs serveur qui entraînent une fuite de ressources au fil du temps. L’argument n’est pas nécessairement respecté par les couches inférieures en raison de limitations techniques pouvant rendre son application impossible. Au moins les connexions HTTP/2 vers les serveurs le respecteront.

Lorsqu’il est utilisé dans un contexte anneau :

L’argument « max-reuse » indique que les processeurs de connexion TCP du réceptacle ne doivent pas réutiliser une connexion serveur plus de ce nombre de fois pour envoyer des messages. Cela signifie que la connexion vers le serveur sera détruite de force une fois qu’au moins « max-reuse + 1 » messages auront été traités sur la même connexion. La connexion vers le serveur sera alors automatiquement recréée. En cas de traitement d’un grand nombre de messages dans un contexte multithreadé, cela peut aider à mieux répartir la charge de l’anneau sur plusieurs threads. En effet, chaque connexion est associée au même thread CPU pendant toute sa durée : contrairement au protocole HTTP, il n’existe pas de transaction syslog, aussi la connexion serveur peut-elle persister indéfiniment tant que le serveur ne ferme pas la connexion ou qu’aucune erreur réseau ne se produit. En détruisant périodiquement les connexions, on donne la possibilité aux autres threads de traiter des messages à leur tour. Cela peut également aider à effectuer une rotation propre des serveurs de journalisation dans des contextes où il existe une couche supplémentaire de répartition de charge entre HAProxy et les serveurs de journalisation. Toutefois, gardez à l’esprit qu’à chaque recyclage de connexion, un port sortant reste en état TIME_WAIT pendant environ une minute sur les systèmes d’exploitation modernes, et qu’il convient donc d’éviter d’utiliser des valeurs trop faibles afin de prévenir l’épuisement rapide des ports sources. En règle générale, assurez-vous de ne jamais fermer plus de quelques fois par seconde, et idéalement beaucoup moins souvent. Les valeurs autorisées sont -1 (valeur par défaut), qui désactive cette limite, ou toute valeur positive. Contrairement au contexte HTTP, lorsque utilisé avec des serveurs réceptacles, « max-reuse » est une indication optimiste : les messages de l’anneau sont regroupés par lots, aussi la limite est-elle vérifiée entre chaque lot.

minconn <minconn>

minconn <minconn>

Peut être utilisé dans les contextes suivants : tcp, http

Lorsque le paramètre « minconn » est défini, la limite maxconn devient une limite dynamique suivant la charge du backend. Le serveur acceptera toujours au moins <minconn> connexions, jamais plus de <maxconn>, et la limite évoluera progressivement entre ces deux valeurs lorsque le backend dispose de moins de <fullconn> connexions simultanées. Cela permet de limiter la charge sur le serveur en conditions normales, tout en permettant de pousser davantage la charge en cas de charges importantes, sans surcharger le serveur en cas de charges exceptionnelles. Voir également les paramètres « maxconn » et « maxqueue », ainsi que le mot-clé backend « fullconn ».

namespace <name>

namespace <name>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Sous Linux, il est possible de spécifier l’espace de noms réseau auquel un socket appartient. Cette directive permet de lier explicitement un serveur à un espace de noms différent de celui par défaut. Veuillez vous référer à la documentation de votre système d’exploitation pour obtenir davantage de détails sur les espaces de noms réseau.

no-agent-check

no-agent-check

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « agent-check » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « agent-check » « default-server » précédent.

no-backup

no-backup

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « backup » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « backup » précédent défini sur « default-server ».

no-check

no-check

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « check » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « check » « default-server » précédent.

no-check-reuse-pool

no-check-reuse-pool

Peut être utilisé dans les contextes suivants : tcp, http

Cette option annule toute option « check-reuse-pool » précédemment définie, éventuellement héritée d’un « default-server ». Toutes les vérifications seront effectuées sur sa connexion dédiée.

no-check-sni-auto

no-check-sni-auto

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée en tant que paramètre « server » pour désactiver la sélection automatique du SNI pour les vérifications de santé SSL, qui est activée par défaut.

Voir l’option « no-sni-auto » pour désactiver la sélection automatique du SNI pour le trafic proxyé.

no-check-ssl

no-check-ssl

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « check-ssl » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « check-ssl » précédent défini sur « default-server ».

no-renegotiate

no-renegotiate

Peut être utilisé dans les contextes suivants : tcp, http, log

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il désactive les mécanismes de renégociation, qu’il s’agisse de l’ancien mécanisme non sécurisé ou du mécanisme plus récent « renégociation sécurisée » (extension RFC 5746 TLS Renegotiation Indication). Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». La renégociation n’est plus possible dans TLS 1.3. Si ni « renegotiate » ni « no-renegotiate » n’est spécifié, le comportement par défaut de la bibliothèque SSL est conservé. Notez qu’OpenSSL active par défaut la renégociation sécurisée, tandis qu’AWS-LC la désactive. Voir également « renegotiate ».

no-send-proxy

no-send-proxy

Peut être utilisé dans les contextes suivants : tcp, http

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « send-proxy » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « send-proxy » « default-server » précédent.

no-send-proxy-v2

no-send-proxy-v2

Peut être utilisé dans les contextes suivants : tcp, http

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « send-proxy-v2 » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « send-proxy-v2 » précédemment défini sur « default-server ».

no-send-proxy-v2-ssl

no-send-proxy-v2-ssl

Peut être utilisé dans les contextes suivants : tcp, http

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « send-proxy-v2-ssl » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « send-proxy-v2-ssl » précédemment défini sur « default-server ».

no-send-proxy-v2-ssl-cn

no-send-proxy-v2-ssl-cn

Peut être utilisé dans les contextes suivants : tcp, http

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « send-proxy-v2-ssl-cn » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « send-proxy-v2-ssl-cn » précédemment défini sur « default-server ».

no-sni-auto

no-sni-auto

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée en tant que paramètre « server » pour désactiver la sélection automatique du SNI, qui est activée par défaut.

Voir l’option « no-check-sni-auto » pour désactiver la sélection automatique du SNI pour les contrôles d’état SSL.

no-ssl

no-ssl

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « ssl » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « ssl » « default-server » précédent.

Notez que l’utilisation de la configuration default-server ssl et de no-ssl sur le serveur initie toutefois une connexion SSL, qui peut ensuite être activée via l’API d’exécution : consultez les commandes set server dans la documentation d’administration.

no-ssl-reuse

no-ssl-reuse

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la réutilisation des sessions SSL lors de la communication avec le serveur. Elle oblige le serveur à effectuer une négociation complète pour chaque nouvelle connexion. Elle est probablement utile uniquement à des fins de benchmark, de dépannage ou pour des utilisateurs paranoïaques.

no-sslv3

no-sslv3

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la prise en charge de SSLv3 lors de la communication avec le serveur via SSL. Notez que SSLv2 est désactivé dans le code et ne peut pas être activé à l’aide de toute option de configuration. Utilisez plutôt « ssl-min-ver » et « ssl-max-ver ».

Pris en charge dans default-server : Non

no-tls-tickets

no-tls-tickets

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il désactive la reprise de session sans état (extension TLS Ticket RFC 5077) et force l’utilisation de la reprise de session avec état. La reprise de session sans état est plus coûteuse en ressources CPU pour les serveurs. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Le mécanisme des tickets TLS n’est utilisé qu’avec TLS 1.2 au maximum. La confidentialité à long terme est compromise avec les tickets TLS, sauf si les clés de ticket sont régulièrement renouvelées (par rechargement ou en utilisant « tls-ticket-keys »). Voir également « tls-tickets ».

no-tlsv10

no-tlsv10

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la prise en charge de TLSv1.0 lors de l’utilisation de SSL pour la communication avec le serveur. Notez que SSLv2 est désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. TLSv1 est plus coûteux que SSLv3, il est donc souvent pertinent de le désactiver lors de la communication avec des serveurs locaux. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Privilégiez plutôt les options « ssl-min-ver » et « ssl-max-ver ».

Pris en charge dans default-server : Non

no-tlsv11

no-tlsv11

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la prise en charge de TLSv1.1 lors de l’utilisation de SSL pour la communication avec le serveur. Notez que SSLv2 est désactivé dans le code et ne peut pas être activé à l’aide de toute option de configuration. TLSv1 est plus coûteux que SSLv3, il est donc souvent pertinent de le désactiver lors de la communication avec des serveurs locaux. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Privilégiez plutôt les options « ssl-min-ver » et « ssl-max-ver ».

Pris en charge dans default-server : Non

no-tlsv12

no-tlsv12

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la prise en charge de TLSv1.2 lors de l’utilisation de SSL pour la communication avec le serveur. Notez que SSLv2 est désactivé dans le code et ne peut pas être activé à l’aide d’aucune option de configuration. TLSv1 est plus coûteux que SSLv3, il est donc souvent pertinent de le désactiver lors de la communication avec des serveurs locaux. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Privilégiez plutôt les options « ssl-min-ver » et « ssl-max-ver ».

Pris en charge dans default-server : Non

no-tlsv13

no-tlsv13

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option désactive la prise en charge de TLSv1.3 lors de l’utilisation de SSL pour la communication avec le serveur. Notez que SSLv2 est désactivé dans le code et ne peut pas être activé à l’aide de toute option de configuration. TLSv1 est plus coûteux que SSLv3, il est donc souvent pertinent de le désactiver lors de la communication avec des serveurs locaux. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Privilégiez plutôt les options « ssl-min-ver » et « ssl-max-ver ».

Pris en charge dans default-server : Non

no-verifyhost

no-verifyhost

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « verifyhost » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « verifyhost » « default-server » précédent.

no-tfo

no-tfo

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « tfo » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre « tfo » « default-server » précédent.

non-stick

non-stick

Peut être utilisé dans les contextes suivants : tcp, http

N’ajoutez jamais les connexions attribuées à ce serveur à une table de persistance. Cela peut être utilisé conjointement avec backup afin de désactiver la persistance de la table de persistance pour les serveurs de secours.

npn <protocols>

npn <protocols>

Peut être utilisé dans les contextes suivants : tcp, http

Cela active l’extension TLS NPN et annonce la liste de protocoles spécifiée comme prise en charge au-dessus de NPN. La liste de protocoles est constituée d’une liste séparée par des virgules de noms de protocoles, par exemple : “http/1.1,http/1.0” (sans guillemets). Cela nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifiez avec HAProxy -vv). Notez que l’extension NPN a été remplacée par l’extension ALPN (voir le mot-clé « alpn »), bien que celle-ci ne soit disponible qu’à partir d’OpenSSL 1.0.2.

observe <mode>

observe <mode>

Peut être utilisé dans les contextes suivants : tcp, http

Cette option active l’ajustement de l’état du serveur en fonction de l’observation de la communication avec celui-ci. Par défaut, cette fonctionnalité est désactivée, et son activation nécessite également l’activation des contrôles d’état. Deux modes sont pris en charge : “layer4” et “layer7”. En mode layer4, seules les connexions TCP réussies ou non réussies sont prises en compte. En mode layer7, qui n’est autorisé que pour les proxies HTTP, les réponses reçues du serveur sont vérifiées, comme un code HTTP valide/incorrect, des en-têtes non parsables, un délai d’expiration, etc. Les codes d’état valides incluent les codes 100 à 499, ainsi que 501 et 505.

Voir également les options « check », « on-error » et « error-limit ».

on-error <mode>

on-error <mode>

Peut être utilisé dans les contextes suivants : tcp, http, log

Sélectionnez l’action à effectuer lorsqu’un nombre suffisant d’erreurs consécutives est détecté. Actuellement, quatre modes sont disponibles :

  • fastinter : force l’activation de fastinter
  • fail-check : simule un contrôle d’état échoué, active également fastinter (par défaut)
  • sudden-death : simule un échec de contrôle d’état pré-fatal, un autre échec entraînera la mise hors ligne du serveur, force l’activation de fastinter
  • mark-down : met immédiatement le serveur hors ligne et force l’activation de fastinter

Voir également les options « check », « observe » et « error-limit ».

on-marked-down <action>

on-marked-down <action>

Peut être utilisé dans les contextes suivants : tcp, http, log

Modifiez ce qui se produit lorsque serveur est marqué comme hors service. Actuellement, une action est disponible :

  • shutdown-sessions : Arrêt des flux pairs. Lorsque cette option est activée, toutes les connexions vers le serveur sont immédiatement terminées lorsque le serveur tombe en panne. Elle peut être utilisée si le contrôle d’état détecte des cas plus complexes qu’un simple statut de connexion, et que des délais d’expiration longs entraîneraient une indisponibilité prolongée du service. Par exemple, un contrôle d’état pourrait détecter qu’une base de données est bloquée et qu’il n’y a plus aucune chance de réutiliser les connexions existantes. Les connexions interrompues de cette manière sont journalisées avec un code de terminaison « D » (pour « Down »).

Les actions sont désactivées par défaut

on-marked-up <action>

on-marked-up <action>

Peut être utilisé dans les contextes suivants : tcp, http, log

Modifiez ce qui se produit lorsque le serveur est marqué comme actif. Actuellement, une action est disponible :

  • shutdown-backup-sessions : Met en arrêt les flux sur tous les serveurs de sauvegarde. Cela n’est effectué que si le serveur n’est pas en état de sauvegarde et s’il n’est pas désactivé (son poids effectif doit être supérieur à 0). Cette option peut parfois être utilisée pour forcer un serveur actif à reprendre tout le trafic après une récupération, notamment lors de sessions longues (par exemple, LDAP, SQL, …). Cette opération peut causer plus de problèmes qu’elle n’en résout (par exemple, transactions incomplètes), aussi doit-elle être utilisée avec une extrême prudence. Les flux interrompus en raison de la remise en service d’un serveur sont journalisés avec un code de terminaison « U » (pour « Up »).

Les actions sont désactivées par défaut

pool-conn-name <expr>

pool-conn-name <expr>

Peut être utilisé dans les contextes suivants : http

Lorsqu’une connexion vers un backend est établie, cette expression est évaluée afin de générer le nom de la connexion. Ce nom est l’une des propriétés clés de la connexion dans le pool de serveurs inactifs. Voir le mot-clé « http-reuse ». Lorsqu’une requête recherche une connexion inactive existante, cette expression est évaluée afin de trouver une connexion identique.

Dans un contexte où le SNI SSL est utilisé pour la connexion au backend, le nom de connexion est automatiquement attribué au résultat de l’expression « sni ». Cette configuration convient à l’utilisation la plus courante. Pour des configurations plus avancées, « pool-conn-name » peut être utilisé pour remplacer cette attribution.

Voir aussi : « http-reuse », « sni »

pool-low-conn <max>

pool-low-conn <max>

Peut être utilisé dans les contextes suivants : http

Définissez un seuil bas sur le nombre de connexions inactives pour un serveur, en dessous duquel un thread ne tentera pas de voler une connexion à un autre thread. Cela peut être utile pour améliorer les performances du processeur dans les scénarios impliquant de nombreux serveurs très rapides, afin de garantir que tous les threads conservent toujours quelques connexions inactives, plutôt que de laisser les connexions s’accumuler sur un seul thread et être migrées d’un thread à l’autre. Des valeurs typiques équivalentes à deux fois le nombre de threads semblent déjà offrir de très bonnes performances avec des temps de réponse inférieurs à un milliseconde. La valeur par défaut est zéro, ce qui indique qu’une connexion inactive peut être utilisée à tout moment. Il s’agit du paramétrage recommandé pour une utilisation normale. Cette option s’applique uniquement aux connexions pouvant être partagées selon les mêmes principes que ceux régissant « http-reuse ». Dans le cas où le partage de connexion entre threads serait désactivé via “tune.idle-pool.shared”, il devient très important d’utiliser ce paramètre afin de garantir qu’un thread dispose toujours de quelques connexions, sinon le taux de réutilisation des connexions diminuera à mesure que le nombre de threads augmente.

pool-max-conn <max>

pool-max-conn <max>

Peut être utilisé dans les contextes suivants : http

Définir le nombre maximal de connexions inactives pour un serveur. -1 signifie un nombre illimité de connexions, 0 signifie aucune connexion inactive. La valeur par défaut est -1.. Lorsque les connexions inactives sont activées, les connexions inactives orphelines qui ne sont plus associées à aucune session cliente sont transférées dans un pool dédié afin de rester utilisables par les clients futurs. Cela ne s’applique qu’aux connexions pouvant être partagées selon les mêmes principes que ceux régissant le « http-reuse ».

pool-purge-delay <delay>

pool-purge-delay <delay>

Peut être utilisé dans les contextes suivants : http

Définit le délai avant le démarrage de la suppression des connexions inactives. À chaque intervalle <delay>, la moitié des connexions inactives est fermée. Une valeur de 0 signifie qu’aucune connexion inactive n’est conservée. La valeur par défaut est 5s.

port <port>

port <port>

Peut être utilisé dans les contextes suivants : tcp, http, log

En utilisant le paramètre « port », il devient possible d’utiliser un port différent pour envoyer les vérifications de santé ou pour interroger l’agent-check. Sur certains serveurs, il peut être souhaitable de réserver un port à un composant spécifique capable d’exécuter des tests complexes, plus adaptés aux vérifications de santé qu’application elle-même. Il est courant, par exemple, d’exécuter un script simple via inetd. Ce paramètre est ignoré si le paramètre « check » n’est pas défini. Voir également le paramètre « addr ».

proto <name>

proto <name>

Peut être utilisé dans les contextes suivants : tcp, http

Force le protocole du multiplexeur à utiliser pour les connexions sortantes vers ce serveur. Il doit être compatible avec le mode du backend (TCP ou HTTP). Il doit également être utilisable du côté du backend. La liste des protocoles disponibles est indiquée dans les propriétés des protocoles HAProxy -vv.The : le mode (TCP/HTTP), le côté (FE/BE), le nom du multiplexeur et ses indicateurs.

Certains protocoles sont sujets au blocage par tête de file côté serveur (drapeau=HOL_RISK). Enfin, certains protocoles ne prennent pas en charge les mises à jour (drapeau=NO_UPG). La compatibilité HTX est également indiquée (drapeau=HTX).

Voici les protocoles pouvant être utilisés en tant qu’argument de la directive « proto » sur une ligne de serveur :

quic: mode=HTTP  side=FE|BE  mux=QUIC  flags=HTX|NO_UPG|FRAMED
qmux: mode=HTTP  side=FE|BE  mux=QMUX  flags=HTX|NO_UPG
h2  : mode=HTTP  side=FE|BE  mux=H2    flags=HTX|HOL_RISK|NO_UPG
fcgi: mode=HTTP  side=BE     mux=FCGI  flags=HTX|HOL_RISK|NO_UPG
h1  : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
none: mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG
spop: mode=SPOP  side=BE     mux=SPOP  flags=HOL_RISK|NO_UPG

L’idée de cette option est de contourner le choix du meilleur protocole multiplexeur pour toutes les connexions établies vers ce serveur.

Si les paramètres ALPN ou NPN sont configurés, les protocoles spécifiés doivent être compatibles avec le protocole du multiplexeur afin d’éviter tout problème. Par exemple, si « proto h1 » est défini, l’ALPN ne doit pas être configuré sur « h2 ».

Voir également « ws » pour utiliser un protocole alternatif pour les flux WebSocket.

QMux est un sous-ensemble de QUIC qui s’exécute sur TCP. Il correspond au protocole proposé dans le brouillon suivant : https://www.ietf.org/archive/id/draft-ietf-quic-qmux-01.html . Il est actuellement considéré comme expérimental dans HAProxy.

quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]

quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]

Ce paramètre est spécifique à QUIC et permet de sélectionner l’algorithme de contrôle de congestion pour toute connexion ciblant ce serveur. Ils sont similaires à ceux utilisés par TCP. Consultez l’option bind, dont le nom est similaire, pour une description complète de toutes les options de personnalisation.

Valeur par défaut : cubic

Voir aussi : “tune.quic.be.tx.pacing” et “tune.quic.be.cc.max-win-size”

redir <prefix>

redir <prefix>

Peut être utilisé dans les contextes suivants : http

Le paramètre « redir » active le mode de redirection pour toutes les requêtes GET et HEAD adressées à ce serveur. Cela signifie qu’au lieu de transmettre la requête au serveur, HAProxy renvoie une réponse « HTTP 302 » dont l’en-tête « Location » est composé de ce préfixe immédiatement suivi de l’URI demandé, commençant par le « / » initial du composant de chemin. Cela implique qu’aucune barre oblique finale ne doit être utilisée après <prefix>. Toutes les requêtes non valides seront rejetées, et toutes les requêtes autres que GET ou HEAD seront normalement servies par le serveur. Notez que, puisque la réponse est entièrement générée, aucune modification d’en-tête ni insertion de cookie n’est possible dans la réponse. Toutefois, les cookies présents dans les requêtes sont toujours analysés, rendant cette solution entièrement utilisable pour rediriger les utilisateurs vers un emplacement distant en cas de catastrophe locale. Son usage principal consiste à augmenter la bande passante des serveurs statiques en faisant établir la connexion directe par les clients. Attention : n’utilisez jamais une localisation relative ici, cela provoquerait une boucle entre le client et HAProxy !

Exemple : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check

renegotiate

renegotiate

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option active le mécanisme de renégociation sécurisée (extension Indication de renégociation TLS RFC 5746) pour un backend SSL donné. Cela ne signifie pas que la client SSL enverra des demandes de renégociation, mais seulement qu’un backend peut renégocier lorsqu’une requête est émise par le serveur. Cette fonctionnalité nécessite que la bibliothèque SSL sous-jacente prenne effectivement en charge la renégociation. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». La renégociation n’est plus possible dans TLS 1.3. Si ni « renegotiate » ni « no-renegotiate » n’est spécifié, le comportement par défaut de la bibliothèque SSL est conservé. Notez qu’OpenSSL active par défaut la renégociation sécurisée, tandis qu’AWS-LC la désactive.

rise <count>

rise <count>

Peut être utilisé dans les contextes suivants : tcp, http, log

Le paramètre « rise » indique qu’un serveur est considéré comme opérationnel après <count> contrôles d’état consécutifs réussis. Cette valeur vaut 2 par défaut si non spécifiée. Voir également les paramètres « check », « inter » et « fall ».

resolve-opts <option>,<option>,… Peut être utilisé dans les contextes suivants : tcp, http, log

Liste séparée par des virgules d’options à appliquer à la résolution DNS liée à ce serveur.

Options disponibles :

  • allow-dup-ip Par défaut, HAProxy empêche la duplication d’adresses IP dans un backend lorsque la résolution DNS est en cours à l’exécution. Toutefois, dans certains cas, il est pertinent qu’un même backend (résolu par le même FQDN) contienne deux serveurs ayant la même adresse IP. Dans ce cas, activez simplement cette option. Il s’agit de l’inverse de prevent-dup-ip.

  • ignore-weight Ignore tout poids défini dans un enregistrement SRV. Cela est utile lorsque vous souhaitez contrôler les poids à l’aide d’une méthode alternative, par exemple en utilisant une vérification d’agent ou via l’API d’exécution.

  • prevent-dup-ip Assure que le comportement par défaut d’HAProxy est appliqué sur un serveur : empêche la réutilisation d’une adresse IP déjà attribuée à un serveur dans le même backend et partageant le même fqdn. Cela constitue l’inverse de allow-dup-ip.

Exemple :

backend b_myapp
  default-server init-addr none resolvers dns
  server s1 myapp.example.com:80 check resolve-opts allow-dup-ip
  server s2 myapp.example.com:81 check resolve-opts allow-dup-ip

Avec l’option allow-dup-ip activée :

  • si le serveur de noms retourne une seule adresse IP, les deux serveurs l’utiliseront
  • Si le serveur de noms retourne 2 adresses IP, chaque serveur choisira une adresse différente

Valeur par défaut : non définie

resolve-prefer <family>

resolve-prefer <family>

Peut être utilisé dans les contextes suivants : tcp, http, log

Lorsque la résolution DNS est activée pour un serveur et que plusieurs adresses IP provenant de familles différentes sont retournées, HAProxy privilégie l’utilisation d’une adresse IP de la famille indiquée dans le paramètre « resolve-prefer ». Voir également le mot-clé global « dns-accept-family » pour imposer une utilisation stricte d’une famille spécifique. Familles disponibles : « ipv4 » et « ipv6 ».

Valeur par défaut : ipv6

Exemple :

server s1 app1.domain.com:80 resolvers mydns resolve-prefer ipv6

resolve-net <network>[,<network[,...]]

resolve-net <network>[,<network[,...]]

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option priorise le choix d’une adresse IP correspondant à un réseau. Cela est utile dans les environnements cloud pour privilégier une adresse locale. Dans certains cas, un service de haute disponibilité cloud peut être annoncé avec plusieurs adresses IP sur différents centres de données. La latence entre les centres de données n’est pas négligeable, aussi cette option permet de privilégier un centre de données local. Si aucune adresse ne correspond au réseau configuré, une autre adresse est sélectionnée.

Exemple :

server s1 app1.domain.com:80 resolvers mydns resolve-net 10.0.0.0/8

resolvers <id>

resolvers <id>

Peut être utilisé dans les contextes suivants : tcp, http, log

Pointe vers une section « resolvers » existante afin de résoudre le nom d’hôte du serveur actuel. Il est généralement recommandé de désactiver la résolution basée sur libc lors de l’utilisation des resolvers, bien que des exceptions existent (voir section 5.3.1 ). Dans tous les cas, il est bon de spécifier explicitement « init-addr » lors de l’utilisation des resolvers afin de ne pas négliger cet élément.

Exemple :

server s1 app1.domain.com:80 init-addr last,none check resolvers mydns

Voir également section 5.3 pour les détails d’implémentation et les pièges à connaître.

send-proxy

send-proxy

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « send-proxy » impose l’utilisation du protocole PROXY sur toute connexion établie vers ce serveur. Le protocole PROXY informe l’autre extrémité des adresses couche 3/4 de la connexion entrante, afin qu’elle puisse connaître l’adresse du client ou l’adresse publique utilisée, quel que soit le protocole de couche supérieure. Pour les connexions acceptées par un écouteur « accept-proxy » ou « accept-netscaler-cip », l’adresse annoncée sera utilisée. Seules les familles d’adresses TCPv4 et TCPv6 sont prises en charge. Les autres familles, telles que les sockets Unix, signaleront une famille INCONNU. Les serveurs utilisant cette option peuvent être entièrement chaînés à une autre instance de HAProxy écoutant avec une configuration « accept-proxy ». Ce paramètre ne doit pas être utilisé si le serveur n’est pas conscient du protocole. Lorsqu’un contrôle d’état est envoyé au serveur, le protocole PROXY est automatiquement utilisé lorsque cette option est activée, sauf si une directive explicite « port » ou « addr » est présente, auquel cas une directive explicite « check-send-proxy » serait également nécessaire pour utiliser le protocole PROXY. Voir également l’option « no-send-proxy » de cette section et les options « accept-proxy » et « accept-netscaler-cip » de la directive « bind ».

send-proxy-v2

send-proxy-v2

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « send-proxy-v2 » impose l’utilisation du protocole PROXY version 2 sur toute connexion établie vers ce serveur. Le protocole PROXY informe l’autre extrémité des adresses couche 3/4 de la connexion entrante, afin qu’elle puisse déterminer l’adresse du client ou l’adresse publique utilisée, quel que soit le protocole de couche supérieure. Il envoie également les informations ALPN si une négociation ALPN a eu lieu. Ce paramètre ne doit pas être utilisé si le serveur n’est pas conscient de cette version du protocole. Voir également l’option « no-send-proxy-v2 » de cette section et l’option « send-proxy » de la directive « bind ».

set-proxy-v2-tlv-fmt(<id>) <fmt>

set-proxy-v2-tlv-fmt(<id>) <fmt>

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « set-proxy-v2-tlv-fmt » est utilisé pour envoyer des TLV arbitraires du protocole PROXY version 2. Pour la plage de type (<id>) du type TLV défini, se référer à la section 2.2.8 de la spécification du protocole PROXY. Toutefois, la valeur peut être choisie librement, à condition de ne pas dépasser la longueur maximale de 65 535 octets. Il peut également être utilisé pour acheminer des TLV en utilisant la commande fetch “fc_pp_tlv” afin de récupérer un TLV reçu depuis le frontal. Il peut être utilisé en tant qu’option serveur ou default-server. Il doit être utilisé en combinaison avec send-proxy-v2 afin que les TLV PPv2 soient effectivement envoyés.

Exemple : server srv1 192.168.1.1:80 send-proxy-v2 set-proxy-v2-tlv-fmt(0x20) %[fc_pp_tlv(0x20)]

Dans ce cas, nous récupérons le TLV de type 0x20 sous forme de chaîne et l’attribuons comme valeur à un nouveau TLV dont le type est également 0x20.

proxy-v2-options <option>[,<option>]*

proxy-v2-options <option>[,<option>]*

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « proxy-v2-options » ajoute des options à envoyer dans le protocole PROXY version 2 lorsque « send-proxy-v2 » est utilisé. Les options disponibles sont :

  • ssl : Voir également « send-proxy-v2-ssl ».
  • cert-cn : Voir également « send-proxy-v2-ssl-cn ».
  • ssl-cipher : Nom de la cipher utilisée.
  • cert-sig : Algorithme de signature du certificat utilisé.
  • cert-key : Algorithme de clé du certificat utilisé.
  • authority : Valeur du nom d’hôte transmise par le client (seul le SNI provenant d’une connexion TLS est pris en charge).
  • crc32c : Somme de contrôle de l’en-tête PROXYv2.
  • unique-id : Envoyer un identifiant unique généré à l’aide du format « unique-id-format » du frontal dans l’en-tête PROXYv2. Cet identifiant unique est principalement destiné à « mode tcp ». Il peut entraîner des résultats inattendus en « mode http », car l’identifiant unique généré est également utilisé pour la première requête HTTP au sein d’une connexion Keep-Alive.

send-proxy-v2-ssl

send-proxy-v2-ssl

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « send-proxy-v2-ssl » impose l’utilisation du protocole PROXY version 2 sur n’importe quelle connexion établie vers ce serveur. Le protocole PROXY informe l’autre extrémité des adresses couche 3/4 de la connexion entrante, afin qu’elle puisse déterminer l’adresse du client ou l’adresse publique utilisée, quel que soit le protocole de couche supérieure. En outre, l’extension d’information SSL du protocole PROXY est ajoutée à l’en-tête du protocole PROXY. Ce paramètre ne doit pas être utilisé si le serveur n’est pas conscient de cette version du protocole. Voir également l’option « no-send-proxy-v2-ssl » de cette section et l’option « send-proxy-v2 » de la commande « bind ».

send-proxy-v2-ssl-cn

send-proxy-v2-ssl-cn

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « send-proxy-v2-ssl » impose l’utilisation du protocole PROXY version 2 sur n’importe quelle connexion établie vers ce serveur. Le protocole PROXY informe l’autre extrémité des adresses couche 3/4 de la connexion entrante, afin qu’elle puisse déterminer l’adresse du client ou l’adresse publique utilisée, quel que soit le protocole de couche supérieure. En outre, l’extension d’information SSL du protocole PROXY, ainsi que le nom commun issu de l’objet du certificat client (le cas échéant), sont ajoutés à l’en-tête du protocole PROXY. Ce paramètre ne doit pas être utilisé si le serveur n’est pas conscient de cette version du protocole. Voir également l’option « no-send-proxy-v2-ssl-cn » de cette section et l’option « send-proxy-v2 » de la mot-clé « bind ».

shard <shard>

shard <shard>

Peut être utilisé dans les contextes suivants : pairs

Ce paramètre n’est utilisé que dans le contexte de la synchronisation des tables de persistance avec le protocole de pairs. Le paramètre « shard » identifie les pairs qui recevront toutes les mises à jour de la table de persistance pour les clés dont le hachage de distribution correspond à cette valeur de « shard ». Les valeurs acceptées vont de 0 à la valeur du paramètre « shards » spécifiée dans la section « peers ». La valeur 0 est la valeur par défaut, ce qui signifie que le pair recevra toutes les mises à jour des clés. Les valeurs supérieures à « shards » seront ignorées. C’est également le cas pour toute valeur fournie au pair local.

Exemple :

peers mypeers shards 3 peer A 127.0.0.1:40001 # local peer without shard value (0 internally) peer B 127.0.0.1:40002 shard 1 peer C 127.0.0.1:40003 shard 2 peer D 127.0.0.1:40004 shard 3

sigalgs <sigalgs>

sigalgs <sigalgs>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré. Il définit la chaîne décrivant la liste des algorithmes de signature négociés pendant l’échange TLSv1.2 et TLSv1.3. Le format de la chaîne est défini dans « man 3 SSL_CTX_set1_sigalgs » des pages de documentation OpenSSL. Il est déconseillé d’utiliser ce paramètre sauf si une compatibilité avec un middlebox est requise.

slowstart <start_time_in_ms>

slowstart <start_time_in_ms>

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « slowstart » d’un serveur accepte une valeur en millisecondes indiquant après combien de temps un serveur revenu en service fonctionnera à pleine vitesse. Comme pour tout autre paramètre basé sur le temps, il peut être spécifié dans n’importe quelle autre unité explicite parmi { us, ms, s, m, h, d }. La vitesse augmente linéairement de 0 à 100 % durant cette période. Cette limitation s’applique à deux paramètres :

  • maxconn : le nombre de connexions acceptées par le serveur passera de 1 à 100 % de la limite dynamique habituelle définie par (minconn, maxconn, fullconn).

  • weight : lorsque le backend utilise un algorithme de pondération dynamique, le poids augmente linéairement de 1 à 100 %. Dans ce cas, le poids est mis à jour à chaque vérification de santé. Il est donc important que le paramètre « inter » soit inférieur au paramètre « slowstart », afin de maximiser le nombre d’étapes.

Le ralentissement initial n’est jamais appliqué au démarrage d’HAProxy, faute de quoi il pourrait perturber les serveurs en cours d’exécution. Il n’est appliqué qu’aux serveurs qui ont été précédemment identifiés comme défaillants.

sni <expression>

sni <expression>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Le paramètre « sni » évalue l’expression d’extraction d’échantillon, la convertit en chaîne de caractères et utilise le résultat comme nom d’hôte envoyé dans l’extension TLS SNI au serveur. Un cas d’utilisation typique consiste à transmettre le SNI reçu du client dans un scénario TCP/SSL en pont, en utilisant l’extraction d’échantillon “ssl_fc_sni” pour l’expression. CETTE UTILISATION NE DOIT PAS ÊTRE EMPLOYÉE POUR HTTPS, où req.hdr(host) doit être utilisé à la place, car le SNI dans HTTPS doit toujours correspondre au champ Host et les clients sont autorisés à utiliser des noms d’hôte différents sur la même connexion. Si « verify required » est défini (ce qui est le paramètre recommandé), le nom résultant sera également comparé aux noms du certificat serveur. Voir la directive « verify » pour plus de détails. Si vous souhaitez définir un SNI pour les contrôles d’état, consultez la directive « check-sni » pour plus de détails.

Par défaut, le SNI est affecté au nom de la connexion pour « http-reuse », sauf substitution par le mot-clé serveur « pool-conn-name ».

sni-auto

sni-auto

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Le paramètre « sni-auto » active la sélection automatique du SNI, si aucune valeur n’a déjà été définie. Il définit l’expression « sni » sur « req.hdr(host),field(1,:)’, ce qui signifie qu’un SNI sera présenté avec le nom d’hôte de la requête envoyée au serveur, en supprimant le numéro de port. Il est activé par défaut, mais ce paramètre peut être utilisé comme paramètre « server » pour réinitialiser toute configuration « no-sni-auto » héritée de la directive « default-server » en tant que valeur par défaut. Il peut également être utilisé comme paramètre « default-server » pour réinitialiser toute configuration précédente « default-server » « no-sni-auto ».

Pour les connexions HTTPS, le SNI sélectionné est déterminé par la valeur de l’en-tête hôte de la requête, le cas échéant. Sinon, il reste non défini. Pour les autres protocoles, cette option est ignorée.

Si la sélection automatique du SNI est utilisée, la valeur est affectée au nom de la connexion pour « http-reuse », sauf substitution par le mot-clé serveur « pool-conn-name ».

Voir l’option « check-sni-auto » pour activer la sélection automatique du SNI pour les contrôles d’état SSL.

source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]

source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
source <addr>[:<pl>[-<ph>]] [interface <name>] ...

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Le paramètre « source » définit l’adresse source utilisée lors de la connexion au serveur. Il suit les mêmes paramètres et principes que le mot-clé « source » du backend, à ceci près qu’il ne s’applique qu’au serveur qui le référence. Veuillez consulter le mot-clé « source » pour plus de détails.

En outre, l’instruction « source » sur une ligne de serveur permet de spécifier une plage de ports sources en indiquant les bornes inférieure et supérieure, séparées par un trait d’union (’-’). Certains systèmes d’exploitation peuvent exiger une adresse IP valide lorsqu’une plage de ports sources est spécifiée. Il est autorisé d’utiliser la même IP/plage pour plusieurs serveurs. Cette pratique permet de contourner la limite de 64 000 connexions simultanées au total. La limite s’élèvera alors à 64 000 connexions par serveur.

Depuis Linux 4.2/libc 2.23, IP_BIND_ADDRESS_NO_PORT est défini pour les connexions spécifiant l’adresse source sans port(s).

ssl

ssl

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option active le chiffrement SSL sur les connexions sortantes vers le serveur. Il est essentiel de vérifier les certificats serveur en utilisant « verify » lors de la connexion SSL aux serveurs, faute de quoi la communication est vulnérable aux attaques de type « homme au milieu » simples, rendant le SSL inutile. Lorsque cette option est utilisée, les contrôles d’état sont automatiquement envoyés en SSL, sauf si une directive « port » ou « addr » indique que le contrôle doit être envoyé à une autre localisation. Consultez « no-ssl » pour désactiver l’option « ssl » et « check-ssl » pour forcer les contrôles d’état en SSL.

ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de <version> ou d’une version inférieure lorsque le protocole SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-min-ver ».

ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option impose l’utilisation de <version> ou d’une version supérieure lorsque le protocole SSL est utilisé pour communiquer avec le serveur. Cette option est également disponible dans l’instruction globale « ssl-default-server-options ». Voir également « ssl-max-ver ».

ssl-reuse

ssl-reuse

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée comme paramètre « server » pour réinitialiser tout paramètre « no-ssl-reuse » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée comme paramètre « default-server » pour réinitialiser tout paramètre précédent « default-server » « no-ssl-reuse ».

stick

stick

Peut être utilisé dans les contextes suivants : tcp, http

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « non-stick » hérité de la directive « default-server » en tant que valeur par défaut. Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « non-stick » précédent défini sur « default-server ».

strict-maxconn

strict-maxconn

Peut être utilisé dans les contextes suivants : tcp, http

La directive maxconn aux serveurs est un peu trompeuse : elle configure en réalité le nombre maximal de requêtes envoyées à un serveur, mais, avec des connexions inactives, le nombre total de connexions vers le serveur peut être supérieur. Si une limite stricte du nombre de connexions vers un serveur est requise, la directive strict-maxconn peut être utilisée. Dans ce cas, nous n’établirons jamais plus de connexions vers un serveur qu’indiqué par maxconn, et nous tenterons de réutiliser ou de fermer des connexions si nécessaire. Veuillez noter toutefois qu’il peut en résulter des requêtes échouées si nous ne parvenons pas à établir une nouvelle connexion et qu’aucune connexion inactive n’est disponible. Cela peut survenir lorsque des connexions « privées » sont établies, c’est-à-dire des connexions liées uniquement à une session, car l’authentification a eu lieu.

socks4 <addr>:<port>

socks4 <addr>:<port>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option active un tunnel SOCKS4 côté amont pour les connexions sortantes vers le serveur. L’utilisation de cette option ne force pas par défaut le contrôle d’état à passer par SOCKS4. Vous devrez utiliser le mot-clé « check-via-socks4 » pour l’activer.

tcp-md5sig <password>

tcp-md5sig <password>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Active la signature TCP MD5 (Protection des sessions BGP via l’option de signature TCP MD5) pour toutes les connexions sortantes vers ce serveur. Cette option n’est disponible que sous Linux. Lorsqu’elle est activée, la chaîne <password> est utilisée pour signer chaque segment TCP à l’aide d’un hachage de 16 octets MD5. Cela protège la connexion TCP contre les attaques par falsification. Le cas d’utilisation principal de cette option est de permettre à BGP de se protéger contre l’introduction de segments TCP falsifiés dans le flux de connexion. Elle peut toutefois être utile pour toute connexion TCP très longue.

tcp-ut <delay>

tcp-ut <delay>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Définit le délai d’expiration utilisateur TCP pour toutes les connexions sortantes vers ce serveur. Cette option est disponible sur Linux depuis la version 2.6.37. Elle permet à HAProxy de configurer un délai d’expiration pour les sockets contenant des données n’ayant pas reçu d’accusé de réception après le délai configuré. Cela est particulièrement utile pour les connexions longues en cours d’utilisation, comme les terminaux distants ou les pools de connexions vers une base de données, où les délais d’expiration du client et du serveur doivent rester élevés afin de permettre de longues périodes d’inactivité, mais où il est important de détecter qu’un serveur est devenu inaccessible afin de libérer toutes les ressources associées à sa connexion (et à la session du client). Un cas d’utilisation typique consiste également à forcer la fermeture des connexions vers un serveur défaillant lorsque les contrôles d’état sont trop lents ou lors d’un rechargement doux, puisque les contrôles d’état sont alors désactivés. L’argument est un délai exprimé en millisecondes par défaut. Cette option ne s’applique qu’aux connexions TCP régulières et est ignorée pour les autres protocoles.

tfo

tfo

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option permet d’utiliser l’ouverture rapide TCP lors de la connexion aux serveurs, sur les systèmes qui la prennent en charge (actuellement uniquement le noyau Linux >= 4.11). Consultez l’option bind « tfo » pour plus d’informations sur l’ouverture rapide TCP. Veuillez noter qu’en utilisant tfo, vous devez également utiliser les mots-clés « conn-failure », « empty-response » et « response-timeout » dans « retry-on », sinon HAProxy ne pourra pas réessayer la connexion en cas d’échec. Voir également « no-tfo ».

track [<backend>/]<server>

track [<backend>/]<server>

Peut être utilisé dans les contextes suivants : tcp, http, log

Cette option permet de définir l’état actuel d’un serveur en suivant celui d’un autre. Il est possible de suivre un serveur qui suit à son tour un autre serveur, à condition qu’à la fin de la chaîne, un serveur ait les contrôles d’état activés. Si <backend> est omis, celui actuel est utilisé. Si disable-on-404 est utilisé, il doit être activé sur les deux proxies.

Exemple :

backend A
server a1 1.1.1.1:80 track B/b1
server a2 1.1.1.2:80 track B/b1

backend B
server b1 2.2.2.2:80 check

tls-tickets

tls-tickets

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Cette option peut être utilisée en tant que paramètre « server » pour réinitialiser tout paramètre « no-tls-tickets » hérité de la directive « default-server » en tant que valeur par défaut. Le mécanisme des tickets TLS n’est utilisé qu’avec TLS 1.2. La confidentialité progressive est compromise avec les tickets TLS, sauf si les clés de tickets sont régulièrement renouvelées (par rechargement ou en utilisant « tls-ticket-keys »). Elle peut également être utilisée en tant que paramètre « default-server » pour réinitialiser tout paramètre « no-tls-tickets » précédent défini sur « default-server ».

verify [none|required]

verify [none|required]

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support OpenSSL a été intégré. Si sa valeur est définie sur « none », la vérification du certificat du serveur est désactivée. Dans les autres cas, le certificat fourni par le serveur est vérifié à l’aide des autorités de certification (CA) provenant du fichier « ca-file » et des listes de révocation de certificats (CRL) optionnelles provenant du fichier « crl-file », après avoir vérifié que les noms présents dans les attributs subject et subjectAlternateNames du certificat correspondent soit au nom passé via la directive « sni », soit, si ce nom n’est pas fourni, au nom d’hôte statique passé via la directive « verifyhost ». Si aucun nom n’est trouvé, les noms du certificat sont ignorés. Pour cette raison, l’utilisation de « verifyhost » est essentielle en l’absence de SNI. En cas d’échec de la vérification, la négociation est interrompue. Il est essentiel de vérifier les certificats serveur lors de la connexion SSL aux serveurs, sinon la communication est vulnérable aux attaques de type « homme du milieu » simples, rendant le SSL totalement inutile. À moins que “ssl_server_verify” n’apparaisse dans la section globale, « verify » est défini par défaut sur « required ».

verifyhost <hostname>

verifyhost <hostname>

Peut être utilisé dans les contextes suivants : tcp, http, log, peers, ring

Ce paramètre n’est disponible que si le support d’OpenSSL a été intégré, et n’a d’effet que si « verify required » est également spécifié. Cette directive définit un nom d’hôte statique par défaut utilisé pour vérifier le certificat du serveur lorsque le SNI n’a pas été utilisé pour établir la connexion. Si le SNI n’est pas utilisé, c’est la seule méthode permettant d’activer la vérification du nom d’hôte. Ce nom d’hôte statique, lorsqu’il est défini, est également utilisé pour les contrôles d’état (qui ne peuvent pas fournir de valeur SNI). Si aucun des noms d’hôte présents dans le certificat ne correspond au nom d’hôte spécifié, la négociation est interrompue. Les noms d’hôte présents dans le certificat fourni par le serveur peuvent inclure des caractères génériques. Voir également les options « verify », « sni » et « no-verifyhost ».

weight <weight>

weight <weight>

Peut être utilisé dans les contextes suivants : tcp, http

Le paramètre « weight » permet d’ajuster le poids d’un serveur par rapport aux autres serveurs. Tous les serveurs reçoivent une charge proportionnelle à leur poids par rapport à la somme de tous les poids, de sorte que plus le poids est élevé, plus la charge est importante. La valeur par défaut est 1, et la valeur maximale est 256. Une valeur de 0 signifie que le serveur ne participe pas à la répartition de charge, mais continue tout de même à accepter les connexions persistantes. Si ce paramètre est utilisé pour répartir la charge en fonction de la capacité du serveur, il est recommandé de choisir des valeurs pouvant à la fois augmenter et diminuer, par exemple entre 10 et 100, afin de laisser suffisamment de marge au-dessus et en dessous pour des ajustements ultérieurs.

ws { auto | h1 | h2 }

ws { auto | h1 | h2 }

Peut être utilisé dans les contextes suivants : http

Cette option permet de configurer le protocole utilisé lors du relais des flux WebSocket. Elle est particulièrement utile lors de l’utilisation d’un backend HTTP/2 ne prenant pas en charge les WebSocket via H2 grâce à RFC8441.

Le mode par défaut est « auto ». Il réutilise le même protocole que celui principal. La seule différence intervient lors de l’utilisation d’ALPN : dans ce cas, il peut tenter de rétrograder l’ALPN à « http/1.1 » uniquement pour les flux WebSocket si l’ALPN serveur configuré le contient.

La valeur « h1 » est utilisée pour forcer HTTP/1.1 sur les flux websockets, via ALPN si ALPN SSL est activé pour le serveur. De même, « h2 » peut être utilisée pour forcer les websockets HTTP/2.0. Utilisez cette valeur avec précaution : le serveur doit prendre en charge RFC8441, faute de quoi HAProxy signalera une erreur lors du relais des websockets.

Notez que NPN n’est pas pris en compte, car son utilisation a été dépréciée en faveur de l’extension ALPN.

Voir également « alpn » et « proto ».

5.3. Résolution d’adresse IP du serveur par DNS

HAProxy permet d’utiliser un nom d’hôte dans la ligne de serveur pour récupérer son adresse IP à l’aide de serveurs de noms. Par défaut, HAProxy résout le nom lors de l’analyse du fichier de configuration, au démarrage, et met en cache le résultat pour la durée de vie du processus. Cette approche est insuffisante dans certains cas, par exemple sur Amazon, où l’adresse IP d’un serveur peut changer après un redémarrage, ou où une IP virtuelle ELB peut varier en fonction de la charge actuelle.

Ce chapitre décrit comment HAProxy peut être configuré pour effectuer la résolution du nom des serveurs en temps réel.

Quel que soit l’état de la résolution dynamique des noms de serveur au moment de l’exécution, HAProxy effectue par défaut la première résolution au démarrage, pendant l’analyse de la configuration, via libc, sauf si cette fonction est désactivée par le paramètre « init-addr ».

5.3.1. Vue d’ensemble

Comme nous l’avons vu dans l’introduction, la résolution de nom dans HAProxy s’effectue à deux étapes différentes du cycle de vie du processus :

1. when starting up, HAProxy parses the server line definition and matches a
   host name. It uses libc functions to get the host name resolved. This
   resolution relies on /etc/resolv.conf file.

2. at run time, HAProxy performs periodically name resolutions for servers
   requiring DNS resolutions.

Quelques autres événements peuvent déclencher une résolution de nom en temps d’exécution :

  • quand un contrôle d’état d’un serveur aboutit à un délai d’expiration de connexion : cela peut être dû au fait que le serveur dispose d’une nouvelle adresse IP. Il est donc nécessaire de déclencher une résolution de nom afin de connaître cette nouvelle adresse.

Lors de l’utilisation de résolveurs, le nom de serveur peut être un nom d’hôte ou une étiquette SRV. HAProxy considère comme une étiquette SRV tout ce qui commence par un trait de soulignement. Si une étiquette SRV est spécifiée, les enregistrements SRV correspondants seront récupérés auprès du serveur DNS, et les noms d’hôte fournis seront utilisés. L’étiquette SRV sera vérifiée périodiquement, et si des serveurs sont ajoutés ou supprimés, HAProxy les mettra automatiquement à jour.

Quelques points importants à noter :

  • tous les serveurs de noms sont interrogés en même temps. HAProxy traitera la première réponse valide.

  • Une résolution est considérée comme invalide (NX, délai d’expiration, refusée), lorsque tous les serveurs renvoient une erreur.

  • Le client DNS implémenté dans HAProxy est très basique et ne comprendra pas le grand nombre d’options ni les configurations avancées que le résolveur d’un système d’exploitation est capable de gérer. En conséquence, sauf dans des configurations très simples où un serveur connu par son nom complet (FQDN) ne possède qu’une seule adresse IP à la fois et peut éventuellement la renouveler (par exemple, après un redémarrage), il est fortement recommandé d’éviter de mélanger la résolution au moment de l’initialisation basée sur libc avec la résolution au runtime basée sur DNS, car de telles configurations sont connues pour entraîner des échecs lors du renouvellement d’adresse. En conclusion, sauf si vous savez exactement ce que vous faites, vous devez toujours exclure « libc » de « init-addr » lorsque vous utilisez « resolvers » dans une ligne de serveur.

5.3.2. La section resolvers

Cette section est dédiée à l’information d’hôte relative à la résolution de noms dans HAProxy. Autant de sections resolvers que nécessaire peuvent être définies. Chaque section peut contenir plusieurs serveurs de noms.

Au démarrage, HAProxy tente de générer une section resolvers nommée « default », si aucune section n’a été nommée ainsi dans la configuration. Cette section est utilisée par défaut par httpclient et utilise le mot-clé parse-resolv-conf. Si HAProxy échoue à générer automatiquement cette section, aucune erreur ni avertissement n’est émis.

Lorsque plusieurs serveurs de noms sont configurés dans une section resolvers, HAProxy utilise la première réponse valide. En cas de réponses non valides, seule la dernière est prise en compte. L’objectif est de permettre à un serveur lent de fournir une réponse valide après un serveur rapide mais erroné ou périmé.

Lorsque chaque serveur retourne un type d’erreur différent, seul le dernier erreur est utilisé par HAProxy. Le traitement suivant est appliqué à cette erreur :

1. HAProxy retries the same DNS query with a new query type. The A queries are
   switch to AAAA or the opposite. SRV queries are not concerned here. Timeout
   errors are also excluded.

2. When the fallback on the query type was done (or not applicable), HAProxy
   retries the original DNS query, with the preferred query type.

3. HAProxy retries previous steps <resolve_retries> times. If no valid
   response is received after that, it stops the DNS resolution and reports
   the error.

Par exemple, avec 2 serveurs de noms configurés dans une section resolvers, les scénarios suivants sont possibles :

  • La première réponse est valide et est appliquée directement, la deuxième réponse est ignorée

  • La première réponse est invalide et la deuxième est valide, la deuxième réponse est donc appliquée

  • La première réponse est un domaine NX et la deuxième une réponse tronquée, HAProxy réessaie alors la requête avec un nouveau type

  • La première réponse est un domaine NX et la deuxième est un délai d’expiration, HAProxy réessaie alors la requête avec un nouveau type

  • La requête a expiré pour les deux serveurs de noms, puis HAProxy la réessaie avec le même type de requête

Comme un serveur DNS ne peut pas répondre à toutes les adresses IP dans une seule requête, HAProxy conserve un cache des réponses précédentes ; une réponse est considérée comme obsolète après <hold obsolete> secondes sans retour d’adresse IP.

resolvers <resolvers id>

resolvers <resolvers id>

Crée une nouvelle liste de serveurs nommés étiquetée <resolvers id>. Comme indiqué ci-dessus, le nom spécial « default » existe toujours et est automatiquement créé s’il n’est pas déclaré explicitement ; il s’agit du serveur utilisé par les services internes tels que httpclient. La déclaration d’une entrée « default » affecte la manière dont ces services effectuent la résolution de noms.

Une section resolvers accepte les paramètres suivants :

accepted_payload_size <nb>

accepted_payload_size <nb>

Définit la taille maximale du payload acceptée par HAProxy et annoncée à tous les serveurs de noms configurés dans cette section resolvers. <nb> est exprimée en octets. Si non définie, HAProxy annonce 512. (valeur minimale définie par le RFC 6891)

Note : la valeur maximale autorisée est 65535. La valeur recommandée pour UDP est 4096, et il n’est pas conseillé de dépasser 8192, sauf si vous êtes certain que votre système et votre réseau peuvent gérer cette charge (dépasser 65507 n’a pas de sens, étant donné que c’est la taille maximale du payload UDP). Si vous utilisez uniquement des serveurs DNS TCP pour gérer de grandes réponses DNS, vous devriez définir cette valeur à son maximum : 65535.

nameserver <name> <address>[:port] [param*]

nameserver <name> <address>[:port] [param*]

Utilisé pour configurer un serveur de noms. <name> du serveur de noms doit être unique. Par défaut, le <address> est considéré comme étant de type datagramme. Cela signifie qu’en l’absence de préfixe d’adresse spécifique (paragraphe 11.), si une adresse IPv4 ou IPv6 est configurée, le protocole UDP sera utilisé. Si un préfixe d’adresse de protocole de flux est utilisé, le serveur de noms sera considéré comme un serveur de flux (TCP par exemple), et les paramètres « server » mentionnés au paragraphe 5.2, qui sont pertinents pour la résolution DNS, seront pris en compte. Note : actuellement, en mode TCP, 4 requêtes sont enfilées sur la même connexion. Un lot de connexions inactives est supprimé toutes les 5 secondes. La valeur « maxconn » peut être configurée pour limiter le nombre de connexions concurrentes, et TLS peut également être utilisé si le serveur le prend en charge.

parse-resolv-conf

parse-resolv-conf

Ajoute tous les serveurs DNS trouvés dans /etc/resolv.conf à la liste des serveurs DNS de ce résolveur. L’ordre est équivalent à celui obtenu en plaçant individuellement chaque serveur DNS de /etc/resolv.conf dans la section resolvers à la place de cette directive.

hold <status> <period>

hold <status> <period>

Lors de la réception de la réponse DNS <status>, détermine si l’état d’un serveur doit passer de UP à DOWN. Pour prendre cette décision, il vérifie si une réponse d’état valide a été reçue au cours des <period> précédents afin de contrer l’état invalide récemment reçu.

`<status>` : statut de résolution du nom de dernière instance.
       nx        Après avoir reçu un statut NXDOMAIN, vérifier s'il existe un statut valide pendant la période de conclusion.

       refused   Après avoir reçu un statut REFUSED, vérifiez la présence d'un statut valide pendant la période de clôture.

       timeout   Une fois que le « délai d'expiration de la tentative » a été atteint, vérifiez s'il existe un statut valide pendant la période de clôture.

       autre     Après avoir reçu un autre statut non valide, vérifiez s'il existe un statut valide pendant la période de conclusion.

       valid     S'applique uniquement aux actions "http-request do-resolve" et
                 "tcp-request content do-resolve". Il définit la période pendant
                 laquelle le serveur maintiendra une réponse valide avant de déclencher
                 une nouvelle résolution. Il n'affecte pas la résolution dynamique des serveurs.

       obsolète  Définit la durée d'attente avant la suppression des enregistrements DNS obsolètes après la réception d'un enregistrement de réponse mis à jour. S'applique aux enregistrements SRV.

`<period>` : Durée dans le passé pendant laquelle une réponse valide doit avoir été reçue. Le format suit celui de HAProxy et est exprimé en millisecondes par défaut.

Pour un serveur qui repose sur une résolution DNS dynamique pour déterminer son adresse IP, la réception d’une réponse DNS non valide, telle que NXDOMAIN, entraîne un changement d’état du serveur de UP à DOWN. Les directives hold définissent jusqu’où remonter dans le passé pour rechercher une réponse valide. Si une réponse valide a été reçue dans les <period>, l’état invalide récemment reçu sera ignoré.

À moins qu’une réponse valide n’ait été reçue pendant la période de clôture, le serveur sera marqué comme DOWN. Par exemple, si « hold nx 30s » est configuré et que la dernière réponse DNS reçue était NXDOMAIN, le serveur sera marqué comme DOWN à moins qu’une réponse valide n’ait été reçue au cours des 30 s précédentes.

Un serveur en état DOWN sera marqué comme UP dès la réception d’un statut valide provenant du serveur DNS.

Un comportement distinct existe pour « hold valid » et « hold obsolete ».

Valeur par défaut : 10 s pour « valid », 0 s pour « obsolete » et 30 s pour les autres.

resolve_retries <nb>

resolve_retries <nb>

Définit le nombre <nb> de requêtes à envoyer pour résoudre un nom de serveur avant d’abandonner. Valeur par défaut : 3

Une nouvelle tentative est effectuée en cas de délai d’expiration du serveur de noms ou lorsque la séquence complète de basculement des types de requête DNS est terminée et que nous devons recommencer à partir de la requête ANY par défaut.

timeout <event> <time>

timeout <event> <time>

Définit les délais d’expiration liés à la résolution de noms <event> : l’événement auquel s’applique la période de délai d’expiration <time>. Les événements disponibles sont : - resolve : délai par défaut pour déclencher la résolution de noms lorsque aucun autre délai n’est appliqué. Valeur par défaut : 1s - retry : délai entre deux requêtes DNS, lorsque aucune réponse valide n’a été reçue. Valeur par défaut : 1s <time> : délai lié à l’événement. Il suit le format de temps HAProxy. <time> est exprimé en millisecondes.

Exemple :

resolvers mydns
  nameserver dns1 10.0.0.1:53
  nameserver dns2 10.0.0.2:53
  nameserver dns3 tcp@10.0.0.3:53
  parse-resolv-conf
  resolve_retries       3
  timeout resolve       1s
  timeout retry         1s
  hold other           30s
  hold refused         30s
  hold nx              30s
  hold timeout         30s
  hold valid           10s
  hold obsolete        30s

15 - 6. Mise en cache

Limites et configuration du cache dans les sections cache et proxy

HAProxy fournit un cache, conçu pour effectuer le mise en mémoire tampon de petits objets (favicon, fichiers CSS…). Il s’agit d’un cache minimaliste, à faible maintenance, qui s’exécute en mémoire RAM.

Le cache repose sur une zone mémoire partagée entre tous les threads, divisée en blocs de 1 ko.

Si un objet n’est plus utilisé, il peut être supprimé afin de stocker un nouvel objet indépendamment de sa date d’expiration. Les objets les plus anciens sont supprimés en premier lorsque l’on tente d’allouer un nouvel objet.

Le cache utilise un hachage de l’en-tête host et de l’URI comme clé.

Il est possible de consulter l’état d’un cache à l’aide de la commande socket Unix « show cache » consultez la section 9.3 « Commandes socket Unix » du Guide d’administration pour plus de détails.

Lorsqu’un objet est livré depuis le cache, le nom du serveur dans le journal est remplacé par “<CACHE>”.

6.1. Limitation

Le cache ne stockera ni ne livrera d’objets dans ces cas :

  • Si la réponse n’est pas un 200

  • Si la réponse contient un en-tête Vary et que l’option process-vary est désactivée, ou qu’un en-tête actuellement non géré est spécifié dans la valeur de Vary (seuls accept-encoding, referer et origin sont gérés pour l’instant)

  • Si la taille du Content-Length + celle des en-têtes est supérieure à “max-object-size”

  • Si la réponse n’est pas mise en cache

  • Si la réponse ne dispose pas de temps d’expiration explicite (directives Cache-Control s-maxage ou max-age) ou d’en-tête Expires, ni de validateur (en-têtes ETag ou Last-Modified)

  • Si l’option process-vary est activée et qu’il existe déjà max-secondary-entries entrées avec la même clé primaire que la réponse actuelle

  • Si l’option process-vary est activée et que la réponse possède une encodage inconnu (non mentionné dans https://www.iana.org/assignments/http-parameters/http-parameters.xhtml ) tout en variant sur l’en-tête client accept-encoding

  • Si la requête n’est pas un GET

  • Si la version HTTP de la requête est inférieure à 1.1

  • Si la requête contient un en-tête Authorization

6.2. Configuration

Pour configurer un cache, vous devez définir une section de cache et l’utiliser dans un proxy à l’aide des actions http-request et http-response correspondantes.

6.2.1. Section cache

cache <name>

cache <name>

Déclare une section de cache, alloue une mémoire partagée nommée <name>, la taille du cache est obligatoire (voir le mot-clé “total-max-size” ci-dessous).

max-age <seconds>

max-age <seconds>

Définir la durée maximale d’expiration. L’expiration est fixée à la valeur la plus faible entre les directives s-maxage ou max-age (dans cet ordre) présentes dans l’en-tête de réponse Cache-Control et cette valeur. La valeur par défaut est de 60 secondes, ce qui signifie que vous ne pouvez pas mettre en cache un objet plus de 60 secondes par défaut.

max-object-size <bytes>

max-object-size <bytes>

Définir la taille maximale des objets à mettre en cache. Ne doit pas dépasser la moitié de « total-max-size ». Si non définie, elle est égale à 1/256 de la taille du cache. Tous les objets dont la taille dépasse « max-object-size » ne seront pas mis en cache.

max-secondary-entries <number>

max-secondary-entries <number>

Définir le nombre maximal d’entrées secondaires simultanées ayant la même clé primaire dans le cache. Cela nécessite que le support de vary soit activé. Sa valeur par défaut est 10 et doit être un entier strictement positif.

process-vary <on/off>

process-vary <on/off>

Active ou désactive le traitement de l’en-tête Vary. Lorsqu’il est désactivé, une réponse contenant cet en-tête n’est jamais mise en cache. Lorsqu’il est activé, il faut calculer un hachage préliminaire pour un sous-ensemble des en-têtes de requête sur toutes les requêtes entrantes (ce qui peut entraîner une charge CPU) afin de construire une clé secondaire pour une requête donnée (voir RFC 7234#4.1). La clé secondaire est actuellement construite à partir du contenu des en-têtes « accept-encoding », « referer » et « origin ». Notez que les en-têtes « origin » et « referer » sont univalués selon la RFC, donc une requête comportant plusieurs occurrences de l’un ou l’autre doit être considérée comme malformée. Pour de telles requêtes, aucune clé secondaire n’est construite, et la réponse n’est jamais servie depuis le cache, afin de laisser le serveur décider de la manière de traiter la situation. La valeur par défaut est off (désactivé).

total-max-size <megabytes>

total-max-size <megabytes>

Définir la taille en mémoire RAM du cache en mégaoctets. Cette taille est divisée en blocs de 1 ko, utilisés par les entrées du cache. Sa valeur maximale est 4095.

6.2.2. Section proxy

La section proxy utilisant le cache devra inclure l’action « cache-use » dans le jeu de règles « http-request » afin de rechercher l’objet demandé dans le cache, et l’action « cache-store » dans le jeu de règles « http-response » afin de stocker ou mettre à jour l’objet récupéré dans le cache. Chacune de ces actions peut éventuellement être soumise à des conditions. Par exemple, on peut décider de passer outre l’action « cache-use » pour un sous-répertoire donné connu pour ne pas être mis en cache, ou de passer outre l’action « cache-store » pour certains types de contenu connus pour être sans intérêt. Veuillez noter que la clé d’indexation du cache est calculée lors de l’action « cache-use », donc si cette action est omise, aucune tentative de mise à jour du cache ne sera effectuée sur le chemin de la réponse.

Exemple :

backend bck1
  mode http

  http-request cache-use foobar
  http-response cache-store foobar
  server srv1 127.0.0.1:80

cache foobar
  total-max-size 4
  max-age 240

16 - 7. Listes de contrôle d'accès et extraction d'échantillon

Correspondance ACL, conditions, convertisseurs, extractions d’échantillon et ACL prédéfinies

HAProxy est capable d’extraire des données des flux de requêtes ou de réponses, des informations client ou serveur, des tables, des informations environnementales, etc. L’opération d’extraction de ces données est appelée « récupération d’un échantillon ». Une fois récupérés, ces échantillons peuvent être utilisés à diverses fins, par exemple comme clé dans une table de persistance, mais les usages les plus courants consistent à les comparer à des données constantes prédéfinies appelées modèles.

7.1. Notions de base sur les ACL

Listes de contrôle d’accès (ACL) consistent à déclarer une méthode nommée permettant de comparer une information quelconque à une liste de modèles prédéfinis. Elles doivent être considérées comme pratiquement équivalentes aux fonctions dans la plupart des langages de programmation, dans la mesure où leur déclaration les rend disponibles pour être appelées ultérieurement lorsqu’elles sont nécessaires. Leur évaluation ne retourne qu’une correspondance ou un manque de correspondance, ce qui est comparable aux valeurs booléennes dans de nombreux langages de programmation. Contrairement aux fonctions dans les langages de programmation, les ACL peuvent être surchargées autant de fois que nécessaire afin de définir des méthodes de correspondance supplémentaires pour le même nom. Dans ce cas, toutes seront évaluées dans l’ordre de leur déclaration jusqu’à ce qu’une correspondance soit trouvée.

L’utilisation des listes de contrôle d’accès (ACL) offre une solution souple pour effectuer un commutage de contenu et, plus généralement, prendre des décisions fondées sur le contenu extrait de la requête, de la réponse ou d’un état environnemental. Le principe est simple :

  • extraire un échantillon de données à partir d’un flux, d’une table ou de l’environnement
  • appliquer éventuellement une conversion de format à l’échantillon extrait
  • appliquer une ou plusieurs méthodes de correspondance de motifs à cet échantillon
  • effectuer des actions uniquement lorsque un motif correspond à l’échantillon

Les actions consistent généralement à bloquer une requête, sélectionner un backend ou ajouter un en-tête.

Pour définir un test, le mot-clé « acl » est utilisé. La syntaxe est :

acl <aclname> <criterion> [flags] [operator] [<value>] ...

Cela crée une nouvelle ACL <aclname> ou complète une existante avec de nouveaux tests. Ces tests s’appliquent à la portion de request/response spécifiée dans <criterion> et peuvent être ajustés à l’aide d’indicateurs facultatifs [flags]. Certains critères prennent également en charge un opérateur, qui peut être précisé avant l’ensemble des valeurs. Facultativement, certains opérateurs de conversion peuvent être appliqués à l’échantillon, et ils seront indiqués sous forme de liste séparée par des virgules de mots-clés, juste après le premier mot-clé. Les valeurs sont du type pris en charge par le critère et sont séparées par des espaces.

Les noms d’ACL doivent être composés de lettres majuscules et minuscules, de chiffres, de ‘-’ (tiret), de ‘_’ (souligné), de ‘.’ (point) et de ‘:’ (deux-points). Les noms d’ACL sont sensibles à la casse, ce qui signifie que “my_acl” et “My_Acl” représentent deux ACL différentes.

Il n’y a aucune limite imposée au nombre d’ACL. Les ACL non utilisées n’affectent pas les performances, elles ne consomment qu’une petite quantité de mémoire.

Le critère est généralement le nom d’une méthode d’extraction d’échantillon, ou l’une de ses déclinaisons spécifiques à une ACL. La méthode de test par défaut est implicite selon le type de sortie de cette méthode d’extraction d’échantillon. Les déclinaisons ACL peuvent décrire des méthodes de correspondance alternatives pour une même méthode d’extraction d’échantillon. Seules les méthodes d’extraction d’échantillon supportent une conversion.

Les méthodes d’extraction d’échantillon renvoient des données pouvant être des types suivants :

  • booléen
  • entier (signé ou non signé)
  • adresse IPv4 ou IPv6
  • chaîne de caractères
  • bloc de données

Les convertisseurs transforment n’importe quel type de données en n’importe quel autre type. Par exemple, certains convertisseurs peuvent convertir une chaîne en une chaîne en minuscules, tandis que d’autres peuvent transformer une chaîne en adresse IPv4 ou appliquer un masque réseau à une adresse IP. L’échantillon résultant est du type du dernier convertisseur appliqué à la liste, qui par défaut correspond au type de la méthode d’extraction d’échantillon.

Chaque échantillon ou convertisseur retourne des données d’un type spécifique, précisé par son mot-clé dans cette documentation. Lorsqu’une ACL est déclarée à l’aide d’une méthode d’extraction d’échantillon standard, certains types impliquent automatiquement une méthode de correspondance par défaut, résumée dans le tableau ci-dessous :

   +---------------------+-----------------+
   | Sample or converter | Default         |
   |    output type      | matching method |
   +---------------------+-----------------+
   | boolean             | bool            |
   +---------------------+-----------------+
   | integer             | int             |
   +---------------------+-----------------+
   | ip                  | ip              |
   +---------------------+-----------------+
   | string              | str             |
   +---------------------+-----------------+
   | binary              | none, use "-m"  |
   +---------------------+-----------------+

Notez qu’en vue de correspondre à des échantillons binaires, il est obligatoire de préciser une méthode de correspondance, voir ci-dessous.

Le moteur ACL peut effectuer des correspondances entre ces types et des modèles des types suivants :

  • booléen
  • entier ou plage d’entiers
  • adresse IP / réseau
  • chaîne (exacte, sous-chaîne, suffixe, préfixe, sous-répertoire, domaine)
  • expression régulière
  • bloc hexadécimal

Les indicateurs ACL suivants sont actuellement pris en charge :

-i: ignore case during matching of all subsequent patterns.
-f: load patterns from a list.
-m: use a specific pattern matching method
-n: forbid the DNS resolutions
-M: load the file pointed by -f like a map.
-u: force the unique id of the ACL
--: force end of flags. Useful when a string looks like one of the flags.

Le drapeau “-f” est suivi du nom qui doit respecter le format décrit en 2.7 concernant le format des noms pour les cartes et les listes ACL. Il est même possible de passer plusieurs arguments “-f” si les modèles doivent être chargés à partir de plusieurs listes. Si un fichier existant est référencé, toutes les lignes seront lues comme des valeurs individuelles. Les lignes vides ainsi que les lignes commençant par un dièse (’#’) seront ignorées. Tous les espaces et tabulations en début de ligne seront supprimés. Si une valeur valide commençant par un dièse doit absolument être insérée, il suffit de lui ajouter un espace en préfixe afin qu’elle ne soit pas interprétée comme un commentaire. Selon le type de données et la méthode de correspondance, HAProxy peut charger les lignes dans un arbre binaire, permettant des recherches très rapides. Cela s’applique aux correspondances exactes sur IPv4 et les chaînes de caractères. Dans ce cas, les doublons seront automatiquement supprimés.

L’indicateur “-M” permet à une liste de contrôle d’accès (ACL) d’utiliser une carte. Si cet indicateur est défini, la liste est analysée comme étant composée de deux colonnes. La première colonne contient les modèles utilisés par l’ACL, et la deuxième colonne contient les échantillons. Ces échantillons peuvent être utilisés ultérieurement par une carte. Cela peut être utile dans certains cas rares où une ACL ne serait utilisée qu’afin de vérifier l’existence d’un modèle dans une carte avant d’appliquer une correspondance.

L’indicateur “-u” impose l’identifiant unique de la liste ACL. Cet identifiant unique est utilisé avec l’interface socket pour identifier la liste ACL et modifier dynamiquement ses valeurs. Notez qu’un fichier est toujours identifié par son nom, même si un identifiant est défini.

En outre, notez que le drapeau “-i” s’applique aux entrées ultérieures et non aux entrées chargées à partir de fichiers antérieurs. Par exemple :

acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test

Dans cet exemple, chaque ligne de “exact-ua.lst” sera exactement correspondante avec l’en-tête « user-agent » de la requête. Ensuite, chaque ligne de « generic-ua » sera correspondante sans tenir compte de la casse. Enfin, le mot « test » sera également correspondant sans tenir compte de la casse.

Le drapeau “-m” est utilisé pour sélectionner une méthode spécifique de correspondance de modèle sur l’échantillon d’entrée. Tous les critères spécifiques aux ACL impliquent une méthode de correspondance de modèle et n’ont généralement pas besoin de ce drapeau. Toutefois, ce drapeau est utile avec les méthodes d’extraction d’échantillon génériques pour préciser la manière dont elles seront comparées aux modèles. Cela est nécessaire pour les extraits d’échantillon renvoyant un type de données pour lequel aucune méthode de correspondance évidente n’existe (par exemple, chaîne ou binaire). Lorsque “-m” est spécifié, suivi d’un nom de méthode de correspondance de modèle, cette méthode est utilisée à la place de celle par défaut pour le critère. Cela permet de correspondre aux contenus de manière non prévue initialement, ou avec des méthodes d’extraction d’échantillon renvoyant une chaîne. La méthode de correspondance affecte également la manière dont les modèles sont analysés. Elle ne doit donc pas être utilisée avec les extraits d’échantillon ayant un suffixe de correspondance (_beg, _end, _sub…). En outre, il n’est pas autorisé de spécifier plusieurs méthodes de correspondance de modèle “-m”.

Le drapeau “-n” interdit les résolutions DNS. Il est utilisé en conjonction avec le chargement de fichiers d’adresses IP. Par défaut, si le parseur ne parvient pas à analyser une adresse IP, il considère que la chaîne analysée pourrait être un nom de domaine et tente une résolution DNS. Le drapeau “-n” désactive cette résolution. Il est utile pour détecter des listes d’adresses IP malformées. Notez que si le serveur DNS n’est pas accessible, l’analyse de la configuration HAProxy peut durer plusieurs minutes en attendant le délai d’expiration. Pendant cette période, aucune message d’erreur n’est affiché. Le drapeau “-n” désactive ce comportement. Notez également que, pendant l’exécution, cette fonction est désactivée pour les modifications dynamiques des ACL.

Toutefois, certaines restrictions s’appliquent. Toutes les méthodes ne peuvent pas être utilisées avec toutes les méthodes d’extraction d’échantillon. En outre, si “-m” est utilisé conjointement avec “-f”, il doit être placé en premier. La méthode de correspondance de modèle doit être l’une des suivantes :

  • “found”: vérifie uniquement si l’échantillon demandé est présent dans le flux, sans le comparer à tout motif. Il est recommandé de ne pas passer de motif afin d’éviter toute confusion. Cette méthode de correspondance est particulièrement utile pour détecter la présence de contenus spécifiques, tels que des en-têtes, des cookies, etc., même s’ils sont vides, sans les comparer à quoi que ce soit ni les compter.

  • “bool” : vérifie la valeur comme une valeur booléenne. Cette option ne peut être utilisée que sur les requêtes renvoyant une valeur booléenne ou entière, et ne prend pas de motif. Une valeur nulle ou fausse ne correspond pas, toutes les autres valeurs correspondent.

  • “int” : correspond à une valeur entière. Peut être utilisé avec des échantillons entiers et booléens. Le booléen faux correspond à l’entier 0, le booléen vrai à l’entier 1.

  • “ip” : correspond à une adresse IPv4 ou IPv6. Elle n’est compatible qu’avec des exemples d’adresses IP, aussi elle est implicite et jamais nécessaire.

  • “bin” : correspondre au contenu à une chaîne hexadécimale représentant une séquence binaire. Cela peut être utilisé avec des échantillons binaires ou des chaînes.

  • “len” : correspond à la longueur de l’échantillon, exprimée sous forme d’entier. Cette option peut être utilisée avec des échantillons binaires ou chaînes de caractères.

  • “str” : correspondance exacte : compare le contenu à une chaîne. Cette option peut être utilisée avec des échantillons binaires ou textuels.

  • “sub” : correspondance de sous-chaîne : vérifie que le contenu contient au moins l’une des chaînes fournies. Cette option peut être utilisée avec des échantillons binaires ou de chaînes.

  • “reg” : correspondance par expression régulière : compare le contenu à une liste d’expressions régulières. Cela peut être utilisé avec des échantillons binaires ou chaînes de caractères.

  • “beg” : correspondance par préfixe : vérifie que le contenu commence par les chaînes fournies. Cela peut être utilisé avec des échantillons binaires ou de chaînes.

  • “end” : correspondance par suffixe : vérifie que le contenu se termine par les motifs de chaîne fournis. Cela peut être utilisé avec des échantillons binaires ou de chaînes.

  • “dir” : sous-répertoire correspondance : vérifie qu’une portion délimitée par des barres obliques du contenu correspond exactement à l’une des chaînes de motifs fournies. Cette option peut être utilisée avec des échantillons binaires ou textuels.

  • “dom” : correspondance de domaine : vérifie que une portion délimitée par des points du contenu correspond exactement à l’une des chaînes fournies. Cette option peut être utilisée avec des échantillons binaires ou textuels.

Par exemple, pour détecter rapidement la présence du cookie « JSESSIONID » dans une requête HTTP, il est possible de procéder ainsi :

acl jsess_present req.cook(JSESSIONID) -m found

Pour appliquer une expression régulière sur les 500 premiers octets de données dans le tampon, on utiliserait la règle d’accès suivante :

acl script_tag req.payload(0,500) -m reg -i <script>

Sur les systèmes où la bibliothèque regex est beaucoup plus lente lors de l’utilisation de “-i”, il est possible de convertir l’exemple en minuscules avant la correspondance, comme ceci :

acl script_tag req.payload(0,500),lower -m reg <script>

Tous les critères spécifiques aux ACL impliquent une méthode de correspondance par défaut. Le plus souvent, ces critères sont composés en concaténant le nom de la méthode d’extraction d’échantillon d’origine et la méthode de correspondance. Par exemple, “hdr_beg” applique la correspondance « beg » aux échantillons récupérés à l’aide de la méthode d’extraction « hdr ». Cette méthode de correspondance n’est utilisable qu’en tant que mot-clé unique, sans convertisseur associé. Si un tel convertisseur était appliqué après un mot-clé ACL de ce type, la méthode de correspondance par défaut du mot-clé ACL est simplement ignorée, car ce qui importe pour la correspondance est le type de sortie du dernier convertisseur. Étant donné que tous les critères spécifiques aux ACL reposent sur une méthode d’extraction d’échantillon, il est toujours possible de remplacer ces critères par la méthode d’extraction d’échantillon d’origine et la méthode de correspondance explicite en utilisant “-m”.

Si une correspondance alternative est spécifiée à l’aide de “-m” sur un critère spécifique à une ACL, la méthode de correspondance est simplement appliquée au mécanisme d’extraction d’échantillon sous-jacent. Par exemple, toutes les ACLs ci-dessous sont exactement équivalentes :

acl short_form  hdr_beg(host)        www.
acl alternate1  hdr_beg(host) -m beg www.
acl alternate2  hdr_dom(host) -m beg www.
acl alternate3  hdr(host)     -m beg www.

Le tableau ci-dessous résume la matrice de compatibilité entre les types d’échantillonnage ou de convertisseur et les types de modèle à interroger. Il indique pour chaque combinaison compatible le nom de la méthode correspondante à utiliser, entouré de crochets « > » et « < » lorsque la méthode est la valeur par défaut et fonctionnera par défaut sans -m.

                           +-------------------------------------------------+
                           |                Input sample type                |
    +----------------------+---------+---------+---------+---------+---------+
    |     pattern type     | boolean | integer |   ip    | string  | binary  |
    +----------------------+---------+---------+---------+---------+---------+
    | none (presence only) |  found  |  found  |  found  |  found  |  found  |
    +----------------------+---------+---------+---------+---------+---------+
    | none (boolean value) |>  bool <|   bool  |         |   bool  |         |
    +----------------------+---------+---------+---------+---------+---------+
    | integer (value)      |   int   |>  int  <|   int   |   int   |         |
    +----------------------+---------+---------+---------+---------+---------+
    | integer (length)     |   len   |   len   |   len   |   len   |   len   |
    +----------------------+---------+---------+---------+---------+---------+
    | IP address           |         |         |>   ip  <|    ip   |    ip   |
    +----------------------+---------+---------+---------+---------+---------+
    | exact string         |   str   |   str   |   str   |>  str  <|   str   |
    +----------------------+---------+---------+---------+---------+---------+
    | prefix               |   beg   |   beg   |   beg   |   beg   |   beg   |
    +----------------------+---------+---------+---------+---------+---------+
    | suffix               |   end   |   end   |   end   |   end   |   end   |
    +----------------------+---------+---------+---------+---------+---------+
    | substring            |   sub   |   sub   |   sub   |   sub   |   sub   |
    +----------------------+---------+---------+---------+---------+---------+
    | subdir               |   dir   |   dir   |   dir   |   dir   |   dir   |
    +----------------------+---------+---------+---------+---------+---------+
    | domain               |   dom   |   dom   |   dom   |   dom   |   dom   |
    +----------------------+---------+---------+---------+---------+---------+
    | regex                |   reg   |   reg   |   reg   |   reg   |   reg   |
    +----------------------+---------+---------+---------+---------+---------+
    | hex block            |         |         |         |   bin   |   bin   |
    +----------------------+---------+---------+---------+---------+---------+

7.1.1. Correspondance des booléens

Pour effectuer une correspondance booléenne, aucune valeur n’est requise et toutes les valeurs sont ignorées. La correspondance booléenne est utilisée par défaut pour toutes les méthodes de récupération de type « boolean ». Lorsqu’elle est utilisée, la valeur récupérée est renvoyée telle quelle : un booléen « true » correspond toujours, tandis qu’un booléen « false » ne correspond jamais.

La correspondance booléenne peut également être imposée en utilisant “-m bool” sur les méthodes de récupération renvoyant une valeur entière. Dans ce cas, la valeur entière 0 est convertie en booléen “false”, et toutes les autres valeurs sont converties en “true”.

7.1.2. Correspondance des entiers

La correspondance entière s’applique par défaut aux méthodes de récupération entières. Elle peut également être imposée aux récupérations booléennes en utilisant “-m int”. Dans ce cas, “false” est converti en entier 0, et “true” en entier 1.

La correspondance entière prend également en charge les plages d’entiers et les opérateurs. Notez que la correspondance entière ne s’applique qu’aux valeurs positives. Une plage est une valeur exprimée avec une borne inférieure et une borne supérieure séparées par deux points, les deux bornes pouvant être omises.

Par exemple, « 1024:65535 » est une plage valide pour représenter une plage de ports non privilégiés, et « 1024: » fonctionnerait également. « 0:1023 » est une représentation valide des ports privilégiés, et « :1023 » fonctionnerait également.

Dans un cas particulier, certaines fonctions ACL prennent en charge des nombres décimaux, qui sont en réalité deux entiers séparés par un point. Cela est utilisé, par exemple, pour certaines vérifications de version. Toutes les propriétés applicables aux entiers s’appliquent également à ces nombres décimaux, y compris les plages et les opérateurs.

Pour une utilisation plus simple, les opérateurs de comparaison sont également pris en charge. Notez qu’utiliser des opérateurs avec des plages ne présente guère de sens et est fortement déconseillé. De même, il ne semble pas pertinent d’effectuer des comparaisons d’ordre avec un ensemble de valeurs.

Opérateurs disponibles pour le correspondance entière :

eq: true if the tested value equals at least one value
ge: true if the tested value is greater than or equal to at least one value
gt: true if the tested value is greater than at least one value
le: true if the tested value is less than or equal to at least one value
lt: true if the tested value is less than at least one value

Par exemple, la règle ACL suivante correspond à tout en-tête Content-Length négatif :

acl negative-length req.hdr_val(content-length) lt 0

Ce paramètre correspond aux versions SSL comprises entre 3.0 et 3.1 (incluses) :

acl sslv3 req.ssl_ver 3:3.1

7.1.3. Chaînes de correspondance

La correspondance de chaînes s’applique aux méthodes d’accès en chaîne ou binaire, et existe sous 6 formes différentes :

  • correspondance exacte (-m str) : la chaîne extraite doit correspondre exactement aux modèles ;

  • correspondance de sous-chaîne (-m sub) : les modèles sont recherchés à l’intérieur de la chaîne extraite, et la règle d’accès correspond si l’un d’entre eux est trouvé à l’intérieur ;

  • correspondance de préfixe (-m début) : les modèles sont comparés au début de la chaîne extraite, et la règle d’accès correspond si l’un d’entre eux correspond.

  • suffix match (-m end) : les modèles sont comparés à la fin de la chaîne extraite, et la règle d’accès (ACL) est appliquée si l’un d’entre eux correspond.

  • sous-répertoire correspondant (-m répertoire) : les modèles sont recherchés n’importe où dans la chaîne extraite, délimités par des barres obliques ("/"), le début ou la fin de la chaîne. La règle d’accès est respectée si l’un des modèles correspond. Ainsi, la chaîne “/images/png/logo/32x32.png” correspond à “/images”, “/images/png”, “images/png”, “/png/logo”, “logo/32x32.png” ou “32x32.png”, mais pas à “png” ni à “32x32”.

  • domain match (-m dom) : les modèles sont recherchés n’importe où dans la chaîne extraite, séparés par des points ("."), des deux-points (":"), des barres obliques ("/"), des points d’interrogation ("?"), au début ou à la fin de la chaîne. Cette option est destinée à être utilisée avec les URL. Les délimiteurs en début ou en fin de modèle sont ignorés. L’ACL correspond si l’un des modèles correspond. Ainsi, dans la chaîne d’exemple “http://www1.dc-eu.example.com:80/blah ”, les modèles “http”, “www1”, “.www1”, “dc-eu”, “example”, “com”, “80”, “dc-eu.example”, “blah”, “:www1:”, “dc-eu.example:80” correspondent, mais pas “eu” ni “dc”. Il n’est généralement pas recommandé de l’utiliser pour correspondre aux suffixes de domaine afin de filtrer ou acheminer le trafic, car l’acheminement pourrait facilement être trompé en ajoutant le préfixe correspondant devant un autre domaine, par exemple.

La correspondance de chaîne s’applique aux chaînes littérales telles qu’elles sont transmises, à l’exception de la barre oblique inverse ("\") qui permet d’échapper certains caractères, tels que l’espace. Si le drapeau “-i” est passé avant la première chaîne, la correspondance sera effectuée sans tenir compte de la casse. Pour correspondre à la chaîne “-i”, soit la définir en deuxième position, soit passer l’option “–” avant la première chaîne. La même règle s’applique bien entendu pour correspondre à la chaîne “–”.

N’utilisez pas de correspondances de chaînes pour les récupérations binaires pouvant contenir des octets nuls (0x00), car la comparaison s’arrête à la première occurrence d’un octet nul. À la place, convertissez d’abord la récupération binaire en chaîne hexadécimale à l’aide du convertisseur hexadécimal.

Exemple :

# matches if the string <tag> is present in the binary sample
acl tag_found req.payload(0,0),hex -m sub 3C7461673E

7.1.4. Correspondance des expressions régulières (regexes)

Tout comme pour la correspondance de chaîne, la correspondance par expression régulière s’applique aux chaînes littérales telles qu’elles sont transmises, à l’exception de la barre oblique inverse ("\") qui permet d’échapper à certains caractères, tels que l’espace. Si le drapeau “-i” est passé avant la première expression régulière, la correspondance se fera sans tenir compte de la casse. Pour correspondre à la chaîne “-i”, il faut soit la placer en deuxième position, soit passer l’option “–” avant la première chaîne. Le même principe s’applique bien entendu pour correspondre à la chaîne “–”.

7.1.5. Correspondance de blocs de données arbitraires

Il est possible de comparer certains échantillons extraits à un bloc binaire qui ne peut pas être représenté en toute sécurité sous forme de chaîne. Pour cela, les modèles doivent être fournis sous forme d’une série de chiffres hexadécimaux en nombre pair, lorsque la méthode de correspondance est définie sur binaire. Chaque séquence de deux chiffres représente un octet. Les chiffres hexadécimaux peuvent être utilisés en majuscules ou en minuscules.

Exemple :

# match "Hello\n" in the input stream (\x48 \x65 \x6c \x6c \x6f \x0a)
acl hello req.payload(0,6) -m bin 48656c6c6f0a

7.1.6. Correspondance des adresses IPv4 et IPv6

Les valeurs d’adresses IPv4 peuvent être spécifiées soit sous forme d’adresses brutes, soit avec un masque réseau ajouté, auquel cas l’adresse IPv4 correspond si elle se trouve dans le réseau. Les adresses brutes peuvent également être remplacées par un nom d’hôte résolvable, mais cette pratique est généralement déconseillée car elle rend la lecture et le débogage des configurations plus difficiles. Si des noms d’hôtes sont utilisés, vous devez au moins vous assurer qu’ils sont présents dans /etc/hosts afin que la configuration ne dépende pas d’une correspondance DNS aléatoire au moment de l’analyse de la configuration.

La notation en adresse IPv4 avec points est prise en charge, tant sous sa forme classique que sous sa forme abrégée, où les octets nuls sont omis :

    +------------------+------------------+------------------+
    |   Example 1      |     Example 2    |     Example 3    |
    +------------------+------------------+------------------+
    |  192.168.0.1     |   10.0.0.12      |   127.0.0.1      |
    |  192.168.1       |   10.12          |   127.1          |
    |  192.168.0.1/22  |   10.0.0.12/8    |   127.0.0.1/8    |
    |  192.168.1/22    |   10.12/8        |   127.1/8        |
    +------------------+------------------+------------------+

Remarque : cela diffère de la notation d’adresses CIDR RFC 4632, dans laquelle 192.168.42/24 serait équivalent à 192.168.42.0/24.

IPv6 peut être entré sous sa forme habituelle, avec ou sans masque réseau ajouté. Seuls les nombres de bits sont acceptés pour les masques réseau IPv6. Afin d’éviter tout risque de problème lié à des adresses IP résolues aléatoirement, les noms d’hôte ne sont jamais autorisés dans les modèles IPv6.

HAProxy est également capable de correspondre aux adresses IPv4 aux adresses IPv6 dans les situations suivantes :

  • l’adresse testée est en IPv4, l’adresse modèle est en IPv4, la correspondance s’applique en IPv4 en utilisant le masque fourni, le cas échéant.
  • l’adresse testée est en IPv6, l’adresse modèle est en IPv6, la correspondance s’applique en IPv6 en utilisant le masque fourni, le cas échéant.
  • l’adresse testée est en IPv6, l’adresse modèle est en IPv4, la correspondance s’applique en IPv4 en utilisant le masque du modèle si l’adresse IPv6 correspond à 2002:IPV4::, ::IPV4 ou ::ffff:IPV4, sinon elle échoue.
  • l’adresse testée est en IPv4, l’adresse modèle est en IPv6, l’adresse IPv4 est d’abord convertie en IPv6 en préfixant ::ffff: devant, puis la correspondance s’applique en IPv6 en utilisant le masque IPv6 fourni.

7.2. Utilisation des ACL pour définir des conditions

Certaines actions ne sont exécutées que si une condition valide est remplie. Une condition est une combinaison d’ACLs avec des opérateurs. Trois opérateurs sont pris en charge :

  • ET (implicite)
  • OU (explicite avec le mot-clé “or” ou l’opérateur “||”)
  • Négation avec le point d’exclamation ("!")

Une condition est formulée sous forme disjonctive :

[!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...

Ces conditions sont généralement utilisées après une instruction « if » ou « unless », indiquant le moment où la condition déclenchera l’action.

Par exemple, bloquer les requêtes HTTP vers l’URL « * » avec des méthodes autres que « OPTIONS », ainsi que les requêtes POST sans en-tête content-length, et les requêtes GET ou HEAD avec un content-length supérieur à 0, et enfin toute requête qui n’est ni GET/HEAD/POST/OPTIONS !

acl missing_cl req.hdr_cnt(Content-length) eq 0 http-request deny if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl http-request deny if METH_GET HTTP_CONTENT http-request deny unless METH_GET or METH_POST or METH_OPTIONS

Pour sélectionner un backend différent pour les requêtes relatives aux contenus statiques du site « www » et pour toutes les requêtes sur les hôtes « img », « video », « download » et « ftp » :

acl url_static  path_beg         /static /images /img /css
acl url_static  path_end         .gif .png .jpg .css .js
acl host_www    hdr_beg(host) -i www
acl host_static hdr_beg(host) -i img. video. download. ftp.
# now use backend "static" for all static-only hosts, and for static URLs
# of host "www". Use backend "www" for the rest.
use_backend static if host_static or host_www url_static
use_backend www    if host_www

Il est également possible de créer des règles à l’aide d’« ACL anonymes ». Il s’agit d’expressions ACL sans nom, qui sont construites dynamiquement sans avoir besoin d’être déclarées. Elles doivent être encloses entre des accolades, avec un espace avant et après chaque accolade (car les accolades doivent être considérées comme des mots indépendants). Exemple :

The following rule:

    acl missing_cl req.hdr_cnt(Content-length) eq 0
    http-request deny if METH_POST missing_cl

Can also be written that way:

    http-request deny if METH_POST { req.hdr_cnt(Content-length) eq 0 }

Il est généralement déconseillé d’utiliser cette construction, car il est bien plus facile de laisser des erreurs dans la configuration lorsqu’elle est écrite de cette manière. Toutefois, pour des règles très simples correspondant à une seule adresse IP source, par exemple, il peut être plus pertinent de l’utiliser que de déclarer des ACLs avec des noms aléatoires. Un autre exemple d’utilisation appropriée est le suivant :

With named ACLs:

     acl site_dead nbsrv(dynamic) lt 2
     acl site_dead nbsrv(static)  lt 2
     monitor fail  if site_dead

With anonymous ACLs:

     monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }

Voir section 4.2 pour obtenir une aide détaillée sur les mots-clés « http-request deny » et “use_backend”.

7.3. Récupération des échantillons

Historiquement, les méthodes d’extraction d’échantillon étaient utilisées uniquement pour récupérer des données afin de les comparer à des modèles à l’aide des listes de contrôle d’accès (ACL). Avec l’arrivée des tables de persistance (stick-tables), une nouvelle catégorie de méthodes d’extraction d’échantillon a été introduite, dont la syntaxe est généralement identique à celle de leurs homologues ACL. Ces méthodes d’extraction d’échantillon sont également appelées « fetches ». À ce jour, les ACL et les fetches se sont convergées. Toutes les méthodes d’extraction d’échantillon disponibles pour les ACL sont désormais accessibles en tant que méthodes fetch, et les ACL peuvent utiliser n’importe quelle méthode d’extraction d’échantillon.

Cette section détaille toutes les méthodes d’extraction d’échantillon disponibles ainsi que leur type de sortie. Certaines méthodes d’extraction d’échantillon disposent d’alias obsolètes, utilisés pour maintenir la compatibilité avec les configurations existantes. Elles sont alors explicitement marquées comme obsolètes et ne doivent pas être utilisées dans de nouvelles configurations.

Les dérivés de ACL sont également indiqués lorsqu’ils sont disponibles, accompagnés de leurs méthodes de correspondance respectives. Tous disposent d’une méthode de correspondance par défaut bien définie, aussi n’est-il jamais nécessaire (bien qu’autorisé) de passer l’option “-m” pour indiquer comment l’échantillon sera correspondant via les ACLs.

Comme indiqué dans la matrice ci-dessus indiquant la compatibilité entre les types d’extraction d’échantillon et les correspondances, lorsque l’on utilise une méthode d’extraction d’échantillon générique dans une ACL, l’option “-m” est obligatoire, sauf si le type d’extraction est l’un des suivants : booléen, entier, IPv4 ou IPv6. Lorsque le même mot-clé existe à la fois comme mot-clé ACL et comme méthode d’extraction standard, le moteur ACL choisit automatiquement celui propre aux ACL par défaut.

Certains de ces mots-clés prennent un ou plusieurs arguments obligatoires, ainsi qu’un ou plusieurs arguments facultatifs. Ces arguments sont fortement typés et vérifiés lors de l’analyse de la configuration, afin d’éviter tout risque d’exécution avec un argument incorrect (par exemple, un nom de backend non résolu). Les arguments des fonctions de récupération sont placés entre parenthèses et séparés par des virgules. Lorsqu’un argument est facultatif, il est indiqué ci-dessous entre crochets (’[ ]’). Lorsque tous les arguments sont facultatifs, les parenthèses peuvent être omises.

Ainsi, la syntaxe d’une méthode d’extraction d’échantillon standard est l’une des suivantes :

  • name
  • name(arg1)
  • name(arg1,arg2)

7.3.1. Convertisseurs

Les méthodes d’extraction d’échantillon peuvent être combinées avec des transformations à appliquer sur l’échantillon extrait (appelées également « convertisseurs »). Ces combinaisons forment ce qu’on appelle des « expressions d’échantillon », dont le résultat est un « échantillon ». Initialement, cette fonctionnalité n’était supportée que par les directives « stick on » et « stick store-request », mais elle a maintenant été étendue à toutes les situations où des échantillons peuvent être utilisés (ACLs, log-format, unique-id-format, add-header, …).

Ces transformations sont énumérées sous la forme d’une série de mots-clés spécifiques placés après la méthode d’extraction d’échantillon. Ces mots-clés peuvent également être ajoutés immédiatement après l’argument du mot-clé fetch, séparés par une virgule. Ces mots-clés peuvent également prendre certains arguments (par exemple, un masque réseau), qui doivent être passés entre parenthèses.

Une catégorie de convertisseurs est constituée d’opérateurs bit à bit et arithmétiques, qui permettent d’effectuer des opérations élémentaires sur des entiers. Certains opérations bit à bit sont prises en charge (et, ou, ou exclusif, complément), ainsi que certaines opérations arithmétiques (addition, soustraction, multiplication, division, modulo, négation). Certains comparateurs sont également fournis (impair, pair, non, booléen), ce qui permet de signaler une correspondance sans avoir à écrire une ACL.

Les mots-clés suivants sont pris en charge :

   keyword                                         input type   output type
------------------------------------------------+-------------+----------------
51d.single(prop[,prop*])                           string       string
add(value)                                         integer      integer
add_item(delim[,var[,suff]])                       string       string
aes_cbc_dec(bits,nonce,key[,<aad>])                binary       binary
aes_cbc_enc(bits,nonce,key[,<aad>])                binary       binary
aes_gcm_dec(bits,nonce,key,aead_tag[,aad])         binary       binary
aes_gcm_enc(bits,nonce,key,aead_tag[,aad])         binary       binary
and(value)                                         integer      integer
b64dec                                             string       binary
base2                                              binary       string
base64                                             binary       string
be2dec(separator,chunk_size[,truncate])            binary       string
le2dec(separator,chunk_size[,truncate])            binary       string
be2hex([separator[,chunk_size[,truncate]]])        binary       string
bool                                               integer      boolean
bytes(offset[,length])                             binary       binary
capture-req(id)                                    string       string
capture-res(id)                                    string       string
concat([start[,var[,end]]])                        string       string
cpl                                                integer      integer
crc32([avalanche])                                 binary       integer
crc32c([avalanche])                                binary       integer
cut_crlf                                           string       string
da-csv-conv(prop[,prop*])                          string       string
date                                               string       integer
debug([prefix][,destination])                       any          same
-- keyword -------------------------------------+- input type + output type -
digest(algorithm)                                  binary       binary
div(value)                                         integer      integer
djb2([avalanche])                                  binary       integer
eth.data                                           binary       binary
eth.dst                                            binary       binary
eth.hdr                                            binary       binary
eth.proto                                          binary       integer
eth.src                                            binary       binary
eth.vlan                                           binary       integer
even                                               integer      boolean
fe_exists                                          string       boolean
field(index,delimiters[,count])                    string       string
fix_is_valid                                       binary       boolean
fix_tag_value(tag)                                 binary       binary
has_ctl([mask])                                    binary       boolean
hex                                                binary       string
hex2i                                              binary       integer
hmac(algorithm,key)                                binary       binary
host_only                                          string       string
htonl                                              integer      integer
http_date([offset[,unit]])                         integer      string
iif(true,false)                                    boolean      string
in_table([table])                                  any          boolean
ip.data                                            binary       binary
ip.df                                              binary       integer
ip.dst                                             binary       address
ip.fp                                              binary       binary
ip.hdr                                             binary       binary
ip.proto                                           binary       integer
ip.src                                             binary       address
ip.tos                                             binary       integer
ip.ttl                                             binary       integer
ip.ver                                             binary       integer
ipmask(mask4[,mask6])                              address      address
json([input-code])                                 string       string
json_query(json_path[,output_type])                string       _outtype_
jwt_decrypt_jwk(<jwk>)                             string       binary
jwt_decrypt_cert(<cert>)                           string       binary
jwt_decrypt_secret(<secret>)                       string       binary
jwt_header_query([json_path[,output_type]])        string       string
jwt_payload_query([json_path[,output_type]])       string       string
-- keyword -------------------------------------+- input type + output type -
jwt_verify(alg,key)                                string       integer
jwt_verify_cert(alg,cert)                          string       integer
language(value[,default])                          string       string
length                                             string       integer
lower                                              string       string
ltime(format[,offset])                             integer      string
ltrim(chars)                                       string       string
map(map_name[,default_value])                      string       string
map_match(map_name[,default_value])                _match_      string
map_match_output(map_name[,default_value])         _match_      _output_
mod(value)                                         integer      integer
mqtt_field_value(pkt_type,fieldname_or_prop_ID)    binary       binary
mqtt_is_valid                                      binary       boolean
ms_ltime(format[,offset])                          integer      string
ms_utime(format[,offset])                          integer      string
mul(value)                                         integer      integer
nbsrv                                              string       integer
neg                                                integer      integer
not                                                integer      boolean
odd                                                integer      boolean
or(value)                                          integer      integer
-- keyword -------------------------------------+- input type + output type -
param(name[,delim])                                string       string
port_only                                          string       integer
protobuf(field_number[,field_type])                binary       binary
regsub(regex,subst[,flags])                        string       string
reverse                                            string       string
reverse_dom                                        string       string
rfc7239_field(field)                               string       string
rfc7239_is_valid                                   string       boolean
rfc7239_n2nn                                       string       address / str
rfc7239_n2np                                       string       integer / str
rfc7239_nn                                         address/str  string
rfc7239_np                                         integer/str  string
rtrim(chars)                                       string       string
sdbm([avalanche])                                  binary       integer
secure_memcmp(var)                                 string       boolean
set-var(var[,cond...])                              any          same
sha1                                               binary       binary
sha2([bits])                                       binary       binary
srv_is_up                                          string       boolean
srv_queue                                          string       integer
strcmp(var)                                        string       boolean
sub(value)                                         integer      integer
table_bytes_in_rate([table])                       any          integer
table_bytes_out_rate([table])                      any          integer
table_clr_gpc(idx[,table])                         any          integer
table_clr_gpc0([table])                            any          integer
table_clr_gpc1([table])                            any          integer
table_conn_cnt([table])                            any          integer
-- keyword -------------------------------------+- input type + output type -
table_conn_cur([table])                            any          integer
table_conn_rate([table])                           any          integer
table_expire([table[,default_value]])              any          integer
table_glitch_cnt([table])                          any          integer
table_glitch_rate([table])                         any          integer
table_gpc(idx[,table])                             any          integer
table_gpc0([table])                                any          integer
table_gpc0_rate([table])                           any          integer
table_gpc1([table])                                any          integer
table_gpc1_rate([table])                           any          integer
table_gpc_rate(idx[,table])                        any          integer
table_gpt(idx[,table])                             any          integer
table_gpt0([table])                                any          integer
table_http_err_cnt([table])                        any          integer
table_http_err_rate([table])                       any          integer
table_http_fail_cnt([table])                       any          integer
table_http_fail_rate([table])                      any          integer
table_http_req_cnt([table])                        any          integer
table_http_req_rate([table])                       any          integer
table_idle([table[,default_value]])                any          integer
table_inc_gpc(idx[,table])                         any          integer
table_inc_gpc0([table])                            any          integer
table_inc_gpc1([table])                            any          integer
table_kbytes_in([table])                           any          integer
-- keyword -------------------------------------+- input type + output type -
table_kbytes_out([table])                          any          integer
table_server_id([table])                           any          integer
table_sess_cnt([table])                            any          integer
table_sess_rate([table])                           any          integer
table_trackers([table])                            any          integer
tcp.dst                                            binary       integer
tcp.flags                                          binary       integer
tcp.options.mss                                    binary       integer
tcp.options.sack                                   binary       integer
tcp.options.tsopt                                  binary       integer
tcp.options.tsval                                  binary       integer
tcp.options.wscale                                 binary       integer
tcp.options.wsopt                                  binary       integer
tcp.options_list                                   binary       binary
tcp.seq                                            binary       integer
tcp.src                                            binary       integer
tcp.win                                            binary       integer
ub64dec                                            string       string
ub64enc                                            string       string
ungrpc(field_number[,field_type])                  binary       binary / int
unset-var(var)                                      any          same
upper                                              string       string
url_dec([in_form])                                 string       string
url_enc([enc_type])                                string       string
us_ltime(format[,offset])                          integer      string
us_utime(format[,offset])                          integer      string
utime(format[,offset])                             integer      string
when(condition)                                     any          same
word(index,delimiters[,count])                     string       string
wt6([avalanche])                                   binary       integer
x509_v_err_str                                     integer      string
xor(value)                                         integer      integer
-- keyword -------------------------------------+- input type + output type -
xxh3([seed])                                       binary       integer
xxh32([seed])                                      binary       integer
xxh64([seed])                                      binary       integer

La liste détaillée des mots-clés convertisseurs suit :

51d.single(<prop>[,<prop>*])

51d.single(<prop>[,<prop>*])

Retourne les valeurs des propriétés demandées sous forme de chaîne, où les valeurs sont séparées par le délimiteur spécifié par « 51degrees-property-separator ». L’appareil est identifié à l’aide de l’en-tête User-Agent transmis au convertisseur. La fonction peut recevoir jusqu’à cinq noms de propriété ; si un nom de propriété n’est pas trouvé, la valeur « NoData » est retournée.

Exemple :

# Here the header "X-51D-DeviceTypeMobileTablet" is added to the request,
# containing values for the three properties requested by using the
# User-Agent passed to the converter.
frontend http-in
  bind *:8081
  default_backend servers
  http-request set-header X-51D-DeviceTypeMobileTablet \
    %[req.fhdr(User-Agent),51d.single(DeviceType,IsMobile,IsTablet)]

add(<value>)

add(<value>)

Ajoute <value> à la valeur d’entrée de type entier signé, et retourne le résultat sous forme d’entier signé. <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 concernant les variables pour plus de détails.

add_item(<delim>[,<var>[,<suff>]])

add_item(<delim>[,<var>[,<suff>]])

Concatène un minimum de 2 et jusqu’à 3 champs situés après l’échantillon courant, qui est ensuite converti en chaîne. Le premier, <delim>, est une chaîne constante, qui est ajoutée immédiatement après l’échantillon existant si l’échantillon existant n’est pas vide et si au moins l’un des champs <var> ou <suff> n’est pas vide. Le second, <var>, est un nom de variable. Cette variable est recherchée, son contenu converti en chaîne, puis ajouté immédiatement après la partie <delim>. Si la variable n’est pas trouvée, rien n’est ajouté. Ce champ est facultatif et peut éventuellement être suivi d’une chaîne constante <suff>, toutefois si <var> est omis, alors <suff> est obligatoire. Ce convertisseur est similaire au convertisseur concat et peut être utilisé pour construire de nouvelles variables à partir d’une succession d’autres variables, mais la principale différence réside dans le fait qu’il effectue des vérifications pour déterminer si l’ajout d’un séparateur est pertinent, contrairement à ce qui serait le cas si, par exemple, l’échantillon courant était vide. Dans ce dernier cas, deux règles distinctes seraient nécessaires en utilisant le convertisseur concat, la première devant vérifier si la chaîne de l’échantillon courant est vide avant d’ajouter un séparateur. Si des virgules ou des parenthèses fermantes sont nécessaires comme séparateurs, ils doivent être protégés par des guillemets ou des barres obliques, eux-mêmes protégés afin de ne pas être supprimés par le parseur de premier niveau (voir la section 2.2 pour la mise en quote et l’échappement). Voir les exemples ci-dessous.

Exemple :

http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score1,"(site1)") if src,in_table(site1)'
http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score2,"(site2)") if src,in_table(site2)'
http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score3,"(site3)") if src,in_table(site3)'
http-request set-header x-tagged %[var(req.tagged)]

http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score1),add_item(",",req.score2)'
http-request set-var(req.tagged) 'var(req.tagged),add_item(",",,(site1))' if src,in_table(site1)

aes_cbc_dec(<bits>,<nonce>,<key>[,<aad>])

aes_cbc_dec(<bits>,<nonce>,<key>[,<aad>])

Déchiffre l’entrée binaire brute en utilisant l’algorithme AES128-CBC, AES192-CBC ou AES256-CBC, selon le paramètre <bits>. Tous les autres paramètres doivent être encodés en base64 et le résultat renvoyé est au format binaire brut. Le paramètre <aad> est facultatif. Si la validation <aad> échoue, le convertisseur ne renvoie aucune donnée. Les paramètres <nonce>, <key> et <aad> peuvent être des chaînes ou des variables. Ce convertisseur nécessite au moins OpenSSL 1.0.1.

Exemple :

http-response set-header X-Decrypted-Text %[var(txn.enc),\
  aes_cbc_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==)]

aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])

aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])

Chiffre l’entrée en octets bruts en utilisant l’algorithme AES128-CBC, AES192-CBC ou AES256-CBC, selon le paramètre <bits>. Les paramètres <nonce>, <key> et <aad> doivent être encodés en base64. Le paramètre <aad> est facultatif. Le résultat renvoyé est au format octets bruts. Les paramètres <nonce>, <key> et <aad> peuvent être des chaînes ou des variables. Ce convertisseur nécessite au moins OpenSSL 1.0.1.

Exemple :

http-response set-header X-Encrypted-Text %[var(txn.plain),\
  aes_cbc_enc(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==)]

aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

Déchiffre l’entrée binaire brute à l’aide de l’algorithme AES128-GCM, AES192-GCM ou AES256-GCM, selon le paramètre <bits>. Tous les autres paramètres doivent être encodés en base64, et le résultat retourné est au format binaire brut. Si la validation <aead_tag> ou <aad> échoue, le convertisseur ne retourne aucune donnée. Le paramètre <aad> est facultatif. Les paramètres <nonce>, <key>, <aead_tag> et <aad> peuvent être des chaînes ou des variables. Ce convertisseur nécessite au moins OpenSSL 1.0.1.

Exemple :

http-response set-header X-Decrypted-Text %[var(txn.enc),\
  aes_gcm_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]

aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

Chiffre l’entrée en octets bruts à l’aide de l’algorithme AES128-GCM, AES192-GCM ou AES256-GCM, selon le paramètre <bits>. Les paramètres <nonce>, <key> et <aad> doivent être encodés en base64. Le paramètre <aead_tag> doit être une variable. Le tag AEAD sera stocké au format base64 dans cette variable. Le paramètre <aad> est facultatif. Le résultat renvoyé est au format octets bruts. Les paramètres <nonce>, <key> et <aad> peuvent être des chaînes ou des variables. Ce convertisseur nécessite au moins OpenSSL 1.0.1.

Exemple :

http-response set-header X-Encrypted-Text %[var(txn.plain),\
  aes_gcm_enc(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]

and(<value>)

and(<value>)

Effectue un opérateur “ET” bit à bit entre <value> et la valeur d’entrée de type entier signé, puis retourne le résultat sous forme d’entier signé. <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 sur les variables pour plus de détails.

b64dec

b64dec

Convertit (décodifie) une chaîne encodée en base64 en sa représentation binaire. Elle effectue l’opération inverse de base64(). Pour la variante base64url(“alphabet sécurisé pour les URL et les noms de fichiers” (RFC 4648)), voir « ub64dec ».

base2

base2

Convertit un échantillon d’entrée binaire en chaîne binaire contenant huit chiffres binaires par octet d’entrée. Elle est utilisée pour permettre la correspondance du préfixe le plus long sur des types dont la représentation native ne permet pas la correspondance de préfixe, par exemple les préfixes IP.

base64

base64

Convertit un échantillon binaire en chaîne base64. Cette fonction est utilisée pour journaliser ou transférer du contenu binaire de manière fiable (par exemple, un identifiant SSL peut être copié dans un en-tête). Pour la variante base64url (“alphabet sécurisé pour les URL et les noms de fichiers” (RFC 4648)), voir « ub64enc ».

be2dec(<separator>,<chunk_size>[,<truncate>])

be2dec(<separator>,<chunk_size>[,<truncate>])

Convertit un échantillon d’entrée binaire au format big-endian en une chaîne contenant un nombre entier non signé par <chunk_size> octets d’entrée. <separator> est inséré tous les <chunk_size> octets d’entrée binaires, le cas échéant. Le drapeau <truncate> indique si l’entrée binaire est tronquée aux limites de <chunk_size>. La valeur maximale de <chunk_size> est limitée par la taille d’un entier long long (8 octets).

Exemple :

bin(01020304050607),be2dec(:,2)   # 258:772:1286:7
bin(01020304050607),be2dec(-,2,1) # 258-772-1286
bin(01020304050607),be2dec(,2,1)  # 2587721286
bin(7f000001),be2dec(.,1)         # 127.0.0.1

le2dec(<separator>,<chunk_size>[,<truncate>])

le2dec(<separator>,<chunk_size>[,<truncate>])

Convertit un échantillon d’entrée binaire en little-endian en une chaîne contenant un nombre entier non signé par <chunk_size> octets d’entrée. <separator> est inséré tous les <chunk_size> octets d’entrée binaires, si spécifié. Le drapeau <truncate> indique si l’entrée binaire est tronquée aux limites <chunk_size>. La valeur maximale de <chunk_size> est limitée par la taille d’un entier long long (8 octets).

Exemple :

bin(01020304050607),le2dec(:,2)   # 513:1284:2055:7
bin(01020304050607),le2dec(-,2,1) # 513-1284-2055
bin(01020304050607),le2dec(,2,1)  # 51312842055
bin(7f000001),le2dec(.,1)         # 127.0.0.1

be2hex([<separator>[,<chunk_size>[,<truncate>]]])

be2hex([<separator>[,<chunk_size>[,<truncate>]]])

Convertit un échantillon d’entrée binaire au format big-endian en chaîne hexadécimale contenant deux chiffres hexadécimaux par octet d’entrée. Elle est utilisée pour journaliser ou transférer des dumps hexadécimaux de données binaires de manière fiable (par exemple, un identifiant SSL peut être copié dans un en-tête). <separator> est inséré tous les <chunk_size> octets d’entrée binaires, le cas échéant. Le drapeau <truncate> indique si l’entrée binaire est tronquée aux limites de <chunk_size>.

Exemple :

bin(01020304050607),be2hex         # 01020304050607
bin(01020304050607),be2hex(:,2)    # 0102:0304:0506:07
bin(01020304050607),be2hex(--,2,1) # 0102--0304--0506
bin(0102030405060708),be2hex(,3,1) # 010203040506

bool

bool

Renvoie une valeur booléenne TRUE si la valeur d’entrée de type entier signé est non nulle, sinon renvoie FALSE. Utilisé en conjonction avec and(), il peut être utilisé pour signaler true/false lors du test de bits sur les valeurs d’entrée (par exemple, vérifier la présence d’un indicateur).

bytes(<offset>[,<length>])

bytes(<offset>[,<length>])

Extrait certains octets à partir d’un échantillon binaire d’entrée. Le résultat est un échantillon binaire commençant à un décalage (en octets) par rapport à l’échantillon d’origine, et éventuellement tronqué à la longueur indiquée. <offset> et <length> peuvent être des valeurs numériques ou des noms de variables. Le convertisseur retourne un échantillon vide si <offset> ou <length> est invalide. Un <offset> invalide signifie une valeur négative ou une valeur supérieure ou égale à la longueur de l’échantillon d’entrée. Un <length> invalide signifie une valeur négative.

Exemple :

http-request set-var(txn.input) req.hdr(input) # let's say input is "012345"

http-response set-header bytes_0 "%[var(txn.input),bytes(0)]"  # outputs "012345"
http-response set-header bytes_1_3 "%[var(txn.input),bytes(1,3)]"  # outputs "123"

http-response set-var(txn.var_start) int(1)
http-response set-var(txn.var_length) int(3)
http-response set-header bytes_var1_var3    "%[var(txn.input),bytes(txn.var_start,txn.var_length)]"  # outputs "123"

capture-req(<id>)

capture-req(<id>)

Capture la chaîne présente dans l’emplacement de requête <id> et la renvoie telle quelle. Si l’emplacement n’existe pas, la capture échoue silencieusement.

Voir aussi : « declare capture », « http-request capture », « http-response capture », “capture.req.hdr” et “capture.res.hdr” (extraction d’échantillon).

capture-res(<id>)

capture-res(<id>)

Capture la chaîne présente dans l’emplacement de réponse <id> et la renvoie telle quelle. Si l’emplacement n’existe pas, la capture échoue silencieusement.

Voir aussi : « declare capture », « http-request capture », « http-response capture », “capture.req.hdr” et “capture.res.hdr” (extraction d’échantillon).

concat([<start>[,<var>[,<end>]]])

concat([<start>[,<var>[,<end>]]])

Concatène jusqu’à 3 champs après l’échantillon courant, qui est ensuite converti en chaîne. Le premier, <start>, est une chaîne constante, ajoutée immédiatement après l’échantillon existant. Il peut être omis s’il n’est pas utilisé. Le second, <var>, est un nom de variable. La variable est recherchée, son contenu converti en chaîne, puis ajouté immédiatement après la partie <first>. Si la variable n’est pas trouvée, rien n’est ajouté. Il peut également être omis. Le troisième champ, <end>, est une chaîne constante ajoutée après la variable. Il peut aussi être omis. Ensemble, ces éléments permettent de concaténer des variables avec des délimiteurs à un ensemble existant de variables. Cela peut être utilisé pour créer de nouvelles variables à partir d’une succession d’autres variables, par exemple des valeurs séparées par des deux-points. Si des virgules ou des parenthèses fermantes sont nécessaires comme délimiteurs, elles doivent être protégées par des guillemets ou des barres obliques, elles-mêmes protégées afin de ne pas être supprimées par le parseur de premier niveau. Cela est souvent utilisé pour construire des variables composées à partir d’autres, mais parfois, l’utilisation d’une chaîne de format avec plusieurs champs peut être plus pratique. Voir les exemples ci-dessous.

Exemple :

tcp-request session set-var(sess.src) src
tcp-request session set-var(sess.dn)  ssl_c_s_dn
tcp-request session set-var(txn.sig) str(),concat(<ip=,sess.ip,>),concat(<dn=,sess.dn,>)
tcp-request session set-var(txn.ipport) "str(),concat('addr=(',sess.ip),concat(',',sess.port,')')"
tcp-request session set-var-fmt(txn.ipport) "addr=(%[sess.ip],%[sess.port])"  ## does the same
http-request set-header x-hap-sig %[var(txn.sig)]

cpl

cpl

Prend la valeur d’entrée de type entier signé, applique une complémentation à un (inverse tous les bits) et renvoie le résultat sous forme d’entier signé.

crc32([<avalanche>])

crc32([<avalanche>])

Hache une entrée binaire en une quantité non signée sur 32 bits en utilisant la fonction de hachage CRC32. Optionnellement, il est possible d’appliquer une fonction de hachage à avalanche complète à la sortie si l’argument facultatif <avalanche> vaut 1. Ce convertisseur utilise les mêmes fonctions que celles employées par les divers algorithmes de répartition de charge basés sur le hachage, il produira donc exactement les mêmes résultats. Il est fourni pour assurer la compatibilité avec d’autres logiciels qui souhaitent calculer un CRC32 à partir de certaines clés d’entrée, il suit donc l’implémentation la plus courante telle qu’elle se trouve dans Ethernet, Gzip, PNG, etc. Il est plus lent que les autres algorithmes, mais peut offrir une répartition meilleure ou du moins moins prévisible. Il ne doit pas être utilisé à des fins de sécurité, car un hachage sur 32 bits est facile à casser. Voir également « djb2 », « sdbm », « wt6 », « crc32c » et la directive « hash-type ».

crc32c([<avalanche>])

crc32c([<avalanche>])

Hache une entrée binaire en une quantité non signée sur 32 bits à l’aide de la fonction de hachage CRC32C. Optionnellement, il est possible d’appliquer une fonction de hachage à avalanche complète à la sortie si l’argument optionnel <avalanche> est égal à 1. Ce convertisseur utilise les mêmes fonctions décrites dans RFC4960, Annexe B [8]. Il est fourni pour assurer la compatibilité avec d’autres logiciels souhaitant calculer un CRC32C sur certaines clés d’entrée. Il est plus lent que les autres algorithmes et ne doit pas être utilisé à des fins de sécurité, car un hachage sur 32 bits est facile à casser. Voir également « djb2 », « sdbm », « wt6 », « crc32 » et la directive « hash-type ».

cut_crlf

cut_crlf

Découpe la représentation sous forme de chaîne d’entrée sur le premier caractère de retour chariot (’\r’) ou de saut de ligne (’\n’) trouvé. Seule la longueur de la chaîne est mise à jour.

da-csv-conv(<prop>[,<prop>*])

da-csv-conv(<prop>[,<prop>*])

Demande au convertisseur DeviceAtlas d’identifier la chaîne User Agent fournie en entrée, puis d’émettre une chaîne constituée de la concaténation des propriétés énumérées en argument, séparées par le séparateur défini par le mot-clé global « deviceatlas-property-separator », ou par défaut le caractère barre verticale (’|’). Une limite de 12 propriétés différentes est imposée par le langage de configuration HAProxy.

Exemple :

frontend www
  bind *:8881
  default_backend servers
  http-request set-header X-DeviceAtlas-Data %[req.fhdr(User-Agent),da-csv(primaryHardwareType,osName,osVersion,browserName,browserVersion,browserRenderingEngine)]

date

date

Ce convertisseur est utilisé pour convertir une date provenant d’un en-tête HTTP. Il peut s’agir d’une date IMF, d’une date ASCTIME ou d’une date RFC850. Il produira une horodatage UNIX.

Exemple :

http-request return lf-string "%[str('Sun, 06 Nov 1994 08:49:37 GMT'),date]\n" content-type text/plain

debug([<prefix][,<destination>])

debug([<prefix][,<destination>])

Ce convertisseur est utilisé comme outil de débogage. Il capture un échantillon d’entrée et l’envoie vers un réceptacle d’événements <destination>, qui peut désigner un tampon circulaire tel que “buf0”, ainsi que “stdout” ou “stderr”. Les réceptacles disponibles peuvent être vérifiés en temps réel en émettant la commande “show events” sur l’interface CLI. Lorsqu’aucun réceptacle n’est spécifié, la sortie par défaut est “buf0”, qui peut être consultée via la commande “show events” de l’interface CLI. Un préfixe optionnel <prefix> peut être fourni afin de distinguer les sorties provenant de plusieurs expressions. Il apparaîtra alors avant deux-points dans le message de sortie. L’échantillon d’entrée est transmis tel quel en sortie, ce qui permet de placer en toute sécurité le convertisseur de débogage n’importe où dans une chaîne, même avec des types d’échantillons non imprimables.

Exemple :

tcp-request connection track-sc0 src,debug(track-sc)

digest(<algorithm>)

digest(<algorithm>)

Convertit un échantillon d’entrée binaire en empreinte de message. Le résultat est un échantillon binaire. Le <algorithm> doit être un nom d’empreinte OpenSSL (par exemple, sha256).

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

div(<value>)

div(<value>)

Divise la valeur d’entrée de type entier signé par <value>, et retourne le résultat sous forme d’entier signé. Si <value> est nul, le plus grand entier non signé est retourné (généralement 2^63-1). <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 concernant les variables pour plus de détails.

djb2([<avalanche>])

djb2([<avalanche>])

Hache un échantillon d’entrée binaire en une quantité non signée sur 32 bits en utilisant la fonction de hachage DJB2. Optionnellement, il est possible d’appliquer une fonction de hachage à avalanche complète à la sortie si l’argument facultatif <avalanche> vaut 1. Ce convertisseur utilise les mêmes fonctions que celles employées par les divers algorithmes de répartition de charge basés sur le hachage, il produira donc exactement les mêmes résultats. Il est principalement destiné au débogage, mais peut être utilisé comme entrée de table de persistance pour collecter des statistiques brutes. Il ne doit pas être utilisé à des fins de sécurité, car un hachage sur 32 bits est facile à casser. Voir également « crc32 », « sdbm », « wt6 », « crc32c » et la directive « hash-type ».

eth.data

eth.data

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “2”. Il ignore l’en-tête Ethernet entier, y compris les VLAN éventuels, et renvoie un bloc de données binaires commençant au protocole de couche 3 (généralement IPv4 ou IPv6). Voir également “fc_saved_syn” et “tcp-ss”.

eth.dst

eth.dst

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “2”. Il renvoie les 6 octets de l’en-tête Ethernet correspondant à l’adresse de destination du cadre, sous forme de bloc binaire. Voir également “fc_saved_syn” et “tcp-ss”.

eth.hdr

eth.hdr

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “2”. Il supprime tout ce qui suit l’en-tête Ethernet tout en conservant éventuellement les VLAN, puis renvoie cet en-tête sous forme de bloc de données binaires. Voir également “fc_saved_syn” et “tcp-ss”.

eth.proto

eth.proto

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “2”. Il retourne le numéro de protocole (également appelé EtherType) trouvé dans un en-tête Ethernet après tout VLAN facultatif, sous forme de valeur entière. Il devrait normalement être soit 0x800 pour IPv4, soit 0x86DD pour IPv6. Voir également “fc_saved_syn” et “tcp-ss”.

eth.src

eth.src

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “2”. Il renvoie les 6 octets de l’en-tête Ethernet correspondant à l’adresse source du cadre, sous forme de bloc binaire. Voir également “fc_saved_syn” et “tcp-ss”.

eth.vlan

eth.vlan

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option bind “tcp-ss” définie sur “2”. Il retourne l’identifiant VLAN dernier trouvé dans un en-tête Ethernet sous forme de valeur entière. Voir également “fc_saved_syn” et “tcp-ss”.

even

even

Renvoie une valeur booléenne TRUE si la valeur d’entrée de type entier signé est paire, sinon renvoie FALSE. Elle est fonctionnellement équivalente à « not,and(1),bool ».

field(<index>,<delimiters>[,<count>])

field(<index>,<delimiters>[,<count>])

Extrait la sous-chaîne à l’indice donné, en comptant depuis le début (indice positif) ou depuis la fin (indice négatif), en tenant compte des délimiteurs spécifiés dans une chaîne d’entrée. Les indices commencent à 1 ou -1. Les délimiteurs sont une liste de caractères formatée sous forme de chaîne. Vous pouvez éventuellement préciser le nombre de champs à extraire (<count> par défaut : 1). Une valeur de 0 indique l’extraction de tous les champs restants.

Exemple :

str(f1_f2_f3__f5),field(4,_)    # <empty>
str(f1_f2_f3__f5),field(5,_)    # f5
str(f1_f2_f3__f5),field(2,_,0)  # f2_f3__f5
str(f1_f2_f3__f5),field(2,_,2)  # f2_f3
str(f1_f2_f3__f5),field(-2,_,3) # f2_f3_
str(f1_f2_f3__f5),field(-3,_,0) # f1_f2_f3

fe_exists

fe_exists

Prend un nom de frontal en valeur d’entrée et renvoie une valeur booléenne TRUE si un frontal portant ce nom existe dans la configuration actuelle, sinon renvoie FALSE. Peut être utilisé là où il est utile de vérifier l’existence d’un frontal à partir d’un nom dynamique, par exemple dans des recherches dans des cartes ou lors de réponses à une vérification externe.

Exemple :

http-request deny unless { var(txn.fe_name),fe_exists }

fix_is_valid

fix_is_valid

Analyse une charge utile binaire et effectue des vérifications de cohérence concernant FIX (Financial Information eXchange) :

  • vérifie que tous les identifiants et valeurs d’étiquettes sont non vides et que les identifiants d’étiquettes sont bien numériques
  • vérifie que l’étiquette BeginString est la première étiquette avec une version FIX valide
  • vérifie que l’étiquette BodyLength est la deuxième étiquette avec la longueur de corps correcte
  • vérifie que l’étiquette MsgType est la troisième étiquette
  • vérifie que la dernière étiquette du message est l’étiquette CheckSum avec un checksum valide

En raison de la conception actuelle d’HAProxy, seul le premier message envoyé par le client et par le serveur peut être analysé.

Ce convertisseur renvoie une valeur booléenne : true si le contenu contient un message FIX valide, false sinon.

Voir également le convertisseur fix_tag_value.

Exemple :

tcp-request inspect-delay 10s
tcp-request content reject unless { req.payload(0,0),fix_is_valid }

fix_tag_value(<tag>)

fix_tag_value(<tag>)

Analyse un message FIX (Financial Information eXchange) et extrait la valeur associée à l’étiquette <tag>. <tag> peut être une chaîne de caractères ou un entier indiquant l’étiquette souhaitée. Toute valeur entière est acceptée, mais seules les chaînes suivantes sont traduites en leur équivalent entier : BeginString, BodyLength, MsgType, SenderCompID, TargetCompID, CheckSum. D’autres noms d’étiquettes peuvent être facilement ajoutés.

En raison de la conception actuelle d’HAProxy, seul le premier message envoyé par le client et par le serveur peut être analysé. Aucune validation du message n’est effectuée par ce convertisseur. Il est fortement recommandé de valider le message en premier lieu à l’aide du convertisseur fix_is_valid.

Voir également le convertisseur fix_is_valid.

Exemple :

tcp-request inspect-delay 10s
tcp-request content reject unless { req.payload(0,0),fix_is_valid }
# MsgType tag ID is 35, so both lines below will return the same content
tcp-request content set-var(txn.foo) req.payload(0,0),fix_tag_value(35)
tcp-request content set-var(txn.bar) req.payload(0,0),fix_tag_value(MsgType)

has_ctl([mask])

has_ctl([mask])

Vérifie l’échantillon binaire d’entrée pour les caractères de contrôle définis par l’argument masque. Le masque est un nombre sur 33 bits (décimal ou hexadécimal préfixé par « 0x »), dont un bit est défini pour chaque caractère à détecter dans la plage 0x00 à 0x1F, et le bit 32 est défini pour correspondre au caractère DEL (0x7F). Lorsqu’aucun masque n’est spécifié, le convertisseur utilise la valeur 0x1FFFFFDFF, qui correspond à tous les caractères de contrôle sauf TAB (0x09), couramment utilisé dans les en-têtes HTTP. Le masque spécial « any » correspond à 0x1FFFFFFFF et correspond à tous les caractères de contrôle, y compris TAB. Le masque spécial « http » correspond à 0x2401 et ne détecte que les caractères de contrôle interdits dans les valeurs d’en-tête HTTP, à savoir CR (0x0D), LF (0x0A) et NUL (0x00).

Exemples :

# reject presence of DEL, CR, LF, NUL characters in the referer header
http-request deny if { req.fhdr(referer),has_ctl(0x100002401) }
# reject presence of any control char but tab in any HTTP header value
http-request deny if { req.hdr(),has_ctl }

hex

hex

Convertit un échantillon binaire en chaîne hexadécimale contenant deux chiffres hexadécimaux par octet d’entrée. Elle est utilisée pour journaliser ou transférer des dumps hexadécimaux de données binaires d’une manière pouvant être transférée de façon fiable (par exemple, un ID SSL peut être copié dans un en-tête).

hex2i

hex2i

Convertit une chaîne hexadécimale contenant deux chiffres hexadécimaux par octet d’entrée en entier. Si la valeur d’entrée ne peut pas être convertie, zéro est retourné.

hmac(<algorithm>,<key>)

hmac(<algorithm>,<key>)

Convertit un échantillon d’entrée binaire en code d’authentification de message à l’aide de la clé fournie. Le résultat est un échantillon binaire. Le paramètre <algorithm> doit être l’un des noms de hachage OpenSSL enregistrés (par exemple, sha256). Le paramètre <key> doit être encodé en base64 et peut être une chaîne ou une variable.

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

host_only

host_only

Convertit une chaîne contenant une valeur d’en-tête Host en supprimant son port. L’entrée doit respecter le format de la valeur d’en-tête Host (rfc9110#section-7.2). Elle prend en charge les entrées suivantes : hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.

Ce convertisseur met également la chaîne en minuscules.

Voir également : le convertisseur “port_only” qui retournera le port.

htonl

htonl

Convertit la valeur entière d’entrée en sa représentation binaire sur 32 bits, selon l’ordre des octets réseau. Comme l’extraction d’échantillon utilise un entier signé 64 bits, lorsque ce convertisseur est utilisé, la valeur entière d’entrée est d’abord convertie en entier non signé sur 32 bits.

http_date([<offset[,<unit>]])

http_date([<offset[,<unit>]])

Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date au format adapté à une utilisation dans des champs d’en-tête HTTP. Si une valeur de décalage est spécifiée, elle est ajoutée à la date avant la conversion. Cela est particulièrement utile pour émettre des champs d’en-tête Date, des valeurs Expires dans les réponses lorsqu’elles sont combinées avec un décalage positif, ou des valeurs Last-Modified lorsque le décalage est négatif. Si une unité est spécifiée, considérer l’horodatage comme étant en « s » pour secondes (comportement par défaut), « ms » pour millisecondes, ou « us » pour microsecondes depuis l’époque. Le décalage est supposé avoir la même unité que l’horodatage d’entrée.

iif(<true>,<false>)

iif(<true>,<false>)

Renvoie la chaîne <true> si la valeur d’entrée est true. Renvoie la chaîne <false> sinon.

Exemple :

http-request set-header x-forwarded-proto %[ssl_fc,iif(https,http)]

in_table([<table>])

in_table([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, une valeur booléenne false est renvoyée. Sinon, une valeur booléenne true est renvoyée. Cette fonction peut être utilisée pour vérifier la présence d’une clé spécifique dans une table suivant certains éléments (par exemple, si une adresse IP source ou un en-tête Authorization a déjà été vue).

ip.data

ip.data

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il ignore l’en-tête IP et toutes les options ou extensions facultatives, puis renvoie un bloc de données binaires commençant au niveau du protocole transport (généralement TCP ou UDP). Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ip.df

ip.df

Utilisé avec un échantillon d’entrée représentant un cadre Ethernet binaire, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Renvoie la valeur entière 1 si le drapeau DF (ne pas fragmenter) est défini dans l’en-tête IP, 0 sinon. IPv6 ne possède pas de drapeau DF et ne fragmente pas par défaut, aussi renvoie-t-il toujours 1. Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ip.dst

ip.dst

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il renvoie l’adresse de destination IPv4 ou IPv6 issue de l’en-tête IPv4/v6. Voir également “fc_saved_syn”, “tcp-ss” et “eth.data”.

ip.fp([<mode>])

ip.fp([<mode>])

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il examine diverses parties de l’en-tête IP et de l’en-tête TCP afin de construire une empreinte de parties invariantes pouvant être utilisées pour distinguer plusieurs hôtes apparemment identiques. Le cas d’utilisation réel consiste à affiner l’identification des hôtes défaillants partageant une même adresse IP, afin d’éviter de bloquer des utilisateurs légitimes lorsque seul un d’entre eux est défaillant et doit être bloqué. Le convertisseur construit un bloc binaire minimal de 8 octets à partir de l’entrée. Les octets de l’empreinte sont disposés comme suit : - octet 0 : champ IP TOS (voir ip.tos) - octet 1 : - bit 7 : IPv6 (1) / IPv4 (0) - bit 6 : ip.df - bit 5..4 : 0 : ip.ttl ≤ 32 ; 1 : ip.ttl ≤ 64 ; 2 : ip.ttl ≤ 128 ; 3 : ip.ttl ≤ 255 - bit 3 : options IP présentes (1) / absentes (0) - bit 2 : données TCP présentes (1) / absentes (0) - bit 1 : le bit CWR de TCP.flags est défini (1) / effacé (0) - bit 0 : le bit ECE de TCP.flags est défini (1) / effacé (0) - octet 2 : - bits 7..4 : longueur de l’en-tête TCP en mots de 4 octets - bits 3..0 : mise à l’échelle de la fenêtre TCP + 1 (1..15) / 0 (aucune mise à l’échelle annoncée) - octet 3..4 : tcp.win - octet 5..6 : tcp.options.mss, ou zéro si absent - octet 7 : 1 bit par option TCP présente, les options 2 à 8 étant mappées respectivement aux bits 0 à 6, et le bit 7 indiquant la présence d’une option quelconque comprise entre 9 et 255

L’argument <mode> permet d’ajouter des informations supplémentaires à l’empreinte. Par défaut, lorsque l’argument <mode> n’est pas défini ou vaut zéro, l’empreinte est constituée uniquement des 8 octets décrits ci-dessus. Si <mode> est spécifié avec une autre valeur, celle-ci correspond à la somme des valeurs suivantes, et les composants correspondants sont concaténés à l’empreinte, dans l’ordre ci-dessous : - 1 : la valeur TTL reçue est ajoutée à l’empreinte (1 octet) - 2 : la liste des types d’options TCP, telle qu’elle est retournée par “tcp.options_list”, comprenant de 0 à 40 octets supplémentaires, est ajoutée à l’empreinte - 4 : l’adresse IP source est ajoutée à l’empreinte, ce qui ajoute 4 octets pour IPv4 et 16 pour IPv6

Exemple : créer une empreinte de 13 à 25 octets en utilisant l’empreinte de base, le TTL et l’adresse source (1+4=5) :

frontend test
    mode http
    bind:4445 tcp-ss 1
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain lf-string &#92;
          "src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp(5),hex]&#92;n"

Voir également “fc_saved_syn”, « tcp-ss », “eth.data”, “ip.df”, “ip.ttl”, “tcp.win”, “tcp.options.mss” et “tcp.options_list”.

ip.hdr

ip.hdr

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il renvoie un bloc de données binaires commençant par l’en-tête IP et s’arrêtant après la dernière option ou extension, avant l’en-tête du protocole de transport. Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ip.proto

ip.proto

Cela est utilisé avec un échantillon d’entrée représentant un cadre Ethernet binaire, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il renvoie le numéro de protocole transport, généralement 6 pour TCP ou 17 pour UDP. Voir également “fc_saved_syn”, “tcp-ss” et “eth.data”.

ip.src

ip.src

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Il retourne l’adresse source IPv4 ou IPv6 à partir de l’en-tête IPv4/v6. Voir également “fc_saved_syn”, “tcp-ss” et “eth.data”.

ip.tos

ip.tos

Utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Renvoie un entier correspondant à la valeur du champ type de service (TOS) dans l’en-tête IPv4 ou du champ classe de trafic (TC) dans l’en-tête IPv6. Notez qu’Internet moderne, ce champ contient généralement une valeur DSCP (Codepoint de services différenciés) dans les 6 bits supérieurs, tandis que les deux bits inférieurs sont soit non utilisés, soit utilisés par l’ECN IP. Voir RFC2474 et RFC8436 pour les valeurs DSCP, et RFC3168 pour les champs ECN IP. Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ip.ttl

ip.ttl

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Cela renvoie un entier correspondant au champ TTL (Time To Live) ou HL (Hop Limit) dans l’en-tête IPv4/IPv6. Cette valeur est généralement prédéfinie à une valeur fixe et décrémentée à chaque routeur traversé par le paquet. Elle peut aider à estimer la distance entre un client et le serveur lorsque la valeur initiale est connue. Notez que la plupart des systèmes d’exploitation modernes partent d’une valeur initiale de 64. Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ip.ver

ip.ver

Cela est utilisé avec un échantillon d’entrée représentant un cadre binaire Ethernet, tel que renvoyé par “fc_saved_syn” combiné à l’option de liaison “tcp-ss” définie sur “1”, ou avec la sortie de “eth.data”. Cela renvoie la version IP présente dans l’en-tête IP, normalement 4 ou 6. Notez que cela ne vérifie pas si le numéro de protocole dans le cadre Ethernet supérieur correspond, mais comme il est attendu qu’il soit utilisé avec des paquets valides, on suppose que le système d’exploitation a déjà effectué cette vérification. Voir également “fc_saved_syn”, “tcp-ss”, et “eth.data”.

ipmask(<mask4>[,<mask6>])

ipmask(<mask4>[,<mask6>])

Applique un masque à une adresse IP, et utilise le résultat pour les recherches et le stockage. Cela permet de faire en sorte que tous les hôtes situés dans une plage définie par un masque partagent les mêmes entrées de table, et utilisent ainsi le même serveur. Le masque4 peut être fourni sous forme décimale pointée (par exemple 255.255.255.0) ou sous forme CIDR (par exemple 24). Le masque6 peut être fourni sous forme quadruplète (par exemple ffff:ffff::) ou sous forme CIDR (par exemple 64). Si aucun masque6 n’est fourni, les adresses IPv6 ne pourront pas être converties, pour des raisons de compatibilité descendante.

json([<input-code>])

json([<input-code>])

Échappe la chaîne d’entrée et produit une chaîne ASCII prête à être utilisée comme chaîne JSON. Le convertisseur tente de décoder la chaîne d’entrée selon le paramètre <input-code>. Celui-ci peut prendre les valeurs « ascii », « utf8 », « utf8s », « utf8p » ou « utf8ps ». Le décodeur « ascii » ne peut jamais échouer. Le décodeur « utf8 » détecte 3 types d’erreurs :

  • séquence UTF-8 non valide (octet de continuation isolé, nombre d’octets de continuation non valide, …)
  • plage non valide (la valeur décodée se trouve dans une plage interdite UTF-8),
  • code trop long (la valeur est encodée avec plus d’octets que nécessaire).

Le codage JSON UTF-8 peut produire une erreur « too long value » lorsque le caractère UTF-8 est supérieur à 0xffff, car la spécification d’échappement des chaînes JSON ne permet que 4 chiffres hexadécimaux pour le codage de la valeur. Le décodeur UTF-8 existe sous 4 variantes, identifiées par une combinaison de deux lettres de suffixe : « p » pour « permissif » et « s » pour « ignorer silencieusement ». Les comportements des décodeurs sont :

  • “ascii” : ne peut jamais échouer ;
  • “utf8” : échoue en cas de détection d’erreurs ;
  • “utf8s” : ne peut jamais échouer, mais supprime les caractères correspondant aux erreurs ;
  • “utf8p” : accepte et corrige les erreurs de surlongueur, mais échoue en cas d’autres erreurs ;
  • “utf8ps” : ne peut jamais échouer, accepte et corrige les erreurs de surlongueur, mais supprime les caractères correspondant aux autres erreurs.

Ce convertisseur est particulièrement utile pour créer un JSON correctement échappé destiné à la journalisation sur des serveurs qui consomment des journaux de trafic au format JSON.

Exemple :

capture request header Host len 15
capture request header user-agent len 150
log-format '{"ip":"%[src]","user-agent":"%[capture.req.hdr(1),json(utf8s)]"}'

Requête entrante du client 127.0.0.1 :

GET / HTTP/1.0
User-Agent: Very "Ugly" UA 1/2

Journal de sortie :

{"ip":"127.0.0.1","user-agent":"Very \"Ugly\" UA 1\/2"}

json_query(<json_path>[,<output_type>])

json_query(<json_path>[,<output_type>])

Le convertisseur json_query prend en charge les types JSON string, boolean, number et array. Les nombres à virgule flottante sont renvoyés sous forme de chaîne. En spécifiant le type de sortie ‘int’, la valeur est convertie en entier. Les tableaux sont renvoyés sous forme de chaîne, entourés de crochets. Le contenu est au format CSV. Selon le type de données, les valeurs du tableau peuvent être entre guillemets. Si les valeurs du tableau sont des types complexes, la chaîne contient la représentation JSON complète de chaque valeur, séparée par une virgule. Exemple de résultat pour une requête roles sur un JWT :

["manage-account","manage-account-links","view-profile"]

Si la conversion n’est pas possible, le convertisseur json_query échoue.

<json_path> doit être une chaîne de chemin JSON valide telle que définie dans https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/

Note : selon le contexte et l’implémentation sous-jacente, l’extraction des clés JSON en double est indéfinie et peut renvoyer la première, la dernière ou toute autre occurrence de la même clé provenant du contenu d’entrée ; si les noms de clés sont passés encodés, ils ne sont pas toujours correctement associés. En résumé, ce convertisseur n’est pas adapté à la purification de contenu.

Exemple :

# get a integer value from the request body
# "{"integer":4}" => 5
http-request set-var(txn.pay_int) req.body,json_query('$.integer','int'),add(1)

# get a key with '.' in the name
# {"my.key":"myvalue"} => myvalue
http-request set-var(txn.pay_mykey) req.body,json_query('$.my\\.key')

# {"boolean-false":false} => 0
http-request set-var(txn.pay_boolean_false) req.body,json_query('$.boolean-false')

# get the value of the key 'iss' from a JWT Bearer token
http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec,json_query('$.iss')

jwt_decrypt_cert(<cert>)

jwt_decrypt_cert(<cert>)

Effectue une validation de signature d’un jeton web JSON conforme au format JSON Web Encryption (voir RFC 7516), reçoit en entrée et renvoie son contenu déchiffré grâce au certificat fourni. Le paramètre <cert> doit être un chemin vers un certificat déjà chargé (pouvant être extrait via la commande CLI « dump ssl cert »). Le certificat doit avoir son option « jwt » explicitement définie sur « on » (voir l’option « jwt » de crt-list). Il peut être fourni directement ou via une variable. Les seuls jetons pris en charge pour l’instant sont ceux utilisant la sérialisation compacte (cinq chaînes encodées en base64-url séparées par un point).

Ce convertisseur peut être utilisé pour les jetons ayant un algorithme (“alg” du champ d’en-tête JOSE) parmi les suivants : RSA-OAEP, RSA-OAEP-256, ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW ou ECDH-ES+A256KW. L’algorithme RSA1_5 est implémenté mais désactivé par défaut, conformément aux recommandations de la section 3.2 de la RFC 8725. Il peut être réactivé si nécessaire grâce à l’option globale ‘jwt.decrypt_alg_list’.

Les algorithmes pris en charge et les algorithmes de chiffrement (“alg” et “enc” dans l’en-tête JOSE respectivement) peuvent être modifiés grâce aux options globales ‘jwt.decrypt_alg_list’ et ‘jwt.decrypt_enc_list’.

Le jeton JWE doit être fourni encodé en base64url, et la sortie sera fournie « brute ». En cas d’erreur lors de l’analyse du jeton, de la vérification de la signature ou du déchiffrement du contenu, une chaîne vide sera renvoyée.

Exemple :

# Get a JWT from the authorization header, put its decrypted content in an
# HTTP header
http-request set-var(txn.bearer) http_auth_bearer
http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_cert("/foo/bar.pem")]

jwt_decrypt_jwk(<jwk>)

jwt_decrypt_jwk(<jwk>)

Effectue une validation de signature d’un jeton web JSON selon le format JSON Web Encryption (voir RFC 7516), fourni en entrée, et retourne son contenu déchiffré grâce à la clé web JSON fournie (RFC7517). Le paramètre <jwk> doit être une JWK valide de type « oct », « EC » ou « RSA » (champ « kty » de la clé JSON) pouvant être fournie soit sous forme de chaîne, soit via une variable.

Les seuls jetons gérés pour l’instant sont ceux utilisant le format de sérialisation Compact (cinq chaînes encodées en base64-url séparées par des points).

Ce convertisseur peut être utilisé pour décoder un jeton ayant un algorithme de type symétrique (champ « alg » de l’en-tête JOSE) parmi les suivants : A128KW, A192KW, A256KW, A128GCMKW, A192GCMKW, A256GCMKW, dir. Dans ce cas, on s’attend à ce que la JWK fournie soit de type « oct ».

Ce convertisseur gère également les jetons dont l’algorithme (champ “alg” de l’en-tête JOSE) appartient à la famille RSA (RSA-OAEP ou RSA-OAEP-256) lorsqu’une JWK ‘RSA’ est fournie, ou à la famille ECDH (ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A192KW ou ECDH-ES+A256KW) lorsqu’une JWK ‘EC’ est fournie. L’algorithme RSA1_5 est implémenté, mais désactivé par défaut conformément à la section 3.2 de RFC 8725. Il peut être réactivé si nécessaire grâce à l’option globale ‘jwt.decrypt_alg_list’.

Veuillez noter que les algorithmes A128KW et A192KW ne sont pas disponibles sur AWS-LC, les algorithmes A128KW, A192KW, ECDH-ES+A128KW et ECDH-ES+A192KW ne fonctionneront donc pas.

Les algorithmes pris en charge et les algorithmes de chiffrement (“alg” et “enc” dans l’en-tête JOSE respectivement) peuvent être modifiés grâce aux options globales ‘jwt.decrypt_alg_list’ et ‘jwt.decrypt_enc_list’.

Le jeton JWE doit être fourni encodé en base64url, et la sortie sera fournie « brute ». En cas d’erreur lors de l’analyse du jeton, de la vérification de la signature ou du déchiffrement du contenu, une chaîne vide sera renvoyée.

En raison de la manière dont les guillemets, les virgules et les guillemets doubles sont traités dans la configuration, le contenu de la JWK doit être correctement échappé pour que ce convertisseur fonctionne correctement (voir section 2.2 pour plus d’informations).

Exemple :

 # Get a JWT from the authorization header, put its decrypted content in an
 # HTTP header
 http-request set-var(txn.bearer) http_auth_bearer
 http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_jwk(\'{\"kty\":\"oct\",\"k\":\"wAsgsg\"}\')

# or via a variable
 http-request set-var(txn.bearer) http_auth_bearer
 http-request set-var(txn.jwk) str(\'{\"kty\":\"oct\",\"k\":\"Q-NFLlghQ\"}\')
 http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_jwk(txn.jwk)

jwt_decrypt_secret(<secret>)

jwt_decrypt_secret(<secret>)

Effectue une validation de signature d’un jeton web JSON conforme au format JSON Web Encryption (voir RFC 7516), reçoit en entrée et renvoie son contenu déchiffré grâce à la clé secrète encodée en base64 fournie. La clé secrète peut être fournie sous forme de chaîne ou via une variable. Seuls les jetons utilisant le format de sérialisation compacte sont actuellement pris en charge (cinq chaînes encodées en base64-url séparées par des points).

Ce convertisseur peut être utilisé pour les jetons ayant un algorithme (“alg” du champ d’en-tête JOSE) parmi les suivants : A128KW, A192KW, A256KW, A128GCMKW, A192GCMKW, A256GCMKW, dir. Veuillez noter que les algorithmes A128KW et A192KW ne sont pas disponibles sur AWS-LC et que le déchiffrement ne fonctionnera pas.

Le jeton JWE doit être fourni encodé en base64url, et la sortie sera fournie « brute ». En cas d’erreur lors de l’analyse du jeton, de la vérification de la signature ou du déchiffrement du contenu, une chaîne vide sera renvoyée.

Exemple :

# Get a JWT from the authorization header, put its decrypted content in an
# HTTP header
http-request set-var(txn.bearer) http_auth_bearer
http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_secret("GawgguFyGrWKav7AX4VKUg")]

jwt_header_query([<json_path>[,<output_type>]])

jwt_header_query([<json_path>[,<output_type>]])

Lorsqu’un jeton Web JSON (JWT) est fourni en entrée, renvoie soit la partie en-tête décodée du jeton (le premier segment encodé en base64-url du JWT) si aucun paramètre n’est fourni, soit effectue une requête json_query sur la partie en-tête décodée du jeton. Pour plus de détails sur les paramètres json_path et output_type pris en charge, reportez-vous au convertisseur “json_query”. Ce convertisseur peut être utilisé avec des jetons JWS ou JWE, à condition qu’ils soient au format de sérialisation compacte.

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

jwt_payload_query([<json_path>[,<output_type>]])

jwt_payload_query([<json_path>[,<output_type>]])

Lorsqu’un jeton JWT au format JWS lui est fourni en entrée, renvoie soit la partie charge utile décodée du jeton (la deuxième partie encodée en base64-url du JWT) si aucun paramètre n’est fourni, soit effectue une requête json_query sur la partie charge utile décodée du jeton. Pour plus de détails sur les paramètres json_path et output_type pris en charge, consulter le convertisseur “json_query”.

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

jwt_verify(<alg>,<key>)

Effectue une vérification de signature pour le jeton JWT (JSON Web Token) fourni en entrée en utilisant l’algorithme <alg> et le paramètre <key>. Pour l’instant, seuls les jetons JWS utilisant le format de sérialisation compacte peuvent être traités (trois chaînes encodées en base64-url séparées par des points). Ce convertisseur ne vérifie que la signature du jeton et n’effectue pas une validation complète du JWT telle que spécifiée dans la section 7.2 de de RFC7519. Nous ne garantissons pas que les contenus de l’en-tête et du chargement utile soient des JSON complets une fois décodés, par exemple, et aucune vérification n’est effectuée concernant leurs contenus respectifs.

  • <alg> peut être une chaîne de caractères ou un nom de variable (voir également « set-var ») qui contient le nom de l’algorithme utilisé pour la vérification.

Les algorithmes mentionnés dans la section 3.1 de RFC7518 sont gérés :

   +--------------+---------------------------------------------------------+
   | "alg" Param  | Digital Signature or MAC Algorithm                      |
   | Value        |                                                         |
   +--------------+---------------------------------------------------------+
   | HS256        | HMAC using SHA-256                                      |
   | HS384        | HMAC using SHA-384                                      |
   | HS512        | HMAC using SHA-512                                      |
   | RS256        | RSASSA-PKCS1-v1_5 using SHA-256                         |
   | RS384        | RSASSA-PKCS1-v1_5 using SHA-384                         |
   | RS512        | RSASSA-PKCS1-v1_5 using SHA-512                         |
   | ES256        | ECDSA using P-256 and SHA-256                           |
   | ES384        | ECDSA using P-384 and SHA-384                           |
   | ES512        | ECDSA using P-521 and SHA-512                           |
   | PS256        | RSASSA-PSS using SHA-256 and MGF1 with SHA-256          |
   | PS384        | RSASSA-PSS using SHA-384 and MGF1 with SHA-384          |
   | PS512        | RSASSA-PSS using SHA-512 and MGF1 with SHA-512          |
   | none         | No digital signature or MAC performed                   |
   +--------------+---------------------------------------------------------+
  • <key> peut être une chaîne de caractères ou un nom de variable (voir également « set-var ») qui contient un secret ou un chemin vers une clé publique.

Les secrets ne sont applicables que lors de l’utilisation d’algorithmes HMAC.

Les clés publiques doivent être au format PKCS#1 (pour les clés RSA, commençant par BEGIN RSA PUBLIC KEY) ou au format SPKI (Subject Public Key Info, commençant par BEGIN PUBLIC KEY). Les clés publiques doivent être disponibles pendant l’analyse de la configuration et ne peuvent pas être mises à jour ou chargées en temps réel. Voir le convertisseur “jwt_verify_cert” pour la validation des jetons JWT basée sur des certificats PEM complets.

Toutes les clés publiques pouvant être utilisées pour vérifier les JWT doivent être connues lors de l’initialisation afin d’être ajoutées à une mémoire tampon dédiée, afin d’éviter tout accès au disque pendant l’exécution.

Renvoie 1 en cas de vérification réussie, 0 en cas d’échec de vérification et une valeur strictement négative pour toute autre erreur. En raison de toutes ces valeurs de retour non nulles, le résultat de ce convertisseur ne doit jamais être converti en booléen. Consultez ci-dessous la liste complète des valeurs de retour possibles.

Les valeurs de retour possibles sont les suivantes :

  +----+----------------------------------------------------------------------+
  | ID | message                                                              |
  +----+----------------------------------------------------------------------+
  |  1 | "Verification success"                                               |
  |  0 | "Verification failure"                                               |
  | -1 | "Unknown algorithm (not mentioned in RFC7518)"                       |
  | -2 | "Unmanaged algorithm"                                                |
  | -3 | "Invalid token"                                                      |
  | -4 | "Out of memory"                                                      |
  | -5 | "Unknown pubkey/certificate"                                         |
  | -6 | "Internal error"                                                     |
  +----+----------------------------------------------------------------------+

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

Exemple :

# Get a JWT from the authorization header, extract the "alg" field of its
# JOSE header and use a public key to verify a signature
http-request set-var(txn.bearer) http_auth_bearer
http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg')
http-request deny unless { var(txn.jwt_alg) -m str "RS256" }
http-request deny unless { var(txn.bearer),jwt_verify(txn.jwt_alg,"/path/to/pubkey.pem") 1 }

jwt_verify_cert(<alg>,<cert>)

Effectue une vérification de signature pour le jeton JSON Web (JWT) fourni en entrée en utilisant l’algorithme <alg> et le paramètre <cert>. Pour l’instant, seuls les jetons JWS utilisant la sérialisation compacte peuvent être traités (trois chaînes encodées en base64-url séparées par des points). Ce convertisseur ne vérifie que la signature du jeton et ne réalise pas une validation complète du JWT telle qu’elle est spécifiée dans la section 7.2 de de RFC7519. Nous ne garantissons pas que les contenus de l’en-tête et du chargement utile soient des JSON complets une fois décodés, ni qu’aucune vérification ne soit effectuée sur leurs contenus respectifs.

  • <alg> peut être une chaîne ou un nom de variable (voir également « set-var ») qui contient le nom de l’algorithme utilisé pour la vérification. Contrairement au convertisseur “jwt_verify”, ce convertisseur n’attend qu’un certificat en deuxième paramètre, il ne doit donc pas être utilisé pour les jetons utilisant des algorithmes HMAC.

Les algorithmes mentionnés dans la section 3.1 de RFC7518 sont gérés (à l’exception des algorithmes HMAC) :

   +--------------+---------------------------------------------------------+
   | "alg" Param  | Digital Signature or MAC Algorithm                      |
   | Value        |                                                         |
   +--------------+---------------------------------------------------------+
   | RS256        | RSASSA-PKCS1-v1_5 using SHA-256                         |
   | RS384        | RSASSA-PKCS1-v1_5 using SHA-384                         |
   | RS512        | RSASSA-PKCS1-v1_5 using SHA-512                         |
   | ES256        | ECDSA using P-256 and SHA-256                           |
   | ES384        | ECDSA using P-384 and SHA-384                           |
   | ES512        | ECDSA using P-521 and SHA-512                           |
   | PS256        | RSASSA-PSS using SHA-256 and MGF1 with SHA-256          |
   | PS384        | RSASSA-PSS using SHA-384 and MGF1 with SHA-384          |
   | PS512        | RSASSA-PSS using SHA-512 and MGF1 with SHA-512          |
   | none         | No digital signature or MAC performed                   |
   +--------------+---------------------------------------------------------+
  • <key> peut être une chaîne de caractères ou un nom de variable (voir également « set-var ») qui contient le chemin d’un certificat.

Les certificats doivent être des certificats PEM standards (commençant par BEGIN CERTIFICATE). Leur chemin peut être passé directement au convertisseur ou référencé via une variable. Si une variable est utilisée, les certificats correspondants peuvent être déclarés dans un crt-store ou chargés dynamiquement via le socket stats. Lorsqu’un chemin est fourni directement, si le certificat correspondant n’a pas encore été chargé dans le magasin de certificats interne, il sera chargé pendant l’analyse de la configuration et doit donc déjà exister, sinon une erreur sera levée.

Seules les certificats explicitement définis comme utilisables pour la validation JWT peuvent être utilisés. Voir l’option « jwt » crt-store.

Il est possible de mettre à jour les certificats de manière dynamique et d’ajouter de nouveaux certificats à l’aide de la socket de statistiques. Voir également « set ssl cert » et « new ssl cert » dans le guide d’administration.

Renvoie 1 en cas de vérification réussie, 0 en cas d’échec de vérification et une valeur strictement négative pour toute autre erreur. En raison de toutes ces valeurs de retour non nulles, le résultat de ce convertisseur ne doit jamais être converti en booléen. Consultez ci-dessous la liste complète des valeurs de retour possibles.

Les valeurs de retour possibles sont les suivantes :

  +----+----------------------------------------------------------------------+
  | ID | message                                                              |
  +----+----------------------------------------------------------------------+
  |  1 | "Verification success"                                               |
  |  0 | "Verification failure"                                               |
  | -1 | "Unknown algorithm (not mentioned in RFC7518)"                       |
  | -2 | "Unmanaged algorithm"                                                |
  | -3 | "Invalid token"                                                      |
  | -4 | "Out of memory"                                                      |
  | -5 | "Unknown pubkey/certificate"                                         |
  | -6 | "Internal error"                                                     |
  | -7 | "Unavailable certificate" (see "jwt")                                |
  +----+----------------------------------------------------------------------+

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

Exemple :

# Get a JWT from the authorization header, extract the "alg" field of its
# JOSE header and use a public certificate to verify a signature
http-request set-var(txn.bearer) http_auth_bearer
http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg')
http-request deny unless { var(txn.jwt_alg) -m str "RS256" }
http-request deny unless { var(txn.bearer),jwt_verify_cert(txn.jwt_alg,"/path/to/cert.pem") 1 }

language(<value>[,<default>])

language(<value>[,<default>])

Retourne la valeur ayant le facteur q le plus élevé à partir d’une liste extraite de l’en-tête « accept-language » en utilisant “req.fhdr”. Les valeurs sans facteur q ont un facteur q de 1. Les valeurs ayant un facteur q de 0 sont supprimées. Seules les valeurs appartenant à la liste séparée par des points-virgules <values> sont prises en compte. La syntaxe de l’argument <value> est « lang[;lang[;lang[;…]]] ». Si aucune valeur ne correspond à la liste fournie et qu’une valeur par défaut est fournie, celle-ci est retournée. Notez que les noms de langue peuvent comporter une variante après un trait d’union (’-’). Si cette variante figure dans la liste, elle sera prise en compte, mais si elle n’est pas présente, seule la langue de base est vérifiée. La correspondance est sensible à la casse, et la chaîne de sortie est toujours l’une des chaînes fournies en argument. L’ordre des arguments est sans importance, seul l’ordre des valeurs dans la requête compte, la première valeur parmi celles ayant le même facteur q étant utilisée.

Exemple :

# this configuration switches to the backend matching a
# given language based on the request:

acl es req.fhdr(accept-language),language(es;fr;en) -m str es
acl fr req.fhdr(accept-language),language(es;fr;en) -m str fr
acl en req.fhdr(accept-language),language(es;fr;en) -m str en
use_backend spanish if es
use_backend french  if fr
use_backend english if en
default_backend choose_your_language

length

length

Obtient la longueur de la chaîne. Cette instruction ne peut être utilisée qu’après une fonction d’extraction d’échantillon de chaîne ou après un mot-clé de transformation retournant un type chaîne. Le résultat est de type entier.

lower

lower

Convertit une chaîne d’échantillon en minuscules. Cette instruction ne peut être utilisée qu’après une fonction d’extraction d’échantillon de chaîne ou après un mot-clé de transformation retournant un type chaîne. Le résultat est de type chaîne.

ltime(<format>[,<offset>])

ltime(<format>[,<offset>])

Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure locale, selon un format défini par la chaîne <format> en utilisant strftime(3). Le but est de permettre l’utilisation de tout format de date dans les journaux. Un décalage optionnel <offset> en secondes peut être appliqué à la date d’entrée (positif ou négatif). Consultez la page man strftime() pour connaître les formats pris en charge par votre système d’exploitation. Voir également le convertisseur utime.

Exemple :

# Emit two colons, one with the local time and another with ip:port
# e.g.  20140710162350 127.0.0.1:57325
log-format %[date,ltime(%Y%m%d%H%M%S)]\ %ci:%cp

ltrim(<chars>)

ltrim(<chars>)

Ignore tout caractère de <chars> au début de la représentation sous forme de chaîne d’entrée.

map(<map_name>[,<default_value>])

map(<map_name>[,<default_value>])
map_<match_type>(<map_name>[,<default_value>])
map_<match_type>_<output_type>(<map_name>[,<default_value>])

Rechercher la valeur d’entrée à partir de <map_name> en utilisant la méthode de correspondance <match_type>, puis retourner la valeur associée convertie dans le type <output_type>. Si la valeur d’entrée ne peut pas être trouvée dans <map_name>, le convertisseur retourne <default_value>. Si <default_value> n’est pas défini, le convertisseur échoue et se comporte comme s’aucune valeur d’entrée n’avait pu être récupérée. Si <match_type> n’est pas défini, sa valeur par défaut est « str ». De même, si <output_type> n’est pas défini, sa valeur par défaut est « str ». Pour plus de commodité, le mot-clé « map » est un alias de “map_str” et permet de mapper une chaîne vers une autre chaîne. <map_name> doit suivre le format décrit en 2.7 concernant le format des noms pour les cartes et les listes de contrôle d’accès.

Il est important d’éviter les chevauchements entre les clés : les adresses IP et les chaînes sont stockées dans des arbres, donc la première correspondance la plus précise sera utilisée. Les autres clés sont stockées dans des listes, donc la première occurrence correspondante sera utilisée.

Le tableau suivant contient la liste de toutes les fonctions de mappage disponibles, triées par type d’entrée, type de correspondance et type de sortie.

  input type | match method | output type str | output type int | output type ip | output type key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | str          | map_str         | map_str_int     | map_str_ip     | map_str_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | beg          | map_beg         | map_beg_int     | map_end_ip     | map_end_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | sub          | map_sub         | map_sub_int     | map_sub_ip     | map_sub_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | dir          | map_dir         | map_dir_int     | map_dir_ip     | map_dir_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | dom          | map_dom         | map_dom_int     | map_dom_ip     | map_dom_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | end          | map_end         | map_end_int     | map_end_ip     | map_end_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | reg          | map_reg         | map_reg_int     | map_reg_ip     | map_reg_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | reg          | map_regm        | map_reg_int     | map_reg_ip     | map_reg_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    int      | int          | map_int         | map_int_int     | map_int_ip     | map_int_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    ip       | ip           | map_ip          | map_ip_int      | map_ip_ip      | map_ip_key
  -----------+--------------+-----------------+-----------------+----------------+----------------

La carte spéciale appelée “map_regm” attend une zone correspondante dans l’expression régulière et modifie la sortie en remplaçant la référence arrière (comme “\1”) par le texte correspondant à la correspondance.

Le type de sortie « key » signifie que la clé de l’entrée correspondante (telle qu’elle apparaît dans le fichier de carte) sera renvoyée sous forme de chaîne de caractères au lieu de la valeur. Notez que l’argument optionnel <default_value> n’est pas pris en charge lorsque le type de sortie « key » est utilisé.

Les fichiers référencés par <map_name> contiennent une paire clé+valeur par ligne. Les lignes commençant par ‘#’ sont ignorées, tout comme les lignes vides. Les tabulations et espaces en début de ligne sont supprimés. La clé correspond alors au premier « mot » (suite de caractères non-space/tabs), et la valeur est ce qui suit cette suite de caractères space/tab jusqu’à la fin de la ligne, en excluant les spaces/tabs. en fin de ligne.

Exemple :

     # this is a comment and is ignored
        2.22.246.0/23    United Kingdom      \n
     <-><-----------><--><------------><---->
      |       |       |         |        `- trailing spaces ignored
      |       |       |         `---------- value
      |       |       `-------------------- middle spaces ignored
      |       `---------------------------- key
      `------------------------------------ leading spaces ignored

mod(<value>)

mod(<value>)

Divise la valeur d’entrée de type entier signé par <value>, et retourne le reste sous forme d’entier signé. Si <value> est nul, alors zéro est retourné. <value> peut être une valeur numérique ou un nom de variable. Voir section 2.8 à propos des variables pour plus de détails.

mqtt_field_value(<packettype>,<fieldname_or_property_ID>)

mqtt_field_value(<packettype>,<fieldname_or_property_ID>)

Valeur renvoyée par <fieldname> trouvée dans le charge utile MQTT d’entrée de type <packettype>. <packettype> peut être soit une chaîne (correspondance insensible à la casse), soit une valeur numérique correspondant au type de paquet dont les données doivent être extraites. Les chaînes et entiers pris en charge figurent ici : https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022

<fieldname> dépend de <packettype> et peut prendre l’une des valeurs suivantes. (Notez que la correspondance <fieldname> est insensible à la casse.) <property id> ne peut être trouvée que dans les flux MQTT v5.0. Vérifiez ce tableau : https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901029

  • CONNECT (ou 1) : drapeaux, nom_protocole, version_protocole, identifiant_client, sujet_annonce, charge_utile_annonce, nom_utilisateur, mot_de_passe, intervalle_heartbeat OU tout identifiant_de_propriété sous forme de valeur numérique (uniquement pour les paquets MQTT v5.0) :
17: Session Expiry Interval
33: Receive Maximum
39: Maximum Packet Size
34: Topic Alias Maximum
25: Request Response Information
23: Request Problem Information
21: Authentication Method
22: Authentication Data
18: Will Delay Interval
 1: Payload Format Indicator
 2: Message Expiry Interval
 3: Content Type
 8: Response Topic
 9: Correlation Data

Non pris en charge pour l’instant :

38: User Property
  • CONNACK (ou 2) : drapeaux, version_protocole, code_raison OU tout identifiant de propriété sous forme de valeur numérique (uniquement pour les paquets MQTT v5.0) :
17: Session Expiry Interval
33: Receive Maximum
36: Maximum QoS
37: Retain Available
39: Maximum Packet Size
18: Assigned Client Identifier
34: Topic Alias Maximum
31: Reason String
40; Wildcard Subscription Available
41: Subscription Identifiers Available
42: Shared Subscription Available
19: Server Keep Alive
26: Response Information
28: Server Reference
21: Authentication Method
22: Authentication Data

Non pris en charge pour l’instant :

38: User Property

En raison de la conception actuelle d’HAProxy, seul le premier message envoyé par le client et le serveur peut être analysé. Ce convertisseur ne peut donc extraire des données que des types de paquets CONNECT et CONNACK. CONNECT est le premier message envoyé par le client, et CONNACK est la première réponse envoyée par le serveur.

Exemple :

acl data_in_buffer req.len ge 4
tcp-request content set-var(txn.username) \
        req.payload(0,0),mqtt_field_value(connect,protocol_name) \
        if data_in_buffer
# do the same as above
tcp-request content set-var(txn.username) \
        req.payload(0,0),mqtt_field_value(1,protocol_name) \
        if data_in_buffer

mqtt_is_valid

mqtt_is_valid

Vérifie que l’entrée binaire est un paquet MQTT valide. Retourne une valeur booléenne.

En raison de la conception actuelle d’HAProxy, seul le premier message envoyé par le client et le serveur peut être analysé. Ce convertisseur ne peut donc extraire des données que des types de paquets CONNECT et CONNACK. CONNECT est le premier message envoyé par le client, et CONNACK est la première réponse envoyée par le serveur.

Seuls MQTT 3.1, 3.1.1 et 5.0 sont pris en charge.

Exemple :

acl data_in_buffer req.len ge 4
tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }

ms_ltime(<format>[,<offset>])

ms_ltime(<format>[,<offset>])

Cela fonctionne comme « ltime » mais prend en entrée une valeur en millisecondes. Il prend également en charge le spécificateur de conversion %N inspiré de date(1). Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure locale, selon un format défini par la chaîne <format> en utilisant strftime(3). L’objectif est de permettre l’utilisation de tout format de date dans les journaux. Une valeur optionnelle <offset> en millisecondes peut être appliquée à la date d’entrée (positive ou négative). Consultez la page de manuel de strftime() pour connaître les formats pris en charge par votre système d’exploitation.

Le spécificateur de conversion %N permet de sortir la partie nanosecondes de la date, la précision étant limitée car l’entrée est en millisecondes. (000000000..999000000). %N peut prendre un argument de largeur entre % et N. Il est utile pour afficher les millisecondes (%3N) ou les microsecondes (%6N). La largeur par défaut et maximale est 9 (%N = %9N).

Voir également le convertisseur utime pour UTC ainsi que les convertisseurs “ltime” et “us_ltime”.

Exemple :

# Emit 3 colons, the local time, the timezone and another with ip:port
# e.g. 2023/07/24/11:53:02.196 +0200 127.0.0.1:41530
log-format %[accept_date(ms),ms_ltime("%Y/%m/%d/%H:%M:%S.%3N %z")]\ %ci:%cp

ms_utime(<format>[,<offset>])

ms_utime(<format>[,<offset>])

Cela fonctionne comme « utime » mais prend une entrée en millisecondes. Il prend également en charge le spécificateur de conversion %N inspiré de date(1). Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure UTC, selon un format défini par la chaîne <format> en utilisant strftime(3). Le but est de permettre l’utilisation de tout format de date dans les journaux. Un <offset> facultatif en millisecondes peut être appliqué à la date d’entrée (positif ou négatif). Consultez la page man strftime() pour connaître les formats pris en charge par votre système d’exploitation.

Le spécificateur de conversion %N permet de sortir la partie nanosecondes de la date, la précision étant limitée car l’entrée est en millisecondes. (000000000..999000000). %N peut prendre un argument de largeur entre % et N. Il est utile pour afficher les millisecondes (%3N) ou les microsecondes (%6N). La largeur par défaut et maximale est 9 (%N = %9N).

Voir également le convertisseur ltime pour les conversions locales ainsi que les convertisseurs utime et “us_utime”.

Exemple :

# Emit 3 colons, the UTC time, the timezone and another with ip:port
# e.g. 2023/07/24/09:53:02.196 +0000 127.0.0.1:41530
log-format %[accept_date(ms),ms_utime("%Y/%m/%d/%H:%M:%S.%3N %z")]\ %ci:%cp

mul(<value>)

mul(<value>)

Multiplie la valeur d’entrée de type entier signé par <value>, et retourne le produit sous forme d’entier signé. En cas de dépassement, la plus grande valeur possible pour le signe est retournée afin que l’opération ne provoque pas de dépassement. <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 pour plus de détails sur les variables.

nbsrv

nbsrv

Prend une valeur d’entrée de type chaîne, l’interprète comme un nom de backend et renvoie le nombre de serveurs utilisables dans ce backend. Peut être utilisé là où l’on souhaite rechercher un backend à partir d’un nom dynamique, comme le résultat d’une recherche dans une table.

neg

neg

Prend la valeur d’entrée de type entier signé, calcule sa valeur opposée, et renvoie le reste sous forme d’entier signé. La valeur 0 est l’identité. Cet opérateur est fourni pour les soustractions inversées : afin de soustraire l’entrée d’une constante, il suffit d’effectuer une opération « neg,add(valeur) ».

not

not

Renvoie une valeur booléenne FALSE si la valeur d’entrée de type entier signé est non nulle, sinon renvoie TRUE. Utilisé en conjonction avec and(), il peut servir à signaler true/false pour le test de bits sur les valeurs d’entrée (par exemple, vérifier l’absence d’un drapeau).

odd

odd

Renvoie une valeur booléenne TRUE si la valeur d’entrée de type entier signé est impaire, sinon renvoie FALSE. Elle est fonctionnellement équivalente à « and(1),bool ».

or(<value>)

or(<value>)

Effectue un opérateur “OU” bit à bit entre <value> et la valeur d’entrée de type entier signé, puis retourne le résultat sous forme d’entier signé. <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 sur les variables pour plus de détails.

param(<name>[,<delim>])

param(<name>[,<delim>])

Cela extrait la première occurrence du paramètre <name> dans la chaîne d’entrée, où les paramètres sont délimités par <delim>, qui vaut par défaut “&”, et le nom et la valeur du paramètre sont séparés par un “=”. Si aucun “=” ni valeur n’est présent avant la fin du segment de paramètre, celui-ci est traité comme ayant une valeur vide.

Cela peut être utile pour extraire des paramètres à partir d’une chaîne de requête, ou éventuellement d’un corps x-www-form-urlencoded. En particulier, query,param(<name>) peut être utilisé comme alternative à urlp(<name>), qui n’utilise que le caractère “&” comme délimiteur, tandis que “urlp” utilise également “?” et “;”.

Notez que ce convertisseur ne traite pas spécialement les caractères encodés dans l’URL. Si vous souhaitez décoder la valeur, vous pouvez utiliser le convertisseur url_dec sur la sortie. Si le nom du paramètre en entrée peut contenir des caractères encodés, vous devriez probablement normaliser l’entrée avant d’appeler “param”. Cela peut être réalisé à l’aide de “http-request normalize-uri”, en particulier avec les options percent-decode-unreserved et percent-to-uppercase.

Exemple :

str(a=b&c=d&a=r),param(a)   # b
str(a&b=c),param(a)         # ""
str(a=&b&c=a),param(b)      # ""
str(a=1;b=2;c=4),param(b,;) # 2
query,param(redirect_uri),urldec()

port_only

port_only

Convertit une chaîne contenant une valeur d’en-tête Host en entier en renvoyant son port. L’entrée doit respecter le format de la valeur d’en-tête Host (rfc9110#section-7.2). Elle prend en charge les entrées suivantes : hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.

Si aucun port n’est fourni dans l’entrée, la valeur renvoyée sera 0.

Voir également : le convertisseur “host_only” qui retournera l’hôte.

protobuf(<field_number>[,<field_type>])

protobuf(<field_number>[,<field_type>])

Cela extrait le champ de message Protocol Buffers en mode brut à partir d’une représentation binaire d’entrée d’un message Protocol Buffers, avec <field_number> comme numéro de champ (notation pointée). Si <field_type> est absent, l’extraction se fait sous forme d’un échantillon entier ; sinon, elle se fait selon le type du champ (voir également “ungrpc” ci-dessous). La liste des types autorisés est la suivante : « int32 », « int64 », « uint32 », « uint64 », « sint32 », « sint64 », « bool », « enum » pour le type de filaire « varint » (type 0), « fixed64 », « sfixed64 », « double » pour le type de filaire 64 bits (type 1), « fixed32 », « sfixed32 », « float » pour le type de filaire 5. Notez que « string » est considéré comme un type délimité par longueur, donc il ne nécessite aucun argument <field_type> pour être extrait. Plus d’informations concernant les types de champs de message Protocol Buffers sont disponibles ici : https://developers.google.com/protocol-buffers/docs/encoding

regsub(<regex>,<subst>[,<flags>])

regsub(<regex>,<subst>[,<flags>])

Applique une substitution basée sur une expression régulière à la chaîne d’entrée. Elle effectue la même opération que l’utilitaire bien connu « sed » avec « s/<regex>/<subst>/ ». Par défaut, elle remplace dans la chaîne d’entrée la première occurrence de la plus grande partie correspondant à l’expression régulière <regex> par la chaîne de substitution <subst>. Il est possible de remplacer toutes les occurrences au lieu de la première en ajoutant le drapeau « g » dans le troisième argument <flags>. Il est également possible de rendre l’expression régulière insensible à la casse en ajoutant le drapeau « i » dans <flags>. Étant donné que <flags> est une chaîne, elle est constituée de la concaténation de tous les drapeaux souhaités. Ainsi, si les deux drapeaux « i » et « g » sont requis, l’utilisation de « gi » ou de « ig » aura le même effet. La première utilisation de ce convertisseur consiste à remplacer certains caractères ou séquences de caractères par d’autres.

Il est fortement recommandé d’entourer la partie regex de guillemets protégés afin d’améliorer la clarté et d’éviter toute confusion entre une parenthèse fermante provenant de la regex et une parenthèse provenant de la fonction. Comme dans le shell Bourne, le premier niveau de guillemets est traité lors de la délimitation des groupes de mots sur la ligne, tandis qu’un second niveau est disponible pour les arguments. Il est recommandé d’utiliser des guillemets simples à l’extérieur, car ceux-ci ne tentent pas de résoudre les barres obliques inverses ni les signes dollar.

Exemples :

# de-duplicate "/" in header "x-path".
# input:  x-path: /////a///b/c/xzxyz/
# output: x-path: /a/b/c/xzxyz/
http-request set-header x-path "%[hdr(x-path),regsub('/+','/','g')]"

# copy query string to x-query and drop all leading '?', ';' and '&'
http-request set-header x-query "%[query,regsub([?;&]*,'')]"

# capture groups and backreferences
# both lines do the same.
http-request redirect location %[url,'regsub("(foo|bar)([0-9]+)?","\2\1",i)']
http-request redirect location %[url,regsub(\"(foo|bar)([0-9]+)?\",\"\2\1\",i)]

reverse

reverse

Inverse la chaîne d’entrée par octets.

Ce convertisseur est indépendant de l’encodage et inverse les octets, pas les caractères ; il n’est pas adapté à la réversibilité du texte humain encodé en UTF-8.

Cela peut transformer les recherches de suffixes sur la chaîne d’origine en recherches de préfixes sur la chaîne inversée, permettant ainsi d’utiliser des correspondances de préfixe indexées telles que “map_beg” sur de grandes cartes.

Exemples :

"example.com" -> "moc.elpmaxe"
"ab cd" -> "dc ba"

# Given a map file where each key contains a reversed hostname:
#   moc.elpmaxe.ppa app1
#   moc.elpmaxe.bd  dbcluster
# Pick a backend based on the domain suffix of the Host header:
use_backend %[req.hdr(host),lower,reverse,map_beg(/etc/haproxy/hosts.map,default)]

reverse_dom

reverse_dom

Convertit une chaîne contenant un nom d’hôte de type FQDN en sa forme inversée par étiquettes. Un point final unique dans l’entrée est ignoré. Les étiquettes vides entraînent l’échec du convertisseur.

Ce convertisseur ne met pas en minuscules son entrée et ne supprime aucun port. Il est destiné à être combiné avec des convertisseurs existants tels que « lower » ou “host_only” lorsqu’il est nécessaire.

La politique des points de fin est intentionnellement laissée au chargeur. Cela permet aux appelants de décider s’ils souhaitent correspondre au sommet également ou uniquement aux sous-domaines.

La forme avec étiquettes inversées est utile pour les grandes cartes de domaine, car elle transforme les recherches de suffixes de domaine en recherches de préfixes, permettant ainsi d’utiliser des correspondances de préfixe indexées telles que “map_beg”.

Exemples :

"example.com" -> "com.example"
"mail.example.com" -> "com.example.mail"
"example.com." -> "com.example"

# match only subdomains of example.net, not the apex
acl example_net_sub req.hdr(Host),host_only,reverse_dom -m beg net.example.

# match only the apex
acl example_net_apex req.hdr(Host),host_only,reverse_dom -i net.example

# exact-or-subdomain prefix lookup using an explicit dotted form
http-request set-var(txn.rev_host) req.hdr(Host),host_only,reverse_dom,concat(.)
use_backend %[var(txn.rev_host),map_beg(/etc/haproxy/domains.map)]

rfc7239_field(<field>)

rfc7239_field(<field>)

Extrait un seul field/parameter à partir d’une valeur d’en-tête conforme à la RFC 7239.

Champs pris en charge : - proto : soit « http » soit « https » - host : hôte conforme à HTTP - for : RFC7239 nœud - par : RFC7239 nœud

Plus d’informations ici :

https://www.rfc-editor.org/rfc/rfc7239.html#section-6

Exemple :

# extract host field from forwarded header and store it in req.fhost var
http-request set-var(req.fhost) req.hdr(forwarded),rfc7239_field(host)
#input: "proto=https;host=\"haproxy.org:80\""
#  output: "haproxy.org:80"

# extract for field from forwarded header and store it in req.ffor var
http-request set-var(req.ffor) req.hdr(forwarded),rfc7239_field(for)
#input: "proto=https;host=\"haproxy.org:80\";for=\"127.0.0.1:9999\""
#  output: "127.0.0.1:9999"

rfc7239_is_valid

rfc7239_is_valid

Renvoie true si la valeur d’en-tête d’entrée est conforme à la RFC 7239, false dans le cas contraire.

Exemple :

acl valid req.hdr(forwarded),rfc7239_is_valid
#input: "for=127.0.0.1;proto=http"
#  output: TRUE
#input: "proto=custom"
#  output: FALSE

rfc7239_n2nn

rfc7239_n2nn

Convertit le nœud RFC7239, fourni par les champs d’en-tête 7239 ‘for’ ou ‘by’, dans la forme finale correspondante de son nom de nœud : - adresse IPv4 - adresse IPv6 - ‘unknown’ - identifiant ‘_obfs’

Exemple :

# extract 'for' field from forwarded header, extract nodename from
# resulting node identifier and store the result in req.fnn
http-request set-var(req.fnn) req.hdr(forwarded),rfc7239_field(for),rfc7239_n2nn
#input: "127.0.0.1:9999"
#  output: 127.0.0.1 (ipv4)
#input: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998"
#  output: ab:cd:ff:ff:ff:ff:ff:ff (ipv6)
#input: "_name:_port"
#  output: "_name" (string)

rfc7239_n2np

rfc7239_n2np

Convertit le nœud RFC7239, fourni par les champs d’en-tête 7239 ‘for’ ou ‘by’, dans la forme finale correspondante de son port de nœud : - entier non signé - identifiant ‘_obfs’

Exemple :

# extract 'by' field from forwarded header, extract node port from
# resulting node identifier and store the result in req.fnp
http-request set-var(req.fnp) req.hdr(forwarded),rfc7239_field(by),rfc7239_n2np
#input: "127.0.0.1:9999"
#  output: 9999 (integer)
#input: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998"
#  output: 9998 (integer)
#input: "_name:_port"
#  output: "_port" (string)

rfc7239_nn

rfc7239_nn

Convertit l’adresse ou la chaîne fournie en un nom de nœud conforme à RFC7239. Cette fonction peut être utilisée pour construire manuellement les champs d’en-tête ‘for’ ou ‘by’ du protocole 7239.

Lorsque l’entrée fournie est une chaîne, elle sera automatiquement préfixée par le caractère ‘_’ afin de représenter un identifiant masqué. La chaîne doit respecter l’ensemble de caractères RFC7239. Si la chaîne est vide, elle sera convertie en identifiant « unknown ».

Exemple :

#input: ipv6(ab:cd:ff:ff:ff:ff:ff:ff)
#  output: "[ab:cd:ff:ff:ff:ff:ff:ff]"
#input: str(test)
#  output: "_test"
#input: str()
#  output: "unknown"

Voir également : “rfc7239_np”

rfc7239_np

rfc7239_np

Convertit l’entrée entier non signé ou chaîne fournie en port de nœud conforme à RFC7239. Elle peut être utilisée pour construire manuellement les champs d’en-tête ‘for’ ou ‘by’ selon la spécification 7239.

Lorsque l’entrée fournie est une chaîne, elle sera automatiquement préfixée par le caractère ‘_’ afin de représenter un identifiant masqué. La chaîne doit respecter l’ensemble de caractères RFC7239 et ne peut pas être vide.

Exemple :

#input: int(12)
#  output: "12"
#input: str(test)
#  output: "_test"

# build 'for' forwarded header field
http-request set-var-fmt(txn.test) "for=\"%[ipv6(::1),rfc7239_nn]:%[int(8080),rfc7239_np]\";"
#  output: "for=\"[::1]:8080\";"

# build RFC-compliant 7239 header:
http-request set-var-fmt(txn.forwarded) "for=\"%[ipv6(::1),rfc7239_nn]:%[str(8888),rfc7239_np]\";host=\"haproxy.org\";proto=http"
# check RFC-compliancy:
http-request set-var(txn.test) "var(txn.forwarded),debug(test,stderr),rfc7239_is_valid,debug(test,stderr)"
#  stderr output:
#    [debug] test: type=str <for="[::1]:_8888";host="haproxy.org";proto=http>
#    [debug] test: type=bool <1>

Voir également : “rfc7239_nn”

rtrim(<chars>)

rtrim(<chars>)

Ignore tout caractère provenant de <chars> à la fin de la représentation sous forme de chaîne de l’échantillon d’entrée.

sdbm([<avalanche>])

sdbm([<avalanche>])

Hache une entrée binaire en une quantité non signée sur 32 bits à l’aide de la fonction de hachage SDBM. Optionnellement, il est possible d’appliquer une fonction de hachage à avalanche complète à la sortie si l’argument optionnel <avalanche> vaut 1. Ce convertisseur utilise les mêmes fonctions que celles employées par les divers algorithmes de répartition de charge basés sur le hachage, il produira donc exactement les mêmes résultats. Il est principalement destiné au débogage, mais peut être utilisé comme entrée de table de persistance pour collecter des statistiques brutes. Il ne doit pas être utilisé à des fins de sécurité, car un hachage sur 32 bits est facile à casser. Voir également « crc32 », « djb2 », « wt6 », « crc32c » et la directive « hash-type ».

secure_memcmp(<var>)

secure_memcmp(<var>)

Compare le contenu de <var> avec la valeur d’entrée. Les deux valeurs sont traitées comme des chaînes binaires. Renvoie une valeur booléenne indiquant si les deux chaînes binaires correspondent.

Si les deux chaînes binaires ont la même longueur, la comparaison sera effectuée en temps constant.

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

Exemple :

http-request set-var(txn.token) hdr(token)
# Check whether the token sent by the client matches the secret token
# value, without leaking the contents using a timing attack.
acl token_given str(my_secret_token),secure_memcmp(txn.token)

set-var(<var>[,<cond>...])

set-var(<var>[,<cond>...])

Définit une variable avec le contenu d’entrée et renvoie le contenu en sortie tel quel si toutes les conditions spécifiées sont remplies (voir ci-dessous la liste des conditions possibles). La variable conserve sa valeur et le type d’entrée associé. Voir section 2.8 sur les variables pour plus de détails.

Vous pouvez passer au plus quatre conditions au convertisseur parmi les conditions suivantes :

  • “siexiste”/“sinaexistent” :
Checks if the variable already existed before the current set-var call.
A variable is usually created through a successful set-var call.
Note that variables of scope "proc" are created during configuration
parsing so the "ifexists" condition will always be true for them.
  • “ifempty”/“ifnotempty” :
Checks if the input is empty or not.
Scalar types are never empty so the ifempty condition will be false for
them regardless of the input's contents (integers, booleans, IPs ...).
  • « ifset » / « ifnotset » :
Checks if the variable was previously set or not, or if unset-var was
called on the variable.
A variable that does not exist yet is considered as not set. A "proc"
variable can exist while not being set since they are created during
configuration parsing.
  • “ifgt”/“iflt” :
Checks if the content of the variable is "greater than" or "less than"
the input. This check can only be performed if both the input and
the variable are of type integer. Otherwise, the check is considered as
true by default.

sha1

sha1

Convertit un échantillon d’entrée binaire en somme de contrôle SHA-1. Le résultat est un échantillon binaire de 20 octets.

sha2([<bits>])

sha2([<bits>])

Convertit un échantillon d’entrée binaire en un hachage de la famille SHA-2. Le résultat est un échantillon binaire de <bits>/8 octets.

Les valeurs autorisées pour <bits> sont 224, 256, 384, 512, chacune correspondant à SHA-<bits>. La valeur par défaut est 256.

Veuillez noter que ce convertisseur n’est disponible que si HAProxy a été compilé avec USE_OPENSSL.

srv_is_up

srv_is_up

Prend une valeur d’entrée de type chaîne, soit un nom de serveur, soit au format <backend>/<server>, et renvoie true lorsque le serveur désigné est actuellement actif. Peut être utilisé là où l’on souhaite vérifier l’état d’un serveur à partir d’un nom dynamique, comme une valeur de cookie (par exemple req.cook(SRVID),srv_is_up), puis prendre une décision pour rediriger une requête ailleurs. Avant de l’utiliser, veuillez noter qu’utiliser ce convertisseur sur des données non contrôlées pourrait permettre à un observateur externe de consulter l’état de n’importe quel serveur dans toute la configuration, ce qui pourrait ne pas être acceptable dans certains environnements.

srv_queue

srv_queue

Prend une valeur d’entrée de type chaîne, soit un nom de serveur, soit au format <backend>/<server>, et retourne le nombre de flux en attente sur ce serveur. Peut être utilisé là où l’on souhaite rechercher le nombre de flux en attente à partir d’un nom dynamique, comme une valeur de cookie (par exemple req.cook(SRVID),srv_queue), puis prendre une décision pour rompre la persistance ou rediriger la requête ailleurs. Avant de l’utiliser, veuillez noter qu’utiliser ce convertisseur sur des données non contrôlées pourrait permettre à un observateur externe de consulter l’état de n’importe quel serveur dans toute la configuration, ce qui pourrait ne pas être acceptable dans certains environnements.

strcmp(<var>)

strcmp(<var>)

Compare le contenu de <var> avec la valeur d’entrée de type chaîne. Retourne le résultat sous forme d’entier signé compatible avec strcmp(3) : 0 si les deux chaînes sont identiques. Une valeur inférieure à 0 si la chaîne de gauche est lexicographiquement plus petite que la chaîne de droite ou si la chaîne de gauche est plus courte. Une valeur supérieure à 0 dans les autres cas (chaîne de droite plus grande que la chaîne de gauche ou la chaîne de droite est plus courte).

Voir également le convertisseur secure_memcmp si vous devez comparer deux chaînes binaires en temps constant.

Exemple :

http-request set-var(txn.host) hdr(host)
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0

sub(<value>)

sub(<value>)

Soustrait <value> à la valeur d’entrée de type entier signé, et retourne le résultat sous forme d’entier signé. Note : pour soustraire la valeur d’entrée d’une constante, il suffit d’effectuer une opération « neg,add(valeur) ». <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 sur les variables pour plus de détails.

table_bytes_in_rate([<table>])

table_bytes_in_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le débit moyen en octets client-serveur associé à l’échantillon d’entrée dans la table désignée, mesuré en quantité d’octets sur la période configurée dans la table. Voir également le mot-clé d’extraction d’échantillon sc_bytes_in_rate.

table_bytes_out_rate([<table>])

table_bytes_out_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne le débit moyen en octets émis par le serveur vers le client associé à l’échantillon d’entrée dans la table désignée, mesuré en quantité d’octets sur la période configurée dans la table. Voir également le mot-clé d’extraction d’échantillon sc_bytes_out_rate.

table_clr_gpc(<idx>[,<table>])

table_clr_gpc(<idx>[,<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Efface le compteur général à l’index <idx> du tableau gpc et retourne sa valeur précédente. <idx> est un entier compris entre 0 et 99. Si l’entrée n’est pas trouvée, une entrée est créée et 0 est retourné. Ce convertisseur s’applique uniquement au type de données ‘gpc’ (et non aux types hérités ‘gpc0’ ni ‘gpc1’). Voir également le mot-clé d’extraction d’échantillon sc_clr_gpc.

table_clr_gpc0([<table>])

table_clr_gpc0([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Efface le premier compteur général ‘0’ et retourne sa valeur précédente. Si l’entrée n’est pas trouvée, une entrée est créée et 0 est retourné. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée :

Exemple :

# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill  src,table_inc_gpc0 gt 5
acl save  src,table_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

Voir également le mot-clé d’extraction d’échantillon sc_clr_gpc0.

table_clr_gpc1([<table>])

table_clr_gpc1([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Efface le premier compteur général ‘1’ et retourne sa valeur précédente. Si l’entrée n’est pas trouvée, une entrée est créée et 0 est retourné. Cela est généralement utilisé comme deuxième mot-clé ACL dans une expression afin de marquer une connexion lorsque la première condition ACL a été vérifiée. Voir également le mot-clé d’extraction d’échantillon sc_clr_gpc1.

table_conn_cnt([<table>])

table_conn_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé de connexions entrantes associées à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_conn_cnt.

table_conn_cur([<table>])

table_conn_cur([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre actuel de connexions simultanées suivies associées à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_conn_cur.

table_conn_rate([<table>])

table_conn_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le débit moyen de connexions entrantes associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_conn_rate.

table_expire([<table>[,<default_value>]])

table_expire([<table>[,<default_value>]])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, le convertisseur échoue, sauf si <default_value> est défini : cela fait échouer le convertisseur et retourne <default_value>. Si la clé est trouvée, le convertisseur retourne le délai d’expiration associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon table_idle.

table_glitch_cnt([<table>])

table_glitch_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé d’instabilités de connexion frontales associées à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_glitch_cnt et fc_glitches pour la valeur mesurée sur la connexion frontale actuelle.

table_glitch_rate([<table>])

table_glitch_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le taux moyen de perturbations de connexion frontale associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_glitch_rate.

table_gpc(<idx>[,<table>])

table_gpc(<idx>[,<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie la valeur actuelle du compteur général à l’index <idx> du tableau associé à l’échantillon d’entrée dans la table de persistance désignée <table>. <idx> est un entier compris entre 0 et 99. Si aucun compteur général n’est stocké à cet index, la valeur entière zéro est également renvoyée. Cela ne s’applique qu’au type de données ‘gpc’ (et non aux types de données hérités ‘gpc0’ ni ‘gpc1’). Voir également le mot-clé d’extraction d’échantillon sc_get_gpc.

table_gpc0([<table>])

table_gpc0([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie la valeur actuelle du premier compteur généraliste associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_get_gpc0.

table_gpc0_rate([<table>])

table_gpc0_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne la fréquence à laquelle le compteur gpc0 a été incrémenté durant la période configurée dans la table, associée à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_get_gpc0_rate.

table_gpc1([<table>])

table_gpc1([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne la valeur actuelle du deuxième compteur généraliste associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_get_gpc1.

table_gpc1_rate([<table>])

table_gpc1_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne la fréquence à laquelle le compteur gpc1 a été incrémenté durant la période configurée dans la table, associée à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_get_gpc1_rate.

table_gpc_rate(<idx>[,<table>])

table_gpc_rate(<idx>[,<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie la fréquence à laquelle le compteur global de but (GPC) à l’index <idx> du tableau (associé à l’échantillon d’entrée dans la table de persistance désignée <table>) a été incrémenté durant la période configurée. <idx> est un entier compris entre 0 et 99. Si aucune valeur gpc_rate n’est stockée à cet index, la valeur entière zéro est également renvoyée. Cela ne s’applique qu’au type de données ‘gpc_rate’ (et non aux types de données hérités ‘gpc0_rate’ ni ‘gpc1_rate’). Voir également le mot-clé d’extraction d’échantillon sc_gpc_rate.

table_gpt(<idx>[,<table>])

table_gpt(<idx>[,<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie la valeur actuelle de l’étiquette générale au niveau <idx> du tableau associé à l’échantillon d’entrée dans la table de persistance désignée <table>. <idx> est un entier compris entre 0 et 99. Si aucune étiquette générale n’est stockée à cet index, la valeur entière zéro est également renvoyée. Cela ne s’applique qu’au type de données ‘gpt’ (et non au type de données hérité ‘gpt0’). Voir également le mot-clé d’extraction sc_get_gpt.

table_gpt0([<table>])

table_gpt0([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie la valeur actuelle de la première étiquette générale associée à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_get_gpt0.

table_http_err_cnt([<table>])

table_http_err_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé d’erreurs HTTP associé à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_http_err_cnt.

table_http_err_rate([<table>])

table_http_err_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, retourne le taux moyen d’erreurs HTTP associé à l’échantillon d’entrée dans la table désignée, exprimé en nombre d’erreurs sur la période configurée dans la table. Voir également le mot-clé d’extraction d’échantillon sc_http_err_rate.

table_http_fail_cnt([<table>])

table_http_fail_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé d’échecs HTTP associés à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_http_fail_cnt.

table_http_fail_rate([<table>])

table_http_fail_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, renvoie le taux moyen d’échecs HTTP associé à l’échantillon d’entrée dans la table désignée, exprimé comme nombre d’échecs sur la période configurée dans la table. Voir également le mot-clé d’extraction sc_http_fail_rate.

table_http_req_cnt([<table>])

table_http_req_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé de requêtes HTTP associées à l’échantillon d’entrée dans la table désignée. Voir également le mot-clé d’extraction d’échantillon sc_http_req_cnt.

table_http_req_rate([<table>])

table_http_req_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, la fréquence moyenne des requêtes HTTP associées à l’échantillon d’entrée dans la table désignée, mesurée en nombre de requêtes sur la période configurée dans la table. Voir également le mot-clé d’extraction sc_http_req_rate.

table_idle([<table>[,<default_value>]])

table_idle([<table>[,<default_value>]])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, le convertisseur échoue, sauf si <default_value> est défini : cela fait échouer le convertisseur et retourne <default_value>. Si la clé est trouvée, le convertisseur retourne le temps pendant lequel l’entrée associée à l’échantillon d’entrée dans la table désignée est restée inactif depuis la dernière mise à jour. Voir également le mot-clé d’extrais d’échantillon table_expire.

table_inc_gpc(<idx>[,<table>])

table_inc_gpc(<idx>[,<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Incrémente le compteur généralisé à l’index <idx> du tableau et retourne sa nouvelle valeur. <idx> est un entier compris entre 0 et 99. Si l’entrée n’est pas trouvée, une entrée est créée et la valeur 1 est retournée. Ce convertisseur s’applique uniquement au type de données ‘gpc’ (et non aux types hérités ‘gpc0’ ni ‘gpc1’). Voir également sc_inc_gpc.

table_inc_gpc0([<table>])

table_inc_gpc0([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Incrémente le compteur généralisé « 0 » et retourne sa nouvelle valeur. Si l’entrée n’est pas trouvée, une entrée est créée et la valeur 1 est retournée. Voir également sc0/sc2/sc2_inc_gpc0.. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée :

Exemple :

acl abuse src,table_req_rate gt 10
acl kill  src,table_inc_gpc0 gt 0
tcp-request connection reject if abuse kill

table_inc_gpc1([<table>])

table_inc_gpc1([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Incrémente le compteur généralisé « 1 » et retourne sa nouvelle valeur. Si l’entrée n’est pas trouvée, une entrée est créée et la valeur 1 est retournée. Voir également sc0/sc2/sc2_inc_gpc1.. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée.

table_kbytes_in([<table>])

table_kbytes_in([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne le nombre cumulé de données client-serveur associées à l’échantillon d’entrée dans la table désignée, exprimé en kilo-octets. Le test est actuellement effectué sur des entiers 32 bits, ce qui limite les valeurs à 4 téraoctets. Voir également le mot-clé d’extraction d’échantillon sc_kbytes_in.

table_kbytes_out([<table>])

table_kbytes_out([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur retourne le nombre cumulé de données serveur-vers-client associées à l’échantillon d’entrée dans la table désignée, exprimé en kilo-octets. Le test est actuellement effectué sur des entiers 32 bits, ce qui limite les valeurs à 4 téraoctets. Voir également le mot-clé d’extraction d’échantillon sc_kbytes_out.

table_server_id([<table>])

table_server_id([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie l’identifiant de serveur associé à l’échantillon d’entrée dans la table désignée. Un identifiant de serveur est associé à un échantillon par une règle « stick » lorsque la connexion à un serveur réussit. Un identifiant de serveur zéro signifie qu’aucun serveur n’est associé à cette clé.

table_sess_cnt([<table>])

table_sess_cnt([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre cumulé de sessions entrantes associées à l’échantillon d’entrée dans la table désignée. Notez qu’une session désigne ici une connexion entrante acceptée par les règles “tcp-request connection”. Voir également le mot-clé d’extraction d’échantillon sc_sess_cnt.

table_sess_rate([<table>])

table_sess_rate([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le taux moyen de sessions entrantes associé à l’échantillon d’entrée dans la table désignée. Notez qu’une session fait référence à une connexion entrante acceptée par les règles “tcp-request connection”. Voir également le mot-clé d’extraction d’échantillon sc_sess_rate.

table_trackers([<table>])

table_trackers([<table>])

Utilise l’échantillon d’entrée pour effectuer une recherche dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Si la clé n’est pas trouvée dans la table, la valeur entière zéro est renvoyée. Sinon, le convertisseur renvoie le nombre actuel de connexions simultanées suivant la même clé que l’échantillon d’entrée dans la table désignée. Contrairement à table_conn_cur, il ne repose pas sur des informations stockées, mais sur le compteur de référence de la table (la valeur « use » renvoyée par la commande « show table » en ligne de commande). Cette approche peut parfois être plus adaptée au suivi de layer7. Elle peut être utilisée pour indiquer à un serveur combien de connexions simultanées proviennent d’une adresse donnée, par exemple. Voir également le mot-clé d’extraction d’échantillon sc_trackers.

tcp.dst

tcp.dst

Cela est utilisé avec un échantillon d’entrée représentant un en-tête binaire TCP, tel que renvoyé par “ip.data”. Il renvoie un entier représentant le port de destination présent dans l’en-tête TCP. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.flags

tcp.flags

Cela est utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que renvoyé par “ip.data”. Il renvoie un entier représentant les drapeaux TCP issus de cet en-tête TCP. Les 8 drapeaux allant de FIN à CWR sont tous récupérés. Chaque drapeau peut être testé à l’aide du convertisseur “and()”. Voir RFC9293 pour la valeur de chaque drapeau. Voir également “fc_saved_syn”, “tcp-ss”, et “ip.data”.

tcp.options.mss

tcp.options.mss

Cela est utilisé avec un échantillon d’entrée représentant un en-tête binaire TCP, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « MSS », et, s’il la trouve, renvoie une valeur entière correspondant à la valeur annoncée dans cette option, sinon zéro. Le MSS est la taille maximale du segment et indique la taille maximale du segment que le pair peut recevoir, en octets. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.options.sack

tcp.options.sack

Cela est utilisé avec un échantillon d’entrée représentant un en-tête binaire TCP, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « Sack-Permitted », et, s’il la trouve, renvoie 1, sinon zéro. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.options.tsopt

tcp.options.tsopt

Cela est utilisé avec un échantillon d’entrée représentant un en-tête binaire TCP, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « Timestamp », et, s’il la trouve, renvoie 1, sinon 0. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.options.tsval

tcp.options.tsval

Utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « Timestamp », et, s’il la trouve, renvoie la valeur d’horodatage émise par le pair ; sinon, il ne renvoie rien. Notez que les horodatages sont des valeurs non signées sur 32 bits sans unité particulière, choisie par le pair, et qu’ils sont censés être indépendants entre différentes connexions. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.options.wscale

tcp.options.wscale

Cela est utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « Window Scale », et, si trouvée, renvoie la valeur d’échelle de fenêtre émise par le pair, sinon zéro. Notez que les valeurs ne sont pas censées dépasser 14, bien que aucune limitation technique ne l’empêche d’être envoyées. Pour détecter si l’option d’échelle de fenêtre a été utilisée, veuillez utiliser “tcp.options.wsopt”. Voir également « tcp-ss », “fc_saved_syn”, “ip.data”, et “tcp.options.wsopt”.

tcp.options.wsopt

tcp.options.wsopt

Cela est utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que renvoyé par “ip.data”. Il recherche une option TCP de type « Window Scale », et, s’il la trouve, renvoie 1, sinon 0. Voir également “fc_saved_syn”, « tcp-ss », “ip.data” “tcp.options.wscale”.

tcp.options_list

tcp.options_list

Utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel qu’il est retourné par “ip.data”. Il construit une séquence binaire contenant tous les types d’options TCP dans le même ordre qu’ils apparaissent dans l’en-tête TCP. Il peut produire entre 0 et 60 octets (dans le cas le plus défavorable). La marque de fin d’options n’est pas émise. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.seq

tcp.seq

Cela est utilisé avec un échantillon d’entrée représentant un en-tête binaire TCP, tel que renvoyé par “ip.data”. Il renvoie un entier représentant le numéro de séquence utilisé par le pair dans l’en-tête TCP. Les numéros de séquence sont des valeurs non signées sur 32 bits. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.src

tcp.src

Cela est utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que renvoyé par “ip.data”. Il renvoie un entier représentant le port source présent dans l’en-tête TCP. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

tcp.win

tcp.win

Utilisé avec un échantillon d’entrée représentant un en-tête TCP binaire, tel que retourné par “ip.data”. Renvoie un entier représentant la taille de fenêtre annoncée par le pair dans l’en-tête TCP. La valeur est fournie telle quelle, sous forme de quantité non signée sur 16 bits, sans appliquer le facteur de mise à l’échelle de la fenêtre. Voir également “fc_saved_syn”, « tcp-ss », et “ip.data”.

ub64dec

ub64dec

Ce convertisseur est la variante base64url du convertisseur b64dec. Le codage base64url est la variante « alphabet sécurisé pour les URL et les noms de fichiers » du codage base64. Il est également utilisé dans la norme JWT (JSON Web Token).

Exemple :

# Decoding a JWT payload:
http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec

ub64enc

ub64enc

Ce convertisseur est la variante base64url du convertisseur base64.

ungrpc(<field_number>[,<field_type>])

ungrpc(<field_number>[,<field_type>])

Cela extrait le champ de message Protocol Buffers en mode brut à partir d’une représentation binaire d’entrée d’un message gRPC, avec <field_number> comme numéro de champ (notation pointée) si <field_type> est absent, ou comme échantillon entier si ce champ est présent. La liste des types autorisés est la suivante : « int32 », « int64 », « uint32 », « uint64 », « sint32 », « sint64 », « bool », « enum » pour le type de filaire « varint » (type 0), « fixed64 », « sfixed64 », « double » pour le type de filaire 64 bits (type 1), « fixed32 », « sfixed32 », « float » pour le type de filaire 5. Notez que « string » est considéré comme un type délimité par longueur, aussi n’exige-t-il aucun argument <field_type> pour être extrait. Plus d’informations sont disponibles ici concernant les types de champs de message Protocol Buffers : https://developers.google.com/protocol-buffers/docs/encoding

Exemple :

// with such a protocol buffer .proto file content adapted from
// https://github.com/grpc/grpc/blob/master/examples/protos/route_guide.proto

message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

message PPoint {
  Point point = 59;
}

message Rectangle {
  // One corner of the rectangle.
  PPoint lo = 48;
  // The other corner of the rectangle.
  PPoint hi = 49;
}

Supposons qu’une requête corporelle contienne une valeur d’objet « Rectangle » (deux messages Protocol Buffers PPoint), les quatre champs des messages Protocol Buffers pourraient être extraits à l’aide de ces directives « ungrpc » :

req.body,ungrpc(48.59.1,int32) # "latitude" of "lo" first PPoint
req.body,ungrpc(48.59.2,int32) # "longitude" of "lo" first PPoint
req.body,ungrpc(49.59.1,int32) # "latitude" of "hi" second PPoint
req.body,ungrpc(49.59.2,int32) # "longitude" of "hi" second PPoint

Nous pourrions également extraire le champ intermédiaire 48.59 sous forme d’échantillon binaire comme suit :

req.body,ungrpc(48.59)

Comme un message gRPC est toujours constitué d’un en-tête gRPC suivi de messages protocol buffers, dans l’exemple précédent, la « latitude » du premier PPoint « lo » aurait pu être extraite à l’aide de ces directives équivalentes :

req.body,ungrpc(48.59),protobuf(1,int32)
req.body,ungrpc(48),protobuf(59.1,int32)
req.body,ungrpc(48),protobuf(59),protobuf(1,int32)

Notez que la première conversion doit être « ungrpc », les suivantes doivent être « protobuf » et seule la dernière peut éventuellement avoir un deuxième argument pour interpréter l’échantillon binaire précédent.

unset-var(<var>)

unset-var(<var>)

Supprime une variable si le contenu d’entrée est défini. Le nom de la variable commence par une indication relative à sa portée. Voir section 2.8 sur les variables pour plus de détails.

upper

upper

Convertit une chaîne d’échantillon en majuscules. Cette instruction ne peut être utilisée qu’après une fonction d’extraction d’échantillon de chaîne ou après un mot-clé de transformation retournant un type chaîne. Le résultat est de type chaîne.

url_dec([<in_form>])

url_dec([<in_form>])

Prend une chaîne encodée URL en entrée et renvoie la version décodée en sortie. L’entrée et la sortie sont de type chaîne. Si l’argument <in_form> est défini à une valeur entière non nulle, la chaîne d’entrée est supposée faire partie d’une chaîne de formulaire ou de requête, et le caractère ‘+’ sera remplacé par un espace (’ ‘). Sinon, cela n’aura lieu qu’après un point d’interrogation indiquant une chaîne de requête (’?’).

url_enc([<enc_type>])

url_enc([<enc_type>])

Prend une chaîne fournie en entrée et renvoie la version encodée en sortie. L’entrée et la sortie sont de type chaîne. Par défaut, le type d’encodage est destiné au type query. Aucun autre type n’est actuellement pris en charge, mais l’argument facultatif est présent pour permettre des évolutions futures.

us_ltime(<format>[,<offset>])

us_ltime(<format>[,<offset>])

Cela fonctionne comme « ltime » mais prend en entrée une valeur en microsecondes. Il prend également en charge le spécificateur de conversion %N inspiré de date(1). Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure locale, selon un format défini par la chaîne <format> en utilisant strftime(3). L’objectif est de permettre l’utilisation de tout format de date dans les journaux. Un <offset> facultatif en microsecondes peut être appliqué à la date d’entrée (positif ou négatif). Consultez la page man strftime() pour connaître les formats pris en charge par votre système d’exploitation.

Le spécificateur de conversion %N permet de sortir la partie nanosecondes de la date, la précision étant limitée car l’entrée est en microsecondes. (000000000..999999000). %N peut prendre un argument de largeur entre % et N. Il est utile pour afficher des millisecondes (%3N) ou des microsecondes (%6N). La largeur par défaut et maximale est 9 (%N = %9N).

Voir également le convertisseur « utime » pour UTC, ainsi que les convertisseurs « ltime » et “ms_ltime”.

Exemple :

# Emit 3 colons, the local time, the timezone and another with ip:port
# e.g. 2023/07/24/09:53:02.196234 +0000 127.0.0.1:41530
log-format %[accept_date(us),us_ltime("%Y/%m/%d/%H:%M:%S.%6N %z")]\ %ci:%cp

us_utime(<format>[,<offset>])

us_utime(<format>[,<offset>])

Cela fonctionne comme « utime » mais prend une entrée en microsecondes. Il prend également en charge le spécificateur de conversion %N inspiré de date(1). Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure UTC selon un format défini par la chaîne <format> en utilisant strftime(3). Le but est de permettre l’utilisation de tout format de date dans les journaux. Un <offset> facultatif en microsecondes peut être appliqué à la date d’entrée (positif ou négatif). Consultez la page de manuel de strftime() pour connaître les formats pris en charge par votre système d’exploitation.

Le spécificateur de conversion %N permet de sortir la partie nanosecondes de la date, la précision étant limitée car l’entrée est en microsecondes. (000000000..999999000). %N peut prendre un argument de largeur entre % et N. Il est utile pour afficher des millisecondes (%3N) ou des microsecondes (%6N). La largeur par défaut et maximale est 9 (%N = %9N).

Voir également le convertisseur « ltime » pour les heures locales ainsi que les convertisseurs « utime » et “ms_utime”.

Exemple :

# Emit 3 colons, the UTC time, the timezone and another with ip:port
# e.g. 2023/07/24/09:53:02.196234 +0000 127.0.0.1:41530
log-format %[accept_date(us),us_utime("%Y/%m/%d/%H:%M:%S.%6N %z")]\ %ci:%cp

utime(<format>[,<offset>])

utime(<format>[,<offset>])

Convertit un entier supposé contenir une date depuis l’époque en une chaîne représentant cette date en heure UTC, selon un format défini par la chaîne <format> en utilisant strftime(3). Le but est de permettre l’utilisation de tout format de date dans les journaux. Un décalage optionnel <offset> en secondes peut être appliqué à la date d’entrée (positif ou négatif). Consultez la page de manuel strftime() pour connaître les formats pris en charge par votre système d’exploitation. Voir également le convertisseur “ltime”, ainsi que “ms_utime” et “us_utime”.

Exemple :

# Emit two colons, one with the UTC time and another with ip:port
# e.g.  20140710162350 127.0.0.1:57325
log-format %[date,utime(%Y%m%d%H%M%S)]\ %ci:%cp

when(<condition>[,<args>...])

when(<condition>[,<args>...])

Évalue la condition et, si elle est vraie, transmet l’échantillon d’entrée tel quel en sortie ; sinon, ne retourne rien. Cette fonction est spécifiquement conçue pour produire des données rarement nécessaires, qui ne doivent être émises que sous certaines conditions, telles que des informations de débogage lorsqu’une erreur est détectée.

La condition est constituée d’un mot-clé parmi la liste suivante, éventuellement précédé d’un point d’exclamation (’!’) pour le nier, et éventuellement suivi de certains arguments propres à cette condition :

- "error" retourne true lorsqu'une erreur est survenue pendant le traitement de la requête ou du flux. Elle utilise les mêmes règles que "dontlog-normal" (par exemple, une réexpédition réussie est considérée comme une erreur).

- "forwarded" retourne true lorsque la requête a été transférée vers un backend

- "normal" renvoie true lorsque aucune erreur ne s'est produite (ce qui équivaut à "!error").

- "processed" retourne true lorsque la requête a été soit transférée vers un backend, soit traitée par un applet.

- "stopping" renvoie true si le processus est actuellement en cours d'arrêt au moment où la règle est évaluée

- "toapplet" retourne true lorsque la requête a été traitée par un applet.

- "acl" renvoie true lorsque l'ACL désignée par l'argument suivant évalue à true. Notez que l'ACL est évaluée inline par le convertisseur, de sorte que ce vers quoi elle fait référence doit être valide dans ce contexte. Un cas d'utilisation particulier consiste à déterminer si le temps total de transfert est trop long avant de décider de journaliser les détails des transferts anormalement longs.

Notez que le contenu est évalué dans tous les cas, donc cette action ne permet pas d’éviter la génération de ces informations. Elle vise uniquement à empêcher leur production.

Par exemple, ajouter des informations de débogage du flux backend dans les journaux uniquement lorsqu’une erreur est survenue pendant le traitement, ou journaliser des informations supplémentaires lors de l’arrêt, etc.

Exemple :

# log "dbg={-}" when fine, or "dbg={... debug info ...}" on error:
log-format "$HAPROXY_HTTP_LOG_FMT dbg={%[bs.debug_str,when(!normal)]}"

Here, the "dbg" field in the log will only contain an dash ('-') to
indicate a missing content when the rule is not validated, and will emit a
whole debugging block when it is.

Exemple # log “dbg={-}” en cas de traitement rapide, ou “dbg={… informations de débogage …}” en cas de transferts lents acl slow_xfer res.timer.data ge 10000 # plus de 10 s est considéré comme lent log-format “$HAPROXY_HTTP_LOG_FMT \ fsdbg={%[fs.debug_str,when(acl,slow_xfer)]} \ bsdbg={%[bs.debug_str,when(acl,slow_xfer)]}”

Exemple # émettre uniquement le backend src/port lorsqu’une connexion réelle a été établie : log-format “$HAPROXY_HTTP_LOG_FMT \ src=[%[bc_src,when(forwarded)]:%[bc_src_port,when(forwarded)]]”

Étant donné qu’il interrompt l’évaluation de l’expression lorsqu’elle est fausse, il est également possible de l’utiliser pour empêcher l’appel d’un convertisseur ultérieur. Cela peut par exemple servir à appeler le convertisseur debug() uniquement en cas d’erreur, ou à journaliser un élément uniquement lorsqu’il est absolument nécessaire.

Exemple :

# emit the whole response headers list to stderr only on error and only
# when the output is a connection. We abuse a dummy variable here.
http-after-response set-var(res.test) \
              res.hdrs,when(error),when(forwarded),debug(hdrs,stderr)

Voir aussi : convertisseur de débogage

word(<index>,<delimiters>[,<count>])

word(<index>,<delimiters>[,<count>])

Extrait le n-ième mot en comptant depuis le début (indice positif) ou depuis la fin (indice négatif) d’une chaîne d’entrée, en tenant compte des délimiteurs spécifiés. Les indices commencent à 1 ou -1. Les délimiteurs sont une liste de caractères formatée sous forme de chaîne. Les mots vides sont ignorés. Cela signifie que les délimiteurs situés au début ou à la fin de la chaîne d’entrée sont ignorés, et que des délimiteurs consécutifs à l’intérieur de la chaîne sont traités comme un seul délimiteur. Vous pouvez éventuellement préciser le nombre <count> de mots à extraire (par défaut : 1). Une valeur de 0 indique l’extraction de tous les mots restants.

Exemple :

str(f1_f2_f3__f5),word(4,_)    # f5
str(f1_f2_f3__f5),word(5,_)    # <not found>
str(f1_f2_f3__f5),word(2,_,0)  # f2_f3__f5
str(f1_f2_f3__f5),word(3,_,2)  # f3__f5
str(f1_f2_f3__f5),word(-2,_,3) # f1_f2_f3
str(f1_f2_f3__f5),word(-3,_,0) # f1_f2
str(/f1/f2/f3/f4),word(1,/)    # f1
str(/f1////f2/f3/f4),word(1,/) # f2

wt6([<avalanche>])

wt6([<avalanche>])

Hache une entrée binaire en une quantité non signée sur 32 bits en utilisant la fonction de hachage WT6. Optionnellement, il est possible d’appliquer une fonction de hachage à avalanche complète à la sortie si l’argument facultatif <avalanche> vaut 1. Ce convertisseur utilise les mêmes fonctions que celles employées par les divers algorithmes de répartition de charge basés sur le hachage, il produira donc exactement les mêmes résultats. Il est principalement destiné au débogage, mais peut être utilisé comme entrée de table de persistance pour collecter des statistiques brutes. Il ne doit pas être utilisé à des fins de sécurité, car un hachage sur 32 bits est facile à casser. Voir également « crc32 », « djb2 », « sdbm », « crc32c » et la directive « hash-type ».

x509_v_err_str

x509_v_err_str

Convertit une valeur numérique en son nom de constante correspondant X509_V_ERR. Utile dans les listes de contrôle d’accès (ACL) afin d’obtenir une configuration fonctionnelle avec plusieurs versions d’OpenSSL, car certains codes peuvent varier selon la version utilisée.

Lorsque le nom de la constante correspondante n’a pas été trouvé, affiche la valeur numérique sous forme de chaîne.

La liste des constantes fournie par OpenSSL est disponible à l’adresse https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES Prenez garde à lire la page correspondant à la bonne version d’OpenSSL.

Exemple :

bind:443 ssl crt common.pem ca-file ca-auth.crt verify optional crt-ignore-err X509_V_ERR_CERT_REVOKED,X509_V_ERR_CERT_HAS_EXPIRED

acl cert_expired ssl_c_verify,x509_v_err_str -m str X509_V_ERR_CERT_HAS_EXPIRED
acl cert_revoked ssl_c_verify,x509_v_err_str -m str X509_V_ERR_CERT_REVOKED
acl cert_ok      ssl_c_verify,x509_v_err_str -m str X509_V_OK

http-response add-header X-SSL Ok if cert_ok
http-response add-header X-SSL Expired if cert_expired
http-response add-header X-SSL Revoked if cert_revoked

http-response add-header X-SSL-verify %[ssl_c_verify,x509_v_err_str]

xor(<value>)

xor(<value>)

Effectue un opérateur “XOR” (OU exclusif) au niveau des bits entre <value> et la valeur d’entrée de type entier signé, et retourne le résultat sous forme d’entier signé. <value> peut être une valeur numérique ou un nom de variable. Voir la section 2.8 sur les variables pour plus de détails.

xxh3([<seed>])

xxh3([<seed>])

Hache une entrée binaire en une quantité signée sur 64 bits en utilisant la variante 64 bits de la fonction de hachage XXhash, XXH3. Ce hachage prend en charge une graine dont la valeur par défaut est zéro, mais une valeur différente peut être passée en tant qu’argument <seed>. Ce hachage est connu pour être très performant et très efficace, aussi peut-il être utilisé pour hacher des URL and/or des paramètres d’URL afin d’en faire des clés de table de persistance, permettant de collecter des statistiques avec un taux de collision faible, bien qu’il faille exercer une vigilance car l’algorithme n’est pas considéré comme sécurisé au sens cryptographique.

xxh32([<seed>])

xxh32([<seed>])

Hache une entrée binaire en une quantité non signée sur 32 bits en utilisant la variante 32 bits de la fonction de hachage XXHash. Ce hachage prend en charge une graine dont la valeur par défaut est zéro, mais une valeur différente peut être passée en tant qu’argument <seed>. Ce hachage est connu pour être très efficace et très rapide, aussi peut-il être utilisé pour hacher des URLs and/or des paramètres d’URL afin d’en faire des clés de table de persistance, permettant de collecter des statistiques avec un taux de collision faible, tout en tenant compte du fait que l’algorithme n’est pas considéré comme sécurisé au niveau cryptographique.

xxh64([<seed>])

xxh64([<seed>])

Hache une entrée binaire en une quantité signée sur 64 bits en utilisant la variante 64 bits de la fonction de hachage XXHash. Ce hachage prend en charge une graine dont la valeur par défaut est zéro, mais une valeur différente peut être passée en tant qu’argument <seed>. Ce hachage est connu pour être très performant et très rapide, aussi peut-il être utilisé pour hacher des URLs and/or des paramètres d’URL afin d’en faire des clés de table de persistance afin de collecter des statistiques avec un taux de collision faible, bien qu’il faille faire preuve de prudence car cet algorithme n’est pas considéré comme sécurisé de manière cryptographique.

7.3.2. Récupération d’échantillons à partir des états internes

Un premier ensemble de méthodes d’extraction d’échantillon s’applique à des informations internes qui ne concernent même pas les clients. Ces méthodes sont parfois utilisées avec les directives « monitor fail » pour signaler un état interne aux observateurs externes. Les méthodes d’extraction d’échantillon décrites dans cette section sont utilisables n’importe où.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                          output type
-------------------------------------------------+-------------
acl([!]<name>[,...])                               boolean
act_conn                                           integer
always_false                                       boolean
always_true                                        boolean
avg_queue([<backend>])                             integer
be_conn([<backend>])                               integer
be_conn_free([<backend>])                          integer
be_sess_rate([<backend>])                          integer
bin(<hex>)                                         bin
bool(<bool>)                                       bool
connslots([<backend>])                             integer
cpu_calls                                          integer
cpu_ns_avg                                         integer
cpu_ns_tot                                         integer
date([<offset>[,<unit>]])                          integer
date_us                                            integer
env(<name>)                                        string
fe_conn([<frontend>])                              integer
fe_req_rate([<frontend>])                          integer
fe_sess_rate([<frontend>])                         integer
hostname                                           string
int(<integer>)                                     signed
ipv4(<ipv4>)                                       ipv4
ipv6(<ipv6>)                                       ipv6
last_entity                                        string
last_rule_file                                     string
last_rule_line                                     integer
lat_ns_avg                                         integer
lat_ns_tot                                         integer
meth(<method>)                                     method
nbsrv([<backend>])                                 integer
pid                                                integer
prio_class                                         integer
prio_offset                                        integer
proc                                               integer
queue([<backend>])                                 integer
quic_enabled                                       boolean
rand([<range>])                                    integer
srv_conn([<backend>/]<server>)                     integer
srv_conn_free([<backend>/]<server>)                integer
srv_is_up([<backend>/]<server>)                    boolean
srv_iweight([<backend>/]<server>)                  integer
srv_queue([<backend>/]<server>)                    integer
srv_sess_rate([<backend>/]<server>)                integer
srv_uweight([<backend>/]<server>)                  integer
srv_weight([<backend>/]<server>)                   integer
stopping                                           boolean
str(<string>)                                      string
table_avl([<table>])                               integer
table_cnt([<table>])                               integer
term_events                                        string
thread                                             integer
txn.id32                                           integer
txn.sess_term_state                                string
uptime                                             integer
uuid([<version>])                                  string
var(<var-name>[,<default>])                        undefined
wait_end                                           boolean
waiting_entity                                     string
-------------------------------------------------+-------------

Liste détaillée :

acl([!]<name>[,...]): boolean

acl([!]<name>[,...]): boolean

Renvoie true si l’évaluation de toutes les ACLs nommées est true, sinon renvoie false. Jusqu’à 12 ACLs peuvent être fournies, chacune séparée par une virgule. Chaque ACL nommée peut être précédée d’un “!” pour inverser le résultat. Si une évaluation produit une erreur, l’échantillon renvoie également une erreur. Notez qu’HAProxy ne réalise aucune vérification de validation sur les ACLs référencées, par exemple si une ACL utilisant un échantillon de requête HTTP est utilisée dans un contexte de réponse. Ce comportement pourrait évoluer à l’avenir.

act_conn : entier Renvoie le nombre total de connexions actives concurrentes sur le processus.

always_false : boolean Toujours retourne la valeur booléenne « false ». Peut être utilisé avec les ACLs comme remplacement temporaire d’une autre lorsque l’ajustement de la configuration est en cours.

always_true : booléen Retourne toujours la valeur booléenne « true ». Peut être utilisé avec les ACLs comme remplacement temporaire d’une autre lorsque l’ajustement de la configuration est en cours.

avg_queue([<backend>]): integer

avg_queue([<backend>]): integer

Renvoie le nombre total de connexions en file d’attente pour le backend spécifié, divisé par le nombre de serveurs actifs. Le backend actuel est utilisé si aucun backend n’est précisé. Cette mesure est très similaire à « queue », sauf qu’elle tient compte de la taille de la ferme afin d’obtenir une estimation plus précise du temps nécessaire au traitement d’une nouvelle connexion. Son usage principal consiste à utiliser une ACL pour renvoyer une page d’excuse aux nouveaux utilisateurs lorsque l’on est certain qu’ils recevront un service dégradé, ou à transmettre cette valeur aux serveurs backend via un en-tête afin qu’ils décident de fonctionner en mode dégradé ou de désactiver certaines fonctions afin d’accélérer le traitement. Notez qu’en cas d’absence de serveur actif, le double du nombre de connexions en file d’attente est considéré comme la valeur mesurée. Il s’agit d’une estimation raisonnable, puisque l’on s’attend à ce qu’un serveur revienne bientôt, mais il est préférable de diriger le trafic nouveau vers un autre backend si celui-ci se trouve dans un meilleur état. Voir également les échantillons d’extraction « queue », “be_conn”, et “be_sess_rate”.

be_conn([<backend>]): integer

be_conn([<backend>]): integer

S’applique au nombre de connexions établies actuellement sur le backend, pouvant inclure la connexion en cours d’évaluation. Si aucun nom de backend n’est précisé, celui en cours est utilisé. Il est également possible de vérifier un autre backend. Cette option peut être utilisée pour utiliser une ferme spécifique lorsque la ferme nominale est pleine. Voir également les critères “fe_conn”, « queue », “be_conn_free”, et “be_sess_rate”.

be_conn_free([<backend>]): integer

be_conn_free([<backend>]): integer

Renvoie une valeur entière correspondant au nombre de connexions disponibles parmi les serveurs du backend. Les emplacements de file d’attente ne sont pas pris en compte. Les serveurs de secours ne sont pas inclus, sauf si tous les autres serveurs sont hors service. Si aucun nom de backend n’est spécifié, celui en cours est utilisé. Il est également possible de vérifier un autre backend. Cela peut être utilisé pour utiliser une ferme spécifique lorsque la ferme nominale est pleine. Voir également les critères “be_conn”, « connslots », et “srv_conn_free”.

AUTRES PRÉCAUTIONS ET NOTES : si l’une des valeurs server maxconn ou maxqueue est égale à 0 (ce qui signifie sans limite), alors cette requête n’a clairement pas de sens ; dans ce cas, la valeur renvoyée sera -1.

be_sess_rate([<backend>]): integer

be_sess_rate([<backend>]): integer

Renvoie une valeur entière correspondant au taux de création de sessions sur le backend, exprimé en nombre de nouvelles sessions par seconde. Cette valeur peut être utilisée avec des ACL pour basculer vers un backend alternatif lorsque le backend coûteux ou fragile atteint un taux de sessions trop élevé, ou pour limiter l’abus de service (par exemple, empêcher l’usure d’un dictionnaire en ligne). Elle peut également être utile pour inclure cet élément dans les journaux à l’aide d’une directive log-format.

Exemple :

# Redirect to an error page if the dictionary is requested too often
backend dynamic
    mode http
    acl being_scanned be_sess_rate gt 100
    redirect location /denied.html if being_scanned

bin(<hex>): bin

bin(<hex>): bin

Renvoie une chaîne binaire. L’entrée est la représentation hexadécimale de la chaîne.

bool(<bool>): bool

bool(<bool>): bool

Renvoie une valeur booléenne. <bool> peut être « true », « false », « 1 » ou « 0 ». « false » et « 0 » sont identiques. « true » et « 1 » sont identiques.

connslots([<backend>]): integer

connslots([<backend>]): integer

Renvoie une valeur entière correspondant au nombre d’emplacements de connexion encore disponibles dans le backend, en additionnant le nombre maximal de connexions sur tous les serveurs et la taille maximale de la file d’attente. Cela n’est probablement utilisé que dans le cadre des ACLs.

L’idée fondamentale consiste à pouvoir mesurer le nombre de “places” de connexion encore disponibles (connexion + file d’attente), afin que tout ce qui dépasse ce seuil (utilisation prévue ; voir le mot-clé “use_backend”) puisse être redirigé vers un autre backend.

‘connslots’ = nombre d’emplacements de connexion serveur disponibles, + nombre d’emplacements de file d’attente serveur disponibles.

Notez que bien que “fe_conn” puisse être utilisé, le paramètre « connslots » est particulièrement utile lorsque le trafic est dirigé vers une seule adresse IP, réparti entre plusieurs backends (par exemple, en utilisant des ACLs pour une répartition de charge basée sur le nom), et que vous souhaitez pouvoir distinguer les différents backends ainsi que leurs connslots disponibles. De plus, contrairement à « nbsrv », qui ne mesure que les serveurs effectivement hors service, cette requête est plus fine et examine également le nombre de connslots disponibles. Voir également « queue » et “avg_queue”.

AUTRES PRÉCAUTIONS ET NOTES : à ce stade, le code ne gère pas les connexions dynamiques. En outre, si l’une des valeurs server maxconn ou maxqueue est égale à 0, alors cette requête n’a clairement pas de sens, auquel cas la valeur renvoyée sera -1.

cpu_calls : entier Retourne le nombre d’appels effectués à la tâche traitant le flux ou la requête en cours depuis son allocation. Ce compteur est réinitialisé pour chaque nouvelle requête sur la même connexion en cas de maintien de la connexion HTTP (keep-alive). Cette valeur devrait généralement rester faible et stable (environ 2 appels pour une requête simple typique), mais peut augmenter si des traitements (compression, mise en cache ou analyse) sont effectués. Cette métrique est destinée exclusivement à la surveillance des performances.

cpu_ns_avg : entier Renvoie le nombre moyen de nanosecondes passées à chaque appel du traitement de la tâche sur le flux ou la requête en cours. Cette valeur est réinitialisée pour chaque nouvelle requête sur la même connexion en cas de maintien de la connexion HTTP (keep-alive). Cette valeur indique le coût global du traitement de la requête ou de la connexion pour chaque appel. Il n’existe pas de valeur bonne ni mauvaise, mais le temps passé dans un appel entraîne automatiquement une latence pour les autres traitements (voir lat_ns_avg ci-dessous) et peut affecter le temps de réponse apparent d’autres connexions. Certaines opérations, comme la compression, les correspondances regex complexes ou les opérations Lua intensives, peuvent directement affecter cette valeur, et son inclusion dans les journaux facilitera la détection du traitement défaillant nécessitant une correction pour retrouver des performances acceptables. Note : cette valeur est exactement égale à cpu_ns_tot divisé par cpu_calls.

cpu_ns_tot : entier Renvoie le nombre total de nanosecondes passées lors de chaque appel au traitement de la tâche sur le flux ou la requête en cours. Cette valeur est réinitialisée pour chaque nouvelle requête sur la même connexion en cas de maintien de la connexion HTTP (keep-alive). Cette valeur indique le coût global du traitement de la requête ou de la connexion pour chaque appel. Il n’existe pas de valeur bonne ni mauvaise, mais le temps passé dans un appel entraîne automatiquement une latence pour les autres traitements (voir lat_ns_avg ci-dessous), engendre des coûts CPU sur la machine et peut affecter le temps de réponse apparent d’autres connexions. Certaines opérations, comme la compression, les correspondances regex complexes ou les opérations Lua intensives, peuvent directement affecter cette valeur, et son inclusion dans les journaux facilite la détection du traitement défaillant qui doit être corrigé pour retrouver des performances correctes. La valeur peut être artificiellement élevée en raison d’un nombre élevé de cpu_calls, par exemple lors du traitement de nombreuses tranches HTTP, et c’est pourquoi il est souvent préférable de journaliser cpu_ns_avg à la place.

cpu_usage_grp : entier Retourne l’utilisation CPU mesurée au cours de la dernière boucle de sondage, comprise entre 0 et 100, moyennée sur tous les threads du groupe de threads courant. Cette mesure peut être utilisée pour le dépannage et la journalisation. La mesure est extrêmement volatile, mais reste précise pour des charges soutenues, chaque thread la mesurant sur quelques dizaines à plusieurs centaines de requêtes.

cpu_usage_proc : entier Retourne l’utilisation CPU mesurée au cours de la dernière boucle d’échantillonnage, comprise entre 0 et 100, moyennée sur tous les threads en cours d’exécution. Cette valeur peut être utilisée pour le dépannage et la journalisation. La mesure est extrêmement volatile, mais reste précise pour des charges soutenues, chaque thread la mesurant sur quelques dizaines à plusieurs centaines de requêtes. Cette valeur correspond à 100 moins celle indiquée dans le ratio inactif de la page de statistiques et dans la commande « show info ».

cpu_usage_thr : integer Renvoie l’utilisation du CPU mesurée au cours de la dernière boucle de sondage, comprise entre 0 et 100, pour le thread appelant. Cette valeur peut être utilisée pour le dépannage et la journalisation. La mesure est extrêmement volatile, mais reste précise pour des charges soutenues, car elle est établie sur quelques dizaines à plusieurs centaines de requêtes. Il s’agit de la même valeur utilisée pour décider d’activer le tuer des connexions en cas de pics trop élevés, ou de désactiver la compression. Voir également “tune.glitches.kill.cpu-usage” et « maxcompcpuusage ».

date([<offset>[,<unit>]]): integer

date([<offset>[,<unit>]]): integer

Renvoie la date actuelle au format epoch (nombre de secondes écoulées depuis 01/01/1970).

Si une valeur d’offset est spécifiée, elle est ajoutée à la date courante avant le retour de la valeur. Cela est particulièrement utile pour calculer des dates relatives, les offsets positifs et négatifs étant autorisés. Il est utile en combinaison avec le convertisseur http_date.

<unit> est facultatif et peut être défini à « s » pour secondes (comportement par défaut), « ms » pour millisecondes ou « us » pour microsecondes. Si l’unité est définie, la valeur renvoyée est un entier représentant respectivement les secondes, millisecondes ou microsecondes écoulées depuis l’époque, augmentées du décalage. Cette option est utile lorsque une résolution temporelle inférieure à une seconde est requise.

Exemple :

# set an expires header to now+1 hour in every response
http-response set-header Expires %[date(3600),http_date]

# set an expires header to now+1 hour in every response, with
# millisecond granularity
http-response set-header Expires %[date(3600000,ms),http_date(0,ms)]

date_us : entier Retourne la partie microsecondes de la date (la partie « seconde » est retournée par date_sample). Cet échantillon est cohérent avec l’échantillon de date car il provient de la même structure timeval.

env(<name>): string

env(<name>): string

Renvoie une chaîne contenant la valeur de la variable d’environnement <name>. Pour rappel, les variables d’environnement sont propres au processus et sont échantillonnées au démarrage du processus. Cela peut être utile pour transmettre certaines informations à un serveur suivant, ou en combinaison avec des listes de contrôle d’accès afin d’effectuer une action spécifique lorsque le processus est lancé d’une manière particulière.

Exemples :

# Pass the Via header to next hop with the local hostname in it
http-request add-header Via 1.1\ %[env(HOSTNAME)]

# reject cookie-less requests when the STOP environment variable is set
http-request deny if !{ req.cook(SESSIONID) -m found } { env(STOP) -m found }

fe_conn([<frontend>]): integer

fe_conn([<frontend>]): integer

Renvoie le nombre de connexions établies actuellement sur le frontal, pouvant inclure la connexion en cours d’évaluation. Si aucun nom de frontal n’est précisé, celui en cours est utilisé. Il est également possible de vérifier un autre frontal. Cette fonction peut être utilisée pour renvoyer une page d’excuses avant un blocage strict, ou pour rediriger les nouvelles requêtes vers un backend spécifique lorsqu’une ferme est considérée comme pleine. Elle est principalement utilisée avec les ACLs, mais peut aussi servir à transmettre certaines statistiques aux serveurs via des en-têtes HTTP. Voir également les récupérations “dst_conn”, “be_conn”, “fe_sess_rate”.

fe_req_rate([<frontend>]): integer

fe_req_rate([<frontend>]): integer

Renvoie une valeur entière correspondant au nombre de requêtes HTTP par seconde envoyées à un frontal. Ce nombre peut différer de “fe_sess_rate” dans les cas où la réutilisation de connexion côté client est activée.

fe_sess_rate([<frontend>]): integer

fe_sess_rate([<frontend>]): integer

Renvoie une valeur entière correspondant au taux de création de sessions sur le frontal, exprimé en nombre de nouvelles sessions par seconde. Cette valeur peut être utilisée avec des ACLs afin de limiter le taux d’arrivée des sessions à une plage acceptable, afin d’éviter toute abuse du service dès le plus tôt possible, par exemple en combinaison avec d’autres ACLs au niveau 4 pour obliger les clients à attendre que le taux descende en dessous de la limite. Elle peut également être utile pour inclure cet élément dans les journaux en utilisant une directive log-format. Voir également la directive « rate-limit sessions » pour une utilisation dans les frontaux.

Exemple :

# This frontend limits incoming mails to 10/s with a max of 100
# concurrent connections. We accept any connection below 10/s, and
# force excess clients to wait for 100 ms. Since clients are limited to
# 100 max, there cannot be more than 10 incoming mails per second.
frontend mail
    bind:25
    mode tcp
    maxconn 100
    acl too_fast fe_sess_rate ge 10
    tcp-request inspect-delay 100ms
    tcp-request content accept if ! too_fast
    tcp-request content accept if WAIT_END

hostname : chaîne Retourne le nom d’hôte du système.

int(<integer>): signed integer

int(<integer>): signed integer

Renvoie un entier signé.

ipv4(<ipv4>): ipv4

ipv4(<ipv4>): ipv4

Renvoie un IPv4.

ipv6(<ipv6>): ipv6

ipv6(<ipv6>): ipv6

Renvoie une adresse ipv6.

last_entity : chaîne Cette valeur retourne l’identité de la dernière entité évaluée lors de l’analyse en flux. Il peut s’agir de la règle finale correspondante ou du filtre ayant interrompu le traitement.

Une règle finale est une règle qui termine l’évaluation de l’ensemble de règles (comme une « accept », une « deny » ou une « redirect »). Cette fonctionnalité s’applique aux règles TCP de requête et de réponse agissant sur les jeux de règles « content », ainsi qu’aux règles HTTP des jeux « http-request », « http-response » et « http-after-response ». Les anciens jeux de règles « redirect » ne sont pas pris en charge (les informations ne sont pas stockées là-bas), ni les jeux de règles « tcp-request connection » ni « tcp-request session », car les informations sont stockées au niveau du flux et les flux n’existent pas lors de l’évaluation de ces règles. Dans ce cas, la valeur renvoyée est équivalente à « last_rule_file:last_rule_line ». Voir également “last_rule_file”, “last_rule_line”.

Pour un filtre, son identifiant est renvoyé tel qu’il est défini par les développeurs. Si cet identifiant n’est pas défini, une valeur hexadécimale est renvoyée, correspondant à un identifiant interne unique.

Le but principal de cette fonction est de permettre de signaler dans les journaux l’entité ayant interrompu le traitement en dernier, afin d’aider au débogage des problèmes. Les informations renvoyées concernant les entités peuvent évoluer au fil du temps et ne doivent pas être utilisées à d’autres fins que le débogage.

Exemple :

# Log the last entity, if any, and only if an error is reported
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[last_entity,when(error)]

last_rule_file: chaîne Cette fonction retourne le nom du fichier de configuration contenant la dernière règle finale correspondante durant l’analyse du flux. Une règle finale est une règle qui termine l’évaluation de l’ensemble des règles (comme une règle « accept », « deny » ou « redirect »). Cette fonction est applicable aux règles TCP de requête et de réponse agissant sur les jeux de règles « content », ainsi qu’aux règles HTTP des jeux « http-request », « http-response » et « http-after-response ». Les anciens jeux de règles « redirect » ne sont pas pris en charge (cette information n’est pas stockée là-dedans), ni les jeux de règles « tcp-request connection » ni « tcp-request session », car l’information est stockée au niveau du flux, or les flux n’existent pas lors de l’évaluation de ces règles. Le but principal de cette fonction est de permettre de signaler dans les journaux où se trouvait la règle qui a donné le verdict final, afin d’aider à déterminer pourquoi une requête a été refusée, par exemple. Voir également “last_rule_line”.

last_rule_line: integer Cette fonction renvoie le numéro de ligne dans le fichier de configuration où se trouve la dernière règle finale correspondante durant l’analyse du flux. Une règle finale est une règle qui met fin à l’évaluation de l’ensemble des règles (comme une règle « accept », « deny » ou « redirect »). Cette fonction est valable pour les règles TCP de requête et réponse agissant sur les jeux de règles « content », ainsi que pour les règles HTTP des jeux « http-request », « http-response » et « http-after-response ». Les jeux de règles « redirect » obsolètes ne sont pas pris en charge (cette information n’est pas stockée là-dedans), ni les jeux de règles « tcp-request connection » ni « tcp-request session », car l’information est stockée au niveau du flux et les flux n’existent pas lors de l’évaluation de ces règles. Le principal objectif de cette fonction est de permettre de signaler dans les journaux où se trouvait la règle qui a donné le verdict final, afin d’aider à déterminer pourquoi une requête a été refusée, par exemple. Voir également “last_rule_file”.

lat_ns_avg : entier Retourne le nombre moyen de nanosecondes passées entre le moment où la tâche gérant le flux est réveillée et le moment où elle est effectivement appelée. Cette valeur est réinitialisée pour chaque nouvelle requête sur la même connexion en cas de maintien de la connexion HTTP (keep-alive). Cette valeur indique la latence globale imposée à la requête courante par toutes les autres requêtes traitées en parallèle, et constitue un indicateur direct des performances perçues en raison de voisins bruyants. Pour maintenir cette valeur faible, il est possible de réduire la profondeur de la file d’exécution du planificateur en utilisant “tune.runqueue-depth”, de réduire le nombre d’événements concurrents traités simultanément en utilisant “tune.maxpollevents”, de diminuer la priorité du flux en utilisant l’option “nice” dans les lignes “bind” ou dans le frontal, d’activer la planification à faible latence en utilisant “tune.sched.low-latency”, ou de rechercher d’autres requêtes lourdes dans les journaux (celles présentant des valeurs élevées de “cpu_ns_avg”), dont le traitement doit être ajusté ou corrigé. La compression de grands tampons pourrait être en cause, tout comme les expressions régulières complexes ou les listes longues d’expressions régulières. Remarque : cette valeur est exactement égale à lat_ns_tot divisé par cpu_calls.

lat_ns_tot : entier Retourne le nombre total de nanosecondes passées entre le moment où la tâche chargée du traitement du flux est réveillée et le moment où elle est effectivement appelée. Cette valeur est réinitialisée pour chaque nouvelle requête sur la même connexion en cas de maintien de la connexion HTTP (keep-alive). Cette mesure indique la latence globale imposée à la requête courante par toutes les autres requêtes en cours d’exécution en parallèle, et constitue un indicateur direct des performances perçues en raison de voisins bruyants. Pour maintenir cette valeur faible, il est possible de réduire la profondeur de la file d’exécution du planificateur en utilisant “tune.runqueue-depth”, de réduire le nombre d’événements concurrents traités simultanément en utilisant “tune.maxpollevents”, de diminuer la priorité du flux en utilisant l’option “nice” dans les lignes “bind” ou au niveau du frontal, d’activer le planification à faible latence en utilisant “tune.sched.low-latency”, ou de rechercher d’autres requêtes lourdes dans les journaux (celles présentant des valeurs élevées de “cpu_ns_avg”), dont le traitement doit être ajusté ou corrigé. La compression de grands tampons pourrait être une cause, tout comme des expressions régulières complexes ou des listes longues d’expressions régulières. Remarque : bien que l’on puisse intuitivement penser que la latence totale s’ajoute au temps de transfert, cela est presque jamais le cas, car pendant qu’une tâche attend le CPU, les tampons réseau continuent de se remplir et l’appel suivant traitera davantage d’un coup. La valeur peut être artificiellement élevée en raison d’un nombre élevé de cpu_calls, par exemple lors du traitement de nombreuses tranches HTTP, et c’est pourquoi il est souvent préférable de journaliser lat_ns_avg à la place, qui constitue un indicateur de performance plus pertinent.

meth(<method>): method

meth(<method>): method

Renvoie une méthode.

nbsrv([<backend>]): integer

nbsrv([<backend>]): integer

Renvoie une valeur entière correspondant au nombre de serveurs utilisables du backend actuel ou du backend nommé. Cette fonction est principalement utilisée avec les ACLs, mais peut également être utile lorsqu’elle est ajoutée aux journaux. Elle est normalement utilisée pour basculer vers un backend alternatif lorsque le nombre de serveurs est trop faible pour gérer une charge donnée. Elle est utile pour signaler une défaillance lorsqu’elle est combinée avec « monitor fail ».

pid : entier Retourne le PID du processus en cours. Dans la plupart des cas, il s’agit du PID du processus worker.

prio_class : integer Renvoie la classe de priorité du flux actuel en mode http ou de la connexion en mode tcp. La valeur correspond à celle définie par l’appel précédent à « http-request set-priority-class » ou « tcp-request content set-priority-class ».

prio_offset : entier Renvoie le décalage de priorité du flux actuel en mode http ou de connexion en mode tcp. La valeur correspond à celle définie par l’appel précédent à « http-request set-priority-offset » ou « tcp-request content set-priority-offset ».

proc : entier Retourne toujours la valeur 1 (historiquement, elle renvoyait le numéro du processus appelant).

queue([<backend>]): integer

queue([<backend>]): integer

Renvoie le nombre total de connexions en file d’attente du backend spécifié, y compris toutes les connexions dans les files d’attente serveur. Si aucun nom de backend n’est précisé, celui actuel est utilisé, mais il est également possible de vérifier un autre backend. Cela est utile avec les listes de contrôle d’accès (ACL) ou pour transmettre des statistiques aux serveurs backend. Cette information peut être utilisée pour déclencher des actions lorsque la file d’attente dépasse un seuil connu, généralement un indicateur d’une forte augmentation du trafic ou d’un ralentissement massif des serveurs. Une action possible pourrait être de rejeter les nouveaux utilisateurs tout en acceptant les anciens. Voir également les récupérations “avg_queue”, “be_conn”, et “be_sess_rate”.

quic_enabled: boolean Retourne true lorsque le support du protocole de transport QUIC a été compilé et que les écouteurs QUIC ne sont pas désactivés par l’option globale “tune.quic.listen”. Voir également l’option globale “tune.quic.listen”.

rand([<range>]): integer

rand([<range>]): integer

Renvoie une valeur entière aléatoire dans une plage de <range> valeurs possibles, en commençant à zéro. Si la plage n’est pas spécifiée, elle vaut par défaut 2^32, ce qui donne des nombres compris entre 0 et 4294967295. Elle peut être utile pour transmettre certaines valeurs permettant de prendre des décisions de routage, par exemple, ou simplement à des fins de débogage. Ce hasard ne doit pas être utilisé à des fins de sécurité.

srv_conn([<backend>/]<server>): integer

srv_conn([<backend>/]<server>): integer

Renvoie une valeur entière correspondant au nombre de connexions établies actuellement sur le serveur désigné, pouvant inclure la connexion en cours d’évaluation. Si <backend> est omis, le serveur est recherché dans le backend actuel. Cette fonction peut être utilisée pour cibler une ferme spécifique lorsqu’un serveur est plein, ou pour informer le serveur de notre vue sur le nombre de connexions actives avec lui. Voir également les méthodes de récupération “fe_conn”, “be_conn”, “queue” et “srv_conn_free”.

srv_conn_free([<backend>/]<server>): integer

srv_conn_free([<backend>/]<server>): integer

Renvoie une valeur entière correspondant au nombre de connexions disponibles sur le serveur désigné, pouvant inclure la connexion en cours d’évaluation. La valeur ne tient pas compte des emplacements dans la file d’attente. Si <backend> est omis, le serveur est recherché dans le backend actuel. Cette fonction peut être utilisée pour sélectionner une ferme spécifique lorsque un serveur est plein, ou pour informer le serveur de notre vue du nombre de connexions actives avec lui. Voir également les méthodes de récupération “be_conn_free” et “srv_conn”.

AUTRES PRÉCAUTIONS ET NOTES : Si la limite maxconn du serveur est 0, alors cette récupération n’a clairement pas de sens, auquel cas la valeur renvoyée sera -1.

srv_is_up([<backend>/]<server>): boolean

srv_is_up([<backend>/]<server>): boolean

Retourne true lorsque le serveur désigné est UP, et false lorsqu’il est DOWN ou en mode maintenance. Si <backend> est omis, le serveur est recherché dans le backend actuel. Il est principalement utilisé pour déclencher une action en fonction d’un état externe rapporté par un contrôle d’état (par exemple, la disponibilité d’un site géographique). Une autre utilisation possible, plus proche d’un hack, consiste à utiliser des serveurs fictifs comme des variables booléennes pouvant être activées ou désactivées depuis la ligne de commande, afin de modifier en temps réel les règles dépendant de ces ACLs.

srv_iweight([<backend>/]<server>): integer

srv_iweight([<backend>/]<server>): integer

Renvoie un entier correspondant au poids initial du serveur. Si <backend> est omis, alors le serveur est recherché dans le backend actuel. Voir également “srv_weight” et “srv_uweight”.

srv_queue([<backend>/]<server>): integer

srv_queue([<backend>/]<server>): integer

Renvoie une valeur entière correspondant au nombre de connexions actuellement en attente dans la file d’attente du serveur désigné. Si <backend> est omis, le serveur est recherché dans le backend actuel. Cette fonction peut parfois être utilisée conjointement avec la directive “use-server” afin de forcer l’utilisation d’un serveur connu plus rapide lorsque celui-ci n’est pas trop chargé. Voir également les méthodes d’extraction “srv_conn”, “avg_queue” et “queue”.

srv_sess_rate([<backend>/]<server>): integer

srv_sess_rate([<backend>/]<server>): integer

Renvoie un entier correspondant au taux de création de sessions sur le serveur désigné, en nombre de nouvelles sessions par seconde. Si <backend> est omis, le serveur est recherché dans le backend actuel. Cette fonction est principalement utilisée avec les ACLs, mais peut également être utile dans les journaux. Elle permet de basculer vers un backend alternatif lorsque celui-ci, coûteux ou fragile, atteint un taux de sessions trop élevé, ou de limiter l’abus de service (par exemple, empêcher les requêtes latentes de surcharger les serveurs).

Exemple :

# Redirect to a separate back
acl srv1_full srv_sess_rate(be1/srv1) gt 50
acl srv2_full srv_sess_rate(be1/srv2) gt 50
use_backend be2 if srv1_full or srv2_full

srv_uweight([<backend>/]<server>): integer

srv_uweight([<backend>/]<server>): integer

Renvoie un entier correspondant au poids du serveur visible par l’utilisateur. Si <backend> est omis, alors le serveur est recherché dans le backend actuel. Voir également “srv_weight” et “srv_iweight”.

srv_weight([<backend>/]<server>): integer

srv_weight([<backend>/]<server>): integer

Renvoie un entier correspondant au poids du serveur actuel (ou effectif). Si <backend> est omis, le serveur est recherché dans le backend actuel. Voir également “srv_iweight” et “srv_uweight”.

arrêt : booléen Retourne TRUE si le processus appelant la fonction est actuellement en arrêt. Cela peut être utile pour la journalisation, ou pour assouplir certaines vérifications ou aider à fermer certaines connexions lors d’un arrêt progressif.

str(<string>): string

str(<string>): string

Renvoie une chaîne de caractères.

table_avl([<table>]): integer

table_avl([<table>]): integer

Renvoie le nombre total d’entrées disponibles dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Voir également “table_cnt”.

table_cnt([<table>]): integer

table_cnt([<table>]): integer

Renvoie le nombre total d’entrées actuellement utilisées dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Voir également “table_conn_cnt” et table_avl pour d’autres méthodes de comptage des entrées.

term_events : chaîne Retourne tous les événements de terminaison connus pour toutes les entités attachées à un flux, côté client et côté serveur. Un tuple de sept éléments est retourné, contenant les informations suivantes :

- les événements de terminaison de la connexion frontale
- les événements de terminaison de la connexion multiplexée frontale
- les événements de terminaison du descripteur de point d’entrée de flux frontale
  (le flux multiplexé ou l’application)
- les événements de terminaison du flux
- les événements de terminaison du descripteur de point d’entrée de flux arrière
  (le flux multiplexé ou l’application)
- les événements de terminaison de la connexion multiplexée arrière
- les événements de terminaison de la connexion arrière

À chaque niveau, les quatre premiers événements sont signalés. Une chaîne vide est renvoyée si aucun événement n’a encore été signalé pour un niveau spécifique. Si les événements de terminaison ne sont pas pris en charge, un tiret “-” est renvoyé.

Il ne doit être utilisé que à des fins de débogage. Le format exact n’est pas documenté car il peut évoluer en fonction des besoins des développeurs.

tgroup : integer Renvoie une valeur entière correspondant à la position du groupe de threads appelant la fonction, comprise entre 0 et (global.thread-groups - 1). Utile à des fins de journalisation et de débogage.

thread : entier Renvoie une valeur entière correspondant à la position du thread appelant la fonction, comprise entre 0 et (global.nbthread-1). Cela est utile à des fins de journalisation et de débogage.

txn.id32 : entier Renvoie l’identifiant interne de la transaction. Il s’agit d’un entier sur 32 bits. En valeur absolue, sa valeur n’est donc pas unique ; les identifiants de transaction peuvent donc s’entourer. La période d’entouragement dépend du débit des requêtes. En pratique, cela ne devrait pas poser de problème. Pour un identifiant unique véritable, voir la directive « unique-id-format ».

txn.sess_term_state : chaîne Retourne l’état de terminaison du flux TCP ou HTTP, tel qu’indiqué dans le journal. Il s’agit d’une chaîne de deux caractères : l’état final du flux suivi de l’événement ayant provoqué sa terminaison. Consultez la section 8.5 pour obtenir la liste des événements possibles. La valeur actuelle au moment de l’évaluation de l’extraction d’échantillon est retournée. Elle peut évoluer. Sauf lorsqu’elle est utilisée dans des règles ACL du type « http-after-response » ou dans des messages de journalisation, elle sera toujours « – ».

Exemple :

# Return a 429-Too-Many-Requests if stream timed out in queue
http-after-response set-status 429 if { txn.sess_term_state  "sQ" }

uptime : entier Retourne le temps d’exécution du worker HAProxy actuel en secondes.

uuid([<version>]): string

uuid([<version>]): string

Renvoie un UUID conforme à la norme RFC 9562. Si la version n’est pas précisée, un UUID de version 4 (entièrement aléatoire) est renvoyé.

Les versions 4 et 7 sont prises en charge.

var(<var-name>[,<default>]): undefined

var(<var-name>[,<default>]): undefined

Renvoie une variable avec son type stocké. Si la variable n’est pas définie, l’extraction d’échantillon échoue, sauf si une valeur par défaut est fournie, auquel cas celle-ci est renvoyée sous forme de chaîne. Les chaînes vides sont autorisées. Voir section 2.8 sur les variables pour plus de détails.

dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string

dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string

Renvoie la liste de toutes les variables dans la portée spécifiée, éventuellement filtrée par un préfixe de nom et avec un délimiteur personnalisable.

Format de sortie : var1=value1<delim>var2=value2<delim>…

Encodage des valeurs par type :

  • Chaînes : entre guillemets et échappées (", \, \r, \n, \b, \0) Exemple : txn.name=“John \“Doe\””
  • Binaire : encodé en hexadécimal avec préfixe ‘x’, non entre guillemets Exemple : txn.data=x48656c6c6f
  • Entiers : décimal non entre guillemets Exemple : txn.count=42
  • Booléens : “true” ou “false” non entre guillemets Exemple : txn.active=true
  • Adresses : chaîne d’adresse IP non entre guillemets Exemple : txn.client=192.168.1.1
  • Méthodes HTTP : chaîne entre guillemets Exemple : req.method=“GET”

Arguments :

  • <scope> (facultatif) : sess, txn, req, res ou proc. Si omis, toutes ces portées sont parcourues dans le même ordre que présenté ici.

  • <prefix> (facultatif) : filtre les variables dont le nom commence par le préfixe spécifié (après suppression du préfixe d’étendue). Note sur les performances : lorsque le filtrage par préfixe est utilisé, toutes les variables de l’étendue sont toujours parcourues. Ce paramètre ne doit pas être utilisé avec des configurations comportant des milliers de variables.

  • <delimiter> (facultatif) : chaîne utilisée pour séparer les variables. Valeur par défaut : “, " (virgule-espace). Peut être personnalisée avec n’importe quelle chaîne. Pour rappel, afin de passer des virgules ou des espaces en tant qu’argument de fonction, ils doivent être enclos entre guillemets simples ou doubles (si l’expression elle-même est déjà entre guillemets, utiliser l’autre type).

Valeur de retour :

  • En cas de succès : chaîne contenant toutes les variables correspondantes
  • En cas d’échec : chaîne vide (l’extraction d’échantillon échoue) si la mémoire tampon de sortie est trop petite. La fonction ne tronque pas la sortie ; elle échoue complètement afin d’éviter les données partielles.

Cela est particulièrement utile pour le débogage, la journalisation ou l’exportation d’états de variables.

Exemples :

# Dump all transaction variables
http-request return string %[dump_all_vars(txn)]

# Dump only variables starting with "user"
http-request set-header X-User-Vars "%[dump_all_vars(txn,user)]"

# Dump all process variables
http-request return string %[dump_all_vars(proc)]

# Custom delimiter (semicolon)
http-request set-header X-Vars "%[dump_all_vars(txn,,; )]"

# Force the default delimiter (comma space)
http-request set-header X-Vars "%[dump_all_vars(txn,,', ')]"

# Prefix filter with custom delimiter
http-request set-header X-Session "%[dump_all_vars(sess,user,|)]"

wait_end : boolean Cette instruction renvoie soit true lorsque la période d’inspection est terminée, soit ne renvoie rien. Elle n’est utilisée qu’avec les listes de contrôle d’accès (ACL), en conjonction avec l’analyse du contenu, afin d’éviter de renvoyer un verdict erroné prématurément. Elle peut également servir à retarder certaines actions, comme un rejet différé pour certaines adresses spéciales. Étant donné qu’elle arrête soit l’évaluation des règles, soit renvoie immédiatement true, il est recommandé de placer cette ACL en dernière position d’une règle. Veuillez noter que la liste de contrôle d’accès par défaut “WAIT_END” est toujours utilisable sans déclaration préalable. Ce test a été conçu pour être utilisé avec l’inspection du contenu des requêtes TCP.

Exemples :

# delay every incoming request by 2 seconds
tcp-request inspect-delay 2s
tcp-request content accept if WAIT_END

# don't immediately tell bad guys they are rejected
tcp-request inspect-delay 10s
acl goodguys src 10.0.0.0/24
acl badguys  src 10.0.1.0/24
tcp-request content accept if goodguys
tcp-request content reject if badguys WAIT_END
tcp-request content reject

waiting_entity : chaîne Cette valeur retourne l’identité de l’entité qui attendait de poursuivre son traitement lorsque une erreur ou un délai d’expiration a été rencontré. Il peut s’agir par exemple d’une règle ou d’un filtre. Toutefois, cette liste n’est pas exhaustive et le format de toutes les entités possibles n’est pas obligatoirement documenté.

Lorsque l’entité est une règle, son emplacement est renvoyé. Il s’agit du fichier de configuration contenant la règle, suivi de la ligne où la règle est définie dans ce fichier, séparés par deux points.

Pour un filtre, son identifiant est renvoyé tel qu’il est défini par les développeurs. Si cet identifiant n’est pas défini, une valeur hexadécimale est renvoyée, correspondant à un identifiant interne unique.

Le but principal de cette fonction est de permettre de signaler dans les journaux l’entité bloquant l’analyse du flux lorsqu’une erreur ou un délai d’expiration est détecté, interrompant ainsi ce traitement, afin d’aider au débogage des problèmes. Les informations renvoyées concernant les entités peuvent évoluer au fil du temps et ne doivent pas être utilisées à d’autres fins que le débogage.

Exemple :

# Log the waiting entity, if any, and only if an error is reported
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[waiting_entity,when(error)]

7.3.3. Récupération des échantillons au niveau 4

Le niveau 4 décrit généralement la couche transport, qui chez HAProxy correspond le plus près à la connexion, où aucun contenu n’est encore disponible. Les méthodes de récupération décrites ici sont utilisables dès la règle “tcp-request connection”, à moins qu’elles nécessitent des informations futures. Celles-ci incluent généralement les adresses et ports TCP/IP, ainsi que les éléments des tables de persistance liés à la connexion entrante. Pour récupérer une valeur à partir d’un compteur de persistance, le numéro du compteur peut être explicitement défini à 0, 1 ou 2 en utilisant les préfixes prédéfinis “sc0_”, “sc1_” ou “sc2_”. Ces trois préfixes prédéfinis ne peuvent être utilisés que si la valeur globale “tune.stick-counters” ne dépasse pas 3 ; sinon, le numéro du compteur peut être spécifié comme premier argument entier lors de l’utilisation du préfixe “sc_”, à partir de “sc_0” jusqu’à “sc_N”, où N est égal à (tune.stick-counters-1). Une table optionnelle peut être spécifiée au format “sc*”, auquel cas la clé actuellement suivie sera recherchée dans cette table alternative plutôt que dans la table actuellement suivie.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                          output type
-------------------------------------------------+-------------
accept_date([<unit>])                              integer
bc.timer.connect                                   integer
bc_be_queue                                        integer
bc_dst                                             ip
bc_dst_port                                        integer
bc_err                                             integer
bc_err_name                                        string
bc_err_str                                         string
bc_glitches                                        integer
bc_http_major                                      integer
bc_nb_streams                                      integer
bc_reused                                          boolean
bc_rtt(<unit>)                                     integer
bc_rttvar(<unit>)                                  integer
bc_settings_streams_limit                          integer
bc_src                                             ip
bc_src_port                                        integer
bc_srv_queue                                       integer
be_id                                              integer
be_name                                            string
be_connect_timeout                                 integer
be_queue_timeout                                   integer
be_server_timeout                                  integer
be_tarpit_timeout                                  integer
be_tunnel_timeout                                  integer
bytes_in                                           integer
bytes_out                                          integer
cur_connect_timeout                                integer
cur_client_timeout                                 integer
cur_queue_timeout                                  integer
cur_server_timeout                                 integer
cur_tarpit_timeout                                 integer
cur_tunnel_timeout                                 integer
dst                                                ip
dst_conn                                           integer
dst_is_local                                       boolean
dst_port                                           integer
fc.timer.handshake                                 integer
fc.timer.total                                     integer
fc_dst                                             ip
fc_dst_is_local                                    boolean
fc_dst_port                                        integer
fc_err                                             integer
fc_err_name                                        string
fc_err_str                                         string
fc_fackets                                         integer
fc_glitches                                        integer
fc_http_major                                      integer
fc_lost                                            integer
fc_nb_streams                                      integer
fc_pp_authority                                    string
fc_pp_tlv(<id>)                                    string
fc_pp_unique_id                                    string
fc_rcvd_proxy                                      boolean
fc_reordering                                      integer
fc_retrans                                         integer
fc_rtt(<unit>)                                     integer
fc_rttvar(<unit>)                                  integer
fc_sacked                                          integer
fc_saved_syn                                       binary
fc_settings_streams_limit                          integer
fc_src                                             ip
fc_src_is_local                                    boolean
fc_src_port                                        integer
fc_unacked                                         integer
fe_tarpit_timeout                                  integer
fe_client_timeout                                  integer
fe_defbe                                           string
fe_id                                              integer
fe_name                                            string
req.bytes_in                                       integer
req.bytes_out                                      integer
res.bytes_in                                       integer
res.bytes_out                                      integer
res.timer.data                                     integer
sc0_bytes_in_rate([<table>])                       integer
sc0_bytes_out_rate([<table>])                      integer
sc0_clr_gpc0([<table>])                            integer
sc0_clr_gpc1([<table>])                            integer
sc0_conn_cnt([<table>])                            integer
sc0_conn_cur([<table>])                            integer
sc0_conn_rate([<table>])                           integer
sc0_get_gpc0([<table>])                            integer
sc0_get_gpc1([<table>])                            integer
sc0_get_gpt0([<table>])                            integer
sc0_glitch_cnt([<table>])                          integer
sc0_glitch_rate([<table>])                         integer
sc0_gpc0_rate([<table>])                           integer
sc0_gpc1_rate([<table>])                           integer
sc0_http_err_cnt([<table>])                        integer
sc0_http_err_rate([<table>])                       integer
sc0_http_fail_cnt([<table>])                       integer
sc0_http_fail_rate([<table>])                      integer
sc0_http_req_cnt([<table>])                        integer
sc0_http_req_rate([<table>])                       integer
sc0_inc_gpc0([<table>])                            integer
sc0_inc_gpc1([<table>])                            integer
sc0_kbytes_in([<table>])                           integer
sc0_kbytes_out([<table>])                          integer
sc0_key                                            any
sc0_sess_cnt([<table>])                            integer
sc0_sess_rate([<table>])                           integer
sc0_tracked([<table>])                             boolean
sc0_trackers([<table>])                            integer
sc1_bytes_in_rate([<table>])                       integer
sc1_bytes_out_rate([<table>])                      integer
sc1_clr_gpc0([<table>])                            integer
sc1_clr_gpc1([<table>])                            integer
sc1_conn_cnt([<table>])                            integer
sc1_conn_cur([<table>])                            integer
sc1_conn_rate([<table>])                           integer
sc1_get_gpc0([<table>])                            integer
sc1_get_gpc1([<table>])                            integer
sc1_get_gpt0([<table>])                            integer
sc1_glitch_cnt([<table>])                          integer
sc1_glitch_rate([<table>])                         integer
sc1_gpc0_rate([<table>])                           integer
sc1_gpc1_rate([<table>])                           integer
sc1_http_err_cnt([<table>])                        integer
sc1_http_err_rate([<table>])                       integer
sc1_http_fail_cnt([<table>])                       integer
sc1_http_fail_rate([<table>])                      integer
sc1_http_req_cnt([<table>])                        integer
sc1_http_req_rate([<table>])                       integer
sc1_inc_gpc0([<table>])                            integer
sc1_inc_gpc1([<table>])                            integer
sc1_kbytes_in([<table>])                           integer
sc1_kbytes_out([<table>])                          integer
sc1_key                                            any
sc1_sess_cnt([<table>])                            integer
sc1_sess_rate([<table>])                           integer
sc1_tracked([<table>])                             boolean
sc1_trackers([<table>])                            integer
sc2_bytes_in_rate([<table>])                       integer
sc2_bytes_out_rate([<table>])                      integer
sc2_clr_gpc0([<table>])                            integer
sc2_clr_gpc1([<table>])                            integer
sc2_conn_cnt([<table>])                            integer
sc2_conn_cur([<table>])                            integer
sc2_conn_rate([<table>])                           integer
sc2_get_gpc0([<table>])                            integer
sc2_get_gpc1([<table>])                            integer
sc2_get_gpt0([<table>])                            integer
sc2_glitch_cnt([<table>])                          integer
sc2_glitch_rate([<table>])                         integer
sc2_gpc0_rate([<table>])                           integer
sc2_gpc1_rate([<table>])                           integer
sc2_http_err_cnt([<table>])                        integer
sc2_http_err_rate([<table>])                       integer
sc2_http_fail_cnt([<table>])                       integer
sc2_http_fail_rate([<table>])                      integer
sc2_http_req_cnt([<table>])                        integer
sc2_http_req_rate([<table>])                       integer
sc2_inc_gpc0([<table>])                            integer
sc2_inc_gpc1([<table>])                            integer
sc2_kbytes_in([<table>])                           integer
sc2_kbytes_out([<table>])                          integer
sc2_key                                            any
sc2_sess_cnt([<table>])                            integer
sc2_sess_rate([<table>])                           integer
sc2_tracked([<table>])                             boolean
sc2_trackers([<table>])                            integer
sc_bytes_in_rate(<ctr>[,<table>])                  integer
sc_bytes_out_rate(<ctr>[,<table>])                 integer
sc_clr_gpc(<idx>,<ctr>[,<table>])                  integer
sc_clr_gpc0(<ctr>[,<table>])                       integer
sc_clr_gpc1(<ctr>[,<table>])                       integer
sc_conn_cnt(<ctr>[,<table>])                       integer
sc_conn_cur(<ctr>[,<table>])                       integer
sc_conn_rate(<ctr>[,<table>])                      integer
sc_get_gpc(<idx>,<ctr>[,<table>])                  integer
sc_get_gpc0(<ctr>[,<table>])                       integer
sc_get_gpc1(<ctr>[,<table>])                       integer
sc_get_gpt(<idx>,<ctr>[,<table>])                  integer
sc_get_gpt0(<ctr>[,<table>])                       integer
sc_glitch_cnt(<ctr>[,<table>])                     integer
sc_glitch_rate(<ctr>[,<table>])                    integer
sc_gpc0_rate(<ctr>[,<table>])                      integer
sc_gpc1_rate(<ctr>[,<table>])                      integer
sc_gpc_rate(<idx>,<ctr>[,<table>])                 integer
sc_http_err_cnt(<ctr>[,<table>])                   integer
sc_http_err_rate(<ctr>[,<table>])                  integer
sc_http_fail_cnt(<ctr>[,<table>])                  integer
sc_http_fail_rate(<ctr>[,<table>])                 integer
sc_http_req_cnt(<ctr>[,<table>])                   integer
sc_http_req_rate(<ctr>[,<table>])                  integer
sc_inc_gpc(<idx>,<ctr>[,<table>])                  integer
sc_inc_gpc0(<ctr>[,<table>])                       integer
sc_inc_gpc1(<ctr>[,<table>])                       integer
sc_kbytes_in(<ctr>[,<table>])                      integer
sc_kbytes_out(<ctr>[,<table>])                     integer
sc_key(<ctr>)                                      any
sc_sess_cnt(<ctr>[,<table>])                       integer
sc_sess_rate(<ctr>[,<table>])                      integer
sc_tracked(<ctr>[,<table>])                        boolean
sc_trackers(<ctr>[,<table>])                       integer
so_id                                              integer
so_name                                            string
src                                                ip
src_bytes_in_rate([<table>])                       integer
src_bytes_out_rate([<table>])                      integer
src_clr_gpc(<idx>[,<table>])                       integer
src_clr_gpc0([<table>])                            integer
src_clr_gpc1([<table>])                            integer
src_conn_cnt([<table>])                            integer
src_conn_cur([<table>])                            integer
src_conn_rate([<table>])                           integer
src_get_gpc(<idx>[,<table>])                       integer
src_get_gpc0([<table>])                            integer
src_get_gpc1([<table>])                            integer
src_get_gpt(<idx>[,<table>])                       integer
src_get_gpt0([<table>])                            integer
src_glitch_cnt([<table>])                          integer
src_glitch_rate([<table>])                         integer
src_gpc0_rate([<table>])                           integer
src_gpc1_rate([<table>])                           integer
src_gpc_rate(<idx>[,<table>])                      integer
src_http_err_cnt([<table>])                        integer
src_http_err_rate([<table>])                       integer
src_http_fail_cnt([<table>])                       integer
src_http_fail_rate([<table>])                      integer
src_http_req_cnt([<table>])                        integer
src_http_req_rate([<table>])                       integer
src_inc_gpc(<idx>[,<table>])                       integer
src_inc_gpc0([<table>])                            integer
src_inc_gpc1([<table>])                            integer
src_is_local                                       boolean
src_kbytes_in([<table>])                           integer
src_kbytes_out([<table>])                          integer
src_port                                           integer
src_sess_cnt([<table>])                            integer
src_sess_rate([<table>])                           integer
src_updt_conn_cnt([<table>])                       integer
srv_id                                             integer
srv_name                                           string
txn.conn_retries                                   integer
txn.redispatched                                   boolean
-------------------------------------------------+-------------

Liste détaillée :

accept_date([<unit>]): integer

accept_date([<unit>]): integer

C’est la date exacte à laquelle la connexion a été reçue par HAProxy (qui peut différer très légèrement de la date observée sur le réseau si une file d’attente s’est formée dans la file de backlog du système). Cette date correspond généralement à celle qui peut apparaître dans les journaux de tout pare-feu en amont. En mode HTTP, le champ accept_date est réinitialisé au moment où la connexion est prête à recevoir une nouvelle requête (fin de la réponse précédente pour HTTP/1, immédiatement après la requête précédente pour HTTP/2).

Renvoie une valeur en nombre de secondes depuis l’époque.

<unit> est facultatif et peut être défini à « s » pour secondes (comportement par défaut), « ms » pour millisecondes ou « us » pour microsecondes. Si l’unité est définie, la valeur renvoyée est un entier représentant respectivement les secondes, millisecondes ou microsecondes écoulées depuis l’époque. Cette option est utile lorsque une résolution temporelle inférieure à une seconde est requise.

bc.timer.connect : entier Temps total nécessaire pour établir la connexion TCP au serveur. Cela correspond à %Tc dans le format de journalisation. Cette valeur est exprimée en millisecondes (ms). Pour plus d’informations, voir Section 8.4 « Événements de temporisation »

bc_be_queue : entier Nombre de flux défilés pendant l’attente d’un slot de connexion sur le backend. Cela correspond à %bq dans le format de journalisation.

bc_dst: ip Adresse IP de destination de la connexion côté serveur, soit l’adresse du serveur vers lequel HAProxy est connecté. Ce champ est de type IP et fonctionne sur les tables IPv4 et IPv6. Sur les tables IPv6, les adresses IPv4 sont mappées vers leur équivalent IPv6, conformément au RFC 4291.

bc_dst_port : entier Renvoie une valeur entière correspondant au port TCP de destination de la connexion côté serveur, c’est-à-dire le port vers lequel HAProxy s’est connecté.

bc_err : integer Renvoie l’identifiant de l’erreur qui pourrait être survenue lors de la connexion au backend actuel. Consultez la requête “fc_err_str” pour obtenir la liste complète des codes d’erreur et leurs messages correspondants.

bc_err_name : chaîne Retourne le nom d’erreur interne décrivant le problème survenu sur le backend de connexion, entraînant une échec de connexion. Cette chaîne est composée d’un seul mot et est vide lorsqu’aucune erreur n’est présente. Elle correspond à la colonne « name » du tableau présenté dans le mot-clé “fc_err_str”.

bc_err_str : chaîne Retourne un message d’erreur décrivant le problème survenu sur le backend actuel, entraînant une échec de connexion. Consultez la récupération “fc_err_str” pour obtenir la liste complète des codes d’erreur et leurs messages correspondants.

bc_glitches : entier Retourne le nombre de dysfonctionnements de protocole détectés sur la connexion au backend. Ces dysfonctionnements couvrent généralement des violations de protocole ainsi que des anomalies mineures qui indiquent généralement un serveur non fiable ou mal comporté, pouvant entraîner des problèmes dans l’infrastructure (par exemple, des connexions interrompues prématurément, provoquant des renégociations TLS fréquentes). Ces dysfonctionnements peuvent également être dus à des réponses trop volumineuses ne pouvant pas tenir dans un seul tampon, expliquant les erreurs HTTP 502. Ce nombre devrait idéalement rester à zéro, bien qu’il soit généralement acceptable qu’il reste très faible par rapport au nombre total de requêtes. Ces valeurs ne devraient normalement pas être considérées comme alarmantes (en particulier lorsqu’elles sont faibles), bien qu’une augmentation soudaine puisse indiquer une anomalie. Tous les multiplexeurs de protocole ne mesurent pas cette métrique, et la seule façon d’obtenir des détails supplémentaires sur les événements est d’activer les traces pour capturer toutes les échanges.

bc_http_major : integer Renvoie la version majeure HTTP de la connexion au backend, qui peut être 1 pour HTTP/0.9 à HTTP/1.1 ou 2 pour HTTP/2.. Note : cette valeur est basée sur le codage sur le réseau et non sur la version présente dans l’en-tête de la requête.

bc_nb_streams : entier Retourne le nombre de flux ouverts sur la connexion backend.

bc_reused : boolean Retourne true si le transfert a été effectué via une connexion backend réutilisée.

bc_rtt(<unit>): integer

bc_rtt(<unit>): integer

Retourne le temps de trajet aller-retour (RTT) mesuré par le noyau pour la connexion au backend. <unit> est facultatif, la valeur par défaut est en millisecondes. <unit> peut être défini sur « ms » pour les millisecondes ou « us » pour les microsecondes. Si la connexion au serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’échantillonnage échoue.

bc_rttvar(<unit>): integer

bc_rttvar(<unit>): integer

Retourne la variance du temps de trajet aller-retour (RTT) mesurée par le noyau pour la connexion au backend. <unit> est facultatif, la valeur par défaut est en millisecondes. <unit> peut être défini sur « ms » pour les millisecondes ou « us » pour les microsecondes. Si la connexion au serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

bc_settings_streams_limit : integer Renvoie le nombre maximum de flux autorisés sur la connexion backend. Pour les connexions TCP et HTTP/1.1, la valeur est toujours 1. Pour les autres protocoles, elle dépend des paramètres négociés avec le serveur.

bc_src: ip Adresse IP de la source de la connexion côté serveur, soit l’adresse du serveur depuis lequel HAProxy s’est connecté. Ce champ est de type IP et fonctionne sur les tables IPv4 et IPv6. Sur les tables IPv6, les adresses IPv4 sont mappées vers leur équivalent IPv6, conformément au RFC 4291.

bc_src_port : entier Renvoie une valeur entière correspondant au port source TCP de la connexion côté serveur, c’est-à-dire le port depuis lequel HAProxy s’est connecté.

bc_srv_queue : entier Nombre de flux défilés pendant l’attente d’un emplacement de connexion sur le serveur cible. Cela correspond à %sq au format de journalisation.

be_id : entier Renvoie un entier contenant l’identifiant du backend actuel. Il peut être utilisé dans les frontaux avec des réponses pour vérifier quel backend a traité la requête. S’il est utilisé dans un frontal et qu’aucun backend n’a été utilisé, il renvoie l’identifiant du frontal actuel. Il peut également être utilisé dans un règle tcp-check ou http-check.

be_connect_timeout : integer Renvoie la valeur de configuration en millisecondes du délai d’expiration de la connexion au backend actuel. Ce délai peut être remplacé par une règle « set-timeout ». Voir également “cur_connect_timeout”.

be_name : chaîne Renvoie une chaîne contenant le nom du backend actuel. Elle peut être utilisée dans les frontaux avec des réponses pour vérifier quel backend a traité la requête. Si elle est utilisée dans un frontal et qu’aucun backend n’a été utilisé, elle renvoie le nom du frontal actuel. Elle peut également être utilisée dans un ensemble de règles tcp-check ou http-check.

be_queue_timeout: integer Retourne la valeur de configuration en millisecondes du délai d’expiration de la file d’attente du backend actuel. Ce délai peut être remplacé par une règle « set-timeout ». Voir également “cur_queue_timeout”.

be_server_timeout: integer Retourne la valeur de configuration en millisecondes pour le délai d’expiration du serveur du backend actuel. Ce délai peut être remplacé par une règle « set-timeout ». Voir également “cur_server_timeout”.

be_tarpit_timeout: integer Retourne la valeur de configuration en millisecondes pour le délai d’expiration de la file d’attente du backend actuel. Ce délai peut être remplacé par une règle « set-timeout ». Voir également “cur_tarpit_timeout”.

be_tunnel_timeout: integer Retourne la valeur de configuration en millisecondes du délai d’expiration du tunnel du backend actuel. Ce délai peut être remplacé par une règle « set-timeout ». Voir également “cur_tunnel_timeout”.

bytes_in : entier Voir “req.bytes_in”.

bytes_out : entier Voir “res.bytes_in”.

cur_connect_timeout : entier Renvoie le délai d’expiration de connexion actuellement appliqué en millisecondes pour le flux. Dans le cas par défaut, cette valeur est égale à be_connect_timeout, sauf si une règle « set-timeout » a été appliquée. Voir également “be_connect_timeout”.

cur_client_timeout : integer Renvoie le délai d’expiration client actuellement appliqué en millisecondes pour le flux. Dans le cas par défaut, cette valeur est égale à fe_client_timeout, sauf si une règle « set-timeout » a été appliquée. Voir également “fe_client_timeout”.

cur_queue_timeout : entier Renvoie le délai d’expiration de file d’attente actuellement appliqué, en millisecondes, pour le flux. Dans le cas par défaut, cette valeur est égale à be_queue_timeout, sauf si une règle « set-timeout » a été appliquée. Voir également “be_queue_timeout”.

cur_server_timeout : integer Renvoie le délai d’expiration serveur actuellement appliqué en millisecondes pour le flux. Dans le cas par défaut, cette valeur est égale à be_server_timeout, sauf si une règle « set-timeout » a été appliquée. Voir également “be_server_timeout”.

cur_tarpit_timeout : integer Renvoie le délai d’expiration actuellement appliqué, en millisecondes, pour le flux. Dans le cas par défaut, cette valeur est égale à fe_tarpit_timeout/be_tarpit_timeout sauf si une règle « set-timeout » a été appliquée. Voir également “fe_tarpit_timeout” et “be_tarpit_timeout”.

cur_tunnel_timeout : integer Renvoie le délai d’expiration du tunnel actuellement appliqué, en millisecondes, pour le flux. Dans le cas par défaut, cette valeur est égale à be_tunnel_timeout, sauf si une règle « set-timeout » a été appliquée. Voir également “be_tunnel_timeout”.

dst: ip Cette adresse IP est celle de la destination de la connexion côté client, c’est-à-dire l’adresse vers laquelle le client s’est connecté. Les règles tcp/http peuvent modifier cette adresse. Elle peut être utile lors de l’exécution en mode transparent. Elle est de type IP et fonctionne sur les tables IPv4 et IPv6. Sur les tables IPv6, les adresses IPv4 sont mappées vers leur équivalent IPv6 selon la RFC 4291. Lorsqu’une connexion entrante passe par une translation ou une redirection impliquant le suivi des connexions, l’adresse de destination d’origine avant la redirection est rapportée. Sur les systèmes Linux, la source et la destination peuvent parfois apparaître inversées si l’option sysctl nf_conntrack_tcp_loose est activée, car une réponse tardive peut réouvrir une connexion expirée et inverser ce qui est considéré comme la source et la destination.

dst_conn : integer Renvoie une valeur entière correspondant au nombre de connexions actuellement établies sur le même socket, y compris celle en cours d’évaluation. Il est normalement utilisé avec des listes de contrôle d’accès (ACL), mais peut également être utilisé pour transmettre des informations aux serveurs via un en-tête HTTP ou dans les journaux. Il peut servir à afficher une page d’excuse avant un blocage strict, ou à rediriger les nouvelles requêtes vers un backend spécifique lorsqu’un socket est considéré comme saturé. Cela permet d’attribuer des limites différentes à différentes adresses ou ports d’écoute. Voir également les récupérations “fe_conn” et “be_conn”.

dst_is_local : booléen Renvoie true si l’adresse de destination de la connexion entrante est locale au système, ou false si l’adresse n’existe pas sur le système, ce qui signifie qu’elle a été interceptée en mode transparent. Cette information peut être utile pour appliquer certaines règles par défaut au trafic transféré, et d’autres règles au trafic ciblant l’adresse réelle de la machine. Par exemple, la page de statistiques pourrait être servie uniquement sur cette adresse, ou l’accès SSH pourrait être redirigé localement. Veuillez noter que la vérification implique quelques appels système, il est donc préférable de la réaliser une seule fois par connexion.

dst_port : integer Renvoie une valeur entière correspondant au port TCP de destination de la connexion côté client, c’est-à-dire le port auquel le client s’est connecté. Les règles tcp/http peuvent modifier cette adresse. Cette information peut être utilisée lors de l’exécution en mode transparent, lors de l’affectation de ports dynamiques à certains clients pour une session d’application entière, pour affecter tous les utilisateurs à un même serveur, ou pour transmettre les informations relatives au port de destination à un serveur via un en-tête HTTP.

fc.timer.handshake : entier Temps total pour accepter une connexion TCP et exécuter les échanges de handshake pour les protocoles de bas niveau. Actuellement, ces protocoles sont proxy-protocol et SSL. Ceci correspond à %Th dans le format de journalisation. Cette valeur est exprimée en millisecondes (ms). Pour plus d’informations, voir Section 8.4 “Événements de temporisation”

fc.timer.total : entier Durée totale du flux, mesurée entre l’instant où le proxy l’a accepté et l’instant où les deux extrémités ont été fermées. Cela correspond à %Tt dans le format de journalisation. Cette valeur est exprimée en millisecondes (ms). Pour plus d’informations, voir Section 8.4 « Événements de temporisation »

fc_dst : ip Cette adresse IP correspond à l’adresse de destination initiale de la connexion du côté client. Seules les règles « tcp-request connection » peuvent modifier cette adresse. Voir « dst » pour plus de détails.

fc_dst_is_local : boolean Renvoie true si l’adresse de destination d’origine de la connexion entrante est locale au système, ou false si l’adresse n’existe pas sur le système. Voir “dst_is_local” pour les détails.

fc_dst_port : entier Renvoie une valeur entière correspondant au port TCP de destination original de la connexion côté client. Seules les règles « tcp-request connection » peuvent modifier cette adresse. Voir « dst-port » pour plus de détails.

fc_err : integer Renvoie l’identifiant de l’erreur qui aurait pu se produire sur la connexion courante. Toute valeur strictement positive de cette requête indique que la connexion n’a pas réussi et entraînera la sortie d’un message d’erreur dans les journaux (comme décrit dans section 8.2.5 ). Voir le “fc_err_str” fetch pour la liste complète des codes d’erreur et leurs messages correspondants.

fc_err_name : chaîne Retourne le nom d’erreur interne décrivant le problème survenu au frontal, entraînant une échec de connexion. Cette chaîne est composée d’un seul mot et est vide lorsqu’aucune erreur n’est présente. Elle correspond à la colonne « name » du tableau présenté dans le mot-clé “fc_err_str”.

fc_err_str : chaîne Retourne un message d’erreur décrivant le problème survenu sur la connexion actuelle, entraînant une échec de connexion. Cette chaîne correspond à la partie « message » du format d’enregistrement d’erreur (voir section 8.2.5 ). Consultez ci-dessous la liste complète des codes d’erreur et leurs messages correspondants :

  +----+------------------+-------------------------------------------------------------------------+
  | ID | name             | message                                                                 |
  +----+------------------+-------------------------------------------------------------------------+
  | 0  | -                | "Success"                                                               |
  | 1  | CONF_FDLIM       | "Reached configured maxconn value"                                      |
  | 2  | PROC_FDLIM       | "Too many sockets on the process"                                       |
  | 3  | SYS_FDLIM        | "Too many sockets on the system"                                        |
  | 4  | SYS_MEMLIM       | "Out of system buffers"                                                 |
  | 5  | NOPROTO          | "Protocol or address family not supported"                              |
  | 6  | SOCK_ERR         | "General socket error"                                                  |
  | 7  | PORT_RANGE       | "Source port range exhausted"                                           |
  | 8  | CANT_BIND        | "Can't bind to source address"                                          |
  | 9  | FREE_PORTS       | "Out of local source ports on the system"                               |
  | 10 | ADDR_INUSE       | "Local source address already in use"                                   |
  | 11 | PRX_EMPTY        | "Connection closed while waiting for PROXY protocol header"             |
  | 12 | PRX_ABORT        | "Connection error while waiting for PROXY protocol header"              |
  | 13 | PRX_TIMEOUT      | "Timeout while waiting for PROXY protocol header"                       |
  | 14 | PRX_TRUNCATED    | "Truncated PROXY protocol header received"                              |
  | 15 | PRX_NOT_HDR      | "Received something which does not look like a PROXY protocol header"   |
  | 16 | PRX_BAD_HDR      | "Received an invalid PROXY protocol header"                             |
  | 17 | PRX_BAD_PROTO    | "Received an unhandled protocol in the PROXY protocol header"           |
  | 18 | CIP_EMPTY        | "Connection closed while waiting for NetScaler Client IP header"        |
  | 19 | CIP_ABORT        | "Connection error while waiting for NetScaler Client IP header"         |
  | 20 | CIP_TIMEOUT      | "Timeout while waiting for a NetScaler Client IP header"                |
  | 21 | CIP_TRUNCATED    | "Truncated NetScaler Client IP header received"                         |
  | 22 | CIP_BAD_MAGIC    | "Received an invalid NetScaler Client IP magic number"                  |
  | 23 | CIP_BAD_PROTO    | "Received an unhandled protocol in the NetScaler Client IP header"      |
  | 24 | SSL_EMPTY        | "Connection closed during SSL handshake"                                |
  | 25 | SSL_ABORT        | "Connection error during SSL handshake"                                 |
  | 26 | SSL_TIMEOUT      | "Timeout during SSL handshake"                                          |
  | 27 | SSL_TOO_MANY     | "Too many SSL connections"                                              |
  | 28 | SSL_NO_MEM       | "Out of memory when initializing an SSL connection"                     |
  | 29 | SSL_RENEG        | "Rejected a client-initiated SSL renegotiation attempt"                 |
  | 30 | SSL_CA_FAIL      | "SSL client CA chain cannot be verified"                                |
  | 31 | SSL_CRT_FAIL     | "SSL client certificate not trusted"                                    |
  | 32 | SSL_MISMATCH     | "Server presented an SSL certificate different from the configured one" |
  | 33 | SSL_MISMATCH_SNI | "Server presented an SSL certificate different from the expected one"   |
  | 34 | SSL_HANDSHAKE    | "SSL handshake failure"                                                 |
  | 35 | SSL_HANDSHAKE_HB | "SSL handshake failure after heartbeat"                                 |
  | 36 | SSL_KILLED_HB    | "Stopped a TLSv1 heartbeat attack (CVE-2014-0160)"                      |
  | 37 | SSL_NO_TARGET    | "Attempt to use SSL on an unknown target (internal error)"              |
  | 38 | SSL_EARLY_FAILED | "Server refused early data"                                             |
  | 39 | SOCKS4_SEND      | "SOCKS4 Proxy write error during handshake"                             |
  | 40 | SOCKS4_RECV      | "SOCKS4 Proxy read error during handshake"                              |
  | 41 | SOCKS4_DENY      | "SOCKS4 Proxy deny the request"                                         |
  | 42 | SOCKS4_ABORT     | "SOCKS4 Proxy handshake aborted by server"                              |
  | 43 | SSL_FATAL        | "SSL fatal error"                                                       |
  | 44 | REVERSE          | "Reverse connect failure"                                               |
  | 45 | POLLERR          | "Poller reported POLLERR"                                               |
  | 46 | EREFUSED         | "ECONNREFUSED returned by OS"                                           |
  | 47 | ERESET           | "ECONNRESET returned by OS"                                             |
  | 48 | EUNREACH         | "ENETUNREACH returned by OS"                                            |
  | 49 | ENOMEM           | "ENOMEM returned by OS"                                                 |
  | 50 | EBADF            | "EBADF returned by OS"                                                  |
  | 51 | EFAULT           | "EFAULT returned by OS"                                                 |
  | 52 | EINVAL           | "EINVAL returned by OS"                                                 |
  | 53 | ENCONN           | "ENCONN returned by OS"                                                 |
  | 54 | ENSOCK           | "ENSOCK returned by OS"                                                 |
  | 55 | ENOBUFS          | "ENOBUFS returned by OS"                                                |
  | 56 | EPIPE            | "EPIPE returned by OS"                                                  |
  +----+------------------+-------------------------------------------------------------------------+

fc_fackets : entier Retourne le compteur fack mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_glitches : integer Retourne le nombre de perturbations de protocole détectées sur la connexion frontale. Ces perturbations couvrent généralement des violations de protocole ainsi que de petites anomalies qui indiquent généralement un client frauduleux ou mal comporté, susceptible de provoquer des problèmes dans l’infrastructure, comme un trop grand nombre d’erreurs dans les journaux, ou de nombreuses connexions interrompues prématurément, entraînant des renégociations TLS fréquentes. Elles peuvent également être causées par des requêtes trop volumineuses pour tenir dans un seul tampon, expliquant les erreurs HTTP 400. Idéalement, ce nombre doit rester à zéro, bien qu’il puisse arriver que certains navigateurs, en jouant avec les limites du protocole, déclenchent cette mesure occasionnellement. Ces valeurs ne devraient normalement pas être considérées comme alarmantes (en particulier les petites valeurs), bien qu’une augmentation soudaine puisse indiquer une anomalie quelque part. Des valeurs élevées (par exemple, des centaines à des milliers par connexion, ou autant que le nombre de requêtes) peuvent indiquer un client spécifiquement conçu pour repérer ou attaquer la pile de protocole. Tous les multiplexeurs de protocole ne mesurent pas cette métrique, et la seule façon d’obtenir des détails supplémentaires sur les événements est d’activer les traces pour capturer toutes les échanges.

fc_http_major : integer Rapporte la version majeure HTTP de la connexion frontale, qui peut être 1 pour HTTP/0.9 à HTTP/1.1 ou 2 pour HTTP/2.. Note : cette information est basée sur le codage sur le réseau et non sur la version présente dans l’en-tête de la requête.

fc_lost : entier Si la connexion n’est ni TCP, ni QUIC, l’extraction d’échantillon échoue. Pour QUIC, retourne le nombre de paquets QUIC perdus par la connexion cliente. Pour TCP, retourne le compteur de pertes mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_nb_streams : entier Retourne le nombre de flux ouverts sur la connexion frontale.

fc_pp_authority : chaîne Retourne la première valeur TLV d’autorité envoyée par le client dans le protocole PROXY, en-tête, le cas échéant.

fc_pp_tlv(<id>): string

fc_pp_tlv(<id>): string

Renvoie la valeur TLV correspondant à l’ID TLV donné. L’ID doit être soit une valeur numérique comprise entre 0 et 255, soit l’un des noms symboliques suivants, qui correspondent aux suffixes de constante TLV spécifiés dans la norme PPv2 : “ALPN” : PP2_TYPE_ALPN, “AUTHORITY” : PP2_TYPE_AUTHORITY, “CRC32” : PP2_TYPE_CRC32C, “NETNS” : PP2_TYPE_NETNS, “NOOP” : PP2_TYPE_NOOP, “SSL” : PP2_TYPE_SSL, “SSL_CIPHER” : PP2_SUBTYPE_SSL_CIPHER, “SSL_CN” : PP2_SUBTYPE_SSL_CN, “SSL_KEY_ALG” : PP2_SUBTYPE_SSL_KEY_ALG, “SSL_SIG_ALG” : PP2_SUBTYPE_SSL_SIG_ALG, “SSL_VERSION” : PP2_SUBTYPE_SSL_VERSION, “UNIQUE_ID” : PP2_TYPE_UNIQUE_ID.

La valeur reçue doit être inférieure ou égale à 1024 octets. Cela permet de prévenir les attaques DoS potentielles. Les valeurs inférieures ou égales à 256 octets peuvent être regroupées en pool mémoire. Par conséquent, privilégiez une longueur de valeur envoyée de 256 octets au maximum pour des performances optimales.

Notez qu’à la différence de fc_pp_authority et fc_pp_unique_id, fc_pp_tlv est capable d’itérer sur toutes les occurrences d’un TLV demandé en cas de duplication d’ID TLV. L’ordre d’itération correspond à la position dans l’en-tête du protocole PROXY. Toutefois, il est généralement préférable d’éviter les doublons, car les TLV sont généralement supposés être uniques. La présence de plusieurs ID TLV identiques indique généralement une erreur côté émetteur de l’en-tête du protocole PROXY.

fc_pp_unique_id : chaîne Retourne le premier identifiant unique TLV envoyé par le client dans le protocole PROXY, en-tête, le cas échéant.

fc_rcvd_proxy : boolean Retourne true si le client a établi la connexion avec un protocole PROXY via un en-tête.

fc_reordering : entier Si la connexion n’est ni TCP, ni QUIC, l’extraction d’échantillon échoue. Pour QUIC, retourne le nombre de paquets réordonnés QUIC pour la connexion cliente. Pour TCP, retourne le compteur de réordonnancement mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_retrans : entier Retourne le compteur de retransmissions mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_rtt(<unit>): integer

fc_rtt(<unit>): integer

Si la connexion n’est ni TCP, ni QUIC, l’extraction d’échantillon échoue. Pour QUIC, retourne le temps de trajet lissé (Smoothed Round Trip Time) de la connexion cliente. Pour TCP, retourne le temps de trajet (RTT) mesuré par le noyau pour la connexion cliente. <unit> est facultatif, la valeur par défaut est en millisecondes. <unit> peut être défini sur « ms » pour les millisecondes ou « us » pour les microsecondes. Si la connexion serveur n’est pas établie, ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_rttvar(<unit>): integer

fc_rttvar(<unit>): integer

Si la connexion n’est ni TCP, ni QUIC, l’extraction d’échantillon échoue. Pour QUIC, renvoie la variance du temps de trajet lissé pour la connexion cliente. Pour TCP, renvoie la variance du temps de trajet (RTT) mesurée par le noyau pour la connexion cliente. <unit> est facultatif, la valeur par défaut est en millisecondes. <unit> peut être défini sur « ms » pour les millisecondes ou « us » pour les microsecondes. Si la connexion serveur n’est pas établie, ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_sacked : integer Renvoie le compteur sacked mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO, par exemple les noyaux Linux antérieurs à la version 2.4, l’extraction d’échantillon échoue.

fc_saved_syn : binaire Renvoie une copie du paquet SYN sauvegardé par le système pendant la mise en place de la connexion entrante. Cela nécessite que l’option « tcp-ss » soit présente dans la ligne « bind », ainsi qu’un noyau Linux 4.3 au minimum. Lorsque « tcp-ss » est défini à 1, seuls les en-têtes IP et TCP sont présents. Lorsque « tcp-ss » est défini à 2, l’en-tête Ethernet est également présent avant l’en-tête IP, et peut être utilisé pour contrôler ou journaliser l’adresse MAC source ou les VLANs, par exemple. Notez qu’aucune garantie n’est donnée quant à la sauvegarde d’un paquet SYN. Par exemple, si les cookies SYN sont utilisés, le paquet SYN n’est pas conservé et la connexion est établie à partir du paquet ACK correspondant. En outre, le système ne garantit pas la conservation de la copie au-delà de la première lecture. Il est donc fortement recommandé de copier ce paquet dans une variable portant la portée « sess » à partir d’une règle « tcp-request connection », et d’utiliser uniquement cette variable pour les manipulations ultérieures. Il convient de noter qu’au niveau de l’interface boucle, le système construit un en-tête Ethernet factice de 14 octets, dont les adresses source et destination sont nulles, et seul le protocole est défini. Il est pratique de convertir ces échantillons en hexadécimal à l’aide du convertisseur « hex » lors du débogage. Exemple (champs séparés manuellement et commentés ci-dessous) :

frontend test
    mode http
    bind:::4445 tcp-ss 2
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain \
                 lf-string "%[var(sess.syn),hex]\n"

$ curl '0:4445'
000000000000 000000000000 0800 \  # MAC_DST MAC_SRC PROTO=IPv4
4500003C0A65400040063255       \  # IPv4 header, proto=6 (TCP)
7F000001 7F000001              \  # IP_SRC=127.0.0.1 IP_DST=127.0.0.1
E1F2 115D 01AF4E3E 00000000    \  # TCP_SPORT=57842 TCP_DPORT=4445, SEQ
A0 02 FFD7 FE300000            \  # OPT_LEN=20 TCP_FLAGS=SYN WIN=65495
0204FFD70402080A01C2A71A0000000001030307 # MSS=65495, TS, SACK, WSCALE 7

$ curl '[::1]:4445'
000000000000 000000000000 86DD   \ # MAC_DST MAC_SRC PROTO=IPv6
6008018F00280640                 \ # IPv6 header, proto=6 (TCP)
00000000000000000000000000000001 \ # SRC=::1
00000000000000000000000000000001 \ # DST=::1
9758 115D B5511F5D 00000000      \ # TCP_SPORT=38744 TCP_DPORT=4445, SEQ
A0 02 FFC4 00300000              \  # OPT_LEN=20 TCP_FLAGS=SYN WIN=65476
0204FFC40402080A9C231D680000000001030307 # MSS=65476, TS, SACK, WSCALE 7

Le convertisseur « bytes() » permet d’extraire des champs spécifiques du paquet. Le convertisseur be2dec() permet également de lire des tronçons et de les émettre sous forme d’entier. Pour une extraction plus précise, veuillez vous référer aux convertisseurs “eth.XXX”.

Exemple avec entrée IPv4 :

frontend test
    mode http
    bind:4445 tcp-ss 2
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain lf-string \
                 "mac_dst=%[var(sess.syn),eth.dst,hex] \
                  mac_src=%[var(sess.syn),eth.src,hex] \
                  proto=%[var(sess.syn),eth.proto,bytes(6),be2hex(,2)] \
                  ipv4h=%[var(sess.syn),eth.data,bytes(0,12),hex] \
                  ipv4_src=%[var(sess.syn),eth.data,ip.src] \
                  ipv4_dst=%[var(sess.syn),eth.data,ip.dst] \
                  tcp_spt=%[var(sess.syn),eth.data,ip.data,tcp.src] \
                  tcp_dpt=%[var(sess.syn),eth.data,ip.data,tcp.dst] \
                  tcp_win=%[var(sess.syn),eth.data,ip.data,tcp.win] \
                  tcp_opt=%[var(sess.syn),eth.data,ip.data,bytes(20),hex]\n"

$ curl '0:4445'
mac_dst=000000000000 mac_src=000000000000 proto=0800 \
ipv4h=4500003CC9B7400040067302 ipv4_src=127.0.0.1 ipv4_dst=127.0.0.1 \
tcp_spt=43970 tcp_dpt=4445 tcp_win=65495 \
tcp_opt=0204FFD70402080A01DC0D410000000001030307

Voir également l’action « set-var », les convertisseurs « be2dec », « bytes », « hex », “eth.XXX”, “ip.XXX”, et “tcp.XXX”.

fc_settings_streams_limit : entier Renvoie le nombre maximum de flux autorisés sur la connexion frontale. Pour les connexions TCP et HTTP/1.1, il est toujours égal à 1. Pour les autres protocoles, cela dépend des paramètres négociés avec le client.

fc_src: ip Cette adresse IP correspond à l’adresse IP source d’origine de la connexion côté client. Seules les règles “tcp-request connection” peuvent modifier cette adresse. Voir “src” pour plus de détails.

fc_src_is_local : boolean Renvoie true si l’adresse source de la connexion entrante est locale au système, ou false si l’adresse n’existe pas sur le système. Voir “src_is_local” pour les détails.

fc_src_port : entier Renvoie une valeur entière correspondant au port source TCP de la connexion côté client. Seules les règles « tcp-request connection » peuvent modifier cette adresse. Voir « src-port » pour plus de détails.

fc_unacked : integer Retourne le compteur d’éléments non confirmés mesuré par le noyau pour la connexion cliente. Si la connexion serveur n’est pas établie, si la connexion n’est pas TCP ou si le système d’exploitation ne prend pas en charge TCP_INFO (par exemple, les noyaux Linux antérieurs à la version 2.4), l’extraction d’échantillon échoue.

fe_client_timeout : entier Renvoie la valeur de configuration en millisecondes pour le délai d’expiration client du frontend actuel. Ce délai peut être remplacé par une règle « set-timeout ».

fe_defbe : chaîne Retourne une chaîne contenant le nom du backend par défaut du frontal. Elle peut être utilisée dans les frontaux pour vérifier quel backend gérera les requêtes par défaut.

fe_id : entier Renvoie un entier contenant l’identifiant du frontend actuel. Il peut être utilisé dans les backends pour vérifier depuis quel frontend il a été appelé, ou pour affecter tous les utilisateurs provenant du même frontend au même serveur.

fe_name : chaîne Retourne une chaîne contenant le nom du frontend actuel. Elle peut être utilisée dans les backends pour vérifier depuis quel frontend elle a été appelée, ou pour affecter tous les utilisateurs provenant du même frontend au même serveur.

fe_tarpit_timeout : entier Retourne la valeur de configuration en millisecondes du délai d’expiration du tarpit du frontend actuel. Ce délai peut être remplacé par une règle « set-timeout ».

req.bytes_in : entier Cette valeur retourne le nombre d’octets reçus depuis le client. La valeur correspond à ce qui a été reçu par HAProxy, y compris certains en-têtes et une surcharge liée à l’encodage interne. La compression des requêtes n’affecte pas la valeur indiquée ici.

req.bytes_out : entier Cette valeur retourne le nombre d’octets envoyés au serveur. La valeur correspond à ce qui a été envoyé par HAProxy, y compris certains en-têtes et une surcharge liée à un encodage interne. La compression des requêtes affecte la valeur rapportée ici.

res.bytes_in : entier Cette valeur retourne le nombre d’octets reçus depuis le serveur. La valeur correspond à ce qui a été reçu par HAProxy, y compris certains en-têtes et une surcharge liée à l’encodage interne. La compression de la réponse n’affecte pas la valeur indiquée ici.

res.bytes_out : entier Cette valeur retourne le nombre d’octets envoyés au client. La valeur correspond à ce qui a été envoyé par HAProxy, y compris certains en-têtes et une surcharge liée à l’encodage interne. La compression de la réponse affecte la valeur rapportée ici.

res.timer.data : entier indique le temps total de transfert du contenu de la réponse jusqu’à l’envoi du dernier octet au client. En HTTP, il commence après le dernier en-tête de réponse (après Tr). Il correspond à %Td dans le format de journalisation et est exprimé en millisecondes (ms). Pour plus d’informations, voir Section 8.4 « Événements de temporisation »

sc_bytes_in_rate(<ctr>[,<table>]): integer

sc_bytes_in_rate(<ctr>[,<table>]): integer
sc0_bytes_in_rate([<table>]): integer
sc1_bytes_in_rate([<table>]): integer
sc2_bytes_in_rate([<table>]): integer

Retourne le débit moyen en octets client-serveur issu des compteurs actuellement suivis, mesuré en quantité d’octets sur la période configurée dans le tableau. Voir également “table_bytes_in_rate”.

sc_bytes_out_rate(<ctr>[,<table>]): integer

sc_bytes_out_rate(<ctr>[,<table>]): integer
sc0_bytes_out_rate([<table>]): integer
sc1_bytes_out_rate([<table>]): integer
sc2_bytes_out_rate([<table>]): integer

Retourne le débit moyen en octets émis par le serveur vers le client, calculé à partir des compteurs actuellement suivis, exprimé en nombre d’octets sur la période configurée dans le tableau. Voir également “table_bytes_out_rate”.

sc_clr_gpc(<idx>,<ctr>[,<table>]): integer

sc_clr_gpc(<idx>,<ctr>[,<table>]): integer

Efface le compteur général à l’index <idx> du tableau associé au compteur suivi désigné d’ID <ctr> depuis la table de persistance du proxy actuel ou depuis la table de persistance désignée <table>, et retourne sa valeur précédente. <idx> est un entier compris entre 0 et 99 et <ctr> un entier compris entre 0 et 2. Avant la première invocation, la valeur stockée est zéro, donc la première invocation retournera toujours zéro. Cette opération s’applique uniquement au type de données ‘gpc’ (et non aux types hérités ‘gpc0’ ni ‘gpc1’).

sc_clr_gpc0(<ctr>[,<table>]): integer

sc_clr_gpc0(<ctr>[,<table>]): integer
sc0_clr_gpc0([<table>]): integer
sc1_clr_gpc0([<table>]): integer
sc2_clr_gpc0([<table>]): integer

Efface le premier compteur généralisé associé aux compteurs actuellement suivis, puis retourne sa valeur précédente. Avant la première invocation, la valeur stockée est zéro, donc la première invocation retournera toujours zéro. Cette fonction est généralement utilisée comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée :

Exemple :

# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse sc0_http_req_rate gt 10
acl kill  sc0_inc_gpc0 gt 5
acl save  sc0_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

sc_clr_gpc1(<ctr>[,<table>]): integer

sc_clr_gpc1(<ctr>[,<table>]): integer
sc0_clr_gpc1([<table>]): integer
sc1_clr_gpc1([<table>]): integer
sc2_clr_gpc1([<table>]): integer

Efface la deuxième compteur général associé aux compteurs actuellement suivis, et retourne sa valeur précédente. Avant la première invocation, la valeur stockée est zéro, donc la première invocation retournera toujours zéro. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée.

sc_conn_cnt(<ctr>[,<table>]): integer

sc_conn_cnt(<ctr>[,<table>]): integer
sc0_conn_cnt([<table>]): integer
sc1_conn_cnt([<table>]): integer
sc2_conn_cnt([<table>]): integer

Retourne le nombre cumulatif de connexions entrantes provenant des compteurs actuellement suivis. Voir également “table_conn_cnt”.

sc_conn_cur(<ctr>[,<table>]): integer

sc_conn_cur(<ctr>[,<table>]): integer
sc0_conn_cur([<table>]): integer
sc1_conn_cur([<table>]): integer
sc2_conn_cur([<table>]): integer

Retourne le nombre actuel de connexions simultanées suivant les mêmes compteurs suivis. Ce nombre est automatiquement incrémenté au début du suivi et décrémenté à la fin du suivi. Voir également “table_conn_cur”.

sc_conn_rate(<ctr>[,<table>]): integer

sc_conn_rate(<ctr>[,<table>]): integer
sc0_conn_rate([<table>]): integer
sc1_conn_rate([<table>]): integer
sc2_conn_rate([<table>]): integer

Renvoie le taux moyen de connexion issu des compteurs actuellement suivis, mesuré en nombre de connexions sur la période configurée dans le tableau. Voir également “table_conn_rate”.

sc_get_gpc(<idx>,<ctr>[,<table>]): integer

sc_get_gpc(<idx>,<ctr>[,<table>]): integer

Renvoie la valeur du compteur généralisé à l’index <idx> du tableau GPC et associée au compteur actuellement suivi d’ID <ctr> dans la table de persistance du proxy actuel ou dans la table de persistance désignée <table>. <idx> est un entier compris entre 0 et 99 et <ctr> un entier compris entre 0 et 2. Si aucun gpc n’est stocké à cet index, la valeur renvoyée est zéro. Cette opération s’applique uniquement au type de données ‘gpc’ (et non aux types hérités ‘gpc0’ ni ‘gpc1’). Voir également “table_gpc” et “sc_inc_gpc”.

sc_get_gpc0(<ctr>[,<table>]): integer

sc_get_gpc0(<ctr>[,<table>]): integer
sc0_get_gpc0([<table>]): integer
sc1_get_gpc0([<table>]): integer
sc2_get_gpc0([<table>]): integer

Renvoie la valeur du premier compteur généralisé associé aux compteurs actuellement suivis. Voir également “table_gpc0” et sc/sc0/sc1/sc2_inc_gpc0.

sc_get_gpc1(<ctr>[,<table>]): integer

sc_get_gpc1(<ctr>[,<table>]): integer
sc0_get_gpc1([<table>]): integer
sc1_get_gpc1([<table>]): integer
sc2_get_gpc1([<table>]): integer

Renvoie la valeur du deuxième compteur généralisé associé aux compteurs actuellement suivis. Voir également “table_gpc1” et sc/sc0/sc1/sc2_inc_gpc1.

sc_get_gpt(<idx>,<ctr>[,<table>]): integer

sc_get_gpt(<idx>,<ctr>[,<table>]): integer
  1. Renvoie la valeur du premier Tag généralisé à l’index <idx> du tableau associé au compteur suivi d’identifiant <ctr> et provenant de la table de persistance du proxy actuel ou de la table de persistance désignée <table>. <idx> est un entier compris entre 0 et 99 et <ctr> un entier compris entre 0 et . Si aucun Tag généralisé n’est stocké à cet index, la valeur zéro est renvoyée. Cette opération s’applique uniquement au type de données ‘gpt’ (et non au type de données hérité ‘gpt0’). Voir également “table_gpt”.

sc_get_gpt0(<ctr>[,<table>]): integer

sc_get_gpt0(<ctr>[,<table>]): integer
sc0_get_gpt0([<table>]): integer
sc1_get_gpt0([<table>]): integer
sc2_get_gpt0([<table>]): integer

Renvoie la valeur de la première balise générale associée aux compteurs actuellement suivis. Voir également “table_gpt0”.

sc_glitch_cnt(<ctr>[,<table>]): integer

sc_glitch_cnt(<ctr>[,<table>]): integer
sc0_glitch_cnt([<table>]): integer
sc1_glitch_cnt([<table>]): integer
sc2_glitch_cnt([<table>]): integer

Renvoie le nombre cumulé de perturbations de connexion frontales observées sur les connexions associées aux compteurs actuellement suivis. Ces perturbations entraînent généralement l’abandon de requêtes ou de connexions, de sorte que la valeur renvoyée correspond souvent à des connexions passées. Il n’existe pas de valeur bonne ou mauvaise, mais un client de mauvaise qualité peut occasionnellement provoquer quelques perturbations par connexion, tandis qu’un client très défectueux ou malveillant peut rapidement entraîner l’ajout de milliers d’événements sur une même connexion. Voir également fc_glitches pour le nombre affectant la connexion actuelle, src_glitch_cnt pour les consulter par source, et sc_glitch_rate pour les mesures de taux d’événements.

sc_glitch_rate(<ctr>[,<table>]): integer

sc_glitch_rate(<ctr>[,<table>]): integer
sc0_glitch_rate([<table>]): integer
sc1_glitch_rate([<table>]): integer
sc2_glitch_rate([<table>]): integer

Retourne le taux moyen auquel des anomalies de connexion côté client ont été observées pour les compteurs actuellement suivis, mesuré en nombre d’événements sur la période configurée dans le tableau. Ces anomalies provoquent généralement l’abandon de requêtes ou de connexions, de sorte que la valeur renvoyée est souvent liée à des connexions passées. Il n’existe pas de valeur bonne ou mauvaise, mais un client de mauvaise qualité peut occasionnellement provoquer quelques anomalies par connexion, ce qui entraîne un taux faible. Toutefois, un client très malveillant ou frauduleux peut rapidement générer des milliers d’événements par connexion, entraînant un taux élevé. Voir également “table_glitch_rate” et “sc_glitch_cnt”.

sc_gpc_rate(<idx>,<ctr>[,<table>]): integer

sc_gpc_rate(<idx>,<ctr>[,<table>]): integer

Renvoie le taux d’incrémentation moyen du compteur généraliste à l’index <idx> du tableau associé au compteur suivi d’ID <ctr> depuis la table du proxy actuel ou depuis la table de persistance désignée <table>. Il indique la fréquence à laquelle le compteur gpc a été incrémenté durant la période configurée. <idx> est un entier compris entre 0 et 99 et <ctr> un entier compris entre 0 et 2. Notez que le tableau de compteurs ‘gpc_rate’ doit être stocké dans la table de persistance pour qu’une valeur soit renvoyée, car ‘gpc’ ne conserve que le nombre d’événements. Cette fonction ne s’applique qu’au type de données ‘gpc_rate’ (et non aux types hérités ‘gpc0_rate’ ni ‘gpc1_rate’). Voir également “table_gpc_rate”, “sc_get_gpc”, et “sc_inc_gpc”.

sc_gpc0_rate(<ctr>[,<table>]): integer

sc_gpc0_rate(<ctr>[,<table>]): integer
sc0_gpc0_rate([<table>]): integer
sc1_gpc0_rate([<table>]): integer
sc2_gpc0_rate([<table>]): integer

Renvoie le taux moyen d’incrémentation du premier compteur généralisé associé aux compteurs actuellement suivis. Il indique la fréquence à laquelle le compteur gpc0 a été incrémenté durant la période configurée. Voir également src_gpc0_rate, sc/sc0/sc1/sc2_get_gpc0, et sc/sc0/sc1/sc2_inc_gpc0..

Notez que le compteur “gpc0_rate” doit être stocké dans la table de persistance pour qu’une valeur soit renvoyée, car « gpc0 » ne conserve que le nombre d’événements.

sc_gpc1_rate(<ctr>[,<table>]): integer

sc_gpc1_rate(<ctr>[,<table>]): integer
sc0_gpc1_rate([<table>]): integer
sc1_gpc1_rate([<table>]): integer
sc2_gpc1_rate([<table>]): integer

Renvoie le taux moyen d’incrémentation du deuxième Compteur Généralisé à usage général associé aux compteurs actuellement suivis. Il indique la fréquence à laquelle le compteur gpc1 a été incrémenté durant la période configurée. Voir également src_gpcA_rate, sc/sc0/sc1/sc2_get_gpc1, et sc/sc0/sc1/sc2_inc_gpc1..

Notez que le compteur “gpc1_rate” doit être stocké dans la table de persistance pour qu’une valeur soit renvoyée, car « gpc1 » ne conserve que le nombre d’événements.

sc_http_err_cnt(<ctr>[,<table>]): integer

sc_http_err_cnt(<ctr>[,<table>]): integer
sc0_http_err_cnt([<table>]): integer
sc1_http_err_cnt([<table>]): integer
sc2_http_err_cnt([<table>]): integer

Retourne le nombre cumulé d’erreurs HTTP provenant des compteurs actuellement suivis. Cela inclut les erreurs de requête ainsi que les réponses avec codes d’erreur 4xx. Voir également “table_http_err_cnt”.

sc_http_err_rate(<ctr>[,<table>]): integer

sc_http_err_rate(<ctr>[,<table>]): integer
sc0_http_err_rate([<table>]): integer
sc1_http_err_rate([<table>]): integer
sc2_http_err_rate([<table>]): integer

Renvoie le taux moyen d’erreurs HTTP provenant des compteurs actuellement suivis, mesuré en nombre d’erreurs sur la période configurée dans le tableau. Cela inclut les erreurs de requête ainsi que les réponses avec codes 4xx. Voir également src_http_err_rate.

sc_http_fail_cnt(<ctr>[,<table>]): integer

sc_http_fail_cnt(<ctr>[,<table>]): integer
sc0_http_fail_cnt([<table>]): integer
sc1_http_fail_cnt([<table>]): integer
sc2_http_fail_cnt([<table>]): integer

Retourne le nombre cumulatif d’échecs de réponse HTTP provenant des compteurs actuellement suivis. Cela inclut les erreurs de réponse ainsi que les codes d’état 5xx autres que 501 et 505. Voir également “table_http_fail_cnt”.

sc_http_fail_rate(<ctr>[,<table>]): integer

sc_http_fail_rate(<ctr>[,<table>]): integer
sc0_http_fail_rate([<table>]): integer
sc1_http_fail_rate([<table>]): integer
sc2_http_fail_rate([<table>]): integer

Renvoie le taux moyen d’échecs de réponses HTTP provenant des compteurs actuellement suivis, mesuré en nombre d’échecs sur la période configurée dans le tableau. Cela inclut les erreurs de réponse ainsi que les codes d’état 5xx autres que 501 et 505. Voir également “table_http_fail_rate”.

sc_http_req_cnt(<ctr>[,<table>]): integer

sc_http_req_cnt(<ctr>[,<table>]): integer
sc0_http_req_cnt([<table>]): integer
sc1_http_req_cnt([<table>]): integer
sc2_http_req_cnt([<table>]): integer

Retourne le nombre cumulatif de requêtes HTTP provenant des compteurs actuellement suivis. Cela inclut chaque requête démarrée, qu’elle soit valide ou non. Voir également src_http_req_cnt.

sc_http_req_rate(<ctr>[,<table>]): integer

sc_http_req_rate(<ctr>[,<table>]): integer
sc0_http_req_rate([<table>]): integer
sc1_http_req_rate([<table>]): integer
sc2_http_req_rate([<table>]): integer

Renvoie le taux moyen de requêtes HTTP issues des compteurs actuellement suivis, mesuré en nombre de requêtes sur la période configurée dans le tableau. Cela inclut toutes les requêtes démarrées, qu’elles soient valides ou non. Voir aussi src_http_req_rate.

sc_inc_gpc(<idx>,<ctr>[,<table>]): integer

sc_inc_gpc(<idx>,<ctr>[,<table>]): integer

Incrémente le compteur généralisé à l’index <idx> du tableau associé au compteur suivi désigné d’ID <ctr> depuis la table de persistance du proxy actuel ou depuis la table de persistance désignée <table>, puis retourne sa nouvelle valeur. <idx> est un entier compris entre 0 et 99 et <ctr> un entier compris entre 0 et 2. Avant la première invocation, la valeur stockée est zéro, donc la première invocation l’augmente à 1 et retourne 1. Cette opération s’applique uniquement au type de données ‘gpc’ (et non aux types hérités ‘gpc0’ ni ‘gpc1’).

sc_inc_gpc0(<ctr>[,<table>]): integer

sc_inc_gpc0(<ctr>[,<table>]): integer
sc0_inc_gpc0([<table>]): integer
sc1_inc_gpc0([<table>]): integer
sc2_inc_gpc0([<table>]): integer

Incrémente le premier compteur généralisé associé aux compteurs actuellement suivis, puis retourne sa nouvelle valeur. Avant la première invocation, la valeur stockée est zéro, donc la première invocation l’augmente à 1 et retourne 1. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée :

Exemple :

acl abuse sc0_http_req_rate gt 10
acl kill  sc0_inc_gpc0 gt 0
tcp-request connection reject if abuse kill

sc_inc_gpc1(<ctr>[,<table>]): integer

sc_inc_gpc1(<ctr>[,<table>]): integer
sc0_inc_gpc1([<table>]): integer
sc1_inc_gpc1([<table>]): integer
sc2_inc_gpc1([<table>]): integer

Incrémente le second compteur généralisé associé aux compteurs actuellement suivis, puis retourne sa nouvelle valeur. Avant la première invocation, la valeur stockée est zéro, donc la première invocation l’augmente à 1 et retourne 1. Cela est généralement utilisé comme deuxième ACL dans une expression afin de marquer une connexion lorsque la première ACL a été vérifiée.

sc_kbytes_in(<ctr>[,<table>]): integer

sc_kbytes_in(<ctr>[,<table>]): integer
sc0_kbytes_in([<table>]): integer
sc1_kbytes_in([<table>]): integer
sc2_kbytes_in([<table>]): integer

Retourne la quantité totale de données client-serveur provenant des compteurs actuellement suivis, exprimée en kilo-octets. Le test est actuellement effectué sur des entiers 32 bits, ce qui limite les valeurs à 4 téraoctets. Voir également “table_kbytes_in”.

sc_kbytes_out(<ctr>[,<table>]): integer

sc_kbytes_out(<ctr>[,<table>]): integer
sc0_kbytes_out([<table>]): integer
sc1_kbytes_out([<table>]): integer
sc2_kbytes_out([<table>]): integer

Retourne la quantité totale de données serveur vers client provenant des compteurs actuellement suivis, mesurée en kilo-octets. Le test est actuellement effectué sur des entiers 32 bits, ce qui limite les valeurs à 4 téraoctets. Voir également “table_kbytes_out”.

sc_key(<ctr>): any sc0_key: any sc1_key: any sc2_key: any Retourne la clé utilisée pour correspondre au compteur actuellement suivi.

sc_sess_cnt(<ctr>[,<table>]): integer

sc_sess_cnt(<ctr>[,<table>]): integer
sc0_sess_cnt([<table>]): integer
sc1_sess_cnt([<table>]): integer
sc2_sess_cnt([<table>]): integer

Retourne le nombre cumulatif de connexions entrantes qui ont été transformées en sessions, c’est-à-dire acceptées par une règle « tcp-request connection », à partir des compteurs actuellement suivis. Un backend peut compter plus de sessions que de connexions, car chaque connexion peut donner lieu à plusieurs sessions backend si une mise en mémoire tampon HTTP keep-alive est utilisée sur la connexion avec le client. Voir également “table_sess_cnt”.

sc_sess_rate(<ctr>[,<table>]): integer

sc_sess_rate(<ctr>[,<table>]): integer
sc0_sess_rate([<table>]): integer
sc1_sess_rate([<table>]): integer
sc2_sess_rate([<table>]): integer

Renvoie le débit moyen de sessions à partir des compteurs actuellement suivis, mesuré en nombre de sessions sur la période configurée dans le tableau. Une session correspond à une connexion ayant franchi les règles précoces « tcp-request connection ». Un backend peut compter plus de sessions que de connexions, car chaque connexion peut donner lieu à plusieurs sessions backend si une maintien de connexion HTTP (keep-alive) est utilisé sur la connexion avec le client. Voir également “table_sess_rate”.

sc_tracked(<ctr>[,<table>]): boolean

sc_tracked(<ctr>[,<table>]): boolean
sc0_tracked([<table>]): boolean
sc1_tracked([<table>]): boolean
sc2_tracked([<table>]): boolean

Renvoie true si le compteur de session désigné est actuellement suivi par la session en cours. Cela peut être utile pour déterminer si nous devons ou non définir certaines valeurs dans un en-tête transmis au serveur.

sc_trackers(<ctr>[,<table>]): integer

sc_trackers(<ctr>[,<table>]): integer
sc0_trackers([<table>]): integer
sc1_trackers([<table>]): integer
sc2_trackers([<table>]): integer

Retourne le nombre actuel de connexions simultanées suivant les mêmes compteurs suivis. Ce nombre est automatiquement incrémenté au début du suivi et décrémenté à la fin du suivi. Il diffère de sc0_conn_cur en ce qu’il ne repose pas sur des informations stockées, mais sur le compteur de référence de la table (valeur « use » renvoyée par « show table » en ligne de commande). Ce mécanisme peut parfois être plus adapté au suivi de layer7. Il peut être utilisé pour indiquer à un serveur le nombre de connexions simultanées provenant d’une adresse donnée, par exemple.

so_id : entier Renvoie un entier contenant l’identifiant du socket d’écoute actuel. Utile dans les frontaux comportant de nombreuses lignes « bind », ou pour affecter tous les utilisateurs arrivant via un même socket au même serveur.

so_name : chaîne Renvoie une chaîne contenant le nom du socket d’écoute actuel, tel qu’il est défini avec le mot-clé name sur une ligne “bind”. Il peut servir aux mêmes fins que so_id, mais avec des chaînes au lieu d’entiers.

src: ip Cette adresse IP est celle du client de la session. Les règles tcp/http peuvent modifier cette adresse. Elle est de type IP et fonctionne sur les tables IPv4 et IPv6. Sur les tables IPv6, les adresses IPv4 sont mappées vers leur équivalent IPv6 selon la RFC 4291. Notez qu’il s’agit de l’adresse source au niveau TCP, et non de l’adresse d’un client derrière un proxy. Toutefois, si la directive bind “accept-proxy” ou “accept-netscaler-cip” est utilisée, cette adresse peut correspondre à celle d’un client derrière un autre composant compatible avec le protocole PROXY, pour l’ensemble des jeux de règles sauf “tcp-request connection”, qui voit l’adresse réelle. Lorsqu’une connexion entrante passe par une translation d’adresse ou une redirection impliquant le suivi des connexions, l’adresse de destination d’origine avant la redirection sera rapportée. Sur les systèmes Linux, la source et la destination peuvent parfois apparaître inversées si l’option sysctl nf_conntrack_tcp_loose est activée, car une réponse tardive peut réouvrir une connexion expirée et inverser ce qui est considéré comme la source et la destination.

Exemple :

# add an HTTP header in requests with the originating address' country
http-request set-header X-Country %[src,map_ip(geoip.lst)]

src_bytes_in_rate([<table>]): integer

src_bytes_in_rate([<table>]): integer

Identique au convertisseur “table_bytes_in_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_bytes_in_rate([<table>])

src_bytes_out_rate([<table>]): integer

src_bytes_out_rate([<table>]): integer

Identique au convertisseur “table_bytes_out_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_bytes_out_rate([<table>])

src_clr_gpc(<idx>[,<table>]): integer

src_clr_gpc(<idx>[,<table>]): integer

Identique au convertisseur “table_clr_gpc” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_clr_gpc(<idx>[,<table>])

src_clr_gpc0([<table>]): integer

src_clr_gpc0([<table>]): integer

Identique au convertisseur “table_clr_gpc0” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_clr_gpc0([<table>])

src_clr_gpc1([<table>]): integer

src_clr_gpc1([<table>]): integer

Identique au convertisseur “table_clr_gpc1” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_clr_gpc1([<table>])

src_conn_cnt([<table>]): integer

src_conn_cnt([<table>]): integer

Identique au convertisseur “table_conn_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_conn_cnt([<table>])

src_conn_cur([<table>]): integer

src_conn_cur([<table>]): integer

Identique au convertisseur “table_conn_cur” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_conn_cur([<table>])

src_conn_rate([<table>]): integer

src_conn_rate([<table>]): integer

Identique au convertisseur “table_conn_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_conn_rate([<table>])

src_get_gpc(<idx>[,<table>]): integer

src_get_gpc(<idx>[,<table>]): integer

Identique au convertisseur “table_gpc” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc(<idx>[,<table>])

src_get_gpc0([<table>]): integer

src_get_gpc0([<table>]): integer

Identique au convertisseur “table_gpc0” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc0([<table>])

src_get_gpc1([<table>]): integer

src_get_gpc1([<table>]): integer

Identique au convertisseur “table_gpc1” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc1([<table>])

src_get_gpt(<idx>[,<table>]): integer

src_get_gpt(<idx>[,<table>]): integer

Identique au convertisseur “table_gpt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpt(<idx>[,<table>])

src_get_gpt0([<table>]): integer

src_get_gpt0([<table>]): integer

Identique au convertisseur “table_gpt0” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpt0([<table>])

src_glitch_cnt([<table>]): integer

src_glitch_cnt([<table>]): integer

Identique au convertisseur “table_glitch_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_glitch_cnt([<table>])

src_glitch_rate([<table>]): integer

src_glitch_rate([<table>]): integer

Identique au convertisseur “table_glitch_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_glitch_rate([<table>])

src_gpc_rate(<idx>[,<table>]): integer

src_gpc_rate(<idx>[,<table>]): integer

Identique au convertisseur “table_gpc_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc_rate(<idx>[,<table>])

src_gpc0_rate([<table>]): integer

src_gpc0_rate([<table>]): integer

Identique au convertisseur “table_gpc0_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc0_rate([<table>])

src_gpc1_rate([<table>]): integer

src_gpc1_rate([<table>]): integer

Identique au convertisseur “table_gpc1_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_gpc1_rate([<table>])

src_http_err_cnt([<table>]): integer

src_http_err_cnt([<table>]): integer

Identique au convertisseur “table_http_err_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_err_cnt([<table>])

src_http_err_rate([<table>]): integer

src_http_err_rate([<table>]): integer

Identique au convertisseur “table_http_err_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_err_rate([<table>])

src_http_fail_cnt([<table>]): integer

src_http_fail_cnt([<table>]): integer

Identique au convertisseur “table_http_fail_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_fail_cnt([<table>])

src_http_fail_rate([<table>]): integer

src_http_fail_rate([<table>]): integer

Identique au convertisseur “table_http_fail_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_fail_rate([<table>])

src_http_req_cnt([<table>]): integer

src_http_req_cnt([<table>]): integer

Identique au convertisseur “table_http_req_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_req_cnt([<table>])

src_http_req_rate([<table>]): integer

src_http_req_rate([<table>]): integer

Identique au convertisseur “table_http_req_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_http_req_rate([<table>])

src_inc_gpc(<idx>[,<table>]): integer

src_inc_gpc(<idx>[,<table>]): integer

Identique au convertisseur “src_inc_gpc” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_inc_gpc(<idx>[,<table>])

src_inc_gpc0([<table>]): integer

src_inc_gpc0([<table>]): integer

Identique au convertisseur “src_inc_gpc0” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_inc_gpc0([<table>])

src_inc_gpc1([<table>]): integer

src_inc_gpc1([<table>]): integer

Identique au convertisseur “src_inc_gpc1” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_inc_gpc1([<table>])

src_is_local : boolean Renvoie true si l’adresse source de la connexion entrante est locale au système, ou false si l’adresse n’existe pas sur le système, ce qui signifie qu’elle provient d’une machine distante. Notez que les adresses UNIX sont considérées comme locales. Il peut être utile d’appliquer certaines restrictions d’accès en fonction de l’origine du client (par exemple, exiger une authentification ou HTTPS pour les machines distantes). Veuillez noter que cette vérification implique quelques appels système, il est donc préférable de la réaliser une seule fois par connexion.

src_kbytes_in([<table>]): integer

src_kbytes_in([<table>]): integer

Identique au convertisseur “table_kbytes_in” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_kbytes_in([<table>])

src_kbytes_out([<table>]): integer

src_kbytes_out([<table>]): integer

Identique au convertisseur “table_kbytes_out” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_kbytes_out([<table>])

src_port : integer Renvoie une valeur entière correspondant au port source TCP de la connexion côté client, c’est-à-dire le port depuis lequel le client s’est connecté. Les règles tcp/http peuvent modifier cette adresse. L’utilisation de cette fonction est très limitée, car les protocoles modernes ne tiennent pas compte des ports sources de nos jours.

src_sess_cnt([<table>]): integer

src_sess_cnt([<table>]): integer

Identique au convertisseur “table_sess_cnt” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_sess_cnt([<table>])

src_sess_rate([<table>]): integer

src_sess_rate([<table>]): integer

Identique au convertisseur “table_sess_rate” avec la clé définie sur l’adresse source de la connexion entrante.

Équivalent à : src,table_sess_rate([<table>])

src_updt_conn_cnt([<table>]): integer

src_updt_conn_cnt([<table>]): integer

Crée ou met à jour l’entrée associée à l’adresse source de la connexion entrante dans la table de persistance du proxy actuel ou dans la table de persistance désignée. Cette table doit être configurée pour stocker le type de données “conn_cnt”, sinon la correspondance sera ignorée. Le compteur actuel est incrémenté de un, et le minuteur d’expiration actualisé. Le compteur mis à jour est retourné, de sorte que cette correspondance ne peut pas retourner zéro. Cette fonctionnalité était utilisée pour rejeter les abusateurs de service en fonction de leur adresse source. Remarque : il est recommandé d’utiliser les actions plus complètes « track-sc* » dans les règles « tcp-request » à la place.

Exemple :

# This frontend limits incoming SSH connections to 3 per 10 second for
# each source address, and rejects excess connections until a 10 second
# silence is observed. At most 20 addresses are tracked.
listen ssh
    bind:22
    mode tcp
    maxconn 100
    stick-table type ip size 20 expire 10s store conn_cnt
    tcp-request content reject if { src_updt_conn_cnt gt 3 }
    server local 127.0.0.1:22

srv_id : entier Renvoie un entier contenant l’identifiant du serveur lors du traitement de la réponse. Bien qu’il soit presque exclusivement utilisé avec les ACLs, il peut également être utilisé pour la journalisation ou le débogage. Il peut également être utilisé dans un ensemble de règles tcp-check ou http-check.

srv_name : chaîne Renvoie une chaîne contenant le nom du serveur lors du traitement de la réponse. Bien qu’il soit presque exclusivement utilisé avec les ACLs, il peut également être utilisé pour la journalisation ou le débogage. Il peut également être utilisé dans un ensemble de règles tcp-check ou http-check.

txn.conn_retries : entier Renvoie le nombre de tentatives de connexion subies par ce flux lors de la tentative de connexion au serveur. Cette valeur peut varier tant que la connexion n’est pas pleinement établie. Pour les connexions HTTP, la valeur peut être affectée par les tentatives de L7.

txn.redispatched : boolean Retourne true si la connexion a fait l’objet d’une redistribution après une tentative de réessai, conformément à la configuration « option redispatch ». Cette valeur peut évoluer tant que la connexion n’est pas entièrement établie. Pour les connexions HTTP, la valeur peut être influencée par les réessais L7.

7.3.4. Récupération des échantillons au niveau 5

Le niveau 5 décrit généralement la couche session, qui, dans HAProxy, correspond le plus près de la session une fois que toutes les négociations de connexion sont terminées, mais avant que tout contenu ne soit disponible. Les méthodes de récupération décrites ici sont utilisables aussi bas que les règles « tcp-request content », à moins qu’elles n’exigent des informations futures. Celles-ci incluent généralement les résultats des négociations SSL.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                          output type
-------------------------------------------------+-------------
51d.all(<prop>[,<prop>*])                          string
bs.aborted                                         boolean
bs.debug_str([<bitmap>])                           string
bs.id                                              integer
bs.rst_code                                        integer
fs.aborted                                         boolean
fs.debug_str([<bitmap>])                           string
fs.id                                              integer
fs.rst_code                                        integer
ssl_bc                                             boolean
ssl_bc_alg_keysize                                 integer
ssl_bc_alpn                                        string
ssl_bc_cipher                                      string
ssl_bc_client_early_traffic_secret                 string
ssl_bc_client_handshake_traffic_secret             string
ssl_bc_client_random                               binary
ssl_bc_client_traffic_secret_0                     string
ssl_bc_curve                                       string
ssl_bc_early_exporter_secret                       string
ssl_bc_err                                         integer
ssl_bc_err_str                                     string
ssl_bc_exporter_secret                             string
ssl_bc_is_resumed                                  boolean
ssl_bc_npn                                         string
ssl_bc_protocol                                    string
ssl_bc_server_handshake_traffic_secret             string
ssl_bc_server_random                               binary
ssl_bc_server_traffic_secret_0                     string
ssl_bc_session_id                                  binary
ssl_bc_session_key                                 binary
ssl_bc_sni                                         string
ssl_bc_unique_id                                   binary
ssl_bc_use_keysize                                 integer
ssl_c_ca_err                                       integer
ssl_c_ca_err_depth                                 integer
ssl_c_chain_der                                    binary
ssl_c_der                                          binary
ssl_c_err                                          integer
ssl_c_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_key_alg                                      string
ssl_c_notafter                                     string
ssl_c_notbefore                                    string
ssl_c_r_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_san                                          string
ssl_c_serial                                       binary
ssl_c_sha1                                         binary
ssl_c_sig_alg                                      string
ssl_c_used                                         boolean
ssl_c_verify                                       integer
ssl_c_version                                      integer
ssl_f_der                                          binary
ssl_f_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_f_key_alg                                      string
ssl_f_notafter                                     string
ssl_f_notbefore                                    string
ssl_f_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_f_serial                                       binary
ssl_f_sha1                                         binary
ssl_f_sig_alg                                      string
ssl_f_version                                      integer
ssl_fc                                             boolean
ssl_fc_alg_keysize                                 integer
ssl_fc_alpn                                        string
ssl_fc_cipher                                      string
ssl_fc_cipherlist_bin([<filter_option>])           binary
ssl_fc_cipherlist_hex([<filter_option>])           string
ssl_fc_cipherlist_str([<filter_option>])           string
ssl_fc_cipherlist_xxh                              integer
ssl_fc_client_early_traffic_secret                 string
ssl_fc_client_handshake_traffic_secret             string
ssl_fc_client_random                               binary
ssl_fc_client_traffic_secret_0                     string
ssl_fc_crtname                                     string
ssl_fc_curve                                       string
ssl_fc_early_exporter_secret                       string
ssl_fc_ecformats_bin                               binary
ssl_fc_eclist_bin([<filter_option>])               binary
ssl_fc_err                                         integer
ssl_fc_err_str                                     string
ssl_fc_exporter_secret                             string
ssl_fc_extlist_bin([<filter_option>])              binary
ssl_fc_has_crt                                     boolean
ssl_fc_has_early                                   boolean
ssl_fc_has_sni                                     boolean
ssl_fc_is_resumed                                  boolean
ssl_fc_npn                                         string
ssl_fc_protocol                                    string
ssl_fc_protocol_hello_id                           integer
ssl_fc_server_handshake_traffic_secret             string
ssl_fc_server_random                               binary
ssl_fc_server_traffic_secret_0                     string
ssl_fc_session_id                                  binary
ssl_fc_session_key                                 binary
ssl_fc_sigalgs_bin([<filter_option>])              binary
ssl_fc_sni                                         string
ssl_fc_supported_versions_bin([<filter_option>])   binary
ssl_fc_unique_id                                   binary
ssl_fc_use_keysize                                 integer
ssl_s_chain_der                                    binary
ssl_s_der                                          binary
ssl_s_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_s_key_alg                                      string
ssl_s_notafter                                     string
ssl_s_notbefore                                    string
ssl_s_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_s_serial                                       binary
ssl_s_sha1                                         binary
ssl_s_sig_alg                                      string
ssl_s_version                                      integer
txn.timer.user                                     integer
-------------------------------------------------+-------------

Liste détaillée :

51d.all(<prop>[,<prop>*]): string

51d.all(<prop>[,<prop>*]): string

Retourne les valeurs des propriétés demandées sous forme de chaîne, où les valeurs sont séparées par le délimiteur spécifié par « 51degrees-property-separator ». L’appareil est identifié à l’aide de tous les en-têtes HTTP importants de la requête. La fonction peut recevoir jusqu’à cinq noms de propriété ; si un nom de propriété n’est pas trouvé, la valeur « NoData » est retournée.

Exemple :

# Here the header "X-51D-DeviceTypeMobileTablet" is added to the request
# containing the three properties requested using all relevant headers from
# the request.
frontend http-in
  bind *:8081
  default_backend servers
  http-request set-header X-51D-DeviceTypeMobileTablet \
    %[51d.all(DeviceType,IsMobile,IsTablet)]

bs.aborted : boolean Retourne true si une interruption a été reçue du serveur pour le flux courant. Sinon, retourne false.

bs.debug_str([<bitmap>]): string

bs.debug_str([<bitmap>]): string

Cette fonction est destinée à être utilisée par les développeurs lors de séances de dépannage complexes. Elle extrait certains états internes des couches inférieures du flux et de la connexion backend, puis les organise sous forme de chaîne, généralement sous la forme d’une série de paires « nom=valeur » séparées par des espaces. L’argument facultatif <bitmap> indique quelle(s) couche(s) extraire, et correspond à une opération OU arithmétique (ou une somme) des valeurs suivantes : - couche socket : 16 - couche connexion : 8 - couche transport (par exemple SSL) : 4 - connexion mux : 2 - flux mux : 1

Ces valeurs peuvent évoluer d’une version à l’autre. La valeur par défaut zéro est spéciale et active toutes les couches. Veuillez ne pas vous fier à la sortie de cette fonction pour un suivi de production à long terme. Elle est destinée à évoluer même au sein d’une branche stable, au fur et à mesure que les besoins en détails croissent. Un cas d’utilisation typique consiste à concaténer ces informations à la fin d’un format de journal, conjointement avec fs.debug_str(). Exemple :

log-format "$HAPROXY_HTTP_LOG_FMT fs=<%[fs.debug_str]> bs=<%[bs.debug_str]>"

bs.id : entier Retourne l’identifiant du flux du multiplexeur côté serveur. Il incombe au multiplexeur de retourner les informations appropriées.

bs.rst_code: integer Retourne le code de réinitialisation reçu du serveur pour le flux courant. Le code du cadre H2 RST_STREAM ou du cadre QUIC STOP_SENDING reçu du serveur est retourné. L’extraction d’échantillon échoue si aucun arrêt n’a été reçu ou si le flux serveur n’est pas un flux H2/QUIC.

fs.aborted : boolean Retourne true si une interruption a été reçue du client pour le flux actuel. Sinon, retourne false.

fs.debug_str([<bitmap>]): string

fs.debug_str([<bitmap>]): string

Cette fonction est destinée à être utilisée par les développeurs lors de séances de dépannage complexes. Elle extrait certains états internes des couches inférieures du flux frontal et de la connexion, puis les organise sous forme de chaîne, généralement sous la forme d’une série de paires « nom=valeur » séparées par des espaces. L’argument facultatif <bitmap> indique la ou les couches dont il faut extraire les informations, et correspond à une opération OU arithmétique (ou une somme) des valeurs suivantes : - couche socket : 16 - couche connexion : 8 - couche transport (par exemple SSL) : 4 - connexion mux : 2 - flux mux : 1

Ces valeurs peuvent évoluer d’une version à l’autre. La valeur par défaut zéro est spéciale et active toutes les couches. Veuillez ne pas vous fier à la sortie de cette fonction pour un suivi de production à long terme. Elle est destinée à évoluer même au sein d’une branche stable, au fur et à mesure que la nécessité d’informations plus détaillées se fait sentir. Un cas d’utilisation typique consiste à concaténer ces informations à la fin d’un format de journal, conjointement avec bs.debug_str(). Exemple :

log-format "$HAPROXY_HTTP_LOG_FMT fs=<%[fs.debug_str]> bs=<%[bs.debug_str]>"

fs.id : entier Renvoie l’identifiant de flux du multiplexeur côté client. Il incombe au multiplexeur de renvoyer les informations appropriées. Par exemple, pour un TCP brut, 0 est toujours renvoyé, car aucun flux n’existe.

fs.rst_code: integer Retourne le code de réinitialisation reçu du client pour le flux courant. Le code du cadre H2 RST_STREAM ou du cadre QUIC STOP_SENDING reçu du client est retourné. L’extraction d’échantillon échoue si aucun arrêt n’a été reçu ou si le flux client n’est pas un flux H2/QUIC.

ssl_bc: boolean Retourne true lorsque la connexion vers le backend a été établie via une couche de transport SSL/TLS et a été déchiffrée localement. Cela signifie que la connexion sortante a été établie vers un serveur ayant l’option “ssl” activée. Cette information peut être utilisée dans une règle tcp-check ou http-check.

ssl_bc_alg_keysize : entier Retourne la taille de la clé du chiffrement symétrique pris en charge, en bits, lorsque la connexion sortante a été établie sur un transport SSL/TLS. Peut être utilisé dans un ensemble de règles tcp-check ou http-check.

ssl_bc_alpn : chaîne Cette directive extrait le champ de négociation de protocole au niveau de la couche application d’une connexion sortante effectuée via une couche transport TLS. Le résultat est une chaîne contenant le nom du protocole négocié avec le serveur. La bibliothèque SSL doit avoir été compilée avec le support des extensions TLS activé (vérifiez haproxy -vv). Notez que l’extension TLS ALPN n’est pas annoncée à moins que le mot-clé “alpn” sur la ligne “server” ne spécifie une liste de protocoles. En outre, rien ne force le serveur à choisir un protocole parmi cette liste ; un autre protocole peut être demandé. L’extension TLS ALPN est destinée à remplacer l’extension TLS NPN. Voir également “ssl_bc_npn”. Elle peut être utilisée dans un ensemble de règles tcp-check ou http-check.

ssl_bc_cipher: chaîne Retourne le nom du chiffrement utilisé lors de la connexion sortante établie sur un transport SSL/TLS. Peut être utilisé dans un ensemble de règles tcp-check ou http-check.

ssl_bc_client_early_traffic_secret : chaîne Renvoie le CLIENT_EARLY_TRAFFIC_SECRET sous forme de chaîne hexadécimale pour la connexion vers le serveur lorsque la connexion sortante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation des clés OpenSSL afin de générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_client_handshake_traffic_secret : chaîne Renvoie le CLIENT_HANDSHAKE_TRAFFIC_SECRET sous forme de chaîne héxadécimale pour la connexion bacl lorsque la connexion sortante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’une des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_client_random : binaire Renvoie la valeur aléatoire du client de la connexion vers le serveur backend lorsque la connexion entrante a été établie via un transport SSL/TLS. Utile pour décrypter le trafic envoyé à l’aide de chiffres éphémères. Nécessite OpenSSL >= 1.1.0 ou BoringSSL. Peut être utilisé dans une règle tcp-check ou http-check.

ssl_bc_client_traffic_secret_0 : chaîne Retourne le CLIENT_TRAFFIC_SECRET_0 sous forme de chaîne héxadécimale pour la connexion vers le back-end lorsque la connexion sortante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_curve : chaîne Retourne le nom de la courbe utilisée dans l’accord de clé lorsqu’une connexion sortante a été établie sur un transport SSL/TLS. Cela nécessite OpenSSL >= 3.0.0 ou AWS-LC >= 1.57.0.

ssl_bc_early_exporter_secret: chaîne Retourne le EARLY_EXPORTER_SECRET sous forme de chaîne héxadécimale pour la connexion vers le serveur backend lorsque la connexion sortante a été établie sur une couche transport TLS 1.3. Nécessite OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation des clés OpenSSL afin de générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_err : entier Lorsque la connexion sortante a été établie via une couche de transport SSL/TLS, renvoie l’ID de la dernière erreur de la première pile d’erreurs levée du côté du backend. Cette valeur peut indiquer des erreurs d’établissement de connexion ainsi que d’autres erreurs de lecture ou d’écriture survenues durant la durée de vie de la connexion. Pour obtenir une description textuelle de ce code d’erreur, vous pouvez soit utiliser l’extraction d’échantillon “ssl_bc_err_str”, soit utiliser la commande “openssl errstr” (qui prend en paramètre un code d’erreur sous forme hexadécimale). Veuillez consulter la documentation de votre bibliothèque SSL pour obtenir la liste exhaustive des codes d’erreur.

ssl_bc_err_str : chaîne Lorsque la connexion sortante a été établie via une couche de transport SSL/TLS, renvoie une représentation sous forme de chaîne du dernier erreur de la première pile d’erreurs levée sur la connexion du point de vue du backend. Voir également “ssl_fc_err”.

ssl_bc_exporter_secret: chaîne Retourne le EXPORTER_SECRET sous forme de chaîne héxadécimale pour la connexion vers le back-end lorsque la connexion sortante a été établie sur une couche transport TLS 1.3. Nécessite OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_is_resumed : boolean Retourne true lorsque la connexion vers le serveur backend a été établie via un transport SSL/TLS et que la nouvelle session SSL a été rétablie à partir d’une session mise en cache ou d’un jeton TLS. Peut être utilisée dans une règle tcp-check ou http-check.

ssl_bc_npn : chaîne Cette option extrait le champ Next Protocol Negotiation d’une connexion sortante effectuée via une couche transport TLS. Le résultat est une chaîne contenant le nom du protocole négocié avec le serveur. La bibliothèque SSL doit avoir été compilée avec le support des extensions TLS activé (vérifiez haproxy -vv). Notez que l’extension TLS NPN n’est pas annoncée à moins que le mot-clé “npn” sur la ligne “server” ne spécifie une liste de protocoles. De plus, rien ne force le serveur à choisir un protocole parmi cette liste ; un autre protocole peut être utilisé. Veuillez noter que l’extension TLS NPN a été remplacée par ALPN. Cette option peut être utilisée dans un ensemble de règles tcp-check ou http-check.

ssl_bc_protocol : chaîne Retourne le nom du protocole utilisé lors de la connexion sortante établie sur une couche transport SSL/TLS. Peut être utilisé dans un ensemble de règles tcp-check ou http-check.

ssl_bc_server_handshake_traffic_secret : chaîne Renvoie le SERVER_HANDSHAKE_TRAFFIC_SECRET sous forme de chaîne héxadécimale pour la connexion retour lorsque la connexion sortante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’une des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_server_random : binaire Renvoie la valeur aléatoire du serveur de la connexion côté serveur lorsque la connexion entrante a été établie via une couche de transport SSL/TLS. Utile pour décrypter le trafic envoyé à l’aide de chiffres éphémères. Nécessite OpenSSL >= 1.1.0 ou BoringSSL. Peut être utilisé dans une règle tcp-check ou http-check.

ssl_bc_server_traffic_secret_0 : chaîne Retourne le SERVER_TRAFFIC_SECRET_0 sous forme de chaîne hexadécimale pour la connexion retour lorsque la connexion sortante a été établie sur une couche transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_bc_session_id: binaire Retourne l’ID SSL de la connexion vers le serveur backend lorsque la connexion sortante a été établie sur une couche transport SSL/TLS. Utile pour la journalisation afin de savoir si la session a été réutilisée ou non. Peut être utilisé dans une règle tcp-check ou http-check.

ssl_bc_session_key : binaire Retourne la clé principale de session SSL de la connexion vers le back-end lorsque la connexion sortante a été établie sur un transport SSL/TLS. Utile pour décrypter le trafic envoyé à l’aide de chiffres éphémères. Nécessite OpenSSL >= 1.1.0 ou BoringSSL. Peut être utilisé dans un ensemble de règles tcp-check ou http-check.

ssl_bc_sni : chaîne Cette option récupère le champ de l’extension TLS SNI (Server Name Indication) utilisé lors de la connexion au serveur. Le résultat (lorsqu’il est présent) est généralement une chaîne correspondant au nom d’hôte HTTPS (253 caractères ou moins). L’utilisation principale est à des fins de journalisation et de débogage (par exemple, déterminer quel SNI a été utilisé lors de l’établissement de la connexion, afin de le comparer à ce que le serveur a vu).

ssl_bc_unique_id: binaire Lorsque la connexion sortante a été établie sur une couche transport SSL/TLS, renvoie l’identifiant TLS unique tel qu défini dans la section 3 de RFC5929 RFC5929 . L’identifiant unique peut être encodé en base64 à l’aide du convertisseur : “ssl_bc_unique_id,base64”. Il peut être utilisé dans une règle tcp-check ou http-check.

ssl_bc_use_keysize : entier Renvoie la taille de la clé du chiffrement symétrique utilisé, en bits, lorsqu’une connexion sortante a été établie sur un transport SSL/TLS. Cette valeur peut être utilisée dans un ensemble de règles tcp-check ou http-check.

ssl_c_ca_err : integer Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie l’ID de la première erreur détectée lors de la vérification du certificat client à une profondeur supérieure à 0, ou 0 si aucune erreur n’a été rencontrée au cours de ce processus de vérification. Veuillez consulter la documentation de votre bibliothèque SSL pour obtenir la liste exhaustive des codes d’erreur.

ssl_c_ca_err_depth: entier Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, retourne la profondeur dans la chaîne de certification de la première erreur détectée lors de la vérification du certificat client. Si aucune erreur n’est détectée, la valeur renvoyée est 0.

ssl_c_chain_der : binaire Renvoie le certificat de chaîne au format DER présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une ACL, les valeurs à comparer peuvent être fournies sous forme hexadécimale. Le résultat peut être analysé à l’aide de toute bibliothèque acceptant des données ASN.1 au format DER. Cette fonction ne prend pas en charge les sessions réinitialisées.

ssl_c_der: binary Retourne le certificat au format DER présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une ACL, les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_c_err : integer Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie l’identifiant de la première erreur détectée lors de la vérification au niveau de profondeur 0, ou 0 si aucune erreur n’a été détectée au cours de ce processus de vérification. Veuillez consulter la documentation de votre bibliothèque SSL pour obtenir la liste exhaustive des codes d’erreur.

ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie le nom distingué complet de l’émetteur du certificat présenté par le client lorsque aucun <entry> n’est spécifié, ou la valeur du premier élément trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième élément à partir du beginning/end du DN. Par exemple, « ssl_c_i_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_c_i_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez modifier uniquement le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_c_i_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme mal formée et aucune donnée n’est renvoyée.

ssl_c_key_alg : chaîne Retourne le nom de l’algorithme utilisé pour générer la clé du certificat présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS.

ssl_c_notafter : chaîne Retourne la date de fin présentée par le client sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion entrante a été établie via une couche de transport SSL/TLS.

ssl_c_notbefore : chaîne Retourne la date de début fournie par le client sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion entrante a été établie via une couche de transport SSL/TLS.

ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS et qu’elle est correctement validée à l’aide du fichier CA configuré, renvoie le nom distingué complet de l’autorité de certification racine du certificat présenté par le client lorsque aucun <entry> n’est spécifié, ou la valeur du premier élément trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième élément donné à partir du beginning/end du DN. Par exemple, « ssl_c_r_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_c_r_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez modifier uniquement le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_c_r_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme malformée et aucune donnée n’est renvoyée.

ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie le nom distingué complet du sujet du certificat présenté par le client lorsque aucun <entry> n’est spécifié, ou la valeur du premier élément trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième élément à partir du beginning/end du DN. Par exemple, « ssl_c_s_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_c_s_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez uniquement modifier le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_c_s_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme malformée et aucune donnée n’est renvoyée.

ssl_c_san: chaîne Lorsque la connexion entrante a été établie via une couche de transport SSL/TLS, et qu’un certificat client a été fourni. Retourne une chaîne de champs Nom de sujet alternatif (Subject Alt Name) séparés par des virgules contenus dans le certificat fourni.

Cela peut être utilisé pour inspecter le certificat client.

Exemple :

acl is_valid_client_cert ssl_c_used && ! ssl_c_verify
http-request set-header X-SSL-Client-SAN %[ssl_c_san] if is_valid_client_cert

aura pour résultat :

X-SSL-Client-SAN: IP Address:127.0.0.1, IP Address:127.0.0.2, IP Address:127.0.0.3, URI:http://docs.haproxy.org/2.7/, DNS:ca.tests.haproxy.com

ssl_c_serial : binary Renvoie le numéro de série du certificat présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une règle d’accès, les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_c_sha1: binary Retourne l’empreinte SHA-1 du certificat présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS. Cette information peut être utilisée pour associer un client à un serveur, ou pour la transmettre à un serveur. Notez que la sortie est binaire, donc si vous souhaitez transmettre cette empreinte au serveur, vous devez la coder en hexadécimal ou en base64, comme illustré dans l’exemple ci-dessous :

Exemple :

http-request set-header X-SSL-Client-SHA1 %[ssl_c_sha1,hex]

ssl_c_sig_alg : chaîne Retourne le nom de l’algorithme utilisé pour signer le certificat présenté par le client lorsque la connexion entrante a été établie sur un transport SSL/TLS.

ssl_c_used : boolean Retourne true si la session SSL actuelle utilise un certificat client, même si la connexion actuelle utilise une reprise de session SSL. Voir également “ssl_fc_has_crt”.

ssl_c_verify: integer Retourne l’identifiant d’erreur du résultat de vérification lorsque la connexion entrante a été établie sur une couche transport SSL/TLS, sinon zéro si aucune erreur n’est détectée. Veuillez vous référer à la documentation de votre bibliothèque SSL pour obtenir la liste exhaustive des codes d’erreur.

ssl_c_version: integer Retourne la version du certificat présenté par le client lors de la connexion entrante établie sur un transport SSL/TLS.

ssl_f_der: binary Retourne le certificat au format DER présenté par le frontal lors de la connexion entrante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une ACL, les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie le nom distingué complet de l’émetteur du certificat présenté par le frontal lorsque aucun <entry> n’est spécifié, ou la valeur du premier champ donné trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du n-ième champ donné à partir du beginning/end du DN. Par exemple, « ssl_f_i_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_f_i_dn(CN) » renvoie le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez uniquement modifier le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_f_i_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme mal formée et aucune donnée n’est renvoyée.

ssl_f_key_alg : chaîne Retourne le nom de l’algorithme utilisé pour générer la clé du certificat présenté par le frontal lors de la connexion entrante établie sur un transport SSL/TLS.

ssl_f_notafter : chaîne Retourne la date de fin présentée par le frontal sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion entrante a été établie via une couche de transport SSL/TLS.

ssl_f_notbefore : chaîne Retourne la date de début présentée par le frontal sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion entrante a été établie via une couche de transport SSL/TLS.

ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie le nom distingué complet du sujet du certificat présenté par le frontal lorsque aucun <entry> n’est spécifié, ou la valeur du premier champ donné trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième champ donné à partir du beginning/end du DN. Par exemple, « ssl_f_s_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_f_s_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez modifier uniquement le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_f_s_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme malformée et aucune donnée n’est renvoyée.

ssl_f_serial: binary Renvoie le numéro de série du certificat présenté par le frontal lors de la connexion entrante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une règle d’accès (ACL), les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_f_sha1 : binaire Retourne l’empreinte SHA-1 du certificat présenté par le frontal lors de la connexion entrante établie sur un transport SSL/TLS. Cela permet de savoir quel certificat a été sélectionné à l’aide de SNI.

ssl_f_sig_alg : chaîne Retourne le nom de l’algorithme utilisé pour signer le certificat présenté par le frontal lorsque la connexion entrante a été établie sur un transport SSL/TLS.

ssl_f_version : integer Renvoie la version du certificat présenté par le frontal lors de la connexion entrante établie sur un transport SSL/TLS.

ssl_fc : boolean Retourne true lorsque la connexion frontale a été établie via une couche de transport SSL/TLS et a été déchiffrée localement. Cela signifie qu’elle correspond à une socket déclarée avec une ligne “bind” comportant l’option “ssl”.

Exemple :

# This passes "X-Proto: https" to servers when client connects over SSL
listen http-https
    bind:80
    bind:443 ssl crt /etc/haproxy.pem
    http-request add-header X-Proto https if { ssl_fc }

ssl_fc_alg_keysize : entier Renvoie la taille de la clé du chiffrement symétrique pris en charge, en bits, lorsque la connexion entrante a été établie sur un transport SSL/TLS.

ssl_fc_alpn : chaîne Cette directive extrait le champ de négociation de protocole au niveau de la couche application d’une connexion entrante effectuée via une couche transport TLS et déchiffrée localement par HAProxy. Le résultat est une chaîne contenant le nom du protocole annoncé par le client. La bibliothèque SSL doit avoir été compilée avec le support des extensions TLS activé (vérifiez haproxy -vv). Notez que l’extension TLS ALPN n’est pas annoncée à moins que le mot-clé « alpn » sur la ligne « bind » ne spécifie une liste de protocoles. En outre, rien ne force le client à choisir un protocole parmi cette liste ; tout autre protocole peut être demandé. L’extension TLS ALPN est destinée à remplacer l’extension TLS NPN. Voir également “ssl_fc_npn”.

ssl_fc_cipher : chaîne Renvoie le nom du chiffrement utilisé lorsque la connexion entrante a été établie sur une couche transport SSL/TLS.

ssl_fc_cipherlist_bin([<filter_option>]): binary

ssl_fc_cipherlist_bin([<filter_option>]): binary

Renvoie la forme binaire de la liste des chiffres du message ClientHello. La longueur maximale de la valeur renvoyée est limitée par la taille du tampon partagé de capture contrôlée par le paramètre “tune.ssl.capture-buffer-size”. La configuration <filter_option> permet de filtrer les données renvoyées. Valeurs acceptées :

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

Exemple :

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]
acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \
    -f /path/to/file/with/malware-ja3.lst
http-request set-header X-Malware True if is_malware
http-request set-header X-Malware False if !is_malware

ssl_fc_cipherlist_hex([<filter_option>]): string

ssl_fc_cipherlist_hex([<filter_option>]): string

Renvoie la forme binaire de la liste des chiffres du client hello encodée en hexadécimal. La longueur maximale de la valeur renvoyée est limitée par la taille du tampon de capture partagé contrôlée par le paramètre “tune.ssl.capture-buffer-size”. Le paramètre <filter_option> permet de filtrer les données renvoyées. Valeurs acceptées :

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

ssl_fc_cipherlist_str([<filter_option>]): string

ssl_fc_cipherlist_str([<filter_option>]): string

Renvoie la forme texte décodée de la liste des chiffres du client hello. La longueur maximale de la valeur renvoyée est limitée par la taille du tampon de capture partagé contrôlée par le paramètre “tune.ssl.capture-buffer-size”. Le paramètre <filter_option> permet de filtrer les données renvoyées. Valeurs acceptées :

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

Notez que cet extrait d’échantillonnage n’est disponible qu’avec OpenSSL >= 1.0.2. Si la fonction n’est pas activée, cet extrait d’échantillonnage retourne le hachage tel que “ssl_fc_cipherlist_xxh”.

ssl_fc_cipherlist_xxh: integer Renvoie un hachage xxh64 de la liste de chiffrements. Ce hachage ne peut être retourné que si la valeur “tune.ssl.capture-buffer-size” est définie à une valeur supérieure à 0, mais il prend en compte l’intégralité des données de la liste de chiffrements.

ssl_fc_client_early_traffic_secret : chaîne Retourne le CLIENT_EARLY_TRAFFIC_SECRET sous forme hexadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur un transport TLS 1.3. Nécessite OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_client_handshake_traffic_secret : chaîne Renvoie le CLIENT_HANDSHAKE_TRAFFIC_SECRET sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_client_random : binaire Renvoie la valeur aléatoire du client de la connexion frontale lorsque la connexion entrante a été établie via un transport SSL/TLS. Utile pour décrypter le trafic envoyé à l’aide de chiffres éphémères. Cela nécessite OpenSSL >= 1.1.0, ou BoringSSL.

ssl_fc_client_traffic_secret_0 : chaîne Retourne le CLIENT_TRAFFIC_SECRET_0 sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_crtname : chaîne Renvoie le nom du certificat sélectionné pour la connexion entrante SSL/TLS. Ce nom correspond à celui affiché par la commande « show ssl cert » : il peut s’agir du nom de fichier avec son chemin relatif ou absolu, ou d’un alias, selon la manière dont le certificat a été déclaré dans la configuration.

Exemple :

crt-store example
    load crt "example.com.pem"

frontend www
    bind *:443 ssl crt "@example/example.com.pem"
    acl match_certificate ssl_fc_crtname -m beg -i "@example/"
    http-request set-header X-Cert-Name %[ssl_fc_crtname] if match_certificate

ssl_fc_curve : chaîne Retourne le nom de la courbe utilisée dans l’accord de clé lorsque la connexion entrante a été établie sur un transport SSL/TLS. Cela nécessite OpenSSL >= 3.0.0.

ssl_fc_early_rcvd : boolean Retourne true si des données anticipées ont été reçues sur cette connexion, indépendamment du fait que la négociation soit depuis terminée. Ce champ n’a pas d’utilité pratique pour le traitement du trafic, mais il constitue pratiquement la seule manière de « détecter » qu’un client a utilisé le 0-RTT pour envoyer des données anticipées, et peut s’avérer utile lors du débogage, car les autres alternatives consistent à capturer le trafic réseau ou à journaliser les indicateurs de la connexion frontale et à les comparer dans le code. Il peut également être utile pour obtenir des statistiques sur les capacités des clients. Voir également “ssl_fc_has_early”.

ssl_fc_early_exporter_secret: chaîne Retourne le EARLY_EXPORTER_SECRET sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur une couche transport TLS 1.3. Nécessite OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation des clés OpenSSL afin de générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_ecformats_bin : binaire Retourne la forme binaire des formats de point de courbe elliptique pris en charge dans le client hello. La longueur maximale de la valeur retournée est limitée par la taille du tampon de capture partagé contrôlée par le paramètre “tune.ssl.capture-buffer-size”.

Exemple :

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]
acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \
    -f /path/to/file/with/malware-ja3.lst
http-request set-header X-Malware True if is_malware
http-request set-header X-Malware False if !is_malware

ssl_fc_eclist_bin([<filter_option>]): binary

ssl_fc_eclist_bin([<filter_option>]): binary

Renvoie la forme binaire des courbes elliptiques prises en charge dans le message ClientHello. La longueur maximale renvoyée est limitée par la taille du tampon de capture partagé contrôlée par le paramètre “tune.ssl.capture-buffer-size”. La configuration <filter_option> permet de filtrer les données renvoyées. Valeurs acceptées :

0: return the full list of supported elliptic curves (default)
1: exclude GREASE (RFC8701) values from the output

Exemple :

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]
acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \
    -f /path/to/file/with/malware-ja3.lst
http-request set-header X-Malware True if is_malware
http-request set-header X-Malware False if !is_malware

ssl_fc_err : entier Lorsque la connexion entrante a été établie via une couche de transport SSL/TLS, renvoie l’ID de la dernière erreur de la première pile d’erreurs levée du côté frontal, ou 0 si aucune erreur n’a été rencontrée. Cette valeur peut être utilisée pour identifier les erreurs liées à l’établissement de la connexion autres que celles liées à la vérification (comme un désaccord sur le chiffrement), ainsi que d’autres erreurs de lecture ou d’écriture survenues pendant la durée de vie de la connexion. Toute erreur survenue lors du processus de vérification du certificat client ne sera pas signalée via cette récupération, mais via les récupérations existantes “ssl_c_err”, “ssl_c_ca_err” et “ssl_c_ca_err_depth”. Pour obtenir une description textuelle de ce code d’erreur, vous pouvez soit utiliser l’exemple de récupération “ssl_fc_err_str”, soit utiliser la commande “openssl errstr” (qui prend en paramètre un code d’erreur sous forme hexadécimale). Veuillez consulter la documentation de votre bibliothèque SSL pour obtenir la liste exhaustive des codes d’erreur.

ssl_fc_err_str : chaîne Lorsqu’une connexion entrante a été établie via une couche de transport SSL/TLS, renvoie une représentation sous forme de chaîne du dernier erreur de la première pile d’erreurs levée du côté frontal. Aucune erreur survenue lors du processus de vérification du certificat client ne sera signalée via cette récupération. Voir également “ssl_fc_err”.

ssl_fc_exporter_secret: chaîne Retourne le EXPORTER_SECRET sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie via un transport TLS 1.3. Nécessite OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation des clés OpenSSL afin de générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_extlist_bin([<filter_option>]): binary

ssl_fc_extlist_bin([<filter_option>]): binary

Renvoie la forme binaire de la liste des extensions ClientHello. La longueur maximale de la valeur renvoyée est limitée par la taille du tampon partagé contrôlée par le paramètre “tune.ssl.capture-buffer-size”. Le paramètre <filter_option> permet de filtrer les données renvoyées. Valeurs acceptées :

0: return the full list of extensions (default)
1: exclude GREASE (RFC8701) values from the output

Exemple :

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]
acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \
    -f /path/to/file/with/malware-ja3.lst
http-request set-header X-Malware True if is_malware
http-request set-header X-Malware False if !is_malware

ssl_fc_has_crt : boolean Renvoie true si un certificat client est présent dans une connexion entrante via le transport SSL/TLS. Utile si l’instruction ‘verify’ est définie sur ‘optional’. Remarque : lors d’une reprise de session SSL avec ID de session ou ticket TLS, le certificat client n’est pas présent dans la connexion actuelle, mais peut être récupéré depuis le cache ou le ticket. Préférez donc “ssl_c_used” si vous souhaitez vérifier si la session SSL actuelle utilise un certificat client.

ssl_fc_has_early : boolean Renvoie true si des données anticipées ont été envoyées, et que la négociation n’est pas encore terminée. Étant donné les implications en matière de sécurité, il peut être utile de refuser ces données, ou d’attendre la fin de la négociation (via l’action « wait-for-handshake »). Voir également “ssl_fc_early_rcvd”.

ssl_fc_has_sni : boolean Cette option vérifie la présence d’une extension TLS Server Name Indication (SNI) dans une connexion entrante établie sur un transport SSL/TLS. Retourne true lorsque la connexion entrante inclut un champ SNI TLS. Cette fonctionnalité nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifiez HAProxy -vv).

ssl_fc_is_resumed : boolean Retourne true si la session SSL/TLS a été rétablie grâce à l’utilisation du cache de session SSL ou des tickets TLS sur une connexion entrante via une couche de transport SSL/TLS.

ssl_fc_npn : chaîne Cette directive extrait le champ Next Protocol Negotiation d’une connexion entrante effectuée via une couche transport TLS et déchiffrée localement par HAProxy. Le résultat est une chaîne contenant le nom du protocole annoncé par le client. La bibliothèque SSL doit avoir été compilée avec le support des extensions TLS activé (vérifiez haproxy -vv). Notez que l’extension TLS NPN n’est pas annoncée à moins que le mot-clé “npn” dans la ligne “bind” ne spécifie une liste de protocoles. En outre, rien n’oblige le client à choisir un protocole parmi cette liste ; un autre protocole peut être demandé. Veuillez noter que l’extension TLS NPN a été remplacée par ALPN.

ssl_fc_protocol : chaîne Retourne le nom du protocole utilisé lorsque la connexion entrante a été établie sur une couche transport SSL/TLS.

ssl_fc_protocol_hello_id : integer Le numéro de version du protocole TLS utilisé par le client pour la communication pendant la session, tel qu’indiqué dans le message Client Hello. Cette valeur n’est renvoyée que si la valeur “tune.ssl.capture-buffer-size” est supérieure à 0.

Exemple :

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]
acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \
    -f /path/to/file/with/malware-ja3.lst
http-request set-header X-Malware True if is_malware
http-request set-header X-Malware False if !is_malware

ssl_fc_server_handshake_traffic_secret : chaîne Renvoie le SERVER_HANDSHAKE_TRAFFIC_SECRET sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur un transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation OpenSSL pour générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_server_random : binaire Renvoie la valeur aléatoire du serveur de la connexion frontale lorsque la connexion entrante a été établie via un transport SSL/TLS. Utile pour décrypter le trafic envoyé à l’aide de chiffres éphémères. Cela nécessite OpenSSL >= 1.1.0, ou BoringSSL.

ssl_fc_server_traffic_secret_0 : chaîne Retourne le SERVER_TRAFFIC_SECRET_0 sous forme de chaîne héxadécimale pour la connexion frontale lorsque la connexion entrante a été établie sur une couche transport TLS 1.3. Exige OpenSSL >= 1.1.1. Il s’agit l’un des clés extraites par le rappel de journalisation des clés OpenSSL afin de générer le fichier SSLKEYLOGFILE. La journalisation des clés SSL doit être activée avec « tune.ssl.keylog on » dans la section globale. Voir également “tune.ssl.keylog”

ssl_fc_session_id : binaire Renvoie l’ID SSL de la connexion frontale lorsque la connexion entrante a été établie via une couche de transport SSL/TLS. Utile pour associer un client donné à un serveur. Il est important de noter que certains navigateurs actualisent leur ID de session tous les quelques minutes.

ssl_fc_session_key : binaire Retourne la clé principale de session SSL de la connexion frontale lorsque la connexion entrante a été établie via une couche de transport SSL/TLS. Utile pour décrypter le trafic envoyé en utilisant des chiffres éphémères. Nécessite OpenSSL >= 1.1.0, ou BoringSSL.

ssl_fc_sigalgs_bin([<filter_option>]): binary

ssl_fc_sigalgs_bin([<filter_option>]): binary

Renvoie le contenu de l’extension TLS signatures_algorithms (13) présentée lors de l’échange Client Hello. Il s’agit d’une liste binaire de algorithmes sur 2 octets, définis dans le RFC TLS : https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3 .

Cette valeur ne peut être retournée que si la valeur “tune.ssl.capture-buffer-size” est définie supérieure à 0. La configuration de <filter_option> permet de filtrer les données retournées. Valeurs acceptées : 0 : retourner la liste complète des chiffrements (par défaut), 1 : exclure les valeurs GREASE (RFC8701) de la sortie

ssl_fc_sni : chaîne Cette option extrait le champ de l’extension TLS Server Name Indication (SNI) d’une connexion entrante effectuée via une couche de transport SSL/TLS et déchiffrée localement par HAProxy. Le résultat (lorsqu’il est présent) est généralement une chaîne correspondant au nom d’hôte HTTPS (253 caractères ou moins). La bibliothèque SSL doit avoir été compilée avec le support des extensions TLS activé (vérifiez HAProxy -vv).

Cette récupération diffère de “req.ssl_sni” ci-dessus en ce qu’elle s’applique à la connexion étant déchiffrée par HAProxy et non aux contenus SSL étant simplement acheminés. Voir également “ssl_fc_sni_end” et “ssl_fc_sni_reg” ci-dessous. Cela nécessite que la bibliothèque SSL soit compilée avec le support des extensions TLS activé (vérifier HAProxy -vv).

ATTENTION ! Sauf dans des conditions très spécifiques, il n’est généralement pas correct d’utiliser ce champ à la place du champ d’en-tête HTTP « Host ». Par exemple, lors du transfert d’une connexion HTTPS vers un serveur, le champ SNI doit être défini à partir du champ d’en-tête HTTP « Host » en utilisant « req.hdr(host) » et non à partir de la valeur SNI côté client. La raison en est que le SNI est utilisé uniquement pour sélectionner le certificat que le serveur présentera, et les clients sont autorisés à envoyer des requêtes avec des valeurs Host différentes, à condition qu’elles correspondent aux noms présents dans le certificat. En conséquence, “ssl_fc_sni” ne devrait normalement pas être utilisé comme argument pour le mot-clé serveur « sni », sauf si le backend fonctionne en mode TCP.

Dérivés ACL :

ssl_fc_sni_end: suffix match
ssl_fc_sni_reg: regex match

ssl_fc_supported_versions_bin([<filter_option>]): binary

ssl_fc_supported_versions_bin([<filter_option>]): binary

Renvoie le contenu de l’extension TLS supported_versions (43) présentée lors du Client Hello. Elle fournit une liste binaire de versions sur 2 octets. TLSv1.3 (0x0304), TLSv1.2 (0x0303).

Cette valeur ne peut être retournée que si la valeur “tune.ssl.capture-buffer-size” est définie supérieure à 0. La configuration de <filter_option> permet de filtrer les données retournées. Valeurs acceptées : 0 : retourner la liste complète des chiffrements (par défaut), 1 : exclure les valeurs GREASE (RFC8701) de la sortie

ssl_fc_unique_id : binaire Lorsque la connexion entrante a été établie via une couche de transport SSL/TLS, renvoie l’identifiant unique TLS tel qu défini dans la section 3 de RFC5929 . L’identifiant unique peut être encodé au format base64 à l’aide du convertisseur : « ssl_fc_unique_id,base64 ».

ssl_fc_use_keysize : entier Renvoie la taille de la clé du chiffrement symétrique utilisée en bits lorsque la connexion entrante a été établie sur un transport SSL/TLS.

ssl_s_chain_der : binaire Renvoie le certificat de chaîne au format DER présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une règle d’accès (ACL), les valeurs à comparer peuvent être fournies sous forme hexadécimale. Le résultat peut être analysé à l’aide de toute bibliothèque acceptant des données ASN.1 au format DER. Cette fonction ne prend pas en charge les sessions réutilisées.

ssl_s_der: binary Retourne le certificat au format DER présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une ACL, les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion sortante a été établie au moyen d’une couche de transport SSL/TLS, renvoie le nom distingué complet de l’émetteur du certificat présenté par le serveur lorsque aucun <entry> n’est spécifié, ou la valeur du premier élément donné trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième élément donné à partir du beginning/end du DN. Par exemple, « ssl_s_i_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_s_i_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez uniquement modifier le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_s_i_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme malformée et aucune donnée n’est renvoyée.

ssl_s_key_alg : chaîne Retourne le nom de l’algorithme utilisé pour générer la clé du certificat présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS.

ssl_s_notafter : chaîne Retourne la date de fin présentée par le serveur sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion sortante a été établie via une couche de transport SSL/TLS.

ssl_s_notbefore : chaîne Retourne la date de début fournie par le serveur sous forme de chaîne formatée YYMMDDhhmmss[Z] lorsque la connexion sortante a été établie via une couche de transport SSL/TLS.

ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string

Lorsqu’une connexion sortante a été établie au moyen d’une couche de transport SSL/TLS, renvoie le nom distingué complet du sujet du certificat présenté par le serveur lorsque aucun <entry> n’est spécifié, ou la valeur du premier élément trouvé à partir du début du DN. Si un nombre d’occurrence positive/negative est spécifié en tant qu’argument optionnel second, renvoie la valeur du nième élément à partir du beginning/end du DN. Par exemple, « ssl_s_s_dn(OU,2) » renvoie la deuxième unité organisationnelle, et « ssl_s_s_dn(CN) » récupère le nom commun. Le paramètre <format> permet de recevoir un DN adapté à la consommation par différents protocoles. Actuellement pris en charge : rfc2253 pour LDAP v3. Si vous souhaitez uniquement modifier le format, vous pouvez spécifier une chaîne vide et zéro pour les deux premiers paramètres. Exemple : ssl_s_s_dn(,0,rfc2253). Si la valeur ASN.1 de l’entrée demandée (ou, lorsqu’aucun <entry> n’est spécifié, toute entrée du DN) contient un octet NUL intégré suivi d’autres données, elle est considérée comme malformée et aucune donnée n’est renvoyée.

ssl_s_serial: binary Renvoie le numéro de série du certificat présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS. Lorsqu’il est utilisé dans une règle d’accès, les valeurs à comparer peuvent être fournies sous forme hexadécimale.

ssl_s_sha1 : binaire Retourne l’empreinte SHA-1 du certificat présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS. Cela permet de savoir quel certificat a été sélectionné à l’aide de SNI.

ssl_s_sig_alg : chaîne Retourne le nom de l’algorithme utilisé pour signer le certificat présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS.

ssl_s_version: integer Retourne la version du certificat présenté par le serveur lors de la connexion sortante établie sur un transport SSL/TLS.

txn.timer.user : entier Temps total estimé perçu par le client, entre l’instant où le proxy l’a accepté et l’instant où les deux extrémités ont été fermées, sans temps d’inactivité. Il s’agit de l’équivalent de %Tu dans le format de journalisation et est exprimé en millisecondes (ms). Pour plus de détails, voir Section 8.4 “Événements de temporisation”

7.3.5. Récupération d’échantillons à partir du contenu du tampon (couche 6)

Extraire des échantillons à partir du contenu du tampon diffère un peu des extraits d’échantillons précédents, car les données échantillonnées sont éphémères. Ces données ne peuvent être utilisées que lorsqu’elles sont disponibles et seront perdues lorsqu’elles seront transmises. Pour cette raison, les échantillons extraits à partir du contenu du tampon au cours d’une requête ne peuvent par exemple pas être utilisés dans une réponse. Même pendant leur extraction, ces données peuvent changer. Il peut être nécessaire de définir certains délais ou de combiner plusieurs méthodes d’extraction d’échantillons afin de garantir que les données attendues sont complètes et utilisables, par exemple via l’inspection du contenu de requête TCP. Voir le mot-clé « tcp-request content » pour plus d’informations détaillées sur le sujet.

Avertissement : Les extraits d’échantillons suivants sont ignorés s’ils sont utilisés depuis des proxies HTTP. Ils ne traitent que les contenus bruts présents dans les tampons. En revanche, les proxies HTTP utilisent des contenus structurés. Par conséquent, la représentation brute de ces données est sans sens. Un avertissement est émis si une ACL repose sur l’un des extraits d’échantillons suivants. Toutefois, il n’est pas possible de détecter toutes les utilisations incorrectes (par exemple, dans un format de journal personnalisé ou une expression d’échantillonnage). Faites donc preuve de prudence.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                             output type
----------------------------------------------------+-------------
distcc_body(<token>[,<occ>])                          binary
distcc_param(<token>[,<occ>])                         integer
payload(<offset>,<length>)                            binary
payload_lv(<offset1>,<length>[,<offset2>])            binary
rdp_cookie([<name>])                                  string
rdp_cookie_cnt([name])                                integer
rep_ssl_hello_type                                    integer
req.len                                               integer
req.payload(<offset>,<length>)                        binary
req.payload_lv(<offset1>,<length>[,<offset2>])        binary
req.proto_http                                        boolean
req.rdp_cookie([<name>])                              string
req.rdp_cookie_cnt([name])                            integer
req.ssl_alpn                                          string
req.ssl_cipherlist                                    binary
req.ssl_ec_ext                                        boolean
req.ssl_hello_type                                    integer
req.ssl_keyshare_groups                               binary
req.ssl_sigalgs                                       binary
req.ssl_sni                                           string
req.ssl_st_ext                                        integer
req.ssl_supported_groups                              binary
req.ssl_ver                                           integer
req_len                                               integer
req_proto_http                                        boolean
req_ssl_hello_type                                    integer
req_ssl_sni                                           string
req_ssl_ver                                           integer
res.len                                               integer
res.payload(<offset>,<length>)                        binary
res.payload_lv(<offset1>,<length>[,<offset2>])        binary
res.ssl_hello_type                                    integer
----------------------------------------------------+-------------

Liste détaillée :

distcc_body(<token>[,<occ>]): binary

distcc_body(<token>[,<occ>]): binary

Analyse un message distcc et renvoie le corps associé à l’occurrence #<occ> du jeton <token>. Les occurrences commencent à 1, et lorsqu’elles ne sont pas spécifiées, toute occurrence peut correspondre, bien que dans la pratique seule la première soit vérifiée pour l’instant. Cette fonction peut être utilisée pour extraire des noms de fichiers ou des arguments dans des fichiers compilés à l’aide de distcc via HAProxy. Veuillez vous référer à la documentation du protocole distcc pour la liste complète des jetons pris en charge.

distcc_param(<token>[,<occ>]): integer

distcc_param(<token>[,<occ>]): integer

Analyse un message distcc et renvoie le paramètre associé à l’occurrence #<occ> du jeton <token>. Les occurrences commencent à 1, et lorsqu’elles ne sont pas précisées, toute occurrence peut correspondre, bien que dans la pratique seule la première soit vérifiée pour l’instant. Cette fonctionnalité peut être utilisée pour extraire certaines informations, telles que la version du protocole, la taille du fichier ou l’argument dans les fichiers compilés via distcc avec HAProxy. Un autre cas d’utilisation consiste à attendre le début du contenu du fichier prétraité avant de se connecter au serveur, afin d’éviter de maintenir des connexions inactives. Veuillez vous référer à la documentation du protocole distcc pour la liste complète des jetons pris en charge.

Exemple :

# wait up to 20s for the pre-processed file to be uploaded
tcp-request inspect-delay 20s
tcp-request content accept if { distcc_param(DOTI) -m found }
# send large files to the big farm
use_backend big_farm if { distcc_param(DOTI) gt 1000000 }

payload(<offset>,<length>): binary (deprecated)

payload(<offset>,<length>): binary (deprecated)

Ceci est un alias de “req.payload” lorsqu’il est utilisé dans le contexte d’une requête (par exemple, « stick on », « stick match »), et de “res.payload” lorsqu’il est utilisé dans le contexte d’une réponse, par exemple dans « stick store response ».

payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)

payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)

Ceci est un alias de “req.payload_lv” lorsqu’il est utilisé dans le contexte d’une requête (par exemple, « stick on », « stick match »), et de “res.payload_lv” lorsqu’il est utilisé dans le contexte d’une réponse, par exemple dans « stick store response ».

req.len : integer req_len : integer (obsolète) Renvoie une valeur entière correspondant au nombre d’octets présents dans le tampon de requête. Cette fonction est principalement utilisée dans les ACL. Il est important de comprendre que ce test ne renvoie pas false tant que le tampon est en cours de modification. Cela signifie qu’une vérification d’égalité à zéro correspond presque toujours immédiatement au début de la session, tandis qu’un test pour plus de données attendra que les données arrivent et ne renverra false que lorsque HAProxy est certain qu’aucune autre donnée ne parviendra. Ce test a été conçu pour être utilisé avec l’inspection du contenu des requêtes TCP.

req.payload(<offset>,<length>): binary

req.payload(<offset>,<length>): binary

Cela extrait un bloc binaire de <length> octets à partir de l’octet <offset> dans le tampon de requête. Dans un cas particulier, si l’argument <length> vaut zéro, l’intégralité du tampon depuis <offset> jusqu’à la fin est extraite. Cette fonctionnalité peut être utilisée avec des listes de contrôle d’accès afin de vérifier la présence de certains contenus dans un tampon à n’importe quelle position.

Dérivés ACL :

req.payload(<offset>,<length>): hex binary match

req.payload_lv(<offset1>,<length>[,<offset2>]): binary

req.payload_lv(<offset1>,<length>[,<offset2>]): binary

Cela extrait un bloc binaire dont la taille est spécifiée à <offset1> pour <length> octets, et qui commence à <offset2> si spécifié, ou juste après la longueur dans le tampon de requête. Le paramètre <offset2> prend également en charge des décalages relatifs si précédés d’un signe ‘+’ ou ‘-’.

Dérivés ACL :

req.payload_lv(<offset1>,<length>[,<offset2>]): hex binary match

Exemple : consultez l’exemple fourni avec le mot-clé « stick store-response ».

req.proto_http : boolean req_proto_http : boolean (obsolète) Retourne true lorsque les données dans le tampon de requête semblent être HTTP et se parse correctement comme telles. Il s’agit du même analyseur que celui utilisé par l’analyseur de requête HTTP classique, ce qui garantit une comportement prévisible. Le test ne s’effectue pas tant que la requête n’est pas complète, échouée ou expirée. Ce test peut être utilisé pour signaler le protocole dans les journaux TCP, mais son usage principal consiste à bloquer l’analyse des requêtes TCP jusqu’à ce qu’une requête HTTP complète soit présente dans le tampon, par exemple pour suivre un en-tête.

Exemple :

# track request counts per "base" (concatenation of Host+URL)
tcp-request inspect-delay 10s
tcp-request content reject if !HTTP
tcp-request content track-sc0 base table req-rate

req.rdp_cookie([<name>]): string

req.rdp_cookie([<name>]): string
rdp_cookie([<name>]): string (deprecated)

Lorsque le tampon de requête ressemble au protocole RDP, extrait le cookie RDP <name>, ou tout cookie si non spécifié. Le parseur ne vérifie qu’un seul cookie, comme illustré dans la spécification du protocole RDP. Le nom du cookie est insensible à la casse. En général, le nom de cookie « MSTS » est utilisé, car il peut contenir le nom d’utilisateur du client se connectant au serveur si correctement configuré côté client. Le cookie « MSTSHASH » est également fréquemment utilisé pour assurer la persistance de session vers les serveurs.

Cela diffère de « balance rdp-cookie » en ce sens qu’un algorithme de répartition quelconque peut être utilisé, et la répartition des clients vers les serveurs backend n’est donc pas liée au hachage du cookie RDP. Il est prévu qu’en utilisant un algorithme de répartition tel que « balance roundrobin » ou « balance leastconn », on obtienne une répartition plus équilibrée des clients vers les serveurs backend qu’avec le hachage utilisé par « balance rdp-cookie ».

Dérivés ACL :

req.rdp_cookie([<name>]): exact string match

Exemple :

listen tse-farm
    bind 0.0.0.0:3389
    # wait up to 5s for an RDP cookie in the request
    tcp-request inspect-delay 5s
    tcp-request content accept if RDP_COOKIE
    # apply RDP cookie persistence
    persist rdp-cookie
    # Persist based on the mstshash cookie
    # This is only useful makes sense if
    # balance rdp-cookie is not used
    stick-table type string size 204800
    stick on req.rdp_cookie(mstshash)
    server srv1 1.1.1.1:3389
    server srv1 1.1.1.2:3389

Voir également : « balance rdp-cookie », « persist rdp-cookie », « tcp-request » et la liste ACL “req.rdp_cookie”.

req.rdp_cookie_cnt([name]): integer

req.rdp_cookie_cnt([name]): integer
rdp_cookie_cnt([name]): integer (deprecated)

Tente d’analyser le tampon de requête selon le protocole RDP, puis renvoie un entier correspondant au nombre de cookies RDP trouvés. Si un nom de cookie facultatif est fourni, seuls les cookies correspondant à ce nom sont pris en compte. Cela est principalement utilisé dans les listes de contrôle d’accès (ACL).

Dérivés ACL :

req.rdp_cookie_cnt([<name>]): integer match

req.ssl_alpn : chaîne Retourne une chaîne contenant les valeurs de l’extension de négociation de protocole au niveau de la couche application (ALPN) TLS (RFC7301), envoyées par le client dans le message SSL ClientHello. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche de données SSL, donc cela ne fonctionnera pas avec les lignes « bind » comportant l’option « ssl ». Cela est utile dans les ACL pour prendre une décision de routage basée sur les préférences ALPN d’un client TLS, comme dans l’exemple ci-dessous. Voir également “ssl_fc_alpn”. Ce récupérateur analyse uniquement le premier message ClientHello trouvé dans le tampon de requête, consultez la documentation du mot-clé “req.ssl_sni” pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré).

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend bk_acme if { req.ssl_alpn acme-tls/1 }
default_backend bk_default

req.ssl_cipherlist binary

req.ssl_cipherlist binary

Renvoie la forme binaire de la liste des options de chiffrement symétrique prises en charge par le client, telles qu’indiquées dans le contenu d’un message ClientHello TLS. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, ce qui signifie que cela ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Reportez-vous à “ssl_fc_cipherlist_bin”, qui est l’équivalent bind SSL pouvant être utilisé lorsque l’option « ssl » est spécifiée. Cette fonction ne traite que le premier message ClientHello trouvé dans le tampon de requête ; consultez la documentation du mot-clé “req.ssl_sni” pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré).

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_cipherlist,be2hex(:,2),lower -m sub 1302:009f }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

req.ssl_ec_ext : boolean Renvoie une valeur booléenne indiquant si le client a envoyé l’extension Courbes elliptiques prises en charge, telle que définie dans RFC4492, section 5.1 , dans le message SSL ClientHello. Cette information peut être utilisée pour présenter un certificat EC aux clients compatibles ECC, et utiliser RSA pour tous les autres, sur la même adresse IP. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête, et non aux contenus déchiffrés via une couche SSL, donc cela ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Cette fonction ne traite que le premier message ClientHello trouvé dans le tampon de requête ; pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré), consulter la documentation du mot-clé “req.ssl_sni”.

req.ssl_hello_type : entier req_ssl_hello_type : entier (obsolète) Renvoie une valeur entière contenant le type du message SSL hello trouvé dans le tampon de requête, si ce tampon contient des données qui s’interprètent comme un message ClientHello SSL complet (v3 ou supérieur). Notez que cela ne s’applique qu’aux contenus bruts présents dans le tampon de requête, et non aux contenus déchiffrés via une couche SSL, donc cela ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Cette fonction est principalement utilisée dans les ACL pour détecter la présence d’un message SSL hello supposé contenir un identifiant de session SSL utilisable pour la persistance. Cette fonction n’analyse qu’le premier message ClientHello trouvé dans le tampon de requête ; pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, Encrypted Client Hello), consultez la documentation du mot-clé “req.ssl_sni”.

req.ssl_keyshare_groups binary

req.ssl_keyshare_groups binary

Renvoie le format binaire de la liste des paramètres cryptographiques pris en charge par le client pour l’échange de clés, tel que rapporté dans le message TLS ClientHello. En TLS v1.3, keyshare fait partie du message ClientHello et constitue la dernière extension du ClientHello. Notez que cette fonctionnalité ne s’applique qu’aux contenus bruts présents dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, ce qui signifie qu’elle ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Cette fonction ne traite que le premier message ClientHello trouvé dans le tampon de requête ; pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, Encrypted Client Hello), consultez la documentation du mot-clé “req.ssl_sni”.

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_keyshare_groups,be2hex(:,2),lower -m sub 001d  }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

req.ssl_sigalgs binary

req.ssl_sigalgs binary

Renvoie la forme binaire de la liste des algorithmes de signature pris en charge par le client, telle qu’elle est rapportée dans le TLS ClientHello. Cette information est disponible sous forme d’extension ClientHello. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, ce qui signifie qu’elle ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Reportez-vous à “ssl_fc_sigalgs_bin”, qui est l’équivalent SSL pour la liaison et peut être utilisé lorsque l’option « ssl » est spécifiée. Cette fonction ne traite que le premier message ClientHello trouvé dans le tampon de requête ; consultez la documentation du mot-clé “req.ssl_sni” pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré).

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe4 if { req.ssl_sigalgs,be2hex(:,2),lower -m sub 0403:0805 }
server fe4  ${htst_fe4_addr}:${htst_fe4_port}

req.ssl_sni: chaîne req_ssl_sni: chaîne (obsolète) Retourne une chaîne contenant la valeur de l’extension TLS Server Name envoyée par un client dans un flux TLS passant par le tampon de requête, si le tampon contient des données qui s’interprètent comme un message complet de type Hello client SSL (v3 ou supérieur). Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, donc cela ne fonctionnera pas avec les lignes « bind » comportant l’option « ssl ». Cela ne fonctionne que pour les protocoles TLS implicite, comme HTTPS (443), IMAPS (993), SMTPS (465), mais ne fonctionnera pas pour les protocoles TLS explicite, comme SMTP (25/587) ou IMAP (143). Le SNI contient normalement le nom de l’hôte vers lequel le client tente de se connecter (pour les navigateurs récents). Cette fonction a été conçue pour être utilisée avec l’inspection du contenu des requêtes TCP. Si un commutateur de contenu est nécessaire, il est recommandé d’attendre tout d’abord un message Hello client complet (type 1), comme dans l’exemple ci-dessous. Voir également “ssl_fc_sni”. Attention, pour les raisons détaillées ci-dessous (HelloRetryRequest, Renégociation, Hello client chiffré), la valeur retournée par cette fonction n’est pas suffisamment fiable pour être utilisée seule afin d’autoriser ou de refuser l’accès à certains hôtes.

Cette récupération ne parse que le premier message ClientHello trouvé dans le tampon de requête. Si le client envoie plusieurs messages ClientHello au sein du même flux TCP — par exemple parce que le serveur a demandé une HelloRetryRequest (HRR) dans le cadre de TLS 1.3, ou parce que le client initie une renegotiation TLS (qui envoie un nouveau ClientHello ultérieurement dans le même flux TCP, éventuellement portant un SNI différent) — seul le SNI porté par ce premier ClientHello sera retourné ; le contenu de tout ClientHello ultérieur sera ignoré.

Lorsque le Client Hello chiffré (ECH) est utilisé, le ClientHello observé sur le réseau n’est que le ClientHello « externe », qui contient le ClientHello « interne » réel, chiffré. Le SNI extrait par cette requête dans ce cas est celui du ClientHello externe, qui constitue un SNI trompeur et non l’hôte réel que le client souhaite atteindre. Cette requête ne peut actuellement ni déchiffrer ni analyser le ClientHello interne, elle ne doit donc pas être utilisée pour prendre des décisions de routage ou de contrôle d’accès lorsque ECH est activé.

Dérivés ACL :

req.ssl_sni: exact string match

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend bk_allow if { req.ssl_sni -f allowed_sites }
default_backend bk_sorry_page

req.ssl_st_ext : integer Retourne 0 si le client n’a pas envoyé d’extension SessionTicket TLS (RFC5077) Retourne 1 si le client a envoyé une extension SessionTicket TLS Retourne 2 si le client a également envoyé un ticket TLS de longueur non nulle Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, donc cela ne fonctionne pas avec les lignes « bind » comportant l’option « ssl ». Cela peut par exemple être utilisé pour détecter si le client a envoyé un ticket de session ou non, et agir en conséquence : en cas d’absence de ticket de session, utiliser l’identifiant de session ou ne pas effectuer de persistance, car il n’y a pas d’état côté serveur lorsque les tickets de session sont utilisés. Cette requête analyse uniquement le premier message ClientHello trouvé dans le tampon de requête ; pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré), consulter la documentation de la clé “req.ssl_sni”.

req.ssl_supported_groups binary

req.ssl_supported_groups binary

Renvoie la forme binaire de la liste des groupes pris en charge par le client, tels qu’indiqués dans le message TLS ClientHello et utilisés pour l’échange de clés, pouvant inclure à la fois des courbes elliptiques et des échanges de clés non-EC. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche SSL, donc cela ne fonctionne pas avec les lignes « bind » ayant l’option « ssl ». Reportez-vous à “ssl_fc_eclist_bin”, qui est l’équivalent SSL de la directive bind et peut être utilisé lorsque l’option « ssl » est spécifiée. Cette fonction ne traite que le premier message ClientHello trouvé dans le tampon de requête ; consultez la documentation du mot-clé “req.ssl_sni” pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré).

Exemples :

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_supported_groups, be2hex(:,2),lower -m sub 0017 }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

req.ssl_ver : entier req_ssl_ver : entier (obsolète) Retourne une valeur entière contenant la version du protocole SSL/TLS d’un flux présent dans le tampon de requête. Les messages Hello SSLv2 et les messages SSLv3 sont pris en charge. TLSv1 est annoncé comme version SSL 3.1. La valeur est composée de la version majeure multipliée par 65536, ajoutée à la version mineure. Notez que cela ne s’applique qu’aux contenus bruts trouvés dans le tampon de requête et non aux contenus déchiffrés via une couche de données SSL, ce qui signifie qu’il ne fonctionnera pas avec les lignes « bind » ayant l’option « ssl ». La version ACL du test correspond à une notation décimale sous la forme MAJEUR.MINEUR (par exemple 3.1). Cette fonction est principalement utilisée dans les ACL. Cette fonction n’analyse que le premier message ClientHello trouvé dans le tampon de requête ; consultez la documentation du mot-clé “req.ssl_sni” pour plus de détails sur les implications de cette limitation (HelloRetryRequest, renegotiation, ClientHello chiffré).

Dérivés ACL :

req.ssl_ver: decimal match

res.len : integer Renvoie une valeur entière correspondant au nombre d’octets présents dans le tampon de réponse. Cette fonction est principalement utilisée dans les ACL. Il est important de comprendre que ce test ne renvoie pas false tant que le tampon est en cours de modification. Cela signifie qu’une vérification d’égalité à zéro correspond presque toujours immédiatement au début du flux, tandis qu’un test pour plus de données attendra que les données arrivent et ne renverra false que lorsque HAProxy est certain qu’aucune autre donnée n’arrivera. Ce test a été conçu pour être utilisé avec l’inspection du contenu des réponses TCP. Il peut également être utilisé dans les règles d’attente basées sur tcp-check.

res.payload(<offset>,<length>): binary

res.payload(<offset>,<length>): binary

Cela extrait un bloc binaire de <length> octets à partir de l’octet <offset> dans le tampon de réponse. Dans un cas particulier, si l’argument <length> vaut zéro, tout le tampon à partir de <offset> jusqu’à la fin est extrait. Cela peut être utilisé avec des listes de contrôle d’accès afin de vérifier la présence de certains contenus dans un tampon à n’importe quelle position. Il peut également être utilisé dans les règles d’attente basées sur tcp-check.

res.payload_lv(<offset1>,<length>[,<offset2>]): binary

res.payload_lv(<offset1>,<length>[,<offset2>]): binary

Cela extrait un bloc binaire dont la taille est spécifiée à <offset1> pour <length> octets, et qui commence à <offset2> si spécifié, ou juste après la longueur dans le tampon de réponse. Le paramètre <offset2> prend également en charge des décalages relatifs si précédé d’un signe ‘+’ ou ‘-’. Il peut également être utilisé dans les règles d’attente basées sur tcp-check.

Exemple : consultez l’exemple fourni avec le mot-clé « stick store-response ».

res.ssl_hello_type : integer rep_ssl_hello_type : integer (obsolète) Retourne une valeur entière contenant le type du message SSL hello trouvé dans le tampon de réponse, si ce tampon contient des données qui se parse comme un message SSL complet (v3 ou supérieur). Notez que cela ne s’applique qu’aux contenus bruts présents dans le tampon de réponse et non aux contenus déchiffrés via une couche de données SSL, donc cela ne fonctionne pas avec les lignes « server » ayant l’option « ssl ». Cette fonction est principalement utilisée dans les ACL pour détecter la présence d’un message SSL hello supposé contenir un identifiant de session SSL utilisable pour la persistance.

7.3.6. Récupération d’échantillons HTTP (couche 7)

Il est possible de récupérer des échantillons à partir du contenu HTTP, des requêtes et des réponses. Ce niveau applicatif est également appelé couche 7. Il n’est possible de récupérer les données dans cette section que lorsque toute la requête ou la réponse HTTP a été entièrement analysée à partir de son tampon respectif. Cela est toujours le cas pour toutes les règles spécifiques à HTTP et pour les sections fonctionnant en mode http. Lors de l’inspection TCP, il peut être nécessaire de prendre en charge un délai d’inspection afin de permettre d’abord l’arrivée de la requête ou de la réponse. Ces récupérations peuvent nécessiter un peu plus de ressources CPU que celles de la couche 4, mais pas beaucoup, car les requêtes et les réponses sont indexées.

Note : En ce qui concerne le traitement HTTP des règles tcp-request content, tout fonctionne comme prévu depuis un proxy HTTP. En revanche, depuis un proxy TCP, sans mise à niveau HTTP, cela ne fonctionne que pour le contenu HTTP/1. Pour le contenu HTTP/2, seul le préambule est visible. Il n’est donc possible de s’appuyer que sur les extraits d’échantillon “req.proto_http”, “req.ver” et éventuellement « method ». Tous les autres extraits d’échantillon L7 échoueront. Après une mise à niveau HTTP, ils fonctionneront de la même manière qu’à partir d’un proxy HTTP.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                          output type
-------------------------------------------------+-------------
base                                               string
base32                                             integer
base32+src                                         binary
baseq                                              string
capture.req.hdr(<idx>)                             string
capture.req.method                                 string
capture.req.uri                                    string
capture.req.ver                                    string
capture.res.hdr(<idx>)                             string
capture.res.ver                                    string
cook([<name>])                                     string
cook_cnt([<name>])                                 integer
cook_val([<name>])                                 integer
cookie([<name>])                                   string
hdr([<name>[,<occ>]])                              string
hdr_cnt([<header>])                                integer
hdr_ip([<name>[,<occ>]])                           ip
hdr_val([<name>[,<occ>]])                          integer
http_auth(<userlist>)                              boolean
http_auth_bearer([<header>])                       string
http_auth_group(<userlist>)                        string
http_auth_pass                                     string
http_auth_type                                     string
http_auth_user                                     string
http_first_req                                     boolean
method                                             integer
path                                               string
pathq                                              string
query([<options>])                                 string
req.body                                           binary
req.body_len                                       integer
req.body_param([<name>[,i]])                       string
req.body_size                                      integer
req.cook([<name>])                                 string
req.cook_cnt([<name>])                             integer
req.cook_names([<delim>])                          string
req.cook_val([<name>])                             integer
req.fhdr(<name>[,<occ>])                           string
req.fhdr_cnt([<name>])                             integer
req.hdr([<name>[,<occ>]])                          string
req.hdr_cnt([<name>])                              integer
req.hdr_ip([<name>[,<occ>]])                       ip
req.hdr_names([<delim>])                           string
req.hdr_val([<name>[,<occ>]])                      integer
req.hdrs                                           string
req.hdrs_bin                                       binary
req.timer.hdr                                      integer
req.timer.idle                                     integer
req.timer.queue                                    integer
req.timer.tq                                       integer
req.ver                                            string
req_ver                                            string
request_date([<unit>])                             integer
res.body                                           binary
res.body_len                                       integer
res.body_size                                      integer
res.cache_hit                                      boolean
res.cache_name                                     string
res.comp                                           boolean
res.comp_algo                                      string
res.cook([<name>])                                 string
res.cook_cnt([<name>])                             integer
res.cook_names([<delim>])                          string
res.cook_val([<name>])                             integer
res.fhdr([<name>[,<occ>]])                         string
res.fhdr_cnt([<name>])                             integer
res.hdr([<name>[,<occ>]])                          string
res.hdr_cnt([<name>])                              integer
res.hdr_ip([<name>[,<occ>]])                       ip
res.hdr_names([<delim>])                           string
res.hdr_val([<name>[,<occ>]])                      integer
res.hdrs                                           string
res.hdrs_bin                                       binary
res.timer.hdr                                      integer
res.ver                                            string
resp_ver                                           string
scook([<name>])                                    string
scook_cnt([<name>])                                integer
scook_val([<name>])                                integer
server_status                                      integer
set-cookie([<name>])                               string
shdr([<name>[,<occ>]])                             string
shdr_cnt([<name>])                                 integer
shdr_ip([<name>[,<occ>]])                          ip
shdr_val([<name>[,<occ>]])                         integer
status                                             integer
txn.status                                         integer
txn.timer.total                                    integer
unique-id                                          string
url                                                string
url32                                              integer
url32+src                                          binary
url_ip                                             ip
url_param([<name>[,<delim>[,i]]])                  string
url_port                                           integer
urlp([<name>[,<delim>[,i]]])                       string
urlp_val([<name>[,<delim>[,i]]])                   integer
-------------------------------------------------+-------------

Liste détaillée :

base : chaîne Cette valeur retourne la concaténation de la première en-tête Host et de la partie chemin de la requête, qui commence au premier slash et se termine avant le point d’interrogation. Elle peut être utile dans les environnements à hébergement virtuel pour détecter les abus d’URL ainsi que pour améliorer l’efficacité des caches partagés. En l’utilisant avec une table de persistance de taille limitée, il est possible de collecter des statistiques sur les objets les plus fréquemment demandés par host/path.. Avec des listes de contrôle d’accès (ACL), elle permet d’implémenter des règles simples de commutation de contenu impliquant à la fois l’hôte et le chemin, telles que « www.example.com/favicon.ico ». Voir également « path » et « uri ».

Dérivés ACL :

base    : exact string match
base_beg: prefix match
base_dir: subdir match
base_dom: domain match
base_end: suffix match
base_len: length match
base_reg: regex match
base_sub: substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

base32 : entier Cette commande retourne un hachage 32 bits de la valeur renvoyée par la méthode de récupération « base » ci-dessus. Cela est utile pour suivre l’activité par URL sur des sites à fort trafic sans avoir à stocker toutes les URLs. Au lieu de cela, un hachage plus court est stocké, ce qui permet d’économiser beaucoup de mémoire. Le type de sortie est un entier non signé. La fonction de hachage utilisée est SDBM avec avalanche complète sur la sortie. Techniquement, base32 est exactement équivalent à « base,sdbm(1) ».

base32+src : binaire Cette commande retourne la concaténation de la récupération base32 ci-dessus et de la récupération src ci-dessous. Le type résultant est de type binaire, avec une taille de 8 ou 20 octets selon la famille d’adresse source. Cela peut être utilisé pour suivre des compteurs par IP ou par URL.

baseq : chaîne Cette valeur retourne la concaténation du premier en-tête Host et de la partie chemin de la requête avec la chaîne de requête, qui commence au premier slash. Utiliser cette valeur à la place de « base » permet d’identifier correctement la ressource cible, notamment pour les cas d’utilisation statistiques ou de mise en cache. Voir également « path », « pathq » et « base ».

capture.req.hdr(<idx>): string

capture.req.hdr(<idx>): string

Cela extrait le contenu de l’en-tête capturé par la directive « capture request header », idx correspond à la position du mot-clé capture dans la configuration. La première entrée a un index de 0. Voir également : « capture request header ».

capture.req.method : chaîne Cela extrait la méthode d’une requête HTTP. Il peut être utilisé dans les requêtes et les réponses. Contrairement à « method », il peut être utilisé dans les requêtes et les réponses car il est alloué.

capture.req.uri : chaîne Cela extrait l’URI de la requête, qui commence au premier slash et se termine avant le premier espace dans la requête (sans la partie hôte). Contrairement à « path » et « url », il peut être utilisé à la fois dans les requêtes et les réponses, car il est alloué.

capture.req.ver : chaîne Cette extraction d’échantillon récupère la version HTTP de la requête et la renvoie au format “HTTP/<major>.<minor>”. Elle peut être utilisée dans les requêtes, les réponses et les journaux, car elle repose sur une information persistante. Si la version de la requête n’est pas valide, cette extraction d’échantillon échoue.

capture.res.hdr(<idx>): string

capture.res.hdr(<idx>): string

Cela extrait le contenu de l’en-tête capturé par la directive « capture response header », idx correspond à la position du mot-clé de capture dans la configuration. La première entrée a un index de 0. Voir également : « capture response header »

capture.res.ver : chaîne Cette extraction récupère la version HTTP de la réponse et la renvoie au format “HTTP/<major>.<minor>”. Elle peut être utilisée dans les journaux car elle repose sur une information persistante. Si la version de la réponse n’est pas valide, cette extraction d’échantillon échoue.

cookie([<name>]): string (deprecated)

cookie([<name>]): string (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> dans une ligne d’en-tête « Cookie » de la requête, ou dans un en-tête « Set-Cookie » de la réponse, et retourne sa valeur sous forme de chaîne. Un usage courant consiste à faire en sorte que plusieurs clients partageant un même profil utilisent le même serveur. Cela peut être similaire à ce que faisait « appsession » avec l’instruction « request-learn », mais avec prise en charge de la synchronisation multi-pair et du maintien d’état entre redémarrages. Si aucun nom n’est spécifié, la première valeur de cookie est retournée. Cette fonction de récupération ne doit plus être utilisée et doit être remplacée par req.cook() ou res.cook() à la place, car elle utilise de manière ambiguë la direction en fonction du contexte dans lequel elle est utilisée.

hdr([<name>[,<occ>]]): string

hdr([<name>[,<occ>]]): string

Cela équivaut à req.hdr() lorsqu’il est utilisé sur les requêtes, et à res.hdr() lorsqu’il est utilisé sur les réponses. Veuillez vous référer à ces extraits respectifs pour plus de détails. En cas de doute sur le sens de l’extraction, utilisez les formes explicites. Notez qu’à la différence de la méthode d’extraction hdr(), les mots-clés ACL hdr_* s’appliquent sans ambiguïté aux en-têtes de requête.

http_auth(<userlist>): boolean

http_auth(<userlist>): boolean

Renvoie une valeur booléenne indiquant si les données d’authentification reçues du client correspondent à un couple nom d’utilisateur et mot de passe stocké dans la liste d’utilisateurs spécifiée. Cette fonction de récupération n’est pas vraiment utile en dehors des ACLs. Seule l’authentification HTTP basique est actuellement prise en charge.

http_auth_bearer([<header>]): string

http_auth_bearer([<header>]): string

Renvoie le jeton fourni par le client, extrait des données d’autorisation lorsque le schéma Bearer est utilisé (par exemple, pour envoyer des jetons Web JSON). Aucune vérification n’est effectuée sur les données envoyées par le client. Si un <header> spécifique est fourni, il analysera cet en-tête au lieu de l’en-tête Authorization.

http_auth_group(<userlist>): string

http_auth_group(<userlist>): string

Renvoie une chaîne correspondant au nom d’utilisateur extrait des données d’authentification reçues du client, si le nom d’utilisateur et le mot de passe sont valides selon la liste d’utilisateurs spécifiée. Son usage principal consiste à l’utiliser dans les ACLs, où l’on vérifie ensuite si l’utilisateur appartient à un groupe figurant dans une liste. Cette fonction de récupération n’est pas vraiment utile en dehors des ACLs. Seule l’authentification HTTP basique est actuellement prise en charge.

Dérivés ACL :

http_auth_group(<userlist>): group ...
Returns true when the user extracted from the request and whose password is
valid according to the specified userlist belongs to at least one of the
groups.

http_auth_pass : chaîne Renvoie le mot de passe de l’utilisateur trouvé dans les données d’authentification reçues du client, tel qu’indiqué dans l’en-tête Authorization. Aucune vérification n’est effectuée par cette extraction d’échantillon. Seule l’authentification Basic est prise en charge.

http_auth_type : chaîne Retourne la méthode d’authentification trouvée dans les données d’authentification reçues du client, telles qu’elles sont fournies dans l’en-tête Authorization. Aucune vérification n’est effectuée par cette requête d’échantillonnage. Seule l’authentification Basic est prise en charge.

http_auth_user : chaîne Renvoie le nom d’utilisateur extrait des données d’authentification reçues du client, tel qu’indiqué dans l’en-tête Authorization. Aucune vérification n’est effectuée par cette extraction d’échantillon. Seule l’authentification Basic est prise en charge.

http_first_req : boolean Retourne true lorsque la requête en cours de traitement est la première de la connexion. Cela peut être utilisé pour ajouter ou supprimer des en-têtes manquants dans certaines requêtes lorsque celle-ci n’est pas la première, ou pour aider à regrouper les requêtes dans les journaux.

method : entier + chaîne Renvoie une valeur entière correspondant à la méthode dans la requête HTTP. Par exemple, « GET » vaut 1 (vérifier les sources pour établir la correspondance). La valeur 9 signifie « autre méthode » et peut être convertie en chaîne extraite du flux. Cette valeur ne doit pas être utilisée directement comme échantillon ; elle n’est destinée qu’à être utilisée dans les ACL, qui convertissent automatiquement les méthodes à partir de modèles en ces valeurs entier + chaîne. Certaines ACL prédéfinies vérifient déjà les méthodes les plus courantes.

Dérivés ACL :

method: case insensitive method match

Exemple :

# only accept GET and HEAD requests
acl valid_method method GET HEAD
http-request deny if ! valid_method

path : chaîne Cela extrait le chemin de l’URL de la requête, qui commence au premier slash et se termine avant le point d’interrogation (sans la partie hôte). Une utilisation typique consiste à combiner cette fonctionnalité avec des caches capables de préchargement, ainsi qu’avec des portails qui doivent agréger plusieurs informations provenant de bases de données et les conserver en mémoire cache. Notez que, pour les caches sortants, il serait préférable d’utiliser « url » à la place. Avec les listes de contrôle d’accès (ACL), elle est généralement utilisée pour correspondre à des noms de fichiers exacts (par exemple « /login.php »), ou à des parties de répertoires en utilisant les formes dérivées. Voir également les méthodes d’extraction « url » et « base ». Veuillez noter que toute référence à un fragment dans l’URI (« ‘#’ » après le chemin) est strictement interdite par la norme HTTP et sera rejetée. Toutefois, si le frontal recevant la requête dispose de l’option « accept-unsafe-violations-in-http-request », cette partie de fragment sera acceptée et apparaîtra également dans le chemin.

Dérivés ACL :

path    : exact string match
path_beg: prefix match
path_dir: subdir match
path_dom: domain match
path_end: suffix match
path_len: length match
path_reg: regex match
path_sub: substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

pathq : chaîne Cette extraction d’échantillon récupère le chemin d’URL de la requête, y compris la chaîne de requête, en commençant par la première barre oblique. Cette extraction d’échantillon est particulièrement utile pour toujours récupérer une URI relative, en excluant la partie schéma et autorité, le cas échéant. En effet, bien que cette représentation soit courante pour la cible d’une requête HTTP/1.1, elle est souvent remplacée par une URI absolue dans HTTP/2. Cette extraction d’échantillon retournera le même résultat dans les deux cas. Veuillez noter que toute référence de fragment dans l’URI (’#’ après le chemin) est strictement interdite par la norme HTTP et sera rejetée. Toutefois, si le frontal recevant la requête dispose de l’option accept-unsafe-violations-in-http-request, cette partie de fragment sera acceptée et apparaîtra également dans le chemin.

query([<options>]): string

query([<options>]): string

Cela extrait la chaîne de requête de la requête, qui commence après le premier point d’interrogation. Si aucun point d’interrogation n’est présent, cette fonction retourne rien. Si un point d’interrogation est présent mais qu’il n’est suivi de rien, elle retourne une chaîne vide. Cela permet de déterminer facilement la présence d’une chaîne de requête en utilisant la méthode de correspondance « found ». Cette fonction complète « path », qui s’arrête avant le point d’interrogation, et “query_string”, qui inclut le point d’interrogation.

Un paramètre facultatif peut être utilisé pour personnaliser la valeur de retour. Les options suivantes sont prises en charge :

- with_qm : Inclure le point d'interrogation au début de la chaîne de requête, si elle n'est pas vide.

req.body : binaire Cette fonction renvoie le corps de la requête HTTP disponible sous forme de bloc de données. Il est recommandé d’utiliser « option http-buffer-request » afin de s’assurer d’attendre, dans la mesure du possible, la totalité du corps de la requête.

req.body_len : entier Cette valeur retourne la longueur du corps disponible de la requête HTTP en octets. Elle peut être inférieure à la longueur annoncée si le corps est plus grand que le tampon. Il est recommandé d’utiliser « option http-buffer-request » afin de s’assurer, dans la mesure du possible, d’attendre la totalité du corps de la requête.

req.body_param([<name>[,i]]): string

req.body_param([<name>[,i]]): string

Cette requête suppose que le corps de la requête POST est encodé en URL. L’utilisateur peut vérifier si l’en-tête « content-type » contient la valeur “application/x-www-form-urlencoded”. Cette opération extrait la première occurrence du paramètre “<name>” dans le corps, qui se termine avant le caractère ‘&’. Le nom du paramètre est sensible à la casse, sauf si « i » est ajouté comme deuxième argument. Si aucun nom n’est fourni, tout paramètre correspondra, et la première valeur sera retournée. Le résultat est une chaîne correspondant à la valeur du paramètre “<name>” telle qu’elle apparaît dans le corps de la requête (aucune décodage URL n’est effectué). Notez que la version ACL de cette requête itère sur plusieurs paramètres et signalera successivement toutes les valeurs si aucun nom n’est spécifié.

req.body_size : integer Cette valeur retourne la taille annoncée du corps de la requête HTTP en octets. Elle correspond à la valeur de l’en-tête Content-Length annoncé, ou à la taille des données disponibles en cas de codage par tronçons.

req.cook([<name>]): string

req.cook([<name>]): string
cook([<name>]): string (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> sur une ligne d’en-tête « Cookie » de la requête, et retourne sa valeur sous forme de chaîne. Si aucun nom n’est spécifié, la première valeur de cookie est retournée. Lorsqu’il est utilisé avec des ACLs, tous les cookies correspondants sont évalués. Les espaces autour du nom et de la valeur sont ignorés, conformément à la spécification de l’en-tête Cookie (RFC6265). Le nom de cookie est sensible à la casse. Les cookies vides sont valides, aussi une valeur vide peut-elle être retournée si le cookie est présent. Utilisez la correspondance « found » pour détecter la présence. Utilisez la variante res.cook() pour les cookies envoyés par le serveur dans la réponse.

Dérivés ACL :

req.cook([<name>])    : exact string match
req.cook_beg([<name>]): prefix match
req.cook_dir([<name>]): subdir match
req.cook_dom([<name>]): domain match
req.cook_end([<name>]): suffix match
req.cook_len([<name>]): length match
req.cook_reg([<name>]): regex match
req.cook_sub([<name>]): substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

req.cook_cnt([<name>]): integer

req.cook_cnt([<name>]): integer
cook_cnt([<name>]): integer (deprecated)

Renvoie une valeur entière représentant le nombre d’occurrences du cookie <name> dans la requête, ou de tous les cookies si <name> n’est pas spécifié.

req.cook_names([<delim>]): string

req.cook_names([<delim>]): string

Cela construit une chaîne issue de la concaténation de tous les noms de cookies tels qu’ils apparaissent dans la requête (en-tête Cookie) au moment de l’évaluation de la règle. Le délimiteur par défaut est la virgule (’,’), mais il peut être remplacé par un argument facultatif <delim>. Dans ce cas, seul le premier caractère de <delim> est pris en compte.

req.cook_val([<name>]): integer

req.cook_val([<name>]): integer
cook_val([<name>]): integer (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> sur une ligne d’en-tête « Cookie » de la requête, et convertit sa valeur en entier, qui est ensuite retournée. Si aucun nom n’est spécifié, la première valeur de cookie est retournée. Lorsqu’il est utilisé dans des ACL, tous les noms correspondants sont parcourus jusqu’à ce qu’une valeur corresponde.

req.fhdr(<name>[,<occ>]): string

req.fhdr(<name>[,<occ>]): string

Cela renvoie la valeur complète de la dernière occurrence de l’en-tête <name> dans une requête HTTP. Il diffère de req.hdr() en ce sens que les virgules présentes dans la valeur sont renvoyées et ne sont pas utilisées comme délimiteurs. Cela peut parfois être utile avec des en-têtes tels que User-Agent.

Lorsqu’il est utilisé dans une ACL, toutes les occurrences sont parcourues jusqu’à ce qu’une correspondance soit trouvée.

Optionnellement, une occurrence spécifique peut être précisée sous forme de numéro de position. Les valeurs positives indiquent une position à partir de la première occurrence, 1 étant la première. Les valeurs négatives indiquent des positions relatives à la dernière, -1 étant la dernière.

req.fhdr_cnt([<name>]): integer

req.fhdr_cnt([<name>]): integer

Renvoie une valeur entière représentant le nombre d’occurrences du nom de champ d’en-tête de requête <name>, ou le nombre total de champs d’en-tête si <name> n’est pas spécifié. Contrairement à res.hdr_cnt(), il ne fractionne pas les en-têtes aux virgules.

req.hdr([<name>[,<occ>]]): string

req.hdr([<name>[,<occ>]]): string

Cela retourne la dernière valeur séparée par des virgules de l’en-tête <name> dans une requête HTTP. La récupération considère toute virgule comme un délimiteur entre des valeurs distinctes. Cela est utile si vous devez traiter des en-têtes définis comme une liste de valeurs, tels que Accept ou X-Forwarded-For. Si vous souhaitez obtenir l’en-tête complet à la place, utilisez req.fhdr(). Veuillez vérifier soigneusement le RFC 7231 pour connaître la manière correcte de parser certains en-têtes. Certains d’entre eux sont également insensibles à la casse (par exemple, Connection).

Lorsqu’il est utilisé dans une ACL, toutes les occurrences sont parcourues jusqu’à ce qu’une correspondance soit trouvée.

Optionnellement, une occurrence spécifique peut être précisée sous forme de numéro de position. Les valeurs positives indiquent une position à partir de la première occurrence, 1 étant la première. Les valeurs négatives indiquent des positions relatives à la dernière, -1 étant la dernière.

Un usage typique consiste à utiliser l’en-tête X-Forwarded-For une fois converti en adresse IP, associé à une table IP.

Dérivés ACL :

hdr([<name>[,<occ>]])    : exact string match
hdr_beg([<name>[,<occ>]]): prefix match
hdr_dir([<name>[,<occ>]]): subdir match
hdr_dom([<name>[,<occ>]]): domain match
hdr_end([<name>[,<occ>]]): suffix match
hdr_len([<name>[,<occ>]]): length match
hdr_reg([<name>[,<occ>]]): regex match
hdr_sub([<name>[,<occ>]]): substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

req.hdr_cnt([<name>]): integer

req.hdr_cnt([<name>]): integer
hdr_cnt([<header>]): integer (deprecated)

Renvoie une valeur entière représentant le nombre d’occurrences du nom de champ d’en-tête de requête <name>, ou le nombre total de valeurs de champ d’en-tête si <name> n’est pas spécifié. Comme req.hdr(), il compte chaque partie séparée par une virgule de la valeur de l’en-tête. Si l’on souhaite compter les en-têtes complets, il convient d’utiliser req.fhdr_cnt() à la place.

Avec les listes de contrôle d’accès (ACL), il peut être utilisé pour détecter la présence, l’absence ou l’abus d’un en-tête spécifique, ainsi que pour bloquer les attaques par camouflage de requête en rejetant les requêtes contenant plus d’un des en-têtes suivants.

Consultez req.hdr() pour plus d’informations sur le correspondance des en-têtes.

req.hdr_ip([<name>[,<occ>]]): ip

req.hdr_ip([<name>[,<occ>]]): ip
hdr_ip([<name>[,<occ>]]): ip (deprecated)

Cela extrait la dernière occurrence de l’en-tête <name> dans une requête HTTP, la convertit en adresse IPv4 ou IPv6, puis renvoie cette adresse. Lorsqu’il est utilisé avec des ACL, toutes les occurrences sont vérifiées, et si <name> est omis, chaque valeur de chaque en-tête est vérifiée. Le parseur respecte strictement le format décrit dans RFC7239, avec l’extension selon laquelle les adresses IPv4 peuvent éventuellement être suivies d’un deux-points (’:’) et d’un numéro de port décimal valide (compris entre 0 et 65535), qui sera ignoré sans avertissement. Toutes les autres formes ne correspondent pas et entraînent l’ignorance de l’adresse.

Le paramètre <occ> est traité comme avec req.hdr().

Un usage courant consiste à utiliser les en-têtes X-Forwarded-For et X-Client-IP.

req.hdr_names([<delim>]): string

req.hdr_names([<delim>]): string

Cela construit une chaîne formée par la concaténation de tous les noms d’en-tête tels qu’ils apparaissent dans la requête au moment d’évaluer la règle. Le délimiteur par défaut est la virgule (’,’), mais il peut être remplacé par un argument optionnel <delim>. Dans ce cas, seul le premier caractère de <delim> est pris en compte.

req.hdr_val([<name>[,<occ>]]): integer

req.hdr_val([<name>[,<occ>]]): integer
hdr_val([<name>[,<occ>]]): integer (deprecated)

Cela extrait la dernière occurrence de l’en-tête <name> dans une requête HTTP, et la convertit en valeur entière. Lorsqu’il est utilisé avec des listes de contrôle d’accès (ACL), toutes les occurrences sont vérifiées, et si <name> est omis, chaque valeur de chaque en-tête est vérifiée.

Le paramètre <occ> est traité comme avec req.hdr().

Un usage courant consiste à utiliser l’en-tête X-Forwarded-For.

req.hdrs : chaîne Retourne les en-têtes de la requête courante sous forme de chaîne, y compris la dernière ligne vide séparant les en-têtes du corps de la requête. La dernière ligne vide peut être utilisée pour détecter un bloc d’en-têtes tronqué. Cette extraction d’échantillon est utile pour certains analyseurs d’en-têtes SPOE et pour la journalisation avancée.

req.hdrs_bin : binaire Retourne les en-têtes de la requête actuelle sous forme binaire préanalyse. Cela est utile pour déléguer certaines opérations avec SPOE. Chaque chaîne est décrite par une longueur suivie du nombre d’octets indiqué par cette longueur. La longueur est représentée à l’aide du codage entier variable décrit dans la documentation SPOE. La fin de la liste est marquée par une paire de noms d’en-tête et de valeurs vides (longueur de 0 pour les deux).

*(<str:header-name>``<str:header-value>)<empty string>``<empty string>

int : consultez la documentation SPOE pour le codage ; str : <int:length>``<bytes>

req.timer.hdr : entier Temps total pour obtenir la requête client (mode HTTP uniquement). Il s’agit du temps écoulé entre la réception des premiers octets et le moment où le proxy a reçu la ligne vide marquant la fin des en-têtes HTTP. Cette valeur est exprimée en millisecondes (ms) et équivaut à %TR dans le format de journalisation. Voir section 8.4 « Événements de temporisation » pour plus de détails.

req.timer.idle : entier Ce paramètre indique le délai d’inactivité avant la requête HTTP (mode HTTP uniquement). Ce minuteur compte entre la fin des échanges de main et la première octet de la requête HTTP. La valeur est exprimée en millisecondes et équivaut à %Ti dans le format de journalisation. Pour plus de détails, voir section 8.4 « Événements de temporisation ».

req.timer.queue : entier Temps total passé dans les files d’attente en attente d’une slot de connexion. Cette valeur est exprimée en millisecondes et équivaut à %Tw dans le format de journalisation. Voir section 8.4 « Événements de temporisation » pour plus de détails.

req.timer.tq : entier temps total pour obtenir la requête client à partir de la date d’acceptation ou depuis l’émission du dernier octet de la réponse précédente. Cette valeur est exprimée en millisecondes et équivaut à %Tq dans le format de journalisation. Voir section 8.4 « Événements de temporisation » pour plus de détails.

req.ver : chaîne req_ver : chaîne (obsolète) Retourne la chaîne de version de la requête HTTP, au format “<major>.<minor>”. Cela peut être utile pour les ACL. Certaines ACL prédéfinies vérifient déjà les versions courantes. Cette extraction peut être utilisée dans les requêtes, les réponses et les journaux, car elle repose sur des informations persistantes. Si la version de la requête n’est pas valide, cette extraction d’échantillon échoue.

Les valeurs courantes sont “1.0”, “1.1”, “2.0” ou “3.0”.

Dérivés ACL :

req.ver: exact string match

request_date([<unit>]): integer

request_date([<unit>]): integer

C’est la date exacte à laquelle le premier octet de la requête HTTP a été reçu par HAProxy (alias de format de journalisation %tr). Cette valeur est calculée à partir de accept_date + temps de main-handshake (%Th) + temps d’attente (%Ti).

Renvoie une valeur en nombre de secondes depuis l’époque.

<unit> est facultatif et peut être défini à « s » pour secondes (comportement par défaut), « ms » pour millisecondes ou « us » pour microsecondes. Si l’unité est définie, la valeur renvoyée est un entier représentant respectivement les secondes, millisecondes ou microsecondes écoulées depuis l’époque. Cette option est utile lorsque une résolution temporelle inférieure à une seconde est requise.

res.body : binaire Cette commande renvoie le corps disponible de la réponse HTTP sous forme de bloc de données. Contrairement au côté requête, aucune directive n’est disponible pour attendre le corps de la réponse. Cette extraction d’échantillon est particulièrement utile (et utilisable) dans le contexte de vérification de santé.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.body_len : entier Cette valeur retourne la longueur du corps de la réponse HTTP disponible, en octets. Contrairement au côté requête, il n’existe aucune directive pour attendre le corps de la réponse. Cette extraction d’échantillon est particulièrement utile (et utilisable) dans le contexte de vérification de santé.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.body_size : entier Cette valeur retourne la taille annoncée du corps de la réponse HTTP en octets. Elle correspond à la valeur de l’en-tête Content-Length annoncé, ou à la taille des données disponibles en cas de codage par tronçons. Contrairement au côté requête, aucune directive n’exige d’attendre le corps de la réponse. Cette extraction d’échantillon est particulièrement utile (et utilisable) dans le contexte de vérification de santé.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.cache_hit : boolean Renvoie la valeur booléenne « true » si la réponse a été construite à partir d’une entrée du cache HTTP, sinon renvoie la valeur booléenne « false ».

res.cache_name : chaîne Retourne une chaîne contenant le nom du cache HTTP utilisé pour construire la réponse HTTP si res.cache_hit est vrai, sinon retourne une chaîne vide.

res.comp : boolean Retourne la valeur booléenne « true » si la réponse a été compressée par HAProxy, sinon retourne la valeur booléenne « false ». Cette information peut être utilisée pour ajouter des données dans les journaux.

res.comp_algo : chaîne Retourne une chaîne contenant le nom de l’algorithme utilisé si la réponse a été compressée par HAProxy, par exemple : « deflate ». Cette information peut être utilisée pour ajouter des données aux journaux.

res.cook([<name>]): string

res.cook([<name>]): string
scook([<name>]): string (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> sur une ligne d’en-tête « Set-Cookie » de la réponse, et retourne sa valeur sous forme de chaîne. Si aucun nom n’est spécifié, la première valeur de cookie est retournée.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

Dérivés ACL :

res.scook([<name>]: exact string match

res.cook_cnt([<name>]): integer

res.cook_cnt([<name>]): integer
scook_cnt([<name>]): integer (deprecated)

Renvoie une valeur entière représentant le nombre d’occurrences du cookie <name> dans la réponse, ou de tous les cookies si <name> n’est pas spécifié. Cela est principalement utile lorsqu’il est combiné avec des ACLs pour détecter des réponses suspectes.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.cook_names([<delim>]): string

res.cook_names([<delim>]): string

Cela construit une chaîne formée par la concaténation de tous les noms de cookies tels qu’ils apparaissent dans la réponse (en-têtes Set-Cookie) au moment de l’évaluation de la règle. Le délimiteur par défaut est la virgule (’,’), mais il peut être remplacé par un argument optionnel <delim>. Dans ce cas, seul le premier caractère de <delim> est pris en compte.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.cook_val([<name>]): integer

res.cook_val([<name>]): integer
scook_val([<name>]): integer (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> sur une ligne d’en-tête « Set-Cookie » de la réponse, et convertit sa valeur en entier, qui est ensuite retournée. Si aucun nom n’est spécifié, la première valeur de cookie est retournée.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.fhdr([<name>[,<occ>]]): string

res.fhdr([<name>[,<occ>]]): string

Cette requête fonctionne comme la requête req.fhdr() avec la différence qu’elle agit sur les en-têtes présents dans une réponse HTTP.

Comme req.fhdr(), la fonction res.fhdr() renvoie les valeurs complètes. Si l’en-tête est défini comme une liste, vous devez utiliser res.hdr().

Cette récupération est parfois utile avec des en-têtes tels que Date ou Expires.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.fhdr_cnt([<name>]): integer

res.fhdr_cnt([<name>]): integer

Cette requête fonctionne comme la requête req.fhdr_cnt() avec la différence qu’elle agit sur les en-têtes présents dans une réponse HTTP.

Comme req.fhdr_cnt(), l’action res.fhdr_cnt() agit sur les valeurs complètes. Si l’en-tête est défini comme une liste, vous devez utiliser res.hdr_cnt().

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.hdr([<name>[,<occ>]]): string

res.hdr([<name>[,<occ>]]): string
shdr([<name>[,<occ>]]): string (deprecated)

Cette requête fonctionne comme la requête req.hdr(), à la différence qu’elle agit sur les en-têtes présents dans une réponse HTTP.

Comme req.hdr(), la fonction res.hdr() considère la virgule comme un séparateur. Si ce comportement n’est pas souhaité, res.fhdr() doit être utilisée.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

Dérivés ACL :

res.hdr([<name>[,<occ>]])    : exact string match
res.hdr_beg([<name>[,<occ>]]): prefix match
res.hdr_dir([<name>[,<occ>]]): subdir match
res.hdr_dom([<name>[,<occ>]]): domain match
res.hdr_end([<name>[,<occ>]]): suffix match
res.hdr_len([<name>[,<occ>]]): length match
res.hdr_reg([<name>[,<occ>]]): regex match
res.hdr_sub([<name>[,<occ>]]): substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

res.hdr_cnt([<name>]): integer

res.hdr_cnt([<name>]): integer
shdr_cnt([<name>]): integer (deprecated)

Ce récupérateur fonctionne comme req.hdr_cnt() mais agit sur les en-têtes présents dans une réponse HTTP.

Comme req.hdr_cnt(), la fonction res.hdr_cnt() considère la virgule comme un délimiteur. Si ce comportement n’est pas souhaité, il faut utiliser res.fhdr_cnt().

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.hdr_ip([<name>[,<occ>]]): ip

res.hdr_ip([<name>[,<occ>]]): ip
shdr_ip([<name>[,<occ>]]): ip (deprecated)

Ce récupérateur fonctionne comme req.hdr_ip() mais agit sur les en-têtes présents dans une réponse HTTP.

Cela peut être utile pour charger certaines données dans une table de persistance.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.hdr_names([<delim>]): string

res.hdr_names([<delim>]): string

Cela construit une chaîne formée par la concaténation de tous les noms d’en-tête tels qu’ils apparaissent dans la réponse lorsque la règle est évaluée. Le délimiteur par défaut est la virgule (’,’), mais il peut être remplacé par un argument optionnel <delim>. Dans ce cas, seul le premier caractère de <delim> est pris en compte.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.hdr_val([<name>[,<occ>]]): integer

res.hdr_val([<name>[,<occ>]]): integer
shdr_val([<name>[,<occ>]]): integer (deprecated)

Ce récupérateur fonctionne comme req.hdr_val(), à ceci près qu’il agit sur les en-têtes présents dans une réponse HTTP.

Cela peut être utile pour charger certaines données dans une table de persistance.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

res.hdrs : string Retourne les en-têtes de réponse actuels sous forme de chaîne, y compris la dernière ligne vide séparant les en-têtes du corps de la réponse. Cette ligne vide peut être utilisée pour détecter un bloc d’en-têtes tronqué. Cette extraction d’échantillon est utile pour certains analyseurs d’en-têtes SPOE et pour la journalisation avancée.

Il peut également être utilisé dans les règles d’attente basées sur tcp-check.

res.hdrs_bin : binaire Retourne les en-têtes de réponse actuels sous forme binaire préanalyse. Cela est utile pour déléguer certains traitements avec SPOE. Il peut être utilisé dans les règles d’attente basées sur tcp-check. Chaque chaîne est décrite par une longueur suivie du nombre d’octets indiqué par cette longueur. La longueur est représentée à l’aide du codage entier variable décrit dans la documentation SPOE. La fin de la liste est marquée par une paire de noms d’en-tête et de valeurs vides (longueur de 0 pour les deux).

*(<str:header-name>``<str:header-value>)<empty string>``<empty string>

int : consultez la documentation SPOE pour le codage ; str : <int:length>``<bytes>

res.timer.hdr : integer Il s’agit du temps écoulé entre l’instant où la connexion TCP a été établie avec le serveur et l’instant où le serveur a envoyé l’intégralité de ses en-têtes de réponse. Cette valeur est exprimée en millisecondes et correspond à %Tr dans le format de journalisation. Voir section 8.4 « Événements de temporisation » pour plus de détails.

res.ver : chaîne resp_ver : chaîne (obsolète) Retourne la chaîne de version provenant de la réponse HTTP, au format “<major>.<minor>”. Cela peut être utile pour les journaux, mais sert principalement aux ACL. Si la version de la réponse n’est pas valide, cette extraction d’échantillon échoue.

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

Dérivés ACL :

resp.ver: exact string match

server_status : integer Renvoie un entier contenant le code d’état HTTP reçu du serveur. Si aucune réponse n’a été reçue du serveur, l’extraction d’échantillon échoue.

set-cookie([<name>]): string (deprecated)

set-cookie([<name>]): string (deprecated)

Cela extrait la dernière occurrence du nom de cookie <name> dans une ligne d’en-tête « Set-Cookie » de la réponse et utilise la valeur correspondante pour effectuer la correspondance. Cela peut être comparé à ce que faisait « appsession » avec les options par défaut, mais avec prise en charge de la synchronisation multi-pair et du maintien de l’état entre redémarrages.

Cette fonction de récupération est obsolète et a été remplacée par la fonction de récupération “res.cook”. Ce mot-clé disparaîtra prochainement.

status : integer Renvoie un entier contenant le code d’état HTTP dans la réponse HTTP, par exemple 302. Il est principalement utilisé dans les ACLs et les plages d’entiers, par exemple pour supprimer tout en-tête Location si la réponse n’est pas un 3xx. Il correspond au code d’état reçu par le client s’il n’est pas modifié, par exemple via une action « set-status ».

Il peut être utilisé dans les règles d’attente basées sur tcp-check.

txn.status : integer Renvoie un entier contenant le code d’état HTTP de la transaction, tel qu’il est indiqué dans le journal.

txn.timer.total : entier Temps total d’activité pour la requête HTTP, compris entre le moment où le proxy a reçu le premier octet de l’en-tête de la requête et l’émission du dernier octet du corps de la réponse. Il s’agit de l’équivalent de %Ta dans le format de journalisation et est exprimé en millisecondes (ms). Pour plus d’informations, voir Section 8.4 “Événements de temporisation”

unique-id : chaîne Retourne l’identifiant unique attaché à la requête. La directive « unique-id-format » doit être définie. Si elle n’est pas définie, l’extraction d’échantillon unique-id échoue. Notez que l’identifiant unique est généralement utilisé avec les requêtes HTTP, mais cette extraction d’échantillon peut être utilisée avec d’autres protocoles. Évidemment, si elle est utilisée avec des protocoles autres que HTTP, la directive unique-id-format ne doit pas contenir de parties spécifiques à HTTP. Voir : unique-id-format et unique-id-header

url : chaîne Cette extraction permet d’obtenir l’URL de la requête telle qu’elle est présentée dans la requête. Un usage courant consiste à l’utiliser avec des caches capables de préchargement, ainsi que dans les portails qui doivent agréger plusieurs informations provenant de bases de données et les conserver en cache. Avec les listes de contrôle d’accès (ACL), il est préférable d’utiliser « path » plutôt que « url », car les clients peuvent envoyer une URL complète, comme cela se fait normalement avec les proxies. L’unique utilisation réelle consiste à effectuer un match avec « * », qui ne peut pas être effectué avec « path », et pour lequel une ACL prédéfinie existe déjà. Voir également « path » et « base ». Veuillez noter que toute référence à un fragment dans l’URI (’#’ après le chemin) est strictement interdite par la norme HTTP et sera rejetée. Toutefois, si le frontal recevant la requête dispose de l’option « accept-unsafe-violations-in-http-request », cette partie de fragment sera acceptée et apparaîtra également dans « url ».

Dérivés ACL :

url    : exact string match
url_beg: prefix match
url_dir: subdir match
url_dom: domain match
url_end: suffix match
url_len: length match
url_reg: regex match
url_sub: substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

url32 : entier Cette fonction retourne un hachage 32 bits de la valeur obtenue en concaténant le premier en-tête Host et l’URL entière, y compris les paramètres (et non seulement la partie chemin de la requête, comme dans la récupération « base32 » ci-dessus). Cette fonction est utile pour suivre l’activité par URL. Un hachage plus court est stocké, ce qui permet d’économiser beaucoup de mémoire. Le type de sortie est un entier non signé.

url32+src : binaire Cette commande retourne la concaténation des récupérations « url32 » et « src ». Le type résultant est binaire, de taille 8 ou 20 octets selon la famille d’adresse de la source. Cette fonction peut être utilisée pour suivre des compteurs par IP ou par URL.

url_ip: ip Cela extrait l’adresse IP de l’URL de la requête lorsque la partie hôte est présentée sous forme d’adresse IP. Son utilisation est très limitée. Par exemple, un système de surveillance pourrait utiliser ce champ comme alternative à l’adresse IP source afin de tester le chemin suivi par une adresse source donnée, ou pour forcer une entrée dans une table pour une adresse source donnée. Il peut être utilisé en combinaison avec « http-request set-dst » afin d’émuler l’option « option http_proxy » plus ancienne.

url_port : entier Cette option extrait la partie port de l’URL de la requête. Notez que si le port n’est pas spécifié dans la requête, le port 80 est supposé.

urlp([<name>[,<delim>[,i]]]): string

urlp([<name>[,<delim>[,i]]]): string
url_param([<name>[,<delim>[,i]]]): string

Cela extrait la première occurrence du paramètre <name> dans la chaîne de requête, qui commence après soit ‘?’ soit <delim>, et se termine avant ‘&’, ‘;’ ou <delim>. Le nom du paramètre est sensible à la casse, sauf si « i » est ajouté en troisième argument. Si aucun nom n’est fourni, tout paramètre correspondra, et le premier sera retourné. Le résultat est une chaîne correspondant à la valeur du paramètre <name> telle qu’elle apparaît dans la requête (aucune décodage URL n’est effectué). Cela peut être utilisé pour la persistance de session basée sur un identifiant client, pour extraire un cookie d’application transmis en tant que paramètre d’URL, ou dans les ACLs pour appliquer certaines vérifications. Notez que la version ACL de cette fonction itère sur plusieurs paramètres et signalera successivement toutes les valeurs si aucun nom n’est spécifié.

Dérivés ACL :

urlp(<name>[,<delim>])    : exact string match
urlp_beg(<name>[,<delim>]): prefix match
urlp_dir(<name>[,<delim>]): subdir match
urlp_dom(<name>[,<delim>]): domain match
urlp_end(<name>[,<delim>]): suffix match
urlp_len(<name>[,<delim>]): length match
urlp_reg(<name>[,<delim>]): regex match
urlp_sub(<name>[,<delim>]): substring match

Note : Les dérivés ACL ne doivent pas être utilisés suivis d’un convertisseur ou dans des ACL utilisant une méthode de correspondance avec un modèle “-m”.

Exemple :

# match http://example.com/foo?PHPSESSIONID=some_id
stick on urlp(PHPSESSIONID)
# match http://example.com/foo;JSESSIONID=some_id
stick on urlp(JSESSIONID,;)

urlp_val([<name>[,<delim>[,i]]]): integer

urlp_val([<name>[,<delim>[,i]]]): integer

Voir « urlp » ci-dessus. Celui-ci extrait le paramètre d’URL <name> de la requête et le convertit en valeur entière. Cela peut être utilisé pour la persistance de session basée sur un identifiant utilisateur, par exemple, ou avec des listes de contrôle d’accès (ACL) pour correspondre à un numéro de page ou un prix.

7.3.7. Récupération d’exemples pour les développeurs

Cet ensemble de méthodes d’extraction d’échantillon est réservé aux développeurs et ne doit jamais être utilisé dans un environnement de production, sauf sur demande explicite du développeur, à des fins de débogage. En outre, aucune attention particulière ne sera portée à la compatibilité descendante. Aucune garantie n’est donnée quant au fait que les extraits d’échantillons suivants ne changeront pas, ne seront pas renommés ou ne seront pas simplement supprimés. Soyez donc particulièrement prudent si vous devez en utiliser un. Pour éviter toute ambiguïté, ces extraits d’échantillons sont placés dans la portée dédiée « internal », par exemple “internal.strm.is_htx”.

Résumé des méthodes d’extraction d’échantillon de cette section et de leurs types respectifs :

  keyword                                          output type
-------------------------------------------------+-------------
internal.htx.data                                  integer
internal.htx.free                                  integer
internal.htx.free_data                             integer
internal.htx.has_eom                               boolean
internal.htx.nbblks                                integer
internal.htx.size                                  integer
internal.htx.used                                  integer
internal.htx_blk.size(<idx>)                       integer
internal.htx_blk.type(<idx>)                       string
internal.htx_blk.data(<idx>)                       binary
internal.htx_blk.hdrname(<idx>)                    string
internal.htx_blk.hdrval(<idx>)                     string
internal.htx_blk.start_line(<idx>)                 string
internal.strm.is_htx                               boolean
-------------------------------------------------+-------------

Liste détaillée :

internal.htx.data : entier Renvoie la taille en octets utilisée par les données dans le message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.free : entier Renvoie l’espace libre (taille - utilisé) en octets dans le message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.free_data : entier Retourne l’espace libre pour les données en octets dans le message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.has_eom : boolean Renvoie true si le message HTX associé à un canal contient le drapeau de fin de message (EOM). Sinon, renvoie false. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.nbblks : entier Renvoie le nombre de blocs présents dans le message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.size : entier Renvoie la taille totale en octets du message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx.used : entier Retourne la taille totale utilisée en octets (données + métadonnées) dans le message HTX associé à un canal. Le canal est sélectionné en fonction de la direction de l’échantillonnage.

internal.htx_blk.size(<idx>): integer

internal.htx_blk.size(<idx>): integer

Retourne la taille du bloc situé à la position <idx> dans le message HTX associé à un canal ou 0 s’il n’existe pas. Le canal est sélectionné en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes : * head : le bloc le plus ancien inséré * tail : le bloc le plus récent inséré * first : le premier bloc à partir duquel (re)commencer l’analyse

internal.htx_blk.type(<idx>): string

internal.htx_blk.type(<idx>): string

Renvoie le type du bloc à la position <idx> dans le message HTX associé à un canal ou “HTX_BLK_UNUSED” s’il n’existe pas. Le canal est sélectionné en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes : * head : le bloc le plus ancien inséré * tail : le bloc le plus récent inséré * first : le premier bloc à partir duquel (re)commencer l’analyse

internal.htx_blk.data(<idx>): binary

internal.htx_blk.data(<idx>): binary

Renvoie la valeur du bloc DATA à la position <idx> dans le message HTX associé à un canal ou une chaîne vide si celui-ci n’existe pas ou s’il ne s’agit pas d’un bloc DATA. Le canal est sélectionné en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes :

* head : Le bloc inséré le plus ancien
* tail : Le bloc inséré le plus récent
* first : Le premier bloc à partir duquel (re)commencer l'analyse

internal.htx_blk.hdrname(<idx>): string

internal.htx_blk.hdrname(<idx>): string

Renvoie le nom de l’en-tête du bloc EN-TÊTE à la position <idx> dans le message HTX associé à un canal ou une chaîne vide si celui-ci n’existe pas ou s’il ne s’agit pas d’un bloc EN-TÊTE. Le canal est choisi en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes :

* head : Le bloc inséré le plus ancien
* tail : Le bloc inséré le plus récent
* first : Le premier bloc à partir duquel (re)commencer l'analyse

internal.htx_blk.hdrval(<idx>): string

internal.htx_blk.hdrval(<idx>): string

Renvoie la valeur de l’en-tête du bloc EN-TÊTE à la position <idx> dans le message HTX associé à un canal ou une chaîne vide si celui-ci n’existe pas ou s’il ne s’agit pas d’un bloc EN-TÊTE. Le canal est sélectionné en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes :

* head : Le bloc inséré le plus ancien
* tail : Le bloc inséré le plus récent
* first : Le premier bloc à partir duquel (re)commencer l'analyse

internal.htx_blk.start_line(<idx>): string

internal.htx_blk.start_line(<idx>): string

Renvoie la valeur du bloc REQ_SL ou RES_SL à la position <idx> dans le message HTX associé à un canal, ou une chaîne vide si celui-ci n’existe pas ou s’il ne s’agit pas d’un bloc SL. Le canal est sélectionné en fonction de la direction de l’échantillonnage. <idx> peut être un entier positif quelconque ou l’une des valeurs spéciales suivantes :

* head : Le bloc inséré le plus ancien
* tail : Le bloc inséré le plus récent
* first : Le premier bloc à partir duquel (re)commencer l'analyse

internal.strm.is_htx : boolean Renvoie true si le flux courant est un flux HTX. Cela signifie que les données dans les tampons de canal sont stockées selon la représentation interne HTX. Sinon, renvoie false.

7.4. ACL prédéfinies

Certains ACL prédéfinies sont intégrées en dur afin de ne pas devoir les déclarer dans chaque frontal qui en a besoin. Leur nom est toujours en majuscules pour éviter toute confusion. Leur équivalence est indiquée ci-dessous.

ACL name          Equivalent to                Usage
---------------+----------------------------------+------------------------------------------------------
FALSE            always_false                       never match
HTTP             req.proto_http                     match if request protocol is valid HTTP
HTTP_1.0         req.ver 1.0                        match if HTTP request version is 1.0
HTTP_1.1         req.ver 1.1                        match if HTTP request version is 1.1
HTTP_2.0         req.ver 2.0                        match if HTTP request version is 2.0
HTTP_3.0         req.ver 3.0                        match if HTTP request version is 3.0
HTTP_CONTENT     req.hdr_val(content-length) gt 0   match an existing content-length in the HTTP request
HTTP_URL_ABS     url_reg ^[^/:]*://                 match absolute URL with scheme
HTTP_URL_SLASH   url_beg /                          match URL beginning with "/"
HTTP_URL_STAR    url     *                          match URL equal to "*"
LOCALHOST        src 127.0.0.1/8::1                match connection from local host
METH_CONNECT     method  CONNECT                    match HTTP CONNECT method
METH_DELETE      method  DELETE                     match HTTP DELETE method
METH_GET         method  GET HEAD                   match HTTP GET or HEAD method
METH_HEAD        method  HEAD                       match HTTP HEAD method
METH_OPTIONS     method  OPTIONS                    match HTTP OPTIONS method
METH_POST        method  POST                       match HTTP POST method
METH_PUT         method  PUT                        match HTTP PUT method
METH_TRACE       method  TRACE                      match HTTP TRACE method
RDP_COOKIE       req.rdp_cookie_cnt gt 0            match presence of an RDP cookie in the request buffer
REQ_CONTENT      req.len gt 0                       match data in the request buffer
TRUE             always_true                        always match
WAIT_END         wait_end                           wait for end of content analysis
---------------+----------------------------------+------------------------------------------------------

17 - 8. Journalisation

Niveaux de journalisation, formats, profils, délais, captures, états et exemples

L’un des points forts d’HAProxy réside certainement dans ses journaux précis. Il fournit probablement le niveau d’information le plus poussé disponible pour un tel produit, ce qui est essentiel pour le dépannage des environnements complexes. Les informations standard fournies dans les journaux incluent les ports clients, les compteurs d’état TCP/HTTP, l’état précis du flux à la terminaison et la cause précise de la terminaison, des informations sur les décisions visant à acheminer le trafic vers un serveur, ainsi que, bien entendu, la capacité à capturer des en-têtes arbitraires.

Afin d’améliorer la réactivité des administrateurs, il offre une grande transparence concernant les problèmes rencontrés, qu’ils soient internes ou externes, et il est possible d’envoyer les journaux vers différentes sources simultanément, avec des filtres de niveau différents :

  • journaux au niveau du processus global (erreurs système, démarrage/arrêt, etc.)
  • erreurs système et internes par instance (manque de ressources, bugs, …)
  • problèmes externes par instance (serveurs actifs/inactifs, nombre maximal de connexions)
  • activité par instance (connexions clients), soit à l’établissement, soit à la fermeture.
  • contrôle du niveau de journalisation par requête, par exemple http-request set-log-level silent si sensitive_request

La possibilité de distribuer différents niveaux de journaux vers des serveurs de journaux distincts permet à plusieurs équipes de production d’interagir et de résoudre leurs problèmes aussi rapidement que possible. Par exemple, l’équipe système peut surveiller les erreurs à l’échelle du système, tandis que l’équipe application peut surveiller en temps réel l’état actif/inactif de leurs serveurs, et l’équipe sécurité peut analyser les journaux d’activité avec un délai d’une heure.

8.1. Niveaux de journalisation

Les connexions TCP et HTTP peuvent être journalisées avec des informations telles que la date, l’heure, l’adresse IP source, l’adresse de destination, la durée de la connexion, les temps de réponse, la requête HTTP, le code de retour HTTP, le nombre d’octets transmis, les conditions d’arrêt du flux, ainsi que les valeurs des cookies échangés. Par exemple, suivre les problèmes d’un utilisateur particulier. Tous les messages peuvent être envoyés à jusqu’à deux serveurs syslog. Consultez le mot-clé « log » dans la section 4.2 pour plus d’informations sur les installations de journalisation.

8.2. Formats de journalisation

HAProxy prend en charge 5 formats de journalisation. Plusieurs champs sont communs à ces formats et seront détaillés dans les sections suivantes. Certains de ces champs peuvent varier légèrement selon la configuration, en raison d’indicateurs propres à certaines options. Les formats pris en charge sont les suivants :

  • le format par défaut, très basique et très rarement utilisé. Il ne fournit que des informations très élémentaires sur la connexion entrante au moment où elle est acceptée : adresse IP source:port, adresse IP destination:port et nom du frontal. Ce mode sera progressivement supprimé, aussi ne sera-t-il pas décrit en détail.

  • le format TCP, qui est plus avancé. Ce format est activé lorsque « option tcplog » est configuré sur le frontal. HAProxy attend alors généralement la fermeture de la connexion avant d’effectuer la journalisation. Ce format fournit des informations bien plus riches, telles que les compteurs de temps, le nombre de connexions, la taille de la file d’attente, etc. Ce format est recommandé pour les proxies TCP purs.

  • le format HTTP, le plus avancé pour le proxy HTTP. Ce format est activé lorsque « option httplog » est définie sur le frontal. Il fournit les mêmes informations que le format TCP, complétées par des champs spécifiques à HTTP tels que la requête, le code d’état, ainsi que les captures d’en-têtes et de cookies. Ce format est recommandé pour les proxies HTTP.

  • le format CLF HTTP, qui est équivalent au format HTTP, mais avec les champs disposés dans le même ordre que le format CLF. En ce mode, tous les compteurs, captures, indicateurs, etc. apparaissent un par champ après la fin des champs communs, dans le même ordre qu’ils apparaissent dans le format HTTP standard.

  • le format de journal personnalisé, vous permet de définir votre propre ligne de journal.

Les sections suivantes approfondiront les détails relatifs à chacun de ces formats. La spécification du format sera effectuée au niveau de chaque « champ ». À moins d’indication contraire, un champ correspond à une portion de texte délimitée par un nombre quelconque d’espaces. Étant donné que les serveurs syslog peuvent insérer des champs au début d’une ligne, il est toujours supposé que le premier champ contient le nom du processus et son identifiant.

Note : Étant donné que les lignes de journalisation peuvent être assez longues, les exemples de journaux présentés dans les sections suivantes peuvent être divisés en plusieurs lignes. Les lignes d’exemple de journalisation seront précédées de trois chevrons fermants (’>>>’) et, chaque fois qu’une ligne de journalisation est divisée en plusieurs lignes, chaque ligne non finale se terminera par une barre oblique inverse (’\’) et la ligne suivante commencera indentée de deux caractères.

8.2.1. Format de journal par défaut

Ce format est utilisé lorsque aucune option spécifique n’est définie. Le journal est émis dès l’acceptation de la connexion. Il convient de noter qu’il s’agit actuellement du seul format qui enregistre l’adresse IP et les ports de destination de la requête.

Exemple :

    listen www
        mode http
        log global
        server srv1 127.0.0.1:8000

>>> Feb  6 12:12:09 localhost \
      haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \
      (www/HTTP)

Champ Format Extraits de l’exemple ci-dessus 1 process_name ‘[’ pid ‘]:’ HAProxy[14385]: 2 ‘Connect from’ Connect from 3 source_ip ‘:’ source_port 10.0.1.2:33312 4 ’to’ to 5 destination_ip ‘:’ destination_port 10.0.3.31:8012 6 ‘(’ frontend_name ‘/’ mode ‘)’ (www/HTTP)

Description détaillée des champs :

  • “source_ip” est l’adresse IP du client ayant initié la connexion.
  • “source_port” est le port TCP du client ayant initié la connexion.
  • “destination_ip” est l’adresse IP vers laquelle le client s’est connecté.
  • “destination_port” est le port TCP vers lequel le client s’est connecté.
  • “frontend_name” est le nom du frontal (ou écouteur) qui a reçu et traité la connexion.
  • “mode est le mode d’opération du frontal (TCP ou HTTP).

En cas de socket UNIX, les adresses source et destination sont marquées par « unix: » et les ports correspondent à l’identifiant interne du socket ayant accepté la connexion (identifiant identique à celui rapporté dans les statistiques).

Il est recommandé de ne pas utiliser ce format obsolète pour les nouvelles installations, car il disparaîtra tôt ou tard.

8.2.2. Format de journalisation TCP

Le format TCP est utilisé lorsque l’option « option tcplog » est spécifiée dans le frontal, et constitue le format recommandé pour les proxies TCP purs. Il fournit une quantité d’informations précieuses pour le dépannage. Étant donné que ce format inclut des compteurs de temps et de bytes, le journal est normalement émis à la fin de la session. Il peut être émis plus tôt si l’option « option logasap » est spécifiée, ce qui est pertinent dans la plupart des environnements présentant des sessions longues, comme les terminaux distants. Les sessions correspondant aux règles « monitor » ne sont jamais journalisées. Il est également possible de ne pas émettre de journal pour les sessions durant lesquelles aucune donnée n’a été échangée entre le client et le serveur, en spécifiant « option dontlognull » dans le frontal. Les connexions réussies ne seront pas journalisées si l’option « option dontlog-normal » est spécifiée dans le frontal.

Le format de journalisation TCP est déclaré internement comme un format de journalisation personnalisé basé sur la chaîne exacte suivante, qui peut également servir de base à l’extension du format si nécessaire. En outre, la variable HAPROXY_TCP_LOG_FMT peut être utilisée à la place. Reportez-vous à la section 8.2.6 « Format de journalisation personnalisé » pour savoir comment l’utiliser :

# strict equivalent of "option tcplog"
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts \
            %ac/%fc/%bc/%sc/%rc %sq/%bq"
# or using the HAPROXY_TCP_LOG_FMT variable
log-format "${HAPROXY_TCP_LOG_FMT}"

Et le format de journal CLF est déclaré internement comme un format de journal personnalisé basé sur cette chaîne exacte :

# strict equivalent of "option tcplog clf"
log-format "%{Q}o %{-Q}ci - - [%T] \"TCP \" 000 %B \"\" \"\" %cp \
            %ms %ft %b %s %Th %Tw %Tc %Tt %U %ts-- %ac %fc %bc \
            %sc %rc %sq %bq \"\" \"\" "

Quelques champs peuvent légèrement varier en fonction de certaines options de configuration ; ceux-ci sont marqués d’une étoile (’*’) après leur nom ci-dessous.

Exemple :

    frontend fnt
        mode tcp
        option tcplog
        log global
        default_backend bck

    backend bck
        server srv1 127.0.0.1:8000

>>> Feb  6 12:12:56 localhost \
      haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \
      bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0
ChampFormatExtraction à partir de l’exemple ci-dessus
1process_name ‘[’ pid ‘]:’HAProxy[14387]:
2client_ip ‘:’ client_port10.0.1.2:33313
3‘[’ accept_date ‘]’[06/Feb/2009:12:12:51.443]
4frontend_namefnt
5backend_name ‘/’ server_namebck/srv1
6Tw ‘/’ Tc ‘/’ Tt*0/0/5007
7bytes_read*212
8termination_state–
9actconn ‘/’ feconn ‘/’ beconn ‘/’ srv_conn ‘/’ retries*0/0/0/0/3
10srv_queue ‘/’ backend_queue0/0

Description détaillée des champs :

  • “client_ip” est l’adresse IP du client ayant initié la connexion TCP vers HAProxy. Si la connexion a été acceptée sur une socket UNIX, l’adresse IP est remplacée par le mot « unix ». Notez que lorsque la connexion est acceptée sur une socket configurée avec « accept-proxy » et que le protocole PROXY est correctement utilisé, ou avec « accept-netscaler-cip » et que le protocole d’insertion de l’IP client NetScaler est correctement utilisé, les journaux reflètent alors les informations de la connexion transférée.

  • “client_port” est le port TCP du client ayant initié la connexion. Si la connexion a été acceptée via une socket UNIX, le port est remplacé par l’identifiant de la socket d’acceptation, qui est également rapporté dans l’interface de statistiques.

  • “accept_date” est la date exacte à laquelle la connexion a été reçue par HAProxy (qui peut différer légèrement de la date observée sur le réseau en cas de mise en file d’attente dans la file de connexion du système). Cette date correspond généralement à celle qui peut apparaître dans les journaux de tout pare-feu en amont. En mode HTTP, le champ accept_date est réinitialisé au moment où la connexion est prête à recevoir une nouvelle requête (fin de la réponse précédente pour HTTP/1, immédiatement après la requête précédente pour HTTP/2).

  • “frontend_name” est le nom du frontal (ou de l’écouteur) qui a reçu et traité la connexion.

  • “backend_name” est le nom du backend (ou de l’écouteur) qui a été sélectionné pour gérer la connexion au serveur. Ce nom est identique à celui du frontal si aucune règle de commutation n’a été appliquée, ce qui est courant pour les applications TCP.

  • “server_name” est le nom du dernier serveur vers lequel la connexion a été envoyée, qui peut différer du premier si des erreurs de connexion ont eu lieu et qu’une redistribution a été effectuée. Notez que ce serveur appartient au backend qui a traité la requête. Si la connexion a été interrompue avant d’atteindre un serveur, “<NOSRV>” est indiqué à la place du nom du serveur.

  • “Tw” correspond au temps total, en millisecondes, passé en attente dans les différentes files d’attente. Il peut prendre la valeur “-1” si la connexion a été interrompue avant d’atteindre la file d’attente. Voir « Horloges » ci-dessous pour plus de détails.

  • « Tc » est le temps total, en millisecondes, passé en attente de l’établissement de la connexion avec le serveur final, y compris les tentatives de reconnexion. Il peut être “-1” si la connexion a été interrompue avant qu’une connexion ne puisse être établie. Voir « Horloges » ci-dessous pour plus de détails.

  • « Tt » est le temps total, en millisecondes, écoulé entre l’acceptation et la fermeture finale. Il couvre toutes les étapes de traitement possibles. Une exception existe : si l’option « option logasap » est spécifiée, le comptage du temps s’arrête au moment de l’émission du journal. Dans ce cas, un signe « + » est ajouté avant la valeur, indiquant que la valeur finale sera plus élevée. Voir « Chronomètres » ci-dessous pour plus de détails.

  • “bytes_read” est le nombre total d’octets transmis du serveur vers le client au moment de l’émission du journal. Si l’option logasap est spécifiée, cette valeur sera précédée du signe ‘+’ pour indiquer que la valeur finale peut être plus élevée. Veuillez noter que cette valeur est un compteur 64 bits, les outils d’analyse des journaux doivent donc être capables de la gérer sans débordement.

  • “termination_state” est l’état dans lequel la session se trouvait lors de sa fermeture. Cela indique l’état de la session, le côté ayant provoqué la fermeture, ainsi que la raison (délai d’expiration, erreur, …). Les indicateurs normaux doivent être “–”, ce qui signifie que la session a été fermée par l’une ou l’autre extrémité sans données restantes dans les tampons. Voir ci-dessous « État du flux à la déconnexion » pour plus de détails.

  • “actconn” correspond au nombre total de connexions simultanées sur le processus au moment où la session a été journalisée. Cette information est utile pour détecter lorsque certains plafonds système par processus ont été atteints. Par exemple, si “actconn” est proche de 512 lorsqu’apparaissent plusieurs erreurs de connexion, il est fort probable que le système limite le processus à un maximum de 1024 descripteurs de fichiers, et que tous soient utilisés. Voir section 3 “Section globale” pour savoir comment ajuster le système.

  • « feconn » est le nombre total de connexions simultanées sur le frontal au moment où la session a été journalisée. Cette information est utile pour estimer les ressources nécessaires afin de supporter des charges élevées, et pour détecter lorsque la limite « maxconn » du frontal a été atteinte. En général, une augmentation brutale de cette valeur indique une congestion sur les serveurs backend, mais elle peut aussi être due à une attaque par déni de service.

  • « beconn » correspond au nombre total de connexions simultanées gérées par le backend au moment où la session a été journalisée. Il inclut le nombre total de connexions simultanées actives sur les serveurs ainsi que le nombre de connexions en attente dans les files d’attente. Cette information est utile pour estimer le nombre de serveurs supplémentaires nécessaires afin de supporter des charges élevées pour une application donnée. En général, lorsque cette valeur augmente brusquement, cela indique une congestion sur les serveurs backend, mais cela peut aussi être dû à une attaque par déni de service.

  • “srv_conn” est le nombre total de connexions simultanées encore actives sur le serveur au moment où la session a été journalisée. Il ne peut jamais dépasser le paramètre configuré « maxconn » du serveur. Si cette valeur est très souvent proche ou égale à « maxconn » du serveur, cela signifie que la régulation du trafic est très fréquente, ce qui indique soit que la valeur « maxconn » du serveur est trop faible, soit qu’il n’y a pas assez de serveurs pour traiter la charge avec un temps de réponse optimal. Lorsqu’un seul des serveurs “srv_conn” est élevé, cela signifie généralement que ce serveur rencontre des difficultés entraînant un traitement des connexions plus lent que sur les autres serveurs.

  • “retries” correspond au nombre de tentatives de connexion effectuées par cette session lors de la tentative de connexion au serveur. Il doit normalement être égal à zéro, sauf si le serveur est arrêté au moment précis où la connexion est tentée. Un nombre élevé de tentatives indique généralement un problème réseau entre HAProxy et le serveur, ou une file d’attente de connexion mal configurée sur le serveur empêchant les nouvelles connexions d’être mises en file. Ce champ peut éventuellement être précédé du signe ‘+’ pour indiquer que la session a été réacheminée après avoir atteint le nombre maximal de tentatives sur le serveur initial. Dans ce cas, le nom du serveur apparaissant dans le journal est celui vers lequel la connexion a été réacheminée, et non celui du premier serveur, bien que les deux puissent parfois être identiques, par exemple en cas de hachage. En règle générale, lorsqu’un ‘+’ est présent devant le nombre de tentatives, ce nombre ne doit pas être attribué au serveur indiqué dans le journal.

  • “srv_queue” est le nombre total de requêtes traitées avant celle-ci dans la file du serveur. Il vaut zéro lorsque la requête n’a pas traversé la file du serveur. Il permet d’estimer le temps de réponse approximatif du serveur en divisant le temps passé en file par le nombre de requêtes dans la file. Il convient de noter qu’en cas de réacheminement, si une session traverse deux files du serveur, leurs positions s’additionnent. Une requête ne doit pas traverser à la fois la file du serveur et la file du backend, sauf en cas de réacheminement.

  • “backend_queue” est le nombre total de requêtes traitées avant celle-ci dans la file d’attente globale du backend. Il vaut zéro lorsque la requête n’a pas traversé la file d’attente globale. Ce chiffre permet d’estimer la longueur moyenne de la file, qui se traduit aisément en nombre de serveurs manquants lorsqu’elle est divisée par le paramètre “maxconn” d’un serveur. Il convient de noter qu’en cas de redirigabilité d’une session, une requête peut passer deux fois par la file du backend, et les deux positions seront alors cumulées. Une requête ne doit pas traverser à la fois la file du serveur et la file du backend, sauf en cas de redirigabilité.

8.2.3. Format de journalisation HTTP

Le format HTTP est le plus complet et le mieux adapté aux proxies HTTP. Il est activé lorsque « option httplog » est spécifié dans le frontal. Il fournit le même niveau d’information que le format TCP, avec des fonctionnalités supplémentaires propres au protocole HTTP. Tout comme le format TCP, la journalisation a généralement lieu à la fin du flux, sauf si « option logasap » est spécifiée, ce qui n’a généralement de sens que pour les sites de téléchargement. Les flux correspondant aux règles « monitor » ne sont jamais journalisés. Il est également possible de ne pas journaliser les flux pour lesquels le client n’a envoyé aucune donnée en spécifiant « option dontlognull » dans le frontal. Les connexions réussies ne sont pas journalisées si « option dontlog-normal » est spécifié dans le frontal.

Le format de journalisation HTTP est déclaré internement comme un format de journalisation personnalisé basé sur la chaîne exacte suivante, qui peut également servir de base pour étendre le format si nécessaire. En outre, la variable HAPROXY_HTTP_LOG_FMT peut être utilisée à la place. Reportez-vous à la section 8.2.6 « Format de journalisation personnalisé » pour savoir comment l’utiliser :

# strict equivalent of "option httplog"
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC \
            %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
# or using the HAPROXY_HTTP_LOG_FMT variable
log-format "${HAPROXY_HTTP_LOG_FMT}"

Et le format de journal CLF est déclaré internement comme un format de journal personnalisé basé sur cette chaîne exacte :

# strict equivalent of "option httplog clf"
log-format "%{+Q}o %{-Q}ci - - [%trg] %r %ST %B \"\" \"\" %cp \
            %ms %ft %b %s %TR %Tw %Tc %Tr %Ta %tsc %ac %fc \
            %bc %sc %rc %sq %bq %CC %CS %hrl %hsl"

La plupart des champs sont communs au journal TCP, certains étant différents. Quelques champs peuvent légèrement varier selon certaines options de configuration. Ceux-ci sont marqués d’une étoile (’*’) après leur nom ci-dessous.

Exemple :

    frontend http-in
        mode http
        option httplog
        log global
        default_backend bck

    backend static
        server srv1 127.0.0.1:8000

>>> Feb  6 12:14:14 localhost \
      haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
      static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \
      {} "GET /index.html HTTP/1.1"

Champ Format Extraire de l’exemple ci-dessus 1 process_name ‘[’ pid ‘]:’ HAProxy[14389]: 2 client_ip ‘:’ client_port 10.0.1.2:33317 3 ‘[’ request_date ‘]’ [06/Feb/2009:12:14:14.655] 4 frontend_name http-in 5 backend_name ‘/’ server_name static/srv1 6 TR ‘/’ Tw ‘/’ Tc ‘/’ Tr ‘/’ Ta* 10/0/30/69/109 7 status_code 200 8 bytes_read* 2750 9 captured_request_cookie - 10 captured_response_cookie - 11 termination_state —- 12 actconn ‘/’ feconn ‘/’ beconn ‘/’ srv_conn ‘/’ retries* 1/1/1/1/0 13 srv_queue ‘/’ backend_queue 0/0 14 ‘{’ captured_request_headers* ‘}’ {HAProxy.1wt.eu} 15 ‘{’ captured_response_headers* ‘}’ {} 16 ‘”’ http_request ‘"’ “GET /index.html HTTP/1.1”

Description détaillée des champs :

  • “client_ip” est l’adresse IP du client ayant initié la connexion TCP vers HAProxy. Si la connexion a été acceptée sur une socket UNIX, l’adresse IP est remplacée par le mot « unix ». Notez que lorsque la connexion est acceptée sur une socket configurée avec « accept-proxy » et que le protocole PROXY est correctement utilisé, ou avec « accept-netscaler-cip » et que le protocole d’insertion de l’IP client NetScaler est correctement utilisé, les journaux reflètent alors les informations de la connexion transférée.

  • “client_port” est le port TCP du client ayant initié la connexion. Si la connexion a été acceptée via une socket UNIX, le port est remplacé par l’identifiant de la socket d’acceptation, qui est également rapporté dans l’interface de statistiques.

  • “request_date” est la date exacte à laquelle le premier octet de la requête HTTP a été reçu par HAProxy (champ de journalisation %tr).

  • “frontend_name” est le nom du frontal (ou de l’écouteur) qui a reçu et traité la connexion.

  • “backend_name” est le nom du backend (ou de l’écouteur) qui a été sélectionné pour gérer la connexion au serveur. Ce nom est identique à celui du frontal si aucune règle de commutation n’a été appliquée.

  • “server_name” est le nom du dernier serveur vers lequel la connexion a été envoyée, qui peut différer du premier si des erreurs de connexion ont entraîné une redistribution. Notez que ce serveur appartient au backend ayant traité la requête. Si la requête a été interrompue avant d’atteindre un serveur, “<NOSRV>” est indiqué à la place du nom du serveur. Si la requête a été interceptée par le sous-système de statistiques, “<STATS>” est indiqué à la place.

  • “TR” correspond au temps total, en millisecondes, passé à attendre la réception complète d’une requête HTTP depuis le client (sans compter le corps) après la réception du premier octet. Il peut prendre la valeur “-1” si la connexion a été interrompue avant la réception d’une requête complète ou si une requête invalide a été reçue. Ce temps doit toujours être très faible, car une requête s’inscrit généralement dans un seul paquet. Des valeurs élevées indiquent généralement des problèmes réseau entre le client et HAProxy ou des requêtes saisies manuellement. Voir section 8.4 « Événements de temporisation » pour plus de détails.

  • « Tw » est le temps total, en millisecondes, passé en attente dans les différentes files d’attente. Il peut être “-1” si la connexion a été interrompue avant d’atteindre la file d’attente. Voir section 8.4 « Événements de temporisation » pour plus de détails.

  • « Tc » est le temps total, en millisecondes, passé en attente de l’établissement de la connexion avec le serveur final, y compris les tentatives de reconnexion. Il peut être “-1” si la requête a été interrompue avant qu’une connexion ne puisse être établie. Voir section 8.4 « Événements de temporisation » pour plus de détails.

  • « Tr » est le temps total, en millisecondes, passé à attendre que le serveur envoie une réponse HTTP complète, sans compter les données. Il peut valoir “-1” si la requête a été interrompue avant qu’une réponse complète ne puisse être reçue. Il correspond généralement au temps de traitement du serveur pour la requête, bien qu’il puisse être modifié par la quantité de données envoyées par le client au serveur. Des temps élevés pour les requêtes « GET » indiquent généralement un serveur surchargé. Voir section 8.4 « Événements de temporisation » pour plus de détails.

  • « Ta » est le temps pendant lequel la requête est restée active dans HAProxy, soit le temps total en millisecondes écoulé entre la réception du premier octet de la requête et l’envoi du dernier octet de la réponse. Il englobe toutes les phases de traitement possibles, à l’exception de l’échange d’handshake (voir Th) et du temps d’inactivité (voir Ti). Une exception existe : si l’option « option logasap » est spécifiée, alors le comptage du temps s’arrête au moment de l’émission du journal. Dans ce cas, un signe « + » est ajouté en préfixe de la valeur, indiquant que la valeur finale sera plus élevée. Voir section 8.4 « Événements de temporisation » pour plus de détails.

  • “status_code” est le code d’état HTTP renvoyé au client. Ce code est généralement défini par le serveur, mais peut également être défini par HAProxy lorsque le serveur n’est pas accessible ou lorsque sa réponse est bloquée par HAProxy.

  • “bytes_read” est le nombre total d’octets transmis au client au moment de l’émission du journal. Cette valeur inclut les en-têtes HTTP. Si l’option « option logasap » est spécifiée, cette valeur est précédée d’un signe « + », indiquant que la valeur finale peut être plus élevée. Veuillez noter que cette valeur est un compteur 64 bits, les outils d’analyse des journaux doivent donc être capables de la gérer sans débordement.

  • “captured_request_cookie” est une entrée facultative au format « nom=valeur » indiquant que le client avait ce cookie dans la requête. Le nom du cookie et sa longueur maximale sont définis par l’instruction « capture cookie » dans la configuration du frontal. Ce champ est une simple tiret (’-’) lorsque l’option n’est pas définie. Un seul cookie peut être capturé, ce qui est généralement utilisé pour suivre les échanges d’ID de session entre un client et un serveur afin de détecter les chevauchements de session entre clients dus à des bugs applicatifs. Pour plus de détails, veuillez consulter la section « Capturer des en-têtes et des cookies HTTP » ci-dessous.

  • “captured_response_cookie” est une entrée facultative au format « nom=valeur », indiquant que le serveur a renvoyé un cookie dans sa réponse. Le nom du cookie et sa longueur maximale sont définis par l’instruction « capture cookie » dans la configuration du frontal. Ce champ est un trait d’union unique (’-’) lorsque l’option n’est pas activée. Un seul cookie peut être capturé, ce qui est généralement utilisé pour suivre les échanges d’identifiants de session entre un client et un serveur afin de détecter les chevauchements de session entre clients dus à des bugs applicatifs. Pour plus de détails, veuillez consulter la section « Capturer les en-têtes HTTP et les cookies » ci-dessous.

  • “termination_state” est l’état du flux lorsqu’il s’est terminé. Cela indique l’état du flux, le côté ayant provoqué la fin du flux, la raison (délai d’expiration, erreur, …), de la même manière que dans les journaux TCP, ainsi que des informations sur les opérations de persistance des cookies dans les deux derniers caractères. Les indicateurs normaux doivent commencer par “–”, ce qui signifie que le flux a été fermé par l’une ou l’autre extrémité sans données restantes dans les tampons. Voir ci-dessous « État du flux à la déconnexion » pour plus de détails.

  • “actconn” correspond au nombre total de connexions simultanées sur le processus au moment où le flux a été journalisé. Il est utile pour détecter lorsque certains plafonds système par processus ont été atteints. Par exemple, si actconn est proche de 512 ou 1024 lorsqu’une erreur de connexion multiple survient, il est très probable que le système limite le processus à un maximum de 1024 descripteurs de fichiers, et que tous soient utilisés. Voir section 3 “Section globale” pour savoir comment ajuster le système.

  • « feconn » est le nombre total de connexions simultanées sur le frontal au moment où le flux a été journalisé. Il est utile pour estimer la quantité de ressources nécessaires pour supporter des charges élevées, et pour détecter lorsque la limite « maxconn » du frontal a été atteinte. En général, lorsque cette valeur augmente brusquement, cela indique une congestion sur les serveurs backend, mais cela peut aussi être dû à une attaque par déni de service.

  • « beconn » est le nombre total de connexions simultanées gérées par le backend au moment où le flux a été journalisé. Il inclut le nombre total de connexions simultanées actives sur les serveurs ainsi que le nombre de connexions en attente dans les files d’attente. Cette information est utile pour estimer le nombre de serveurs supplémentaires nécessaires afin de supporter des charges élevées pour une application donnée. En général, lorsque cette valeur augmente brusquement, cela indique une congestion sur les serveurs backend, mais cela peut aussi être dû à une attaque par déni de service.

  • “srv_conn” est le nombre total de connexions simultanées encore actives sur le serveur au moment où le flux a été journalisé. Cette valeur ne peut jamais dépasser le paramètre configuré « maxconn » du serveur. Si cette valeur est très souvent proche ou égale à « maxconn » du serveur, cela signifie que la régulation du trafic est très fréquente, ce qui indique soit que la valeur maxconn du serveur est trop faible, soit qu’il n’y a pas assez de serveurs pour traiter la charge avec un temps de réponse optimal. Lorsqu’un seul des serveurs “srv_conn” est élevé, cela signifie généralement que ce serveur rencontre des difficultés entraînant un traitement plus lent des requêtes par rapport aux autres serveurs.

  • “retries” correspond au nombre de tentatives de connexion effectuées par ce flux lors de la tentative de connexion au serveur. Il doit normalement être égal à zéro, sauf si un serveur est arrêté au moment précis où la connexion est tentée. Des tentatives fréquentes indiquent généralement un problème réseau entre HAProxy et le serveur, ou une configuration incorrecte de la file d’attente de connexion sur le serveur empêchant les nouvelles connexions d’être enregistrées. Ce champ peut éventuellement être précédé du signe ‘+’ pour indiquer qu’une rediffusion a eu lieu après avoir atteint le nombre maximal de tentatives sur le serveur initial. Dans ce cas, le nom du serveur apparaissant dans le journal est celui vers lequel la connexion a été rediffusée, et non celui initial, bien que les deux puissent parfois être identiques, par exemple en cas de hachage. En règle générale, lorsqu’un ‘+’ est présent devant le nombre de tentatives, ce dernier ne doit pas être attribué au serveur indiqué dans le journal.

  • “srv_queue” est le nombre total de requêtes traitées avant celle-ci dans la file d’attente du serveur. Il vaut zéro lorsque la requête n’a pas traversé la file d’attente du serveur. Il permet d’estimer approximativement le temps de réponse du serveur en divisant le temps passé en file par le nombre de requêtes dans la file. Il convient de noter qu’en cas de réacheminement, si un flux traverse deux files d’attente du serveur, leurs positions s’additionnent. Une requête ne doit pas traverser à la fois la file d’attente du serveur et la file d’attente du backend, sauf en cas de réacheminement.

  • “backend_queue” est le nombre total de requêtes traitées avant celle-ci dans la file d’attente globale du backend. Il vaut zéro lorsque la requête n’a pas traversé la file d’attente globale. Ce chiffre permet d’estimer la longueur moyenne de la file, qui se traduit aisément en nombre de serveurs manquants lorsqu’elle est divisée par le paramètre “maxconn” d’un serveur. Il convient de noter qu’une requête pouvant subir une redirigabilité, elle peut passer deux fois par la file du backend, et les deux positions seront alors cumulées. Une requête ne doit pas passer à la fois par la file du serveur et par la file du backend, sauf en cas de redirigabilité.

  • “captured_request_headers” est une liste d’en-têtes capturés dans la requête en raison de la présence de l’instruction « capture en-tête requête » dans le frontal. Plusieurs en-têtes peuvent être capturés, ils seront séparés par un trait vertical (’|’). Lorsqu’aucune capture n’est activée, les accolades ne s’affichent pas, ce qui provoque un décalage des champs restants. Il est important de noter que ce champ peut contenir des espaces, et son utilisation nécessite un analyseur de journaux plus performant qu’en l’absence de capture. Veuillez consulter la section « Capturer des en-têtes HTTP et des cookies » ci-dessous pour plus de détails.

  • “captured_response_headers” est une liste d’en-têtes capturés dans la réponse en raison de la présence de l’instruction « capturer l’en-tête de réponse » dans le frontal. Plusieurs en-têtes peuvent être capturés ; ils seront séparés par un trait vertical (’|’). Lorsqu’aucune capture n’est activée, les accolades ne s’affichent pas, ce qui provoque un décalage des champs restants. Il est important de noter que ce champ peut contenir des espaces, et son utilisation nécessite un analyseur de journaux plus performant que lorsqu’il n’est pas utilisé. Veuillez consulter la section « Capturer les en-têtes HTTP et les cookies » ci-dessous pour plus de détails.

  • “http_request” est la ligne de requête HTTP complète, comprenant la méthode, la requête et la version HTTP. Les caractères non imprimables sont encodés (voir ci-dessous la section « Caractères non imprimables »). Ce champ est toujours le dernier, toujours délimité par des guillemets, et le seul à pouvoir contenir des guillemets. Si de nouveaux champs sont ajoutés au format de journalisation, ils seront insérés avant ce champ. Ce champ peut être tronqué si la requête est trop volumineuse pour tenir dans le tampon standard syslog (1024 caractères). C’est la raison pour laquelle ce champ doit toujours rester le dernier.

8.2.4. Format de journalisation HTTPS

Le format HTTPS est le plus adapté aux connexions HTTP sur SSL. Il s’agit d’une extension du format HTTP (voir section 8.2.3 ) à laquelle sont ajoutées des informations relatives à SSL. Il est activé lorsque l’option « option httpslog » est spécifiée dans le frontal. Tout comme les formats TCP et HTTP, la journalisation a lieu généralement à la fin du flux, sauf si l’option « option logasap » est indiquée. Un flux correspondant aux règles « monitor » ne sera jamais journalisé. Il est également possible de ne pas journaliser les flux pour lesquels le client n’a envoyé aucune donnée en spécifiant « option dontlognull » dans le frontal. Les connexions réussies ne seront pas journalisées si l’option « option dontlog-normal » est spécifiée dans le frontal.

Le format de journalisation HTTPS est déclaré internement comme un format de journalisation personnalisé basé sur la chaîne exacte suivante, qui peut également servir de base pour étendre le format si nécessaire. En outre, la variable HAPROXY_HTTPS_LOG_FMT peut être utilisée à la place. Reportez-vous à la section 8.2.6 « Format de journalisation personnalisé » pour savoir comment l’utiliser :

# strict equivalent of "option httpslog"
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC \
           %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r \
           %[fc_err]/%[ssl_fc_err,hex]/%[ssl_c_err]/\
           %[ssl_c_ca_err]/%[ssl_fc_is_resumed] %[ssl_fc_sni]/%sslv/%sslc"
# or using the HAPROXY_HTTPS_LOG_FMT variable
log-format "${HAPROXY_HTTPS_LOG_FMT}"

Ce format est fondamentalement celui de HTTP (voir section 8.2.3 ) avec des champs supplémentaires ajoutés. Les nouveaux champs (lignes 17 et 18) seront détaillés ici. Pour les champs HTTP, se référer à la section HTTP.

Exemple :

    frontend https-in
        mode http
        option httpslog
        log global
        bind *:443 ssl crt mycerts/srv.pem ...
        default_backend bck

    backend static
        server srv1 127.0.0.1:8000 ssl crt mycerts/clt.pem ...

>>> Feb  6 12:14:14 localhost \
      haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] https-in \
      static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \
      {} "GET /index.html HTTP/1.1" 0/0/0/0/0 \
      1wt.eu/TLSv1.3/TLS_AES_256_GCM_SHA384

Champ Format Extraire de l’exemple ci-dessus 1 process_name ‘[’ pid ‘]:’ HAProxy[14389]: 2 client_ip ‘:’ client_port 10.0.1.2:33317 3 ‘[’ request_date ‘]’ [06/Feb/2009:12:14:14.655] 4 frontend_name https-in 5 backend_name ‘/’ server_name static/srv1 6 TR ‘/’ Tw ‘/’ Tc ‘/’ Tr ‘/’ Ta* 10/0/30/69/109 7 status_code 200 8 bytes_read* 2750 9 captured_request_cookie - 10 captured_response_cookie - 11 termination_state —- 12 actconn ‘/’ feconn ‘/’ beconn ‘/’ srv_conn ‘/’ retries* 1/1/1/1/0 13 srv_queue ‘/’ backend_queue 0/0 14 ‘{’ captured_request_headers* ‘}’ {HAProxy.1wt.eu} 15 ‘{’ captured_response_headers* ‘}’ {} 16 ‘"’ http_request ‘"’ “GET /index.html HTTP/1.1” 17 fc_err ‘/’ ssl_fc_err ‘/’ ssl_c_err ‘/’ ssl_c_ca_err ‘/’ ssl_fc_is_resumed 0/0/0/0/0 18 ssl_fc_sni ‘/’ ssl_version ‘/’ ssl_ciphers 1wt.eu/TLSv1.3/TLS_AES_256_GCM_SHA384

Description détaillée des champs :

  • “fc_err” est l’état de la connexion du côté frontal. Il correspond à l’extraction d’échantillon “fc_err”. Pour plus d’informations, consultez les fonctions d’extraction d’échantillon “fc_err” et “fc_err_str”.

  • “ssl_fc_err” est la dernière erreur de la première pile d’erreurs SSL levée depuis la perspective du frontal. Elle peut être utilisée, par exemple, pour détecter les erreurs d’établissement de main-handshake SSL. Elle vaut 0 si tout s’est déroulé normalement. Pour plus d’informations, consulter la description de l’extraction d’échantillon “ssl_fc_err”.

  • “ssl_c_err” est l’état du processus de vérification du certificat client. La négociation peut réussir tout en ayant un code d’erreur de vérification non nul si cette erreur est ignorée. Voir l’extraction d’échantillon “ssl_c_err” et l’option “crt-ignore-err”.

  • “ssl_c_ca_err” est l’état du processus de vérification de la chaîne de certificat du client. La négociation peut réussir tout en ayant un code d’erreur de vérification non nul si cette erreur est ignorée. Voir l’extraction d’échantillon “ssl_c_ca_err” et l’option “ca-ignore-err”.

  • “ssl_fc_is_resumed” est true si la session TLS entrante a été rétablie à partir de la mémoire tampon étatique ou d’un jeton sans état. N’oubliez pas qu’une session TLS peut être partagée par plusieurs requêtes.

  • “ssl_fc_sni” est l’indication de nom de serveur (SNI) présentée par le client pour sélectionner le certificat à utiliser. Elle correspond généralement au nom d’hôte de la première requête d’une connexion. L’absence de ce champ peut indiquer que le client n’a pas envoyé de SNI, ce qui amène HAProxy à utiliser le certificat par défaut, ou à rejeter la connexion en cas de mode strict-sni.

  • “ssl_version” est la version SSL du frontal.

  • “ssl_ciphers” est le chiffrement SSL utilisé pour la connexion.

8.2.5. Format du journal d’erreurs

Lorsqu’une connexion entrante échoue en raison d’une négociation SSL ou d’un en-tête PROXY invalide, HAProxy journalise l’événement à l’aide d’un format de ligne plus court et fixe, sauf si un format de journalisation d’erreur dédié est défini via une ligne « error-log-format ». Par défaut, les journaux sont émis au niveau LOG_INFO, sauf si l’option « log-separate-errors » est définie dans le backend, auquel cas le niveau LOG_ERR sera utilisé. Les connexions sur lesquelles aucune donnée n’est échangée (par exemple, les sondes) ne sont pas journalisées si l’option « dontlognull » est activée.

Le format par défaut a cette apparence :

  >>> Dec  3 18:27:14 localhost \
        haproxy[6103]: 127.0.0.1:56059 [03/Dec/2012:17:35:10.380] frt/f1: \
        Connection error during SSL handshake

Field   Format                                Extract from the example above
    1   process_name '[' pid ']:'                             haproxy[6103]:
    2   client_ip ':' client_port                            127.0.0.1:56059
    3   '[' accept_date ']'                       [03/Dec/2012:17:35:10.380]
    4   frontend_name "/" bind_name ":"                              frt/f1:
    5   message                        Connection error during SSL handshake

Ces champs ne fournissent que des informations minimales afin d’aider au débogage des échecs de connexion.

En utilisant la directive « error-log-format », le format d’historique hérité décrit ci-dessus ne sera plus utilisé, et toutes les lignes de journal d’erreur suivront le format défini.

Un exemple de format d’erreur suffisamment complet est présenté ci-dessous. Il rapporte l’adresse source et le port, la date d’acceptation de la connexion, le nom du frontend, le nombre de connexions actives sur le processus et sur ce frontend, l’identifiant interne d’erreur d’HAProxy sur la connexion frontale, le numéro d’erreur OpenSSL au format hexadécimal (pouvant être copié-collé dans « OpenSSL errstr » pour une décodage complet), l’état d’extraction du certificat client (0 indique aucune erreur), l’état de validation du certificat client par la CA (0 indique aucune erreur), une valeur booléenne indiquant si la connexion est nouvelle ou a été rétablie, l’indication éventuelle du nom de serveur (SNI) fournie par le client, le nom de la version SSL et les chiffres SSL utilisés sur la connexion, le cas échéant. Notez que les erreurs de connexion backend ne sont jamais rapportées ici, car pour qu’une connexion backend échoue, elle aurait dû passer par un flux réussi, et sera donc disponible sous forme de journal de trafic régulier (voir l’option httplog ou l’option httpslog).

# detailed frontend connection error log
error-log-format "%ci:%cp [%tr] %ft %ac/%fc %[fc_err]/\
      %[ssl_fc_err,hex]/%[ssl_c_err]/%[ssl_c_ca_err]/%[ssl_fc_is_resumed] \
      %[ssl_fc_sni]/%sslv/%sslc"

8.2.6. Format de journal personnalisé

Historiquement, les formats de journalisation personnalisés n’étaient utilisés que pour produire des journaux. Mais leur commodité lorsqu’ils servent à générer une chaîne en assemblant plusieurs expressions complexes a conduit à leur adoption par de nombreuses directives qui n’acceptaient auparavant que des chaînes en argument et qui peuvent désormais également accepter une définition de format de journalisation personnalisé. Ces arguments, généralement désignés par “<fmt>” dans ce document, sont définis exactement de la même manière que l’argument de la directive « log-format », décrite ici.

Lorsqu’il s’agit des journaux et que les formats de journalisation par défaut ne sont pas suffisants, il est possible de définir de nouveaux formats avec une grande précision. Comme la création d’un format de journalisation depuis zéro n’est pas toujours une tâche aisée, il est fortement recommandé de consulter en premier lieu les formats existants (“option tcplog”, “option httplog”, “option httpslog”), de choisir celui qui correspond le plus à l’attente, de copier sa chaîne équivalente “log-format” et de l’ajuster.

Une définition de format de journal personnalisé est un argument unique du point de vue de la configuration. Cela signifie qu’elle ne peut pas contenir d’espaces (blancs ou tabulations), sauf si ces espaces sont échappés à l’aide du caractère barre oblique inversée (’\’), ou si toute la définition est enclose entre guillemets (ce qui est la méthode recommandée pour les utiliser). L’utilisation de chaînes de format non encloses entre guillemets n’est plus recommandée, car l’histoire a montré qu’elle était très sujette aux erreurs, une simple barre oblique inversée manquante pouvant entraîner une troncation silencieuse du format. De telles configurations sont encore fréquemment rencontrées en raison de l’adoption massive des formats de journal après la version 1.5-dev9, soit trois ans avant que les guillemets soient disponibles, mais il est recommandé de les convertir en chaînes entre guillemets et de supprimer les barres obliques inversées.

Une définition de format de journal est composée d’un nombre quelconque d’éléments de format de journal séparés par du texte et des espaces. Un élément de format de journal commence par le caractère ‘%’. Pour émettre un ‘%’ littéral, il doit être précédé d’un autre ‘%’ donnant ‘%%’.

Les éléments de logformat peuvent être soit des alias, soit des expressions d’échantillonnage :

Si un élément est nommé entre crochets (’[’ .. ‘]’), il est utilisé comme une expression d’exemple règle (voir section 7.3 ). Cela est utile pour ajouter certaines informations moins courantes, telles que le DN du certificat SSL du client, ou pour journaliser la clé qui serait utilisée pour stocker une entrée dans une table de persistance. Il est également couramment utilisé avec des actions non loggées (manipulation d’en-têtes, variables, etc.).

Sinon, si l’élément est nommé à l’aide d’un nom alphanumérique, il s’agit d’un alias. (Voir le tableau ci-dessous pour la liste des alias disponibles)

Les éléments peuvent accepter des arguments entre accolades (’{}’), et plusieurs arguments sont séparés par des virgules à l’intérieur des accolades. Les indicateurs peuvent être ajoutés ou supprimés en les préfixant d’un signe ‘+’ ou ‘-’ (voir ci-dessous la liste des indicateurs disponibles).

L’alias spécial “%o” peut être utilisé pour propager ses indicateurs à tous les autres éléments de formatage dans la même chaîne de format. Cela est particulièrement pratique avec les formats de chaîne entre guillemets (“Q”) et les chaînes échappées (“E”).

Alias spécial “%OG” peut être utilisé pour récupérer l’origine du journal (lieu de génération du journal) sous une forme lisible par l’humain. Il est particulièrement utile avec “option logasap” car certaines variables de journal ou extraits d’échantillon pourraient rapporter des valeurs incomplètes ou se comporter différemment selon le moment ou le lieu d’évaluation de l’expression logformat. Les valeurs possibles sont :

  • “sess_error” : le journal a été généré lors du traitement d’une erreur de session
  • “sess_killed” : le journal a été généré lors de l’abandon de session (session embryonnaire interrompue)
  • “txn_accept” : le journal a été généré juste après l’acceptation de la connexion frontale
  • “txn_request” : le journal a été généré après réception de la requête client
  • “txn_connect” : le journal a été généré après établissement de la connexion backend
  • “txn_response” : le journal a été généré lors du traitement de la réponse serveur
  • “txn_close” : le journal a été généré à l’étape finale de la transaction, avant la fermeture
  • “unspec” : inconnu ou non spécifié “%OG” est pertinent uniquement dans un contexte de journalisation.

Les éléments peuvent éventuellement être nommés à l’aide de parenthèses (’()’). Le nom doit être fourni immédiatement après ‘%’ (avant les arguments). Il sera automatiquement utilisé comme nom de clé lorsque le drapeau d’encodage tel que « json » ou « cbor » est défini. Lorsqu’aucun drapeau d’encodage n’est spécifié (par défaut), le nom de l’élément sera ignoré. Il est également possible de forcer le type de sortie de l’élément en ajoutant ‘:type’ après le nom, comme ceci : %(itemname:itemtype)aliasname ou %(itemname:itemtype)[expr], où itemtype peut être ‘str’, ‘sint’ ou ‘bool’. La spécification du type n’est pertinente que lorsqu’une méthode d’encodage est utilisée. Il est également possible de fournir un nom vide afin de forcer le type de sortie sur un élément anonyme : %(:itemtype), par exemple lorsque l’encodage n’est pas défini globalement, voir les définitions des drapeaux ci-dessous pour plus d’informations.

En raison de l’objectif initial des formats de journalisation personnalisés, qui est d’être utilisés uniquement pour la journalisation, une règle spéciale est appliquée aux caractères non imprimables et non sûrs (ceux situés en dehors des codes ASCII 32 à 126, ainsi que quelques autres) selon leur contexte d’utilisation. Section 8.6 décrit précisément ce qui est fait pour les journaux afin de garantir qu’aucun code non sûr n’est envoyé, ce qui pourrait altérer la lisibilité de la sortie dans un terminal. Lorsqu’ils sont utilisés pour former des champs d’en-tête, des contrôles d’état ou des réponses de charge utile, les règles sont moins strictes, et seuls les caractères interdits dans les champs d’en-tête HTTP sont remplacés par leur encodage hexadécimal précédé du caractère ‘%’. Cela ne pose normalement pas de problème, mais cela peut affecter la sortie lorsque le caractère était censé être reproduit tel quel (par exemple, lors de la construction d’une page d’erreur ou d’une charge utile complète de réponse, où les sauts de ligne pourraient apparaître sous la forme “%0A”).

Note : dans les directives de configuration « log-format », « log-format-sd » et « unique-id-format », les espaces sont considérés comme des délimiteurs et sont fusionnés.

Note : lors de l’utilisation du format de message syslog RFC5424, les caractères ‘"’, ‘\’ et ‘]’ figurant dans PARAM-VALUE doivent être échappés en les préfixant par ‘\’ (voir https://tools.ietf.org/html/rfc5424#section-6.3.3 pour plus de détails). Dans de tels cas, l’utilisation du drapeau “E” doit être prise en compte.

Les indicateurs d’éléments pris en charge sont (peuvent être activés/désactivés via les arguments de l’élément) :

  • Q : insérer une chaîne entre guillemets
  • X : représentation hexadécimale (adresses IP, ports, %Ts, %rt, %pid)
  • E : échapper les caractères ‘"’, ‘\’ et ‘]’ dans une chaîne avec ‘\’ comme préfixe (destiné à être utilisé avec les formats de journalisation structurés RFC5424)
  • bin : essayer de préserver les données binaires, ce qui peut être utile avec des expressions d’échantillonnage produisant des données binaires afin de conserver les données d’origine. Faites attention toutefois, car cela peut évidemment générer des caractères non imprimables, y compris des octets NULL, que la plupart des terminaux syslog n’attendent pas. Cette option est donc principalement destinée à être utilisée avec set-var-fmt, les anneaux et les terminaux de journalisation capables de traiter les données binaires. Cette option ne peut être définie qu’au niveau global (avec %o), elle sera ignorée si elle est définie sur les options d’un élément individuel.
  • json : encoder automatiquement la valeur au format JSON (lorsqu’elle est définie au niveau global, seules les entrées de format de journal nommées sont prises en compte). Les valeurs numériques incomplètes (par exemple : ‘%B’ lorsqu’on utilise logasap), qui sont normalement précédées de ‘+’ sans encodage, seront encodées telles quelles. De plus, l’option ‘+E’ sera ignorée.
  • cbor : encoder automatiquement la valeur au format CBOR (lorsqu’il est défini globalement, seuls les éléments de format de journal nommés sont pris en compte). Par défaut, les données encodées en CBOR sont représentées sous forme hexadécimale afin de rester lisibles sur stdout et pouvant être utilisées avec des terminaux syslog classiques. Comme pour l’encodage JSON, les valeurs numériques incomplètes seront encodées telles quelles et l’option ‘+E’ sera ignorée. Lorsqu’elle est combinée avec l’option ‘+bin’, elle génère directement un payload CBOR binaire brut. Attention, cela produit évidemment des caractères non imprimables, aussi cette option est-elle principalement destinée à être utilisée avec set-var-fmt, les files d’attente et les terminaux de journalisation capables de traiter les données binaires.

Exemple :

log-format %T\ %t\ Some\ Text
log-format %{+Q}o\ %t\ %s\ %{-Q}r

log-format-sd %{+Q,+E}o\ [exampleSDID@1234\ header=%[capture.req.hdr(0)]]

log-format "%{+json}o %(request)r %(custom_expr)[str(custom)]"
log-format "%{+cbor}o %(request)r %(custom_expr)[str(custom)]"

Veuillez vous référer au tableau ci-dessous pour les alias actuellement définis :

  +---+------+------------------------------------------------------+---------+
  | R | alias| field name (8.2.2 and 8.2.3 for description)         | type    |
  |   |      | sample fetch alternative                             |         |
  +===+======+======================================================+=========+
  |   | %o   | special, apply flags on all following items          |         |
  +---+------+------------------------------------------------------+---------+
  |                          date formats                                     |
  +---+------+------------------------------------------------------+---------+
  |   | %T   | Accept date UTC + timezone                           |         |
  |   |      | %[accept_date,utime("%d/%b/%Y:%H:%M:%S %z")]         | date    |
  +---+------+------------------------------------------------------+---------+
  |   | %Tl  | Accept date local + timezone                         |         |
  |   |      | %[accept_date,ltime("%d/%b/%Y:%H:%M:%S %z")]         | date    |
  +---+------+------------------------------------------------------+---------+
  |   | %Ts  | Accept date as a UNIX timestamp                      | numeric |
  |   |      | %[accept_date]                                       |         |
  +---+------+------------------------------------------------------+---------+
  |   | %t   | Accept date local (with millisecond resolution)      |         |
  |   |      | %[accept_date(ms),ms_ltime("%d/%b/%Y:%H:%M:%S.%3N")] | date    |
  +---+------+------------------------------------------------------+---------+
  |   | %ms  | Accept date milliseconds                             |         |
  |   |      | %[accept_date(ms),ms_utime("%3N")]                   | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %tr  | Request date local (with millisecond resolution)     |         |
  |   |      | %[request_date(ms),ms_ltime("%d/%b/%Y:%H:%M:%S.%3N")]| date    |
  +---+------+------------------------------------------------------+---------+
  | H | %trg | Request date UTC + timezone                          |         |
  |   |      | %[request_date,utime("%d/%b/%Y:%H:%M:%S %z")]        | date    |
  +---+------+------------------------------------------------------+---------+
  | H | %trl | Request date local + timezone                        |         |
  |   |      | %[request_date,ltime("%d/%b/%Y:%H:%M:%S %z")]        | date    |
  +---+------+------------------------------------------------------+---------+
  |                          Timing events                                    |
  +---+------+------------------------------------------------------+---------+
  | H | %Ta  | Active time of the request (from TR to end)          |         |
  |   |      | %[txn.timer.total]                                   | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Tc  | Tc                                                   |         |
  |   |      | %[bc.timer.connect]                                  | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Td  | Td = Tt - (Tq + Tw + Tc + Tr)                        |         |
  |   |      | %[res.timer.data]                                    | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Th  | connection handshake time (SSL, PROXY proto)         |         |
  |   |      | %[fc.timer.handshake]                                | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %Ti  | idle time before the HTTP request                    |         |
  |   |      | %[req.timer.idle]                                    | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %Tq  | Th + Ti + TR                                         |         |
  |   |      | %[req.timer.tq]                                      | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %TR  | time to receive the full request from 1st byte       |         |
  |   |      | %[req.timer.hdr]                                     | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %Tr  | Tr (response time)                                   |         |
  |   |      | %[res.timer.hdr]                                     | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Tt  | Tt                                                   |         |
  |   |      | %[fc.timer.total]                                    | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Tu  | Tu                                                   |         |
  |   |      | %[txn.timer.user]                                    | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %Tw  | Tw                                                   |         |
  |   |      | %[req.timer.queue]                                   | numeric |
  +---+------+------------------------------------------------------+---------+
  |                          Others                                           |
  +---+------+------------------------------------------------------+---------+
  |   | %B   | bytes_read           (from server to client)         | numeric |
  |   |      | %[res.bytes_in]                                      |         |
  +---+------+------------------------------------------------------+---------+
  | H | %CC  | captured_request_cookie                              | string  |
  +---+------+------------------------------------------------------+---------+
  | H | %CS  | captured_response_cookie                             | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %H   | hostname                                             | string  |
  |   |      | %[hostname]                                          |         |
  +---+------+------------------------------------------------------+---------+
  | H | %HM  | HTTP method (ex: POST)                               | string  |
  |   |      | %[method]
  +---+------+------------------------------------------------------+---------+
  | H | %HP  | HTTP request URI without query string                | string  |
  +---+------+------------------------------------------------------+---------+
  | H | %HPO | HTTP path only (without host nor query string)       | string  |
  +---+------+------------------------------------------------------+---------+
  | H | %HQ  | HTTP request URI query string (ex: ?bar=baz)         | string  |
  |   |      | ?%[query]                                            |         |
  +---+------+------------------------------------------------------+---------+
  | H | %HU  | HTTP request URI (ex: /foo?bar=baz)                  | string  |
  +---+------+------------------------------------------------------+---------+
  | H | %HV  | HTTP version (ex: HTTP/1.0)                          | string  |
  |   |      | HTTP/%[req.ver]                                      |         |
  +---+------+------------------------------------------------------+---------+
  |   | %ID  | unique-id                                            | string  |
  |   |      | %[unique-id]                                         |         |
  +---+------+------------------------------------------------------+---------+
  |   | %ST  | status_code                                          | numeric |
  |   |      | %[txn.status]                                        |         |
  +---+------+------------------------------------------------------+---------+
  |   | %U   | bytes_uploaded       (from client to server)         | numeric |
  |   |      | %[req.bytes_in]                                      |         |
  +---+------+------------------------------------------------------+---------+
  |   | %ac  | actconn                                              |         |
  |   |      | %[act_conn]                                          | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %b   | backend_name                                         |         |
  |   |      | %[be_name]                                           | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %bc  | beconn      (backend concurrent connections)         | numeric |
  |   |      | %[be_conn]                                           |         |
  +---+------+------------------------------------------------------+---------+
  |   | %bi  | backend_source_ip       (connecting address)         |         |
  |   |      | %[bc_src]                                            | IP      |
  +---+------+------------------------------------------------------+---------+
  |   | %bp  | backend_source_port     (connecting address)         |         |
  |   |      | %[bc_src_port]                                       | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %bq  | backend_queue                                        | numeric |
  |   |      | %[bc_be_queue]                                       |         |
  +---+------+------------------------------------------------------+---------+
  |   | %ci  | client_ip                 (accepted address)         |         |
  |   |      | %[src]                                               | IP      |
  +---+------+------------------------------------------------------+---------+
  |   | %cp  | client_port               (accepted address)         |         |
  |   |      | %[src_port]                                          | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %f   | frontend_name                                        | string  |
  |   |      | %[fe_name]                                           |         |
  +---+------+------------------------------------------------------+---------+
  |   | %fc  | feconn     (frontend concurrent connections)         | numeric |
  |   |      | %[fe_conn]                                           |         |
  +---+------+------------------------------------------------------+---------+
  |   | %fi  | frontend_ip              (accepting address)         |         |
  |   |      | %[dst]                                               | IP      |
  +---+------+------------------------------------------------------+---------+
  |   | %fp  | frontend_port            (accepting address)         |         |
  |   |      | %[dst_port]                                          | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %ft  | frontend_name_transport ('~' suffix for SSL)         | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %lc  | frontend_log_counter                                 | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %hr  | captured_request_headers default style               | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %hrl | captured_request_headers CLF style                   | string  |
  |   |      |                                                      | list    |
  +---+------+------------------------------------------------------+---------+
  |   | %hs  | captured_response_headers default style              | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %hsl | captured_response_headers CLF style                  | string  |
  |   |      |                                                      | list    |
  +---+------+------------------------------------------------------+---------+
  | L | %OG  | human readable log origin                            | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %pid | PID                                                  |         |
  |   |      | %[pid]                                               | numeric |
  +---+------+------------------------------------------------------+---------+
  | H | %r   | http_request                                         | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %rc  | retries                                              | numeric |
  |   |      | %[txn.redispatched,iif(+,)]%[txn.conn_retries]       |         |
  +---+------+------------------------------------------------------+---------+
  |   | %rt  | request_counter (HTTP req or TCP session)            | numeric |
  |   |      | %[txn.id32]                                          |         |
  +---+------+------------------------------------------------------+---------+
  |   | %s   | server_name                                          | string  |
  |   |      | %[srv_name]                                          |         |
  +---+------+------------------------------------------------------+---------+
  |   | %sc  | srv_conn     (server concurrent connections)         | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %si  | server_IP                   (target address)         |         |
  |   |      | %[bc_dst]                                            | IP      |
  +---+------+------------------------------------------------------+---------+
  |   | %sp  | server_port                 (target address)         |         |
  |   |      | %[bc_dst_port]                                       | numeric |
  +---+------+------------------------------------------------------+---------+
  |   | %sq  | srv_queue                                            | numeric |
  |   |      | %[bc_srv_queue]                                      |         |
  +---+------+------------------------------------------------------+---------+
  | S | %sslc| ssl_ciphers (ex: AES-SHA)                            |         |
  |   |      | %[ssl_fc_cipher]                                     | string  |
  +---+------+------------------------------------------------------+---------+
  | S | %sslv| ssl_version (ex: TLSv1)                              |         |
  |   |      | %[ssl_fc_protocol]                                   | string  |
  +---+------+------------------------------------------------------+---------+
  |   | %ts  | termination_state                                    | string  |
  |   |      | %[txn.sess_term_state]                               |         |
  +---+------+------------------------------------------------------+---------+
  | H | %tsc | termination_state with cookie status                 | string  |
  +---+------+------------------------------------------------------+---------+
R = Restrictions: H = mode http only; S = SSL only; L = log only

8.3. Options avancées de journalisation

Certaines options avancées de journalisation sont fréquemment recherchées, mais ne sont pas faciles à identifier en examinant uniquement les différentes options. Voici un point d’entrée pour les quelques options permettant une meilleure journalisation. Reportez-vous à la référence des mots-clés pour plus d’informations sur leur utilisation.

8.3.1. Désactivation de la journalisation des tests externes

Il est fréquent de voir des outils de surveillance effectuer des contrôles d’état sur HAProxy. Parfois, il s’agit d’un équilibreur de charge au niveau 3, comme LVS ou tout équilibreur de charge commercial, et parfois d’un système de surveillance plus complet, comme Nagios. Lorsque ces tests sont très fréquents, les utilisateurs demandent souvent comment désactiver la journalisation de ces contrôles. Trois possibilités existent :

  • Si les connexions proviennent de partout et ne sont que des sondes TCP, il est souvent souhaitable de désactiver simplement la journalisation des connexions sans échange de données, en définissant « option dontlognull » dans le frontal. Cela désactive également la journalisation des scans de port, ce qui peut ou non être souhaitable.

  • il est possible d’utiliser l’action « http-request set-log-level silent » avec diverses conditions (source réseau, chemins, user-agents, etc.).

  • si les tests sont effectués sur une URI connue, utilisez « monitor-uri » pour déclarer cette URI comme dédiée au suivi. Tout hôte envoyant cette requête ne recevra que le résultat d’un contrôle de santé, et la requête ne sera pas journalisée.

8.3.2. Journalisation avant d’attendre la fin du flux

Le problème lié à la journalisation à la fin de la connexion est qu’il n’est pas possible de savoir ce qui se passe pendant des flux très longs, comme les sessions de terminal distant ou les téléchargements de fichiers volumineux. Ce problème peut être contourné en spécifiant « option logasap » dans le frontal. HAProxy journalisera alors dès que possible, juste avant le début du transfert de données. Cela signifie qu’en cas de TCP, il journalisera encore l’état de la connexion vers le serveur, et en cas de HTTP, il journalisera juste après le traitement des en-têtes serveur. Dans ce cas, le nombre d’octets rapporté correspond au nombre d’octets d’en-tête envoyés au client. Pour éviter toute confusion avec les journaux normaux, les champs temps total et nombre d’octets sont précédés d’un signe « + », ce qui indique que les valeurs réelles sont certainement plus élevées.

8.3.3. Augmenter le niveau de journalisation en cas d’erreur

Parfois, il est plus pratique de séparer le trafic normal des journaux d’erreurs, par exemple pour faciliter la surveillance des erreurs à partir des fichiers journaux. Lorsque l’option « log-separate-errors » est utilisée, les connexions qui rencontrent des erreurs, des délais d’expiration, des tentatives de reconnexion, des redirigements ou des codes d’état HTTP 5xx verront leur niveau syslog passé de « info » à « err ». Cela permet à un démon syslog de stocker le journal dans un fichier distinct. Il est très important de conserver les erreurs dans le fichier de journal du trafic normal afin de ne pas altérer l’ordre des journaux. Vous devez également faire attention si vous avez déjà configuré votre démon syslog pour stocker tous les journaux de niveau supérieur à « notice » dans un fichier « admin », car le niveau « err » est supérieur à « notice ».

8.3.4. Désactivation de la journalisation des connexions réussies

Bien que cela puisse sembler étrange au premier abord, certains grands sites doivent gérer des milliers de journaux par seconde et éprouvent des difficultés à les conserver intégraux sur une longue période ou à détecter des erreurs au sein d’entre eux. Si l’option « dontlog-normal » est définie sur le frontal, toutes les connexions normales ne seront pas journalisées. Une connexion normale est définie comme une connexion sans erreur, délai d’expiration, tentative de reconnexion ni redirigement. En HTTP, le code de statut est également vérifié, et une réponse avec un statut 5xx n’est pas considérée comme normale et sera journalisée également. Bien entendu, cette pratique est fortement déconseillée, car elle supprime la majeure partie des informations utiles des journaux. Procédez ainsi uniquement si aucune autre alternative n’est disponible.

8.3.5. Profils de journalisation

Bien que certaines directives telles que « log-format », « log-format-sd », « error-log-format » ou « log-tag » permettent de configurer le format des journaux de manière globale ou au niveau du proxy, il peut être pertinent de configurer ces paramètres aussi près que possible des destinations de journalisation, c’est-à-dire par directive « log ».

C’est ici que la section « log-profile » entre en jeu : la section « log-profile » peut être définie n’importe où dans la configuration. Cette section accepte un ensemble de mots-clés différents, utilisés pour décrire la manière dont les journaux émis pour une directive log donnée doivent être construits.

À partir d’une directive « log », il est possible de choisir un profil de journalisation spécifique par son nom. Ce même profil peut être utilisé à partir de plusieurs directives « log ».

log-profile <name> Crée un nouveau profil de journalisation identifié par <name>

log-tag <string> Remplacer l’étiquette de journalisation syslog définie globalement ou par proxy à l’aide de la directive « log-tag ».

sur <step> [drop] [format <fmt>] [sd <sd_fmt>] Remplace la chaîne de format de journalisation utilisée par défaut pour construire la ligne de journal au stade de journalisation <step>. <fmt> permet de remplacer les chaînes “log-format” ou “error-log-format” (selon le <step>), tandis que <sd_fmt> permet de remplacer la chaîne “log-format-sd” (les deux peuvent être combinés).

Mot-clé spécial drop peut être utilisé pour indiquer qu’aucun journal ne doit être émis pour le <step> donné. Il a priorité sur format et sd s’ils ont été définis précédemment.

Valeurs possibles pour <step> sont :

  • “accept” : remplacer log-format si le journal est généré juste après l’acceptation de la connexion frontale
  • “request” : remplacer log-format si le journal est généré après la réception de la requête client
  • “connect” : remplacer log-format si le journal est généré après l’établissement de la connexion backend
  • “response” : remplacer log-format si le journal est généré pendant le traitement de la réponse serveur
  • “close” : remplacer log-format si le journal est généré à l’étape finale de la transaction (txn)
  • “error” : remplacer error-log-format si le journal est généré suite à une erreur de transaction
  • “any” : remplacer à la fois log-format et error-log-format pour toutes les étapes de journalisation, sauf si une substitution plus précise est déclarée.

Voir l’action « do-log » pour les valeurs <step> supplémentaires pertinentes.

Ce paramètre n’est pertinent que pour les directives « log » utilisées dans des contextes où l’utilisation de la directive « log-format » a un sens (par exemple : proxys HTTP et TCP). Dans les autres cas, il sera simplement ignoré.

Exemple :

log-profile myprof

  log-tag "custom-tag"

  on error format "%ci: error"
  on connect drop
  on any sd "custom-sd"

listen myproxy
  mode http
  option httplog
  log-tag "normal"

  log stdout format rfc5424 local0
  # success:
  # <134>1 2024-06-12T10:09:11.823400+02:00 - normal 224482 - - 127.0.0.1:53594 [12/Jun/2024:10:09:11.814] myproxy myproxy/<NOSRV> 0/-1/-1/-1/0 200 49 - - LR-- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
  #
  # error:
  # <134>1 2024-06-12T10:09:44.810929+02:00 - normal 224482 - - 127.0.0.1:59258 [12/Jun/2024:10:09:44.426] myproxy myproxy/<NOSRV> -1/-1/-1/-1/384 400 0 - - CR-- 1/1/0/0/0 0/0 "<BADREQ>"

  log 127.0.0.1:514 format rfc5424 profile myprof local0
  # success:
  # <134>1 2024-06-12T10:09:11.823428+02:00 - custom-tag 224482 - custom-sd 127.0.0.1:53594 [12/Jun/2024:10:09:11.814] myproxy myproxy/<NOSRV> 0/-1/-1/-1/0 200 49 - - LR-- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
  #
  # error:
  # <134>1 2024-06-12T10:09:51.566524+02:00 - custom-tag 224482 - - 127.0.0.1: error

8.4. Événements de temporisation

Les compteurs aident grandement au dépannage des problèmes réseau. Toutes les valeurs sont exprimées en millisecondes (ms). Ces compteurs doivent être utilisés conjointement avec les indicateurs de terminaison de flux. En mode TCP avec l’option « option tcplog » activée sur le frontal, trois points de contrôle sont rapportés sous la forme « Tw/Tc/Tt », et en mode HTTP, cinq points de contrôle sont rapportés sous la forme « TR/Tw/Tc/Tr/Ta ». En outre, trois autres mesures sont fournies : « Th », « Ti » et « Tq ».

Événements de temporisation en mode HTTP :

                 first request               2nd request
      |<-------------------------------->|<-------------- ...
      t         tr                       t    tr ...
   ---|----|----|----|----|----|----|----|----|--
     : Th   Ti   TR   Tw   Tc   Tr   Td: Ti   ...
     :<---- Tq ---->:                  :
     :<-------------- Tt -------------->:
     :<--        -----Tu--------------->:
               :<--------- Ta --------->:

Événements de temporisation en mode TCP :

           TCP session
      |<----------------->|
      t                   t
   ---|----|----|----|----|---
      | Th   Tw   Tc   Td |
      |<------ Tt ------->|
  • Th : temps total nécessaire pour accepter la connexion TCP et exécuter les échanges de protocoles de bas niveau. Actuellement, ces protocoles sont proxy-protocol et SSL. Cet événement ne peut se produire qu’une seule fois au cours de la durée de vie de la connexion. Un temps élevé ici peut indiquer que le client a établi la connexion uniquement sans échanger de données, qu’il rencontre des problèmes réseau empêchant la réalisation d’un échange dans un délai raisonnable (par exemple, des problèmes de MTU), ou qu’une négociation SSL a été particulièrement coûteuse à calculer. Veuillez noter que ce temps n’est rapporté qu’avant la première requête, il est donc sans danger de le moyenniser sur toutes les requêtes afin d’obtenir sa valeur amortie. Les requêtes suivantes rapporteront toujours zéro ici.

Ce minuteur est nommé %Th en tant qu’alias de format de journalisation, et fc.timer.handshake en tant qu’extraction d’échantillon.

  • Ti : est le délai d’inactivité avant la requête HTTP (mode HTTP uniquement). Ce minuteur s’active entre la fin des échanges d’handshake et la réception du premier octet de la requête HTTP. En cas de deuxième requête en mode keep-alive, il démarre après la fin de l’envoi de la réponse précédente. Lorsqu’un protocole multiplexé tel qu’HTTP/2 est utilisé, il démarre immédiatement après la requête précédente. Certains navigateurs établissent des connexions préalables à un serveur afin de réduire la latence d’une requête future, et les maintiennent en attente jusqu’à leur utilisation. Ce délai sera comptabilisé comme temps d’inactivité. Une valeur de -1 indique qu’aucune donnée n’a été reçue sur la connexion.

Ce minuteur est nommé %Ti en tant qu’alias de format de journalisation, et req.timer.idle en tant qu’extraction d’échantillon.

  • TR : temps total pour obtenir la requête client (mode HTTP uniquement). Il s’agit du temps écoulé entre les premiers octets reçus et le moment où le proxy a reçu la ligne vide marquant la fin des en-têtes HTTP. La valeur “-1” indique que la fin des en-têtes n’a jamais été observée. Cela se produit lorsque le client se ferme prématurément ou expiré. Ce temps est généralement très court, car la plupart des requêtes tiennent dans un seul paquet. Un temps élevé peut indiquer une requête saisie manuellement lors d’un test.

Ce minuteur est nommé %TR en tant qu’alias de format de journalisation, et req.timer.hdr en tant qu’extraction d’échantillon.

  • Tq : temps total pour obtenir la requête client à partir de la date d’acceptation ou depuis l’émission du dernier octet de la réponse précédente (mode HTTP uniquement). Il est exactement égal à Th + Ti + TR, sauf si l’un de ces éléments est -1, auquel cas il retourne également -1. Ce chronomètre était autrefois très utile avant l’arrivée de la réutilisation de connexion HTTP et de la fonction de pré-connexion des navigateurs. Il est recommandé de l’abandonner au profit de TR, car le temps d’attente ajoute beaucoup de bruit aux rapports.

Ce minuteur est nommé %Tq en tant qu’alias de format de journalisation, et req.timer.tq en tant qu’extraction d’échantillon.

  • Tw : temps total passé dans les files d’attente en attente d’une slot de connexion. Il tient compte à la fois de la file d’attente du backend et des files d’attente du serveur, et dépend de la taille de la file d’attente ainsi que du temps nécessaire au serveur pour terminer les requêtes précédentes. La valeur “-1” signifie que la requête a été interrompue avant d’atteindre la file d’attente, ce qui se produit généralement pour les requêtes non valides ou refusées.

Ce minuteur est nommé %Tw en tant qu’alias de format de journalisation, et req.timer.queue en tant qu’extraction d’échantillon.

  • Tc : temps total nécessaire à l’établissement de la connexion TCP au serveur. Il correspond au temps écoulé entre l’instant où le proxy a envoyé la requête de connexion et l’instant où celle-ci a été reconnue par le serveur, ou entre l’envoi du paquet TCP SYN et la réception du paquet SYN/ACK correspondant. La valeur “-1” signifie que la connexion n’a pas pu être établie.

Ce minuteur est nommé %Tc en tant qu’alias de format de journalisation, et bc.timer.connect en tant qu’extraction d’échantillon.

  • Tr : temps de réponse du serveur (mode HTTP uniquement). Il s’agit du délai écoulé entre l’instant où la connexion TCP a été établie avec le serveur et l’instant où le serveur a envoyé l’intégralité de ses en-têtes de réponse. Il indique uniquement le temps de traitement de la requête, sans tenir compte de la surcharge réseau due à la transmission des données. Il convient de noter qu’en cas d’envoi de données par le client au serveur, par exemple lors d’une requête POST, le délai est déjà en cours, ce qui peut fausser le temps de réponse apparent. Pour cette raison, il est généralement préférable de ne pas trop se fier à ce champ pour les requêtes POST initiées depuis des clients situés derrière un réseau non fiable. Une valeur de “-1” signifie ici que la dernière en-tête de réponse (ligne vide) n’a jamais été vue, probablement parce que le délai d’expiration du serveur s’est déclenché avant que le serveur n’ait pu traiter la requête ou parce que le serveur a renvoyé une réponse invalide.

Ce minuteur est nommé %Tr en tant qu’alias de format de journalisation, et res.timer.hdr en tant qu’extraction d’échantillon.

  • Td : c’est le temps total de transfert du contenu de la réponse jusqu’à l’envoi du dernier octet au client. En HTTP, il commence après le dernier en-tête de réponse (après Tr).

Les données envoyées ne sont pas garanties d’être reçues par le client ; elles peuvent rester bloquées dans le noyau ou le réseau.

Ce minuteur est nommé %Td en tant qu’alias de format de journalisation, et res.timer.data en tant qu’extraction d’échantillon.

  • Ta : temps d’activité total pour la requête HTTP, compris entre le moment où le proxy a reçu le premier octet de l’en-tête de la requête et l’émission du dernier octet du corps de la réponse. L’exception est lorsque l’option « logasap » est spécifiée. Dans ce cas, il ne correspond qu’à (TR+Tw+Tc+Tr) et est précédé du signe « + ». À partir de ce champ, on peut déduire « Td », le temps de transmission des données, en soustrayant les autres compteurs lorsque ceux-ci sont valides :
Td = Ta - (TR + Tw + Tc + Tr)
Les compteurs dont les valeurs sont "-1" doivent être exclus de cette équation. Notez qu'« Ta » ne peut jamais être négatif.

Ce minuteur est nommé %Ta en tant qu'alias de format de journalisation, et txn.timer.total en tant qu'extraction d'échantillon.
  • Tt : durée totale du flux, entre le moment où le proxy l’a accepté et celui où les deux extrémités ont été fermées. L’exception concerne l’option « logasap ». Dans ce cas, elle ne correspond qu’à (Th+Ti+TR+Tw+Tc+Tr), et est précédée d’un signe « + ». À partir de ce champ, on peut déduire « Td », le temps de transmission des données, en soustrayant les autres temporisateurs lorsque ceux-ci sont valides :
Td = Tt - (Th + Ti + TR + Tw + Tc + Tr)
Les compteurs ayant une valeur "-1" doivent être exclus de cette équation. En mode TCP, les valeurs "Ti", "Tq" et "Tr" doivent également être exclus. Notez que "Tt" ne peut jamais être négatif, et que pour HTTP, Tt est simplement égal à (Th+Ti+Ta).

Ce minuteur est nommé %Tt en tant qu'alias de format de journalisation, et fc.timer.total en tant qu'extraction d'échantillon.
  • Tu : temps estimé total perçu par le client, entre l’instant où le proxy l’a accepté et l’instant où les deux extrémités ont été fermées, sans temps d’inactivité. Cela permet de mesurer grossièrement le temps de bout en bout tel qu’un utilisateur le perçoit, sans la pollution due aux périodes d’inactivité dues à la réutilisation de connexions persistantes entre les requêtes. Ce chronomètre n’est qu’une estimation du temps perçu par l’utilisateur, car il suppose que la latence réseau est identique dans les deux sens. L’exception se produit lorsque l’option « logasap » est spécifiée. Dans ce cas, il ne correspond qu’à (Th+TR+Tw+Tc+Tr) et est précédé du signe « + ».

Ce minuteur est nommé %Tu as un alias de format de journal, et txn.timer.user comme extraction d’échantillon.

Ces délais d’expiration fournissent des indications précieuses sur les causes des problèmes. Étant donné que le protocole TCP définit des délais de retransmission de 3, 6, 12… secondes, on peut affirmer avec certitude que des délais proches des multiples de 3 s sont presque toujours liés à la perte de paquets due à des problèmes réseau (câblage, négociation, congestion). En outre, si « Ta » ou « Tt » est proche d’une valeur de délai d’expiration définie dans la configuration, cela signifie souvent qu’un flux a été interrompu en raison d’un délai d’expiration.

Cas les plus fréquents :

  • Si “Th” ou “Ti” sont proches de 3000, un paquet a probablement été perdu entre le client et le proxy. Cela est très rare sur les réseaux locaux, mais peut survenir lorsque les clients sont situés sur des réseaux distants et envoient des requêtes importantes. Il peut arriver que des valeurs plus élevées que la normale apparaissent ici sans cause réseau. Parfois, lors d’une attaque ou juste après la fin d’une saturation des ressources, HAProxy peut accepter des milliers de connexions en quelques millisecondes. Le temps passé à accepter ces connexions retardera inévitablement légèrement le traitement des autres connexions, et il peut arriver que des temps de requête de l’ordre de quelques dizaines de millisecondes soient mesurés après qu’un nombre de milliers de nouvelles connexions ait été accepté en même temps. L’utilisation d’un mode keep-alive peut faire apparaître des temps d’inactivité plus élevés, car “Ti” mesure le temps passé en attente de requêtes supplémentaires.

  • Si « Tc » est proche de 3000, un paquet a probablement été perdu entre le serveur et le proxy pendant la phase de connexion du serveur. Cette valeur doit toujours être très faible, par exemple de l’ordre de 1 ms sur les réseaux locaux et inférieure à quelques dizaines de ms sur les réseaux distants.

  • Si « Tr » est presque toujours inférieur à 3000, sauf pour certaines valeurs rares qui semblent être la moyenne majorée de 3000, il y a probablement des paquets perdus entre le proxy et le serveur.

  • Si « Ta » est élevé même pour de faibles volumes d’octets, cela est généralement dû au fait que ni le client ni le serveur ne décident de fermer la connexion pendant que HAProxy fonctionne en mode tunnel, et que les deux ont convenu d’un mode de connexion persistante. Pour résoudre ce problème, il faudra spécifier l’une des options HTTP afin de manipuler les options de maintien de connexion ou de fermeture, soit au niveau du frontal, soit au niveau du backend. Il est important de réduire au minimum la valeur de « Ta » ou de « Tt » lorsqu’une régulation des connexions est utilisée avec l’option « maxconn » sur les serveurs, car aucune nouvelle connexion ne sera envoyée au serveur tant qu’une autre n’aura pas été libérée.

Autres cas de journalisation HTTP notables (‘xx’ signifie toute valeur à ignorer) :

TR/Tw/Tc/Tr/+Ta  The "option logasap" is present on the frontend and the log
                 was emitted before the data phase. All the timers are valid
                 except "Ta" which is shorter than reality.

-1/xx/xx/xx/Ta   The client was not able to send a complete request in time
                 or it aborted too early. Check the stream termination flags
                 then "timeout http-request" and "timeout client" settings.

TR/-1/xx/xx/Ta   It was not possible to process the request, maybe because
                 servers were out of order, because the request was invalid
                 or forbidden by ACL rules. Check the stream termination
                 flags.

TR/Tw/-1/xx/Ta   The connection could not establish on the server. Either it
                 actively refused it or it timed out after Ta-(TR+Tw) ms.
                 Check the stream termination flags, then check the
                 "timeout connect" setting. Note that the tarpit action might
                 return similar-looking patterns, with "Tw" equal to the time
                 the client connection was maintained open.

TR/Tw/Tc/-1/Ta   The server has accepted the connection but did not return
                 a complete response in time, or it closed its connection
                 unexpectedly after Ta-(TR+Tw+Tc) ms. Check the stream
                 termination flags, then check the "timeout server" setting.

8.5. État du flux à la déconnexion

Les journaux TCP et HTTP fournissent un indicateur de terminaison de flux dans le champ “termination_state”, juste avant le nombre de connexions actives. Il est composé de 2 caractères en mode TCP, et étendu à 4 caractères en mode HTTP, chacun ayant une signification particulière :

  • Sur le premier caractère, un code indiquant l’événement initial ayant provoqué la fin du flux :
C: the TCP session was unexpectedly aborted by the client.

S: the TCP session was unexpectedly aborted by the server, or the
    server explicitly refused it.

P: the stream or session was prematurely aborted by the proxy, because
    of a connection limit enforcement, because a DENY filter was
    matched, because of a security check which detected and blocked a
    dangerous error in server response which might have caused
    information leak (e.g. cacheable cookie).

L: the stream was locally processed by HAProxy.

R: a resource on the proxy has been exhausted (memory, sockets, source
    ports, ...). Usually, this appears during the connection phase, and
    system logs should contain a copy of the precise error. If this
    happens, it must be considered as a very serious anomaly which
    should be fixed as soon as possible by any means.

I: an internal error was identified by the proxy during a self-check.
    This should NEVER happen, and you are encouraged to report any log
    containing this, because this would almost certainly be a bug. It
    would be wise to preventively restart the process after such an
    event too, in case it would be caused by memory corruption.

D: the stream was killed by HAProxy because the server was detected
    as down and was configured to kill all connections when going down.

U: the stream was killed by HAProxy on this backup server because an
    active server was detected as up and was configured to kill all
    backup connections when going up.

K: the stream was actively killed by an admin operating on HAProxy.

c: the client-side timeout expired while waiting for the client to
    send or receive data.

s: the server-side timeout expired while waiting for the server to
    send or receive data.

-: normal stream completion, both the client and the server closed
    with nothing left in the buffers.
  • sur le deuxième caractère, l’état du flux TCP ou HTTP au moment de sa fermeture :
R: the proxy was waiting for a complete, valid REQUEST from the client
    (HTTP mode only). Nothing was sent to any server.

Q: the proxy was waiting in the QUEUE for a connection slot. This can
    only happen when servers have a 'maxconn' parameter set. It can
    also happen in the global queue after a redispatch consecutive to
    a failed attempt to connect to a dying server. If no redispatch is
    reported, then no connection attempt was made to any server.

C: the proxy was waiting for the CONNECTION to establish on the
    server. The server might at most have noticed a connection attempt.

H: the proxy was waiting for complete, valid response HEADERS from the
    server (HTTP only).

D: the stream was in the DATA phase.

L: the proxy was still transmitting LAST data to the client while the
    server had already finished. This one is very rare as it can only
    happen when the client dies while receiving the last packets.

T: the request was tarpitted. It has been held open with the client
    during the whole "timeout tarpit" duration or until the client
    closed, both of which will be reported in the "Tw" timer.

-: normal stream completion after end of data transfer.
  • le troisième caractère indique si le cookie de persistance a été fourni par le client (uniquement en mode HTTP) :
N: the client provided NO cookie. This is usually the case for new
    visitors, so counting the number of occurrences of this flag in the
    logs generally indicate a valid trend for the site frequentation.

I: the client provided an INVALID cookie matching no known server.
    This might be caused by a recent configuration change, mixed
    cookies between HTTP/HTTPS sites, persistence conditionally
    ignored, or an attack.

D: the client provided a cookie designating a server which was DOWN,
    so either "option persist" was used and the client was sent to
    this server, or it was not set and the client was redispatched to
    another server.

V: the client provided a VALID cookie, and was sent to the associated
    server.

E: the client provided a valid cookie, but with a last date which was
    older than what is allowed by the "maxidle" cookie parameter, so
    the cookie is consider EXPIRED and is ignored. The request will be
    redispatched just as if there was no cookie.

O: the client provided a valid cookie, but with a first date which was
    older than what is allowed by the "maxlife" cookie parameter, so
    the cookie is consider too OLD and is ignored. The request will be
    redispatched just as if there was no cookie.

U: a cookie was present but was not used to select the server because
    some other server selection mechanism was used instead (typically a
    "use-server" rule).

-: does not apply (no cookie set in configuration).
  • le dernier caractère indique les opérations effectuées sur le cookie de persistance renvoyé par le serveur (uniquement en mode HTTP) :
N: NO cookie was provided by the server, and none was inserted either.

I: no cookie was provided by the server, and the proxy INSERTED one.
    Note that in "cookie insert" mode, if the server provides a cookie,
    it will still be overwritten and reported as "I" here.

U: the proxy UPDATED the last date in the cookie that was presented by
    the client. This can only happen in insert mode with "maxidle". It
    happens every time there is activity at a different date than the
    date indicated in the cookie. If any other change happens, such as
    a redispatch, then the cookie will be marked as inserted instead.

P: a cookie was PROVIDED by the server and transmitted as-is.

R: the cookie provided by the server was REWRITTEN by the proxy, which
    happens in "cookie rewrite" or "cookie prefix" modes.

D: the cookie provided by the server was DELETED by the proxy.

-: does not apply (no cookie set in configuration).

La combinaison des deux premiers indicateurs fournit de nombreuses informations sur ce qui s’est produit lors de la fermeture du flux ou de la session, ainsi que sur la raison de cette fermeture. Elle peut aider à détecter une saturation du serveur, des problèmes réseau, une pénurie de ressources système locales, des attaques, etc…

Les combinaisons de drapeaux de terminaison les plus courantes sont indiquées ci-dessous. Elles sont triées par ordre alphabétique, avec l’ensemble minuscule placé immédiatement après l’ensemble majuscule pour faciliter la recherche et la compréhension.

Drapeaux Raison

 --   Normal termination.

 CC   Le client a interrompu la connexion avant qu'elle ne puisse être établie avec le serveur. Cela peut se produire lorsque HAProxy tente de se connecter à un serveur récemment tombé en panne (ou non vérifié), et que le client interrompt la connexion pendant que HAProxy attend la réponse du serveur ou l'expiration du délai de connexion.

 CD   Le client a interrompu inopinément la transmission de données. Cela peut être dû à une panne du navigateur, à un équipement intermédiaire entre le client et HAProxy qui a décidé de rompre activement la connexion, à des problèmes de routage réseau entre le client et HAProxy, ou à une connexion en continu (keep-alive) entre le serveur et le client qui a été fermée en premier par le client.

 cD   Le client n'a ni envoyé ni reconnu de données pendant une durée égale au délai « timeout client ». Cela est souvent dû à une panne réseau côté client, ou au fait que le client quitte le réseau de manière non propre.

 CH   Le client a interrompu la requête pendant l'attente de la réponse du serveur.
      Cela peut être dû au délai de réponse du serveur ou au client cliquant trop rapidement sur le bouton « Arrêter ».

 cH   Le délai d'expiration « client » pendant l'attente des données du client lors d'une requête POST. Cela peut être dû à des valeurs TCP MSS trop élevées sur les réseaux PPPoE, incapables de transmettre des paquets de taille maximale. Cela peut également se produire lorsque le délai d'expiration du client est inférieur à celui du serveur et que ce dernier met trop de temps à répondre.

 CQ   Le client a interrompu la connexion alors que son flux était en attente dans la file d'attente, en attendant un serveur disposant de suffisamment de slots libres pour l'accepter. Cela peut être dû au fait que tous les serveurs étaient saturés ou que le serveur assigné mettait trop de temps à répondre.

 CR   Le client a interrompu la transmission d'une requête HTTP complète. Il s'agit probablement d'une requête saisie manuellement à l'aide d'un client telnet, interrompue trop tôt. Le code d'état HTTP est probablement 400. Dans certains cas, cela peut également être dû à un IDS qui interrompt la connexion entre HAProxy et le client. L'option « http-ignore-probes » peut être utilisée pour ignorer les connexions sans transfert de données.

 cR   Le délai d'expiration « timeout http-request » est déclenché avant que le client n'ait envoyé une requête HTTP complète. Cela peut être dû à des valeurs TCP MSS trop élevées côté client sur des réseaux PPPoE incapables de transmettre des paquets de taille maximale, ou à des clients qui envoient des requêtes manuellement sans taper assez vite, ou en oubliant d'entrer la ligne vide à la fin de la requête. Le code d'état HTTP est probablement 408 ici. Note : récemment, certains navigateurs ont commencé à implémenter une fonctionnalité de « pré-connexion », qui consiste à établir une connexion en avance avec certains sites web récemment visités, au cas où l'utilisateur souhaiterait les visiter. Cela entraîne de nombreuses connexions établies vers des sites web, qui aboutissent à un délai d'expiration 408 si le délai d'expiration est déclenché en premier, ou à une requête 400 Bad Request lorsque le navigateur décide de les fermer en premier. Ces connexions polluent les journaux et alimentent les compteurs d'erreurs. Certains navigateurs ont même été signalés pour afficher directement le code d'erreur. Il est possible de contourner les effets indésirables de ce comportement en ajoutant « option http-ignore-probes » dans le frontal, ce qui fait ignorer entièrement les connexions n'ayant aucune transmission de données. Cela masquera certainement les erreurs des utilisateurs rencontrant des problèmes de connectivité.

 CT   Le client a interrompu la requête pendant qu'elle était soumise à un tarpit. Il est important de vérifier si cela se produit sur des requêtes valides, afin de s'assurer qu'aucune règle de tarpit incorrecte n'a été configurée. Si un grand nombre d'occurrences sont observées, il peut être pertinent de réduire la valeur du « timeout tarpit » afin de la rapprocher de la valeur moyenne du chronomètre « Tw », afin de ne pas consommer de ressources pour quelques attaquants seulement.

 LC   La requête a été interceptée et traitée localement par HAProxy. La requête n'a pas été envoyée au serveur. Cela ne se produit que lors d'une redirection due à un paramètre « redir » sur la ligne du serveur.

 LR   La requête a été interceptée et traitée localement par HAProxy. La requête
      n'a pas été envoyée au serveur. Cela signifie généralement qu'une redirection
      a été renvoyée, une instruction HTTP return a été traitée ou que la requête
      a été gérée par un applet (statistiques, cache, export Prometheus, applet Lua...).

 LH   La réponse a été interceptée et gérée localement par HAProxy. Cela signifie généralement qu'une redirection a été renvoyée ou qu'une instruction HTTP return a été traitée.

 SC   Le serveur ou un équipement situé entre celui-ci et HAProxy a explicitement refusé la connexion TCP (le proxy a reçu un message TCP RST ou un message ICMP en retour). Dans certaines circonstances, cela peut également provenir de la pile réseau qui informe le proxy que le serveur est injoignable (par exemple, absence de route ou absence de réponse ARP sur le réseau local). Lorsqu'une telle situation se produit en mode HTTP, le code de statut est probablement un 502 ou un 503.

 sC   Le délai d'expiration « connect » est déclenché avant la finalisation de la connexion au serveur. Lorsqu'il se produit en mode HTTP, le code de statut est probablement 503 ou 504.

 SD   La connexion au serveur s'est interrompue avec une erreur pendant le transfert de données. Cela signifie généralement que HAProxy a reçu un RST du serveur ou un message ICMP d'un équipement intermédiaire pendant l'échange de données avec le serveur. Cela peut être dû à un plantage du serveur ou à une panne réseau sur un équipement intermédiaire.

 sD   Le serveur n'a ni envoyé ni reconnu de données pendant une durée égale au paramètre « timeout server » durant la phase de données. Cela est souvent dû à des délais d'expiration trop courts sur l'équipement L4 situé avant le serveur (pare-feux, équilibreurs de charge, ...), ainsi qu'à l'expiration des sessions keep-alive entre le client et le serveur, qui se produit avant HAProxy.

 SH   Le serveur a interrompu l'envoi de ses en-têtes de réponse HTTP complets, ou il s'est arrêté de manière anormale pendant le traitement de la requête. Étant donné qu'une interruption du serveur à ce stade est très rare, il est recommandé d'examiner les journaux du serveur afin de vérifier s'il s'est arrêté de manière anormale et pourquoi. La requête journalisée peut indiquer un petit ensemble de requêtes défectueuses, révélant des bogues dans l'application. Parfois, cela peut également être dû à un système de détection d'intrusions (IDS) qui a interrompu la connexion entre HAProxy et le serveur.

 sH   Le délai d'expiration « server » a été atteint avant que le serveur ne puisse renvoyer ses en-têtes de réponse. Il s'agit de l'anomalie la plus fréquente, indiquant des transactions trop longues, probablement causées par une saturation du serveur ou de la base de données. La solution de contournement immédiate consiste à augmenter le paramètre « timeout server », mais il est important de garder à l'esprit que l'expérience utilisateur sera affectée par ces temps de réponse longs. La seule solution à long terme consiste à corriger l'application.

 sQ   Le flux a passé trop de temps dans la file d'attente et a expiré. Consultez les paramètres « timeout queue » et « timeout connect » pour savoir comment résoudre ce problème s'il se produit trop fréquemment. Si cela se produit régulièrement et massivement sur de courtes périodes, cela peut indiquer des problèmes généraux sur les serveurs concernés dus à une congestion d'E/S ou de base de données, ou à une saturation causée par des attaques externes.

 PC   Le proxy a refusé d'établir une connexion avec le serveur car la limite de sockets du processus a été atteinte lors de la tentative de connexion. Le paramètre global « maxconn » peut être augmenté dans la configuration afin d'éviter que cela ne se reproduise. Ce statut est très rare et peut survenir lorsque le paramètre global « ulimit-n » est fixé manuellement.

 PD   Le proxy a bloqué un message encodé en tronçons mal formaté dans une requête ou une réponse, après que le serveur a émis ses en-têtes. Dans la plupart des cas, cela indique un message invalide émis par le serveur vers le client. HAProxy prend en charge des tailles de tronçons allant jusqu'à 2 Go - 1 (2147483647 octets). Toute taille supérieure sera considérée comme une erreur.

 PH   Le proxy a bloqué la réponse du serveur, car elle était invalide, incomplète, dangereuse (contrôle de mise en cache) ou correspondait à un filtre de sécurité. Dans tous les cas, une erreur HTTP 502 est renvoyée au client. Une cause possible de cette erreur est une syntaxe incorrecte dans un nom d’en-tête HTTP contenant des caractères non autorisés. Il est également possible, bien que peu probable, que le proxy ait bloqué une requête codée en chunked depuis le client en raison d'une syntaxe invalide, avant que le serveur ne réponde. Dans ce cas, une erreur HTTP 400 est renvoyée au client et signalée dans les journaux. Enfin, cela peut être dû à un échec de réécriture d’en-tête HTTP dans la réponse. Dans ce cas, une erreur HTTP 500 est renvoyée (voir "tune.maxrewrite" et « http-response strict-mode » pour plus d’informations).

 PR   Le proxy a bloqué la requête HTTP du client, soit en raison d'une syntaxe HTTP invalide, auquel cas il a renvoyé une erreur HTTP 400 au client, soit en raison d'un filtre de refus correspondant, auquel cas il a renvoyé une erreur HTTP 403. Il peut également s'agir d'une erreur de réécriture d'en-tête HTTP sur la requête. Dans ce cas, une erreur HTTP 500 est envoyée (voir "tune.maxrewrite" et « http-request strict-mode » pour plus d'informations).

 PT   Le proxy a bloqué la requête du client et a appliqué une tarpitation à la connexion avant de la renvoyer avec une erreur serveur 500. Aucune donnée n'a été envoyée au serveur. La connexion est restée ouverte aussi longtemps que l'indique le champ du minuteur "Tw".

 RC   Une ressource locale a été épuisée (mémoire, sockets, ports sources),
      empêchant la connexion au serveur d'être établie. Les journaux d'erreurs
      indiqueront précisément quelle ressource manquait. Ce cas est très rare
      et ne peut être résolu que par une adaptation appropriée du système.

La combinaison des deux derniers indicateurs fournit de nombreuses informations sur la manière dont la persistance a été gérée par le client, le serveur et HAProxy. Cela est très important pour diagnostiquer les déconnexions lorsque les utilisateurs déclarent devoir se réauthentifier. Les indicateurs couramment rencontrés sont :

--   Persistence cookie is not enabled.

NN   No cookie was provided by the client, none was inserted in the
     response. For instance, this can be in insert mode with "postonly"
     set on a GET request.

II   A cookie designating an invalid server was provided by the client,
     a valid one was inserted in the response. This typically happens when
     a "server" entry is removed from the configuration, since its cookie
     value can be presented by a client when no other server knows it.

NI   No cookie was provided by the client, one was inserted in the
     response. This typically happens for first requests from every user
     in "insert" mode, which makes it an easy way to count real users.

VN   A cookie was provided by the client, none was inserted in the
     response. This happens for most responses for which the client has
     already got a cookie.

VU   A cookie was provided by the client, with a last visit date which is
     not completely up-to-date, so an updated cookie was provided in
     response. This can also happen if there was no date at all, or if
     there was a date but the "maxidle" parameter was not set, so that the
     cookie can be switched to unlimited time.

EI   A cookie was provided by the client, with a last visit date which is
     too old for the "maxidle" parameter, so the cookie was ignored and a
     new cookie was inserted in the response.

OI   A cookie was provided by the client, with a first visit date which is
     too old for the "maxlife" parameter, so the cookie was ignored and a
     new cookie was inserted in the response.

DI   The server designated by the cookie was down, a new server was
     selected and a new cookie was emitted in the response.

VI   The server designated by the cookie was not marked dead but could not
     be reached. A redispatch happened and selected another one, which was
     then advertised in the response.

8.6. Caractères non imprimables

Afin d’éviter tout problème avec les outils d’analyse de journaux ou les terminaux lors de la consultation des logs, les caractères non imprimables ne sont pas envoyés tels quels dans les fichiers de journal, mais convertis en représentation hexadécimale sur deux chiffres de leur code ASCII, préfixés par le caractère ‘#’. Les seuls caractères pouvant être journalisés sans échappement sont ceux dont la valeur ASCII se situe entre 32 et 126 (inclus). Évidemment, le caractère d’échappement ‘#’ lui-même est également encodé afin d’éviter toute ambiguïté ("#23"). Il en va de même pour le caractère ‘"’, qui devient “#22”, ainsi que pour ‘{’, ‘|’ et ‘}’ lors de la journalisation des en-têtes.

Notez que le caractère espace (’ ‘) n’est pas encodé dans les en-têtes, ce qui peut poser problème pour les outils s’appuyant sur le décompte des espaces pour localiser les champs. Un en-tête typique contenant des espaces est « User-Agent ».

Enfin, il a été observé que certains démons syslog, tels que syslog-ng, échappent la guillemet (« " ») par une barre oblique inverse (« \ »). L’opération inverse peut être effectuée en toute sécurité, car aucune guillemet ne peut apparaître ailleurs dans les journaux.

8.7. Capture de cookies HTTP

La capture de cookie simplifie le suivi d’une session utilisateur complète. Cela peut être réalisé à l’aide de l’instruction « capture cookie » dans le frontal. Voir section 4.2 pour plus de détails. Une seule cookie peut être capturée, et la même cookie est simultanément vérifiée dans la requête (en-tête « Cookie: ») et dans la réponse (en-tête « Set-Cookie: »). Les valeurs correspondantes seront reportées dans les journaux HTTP aux emplacements “captured_request_cookie” et “captured_response_cookie” (voir section 8.2.3 sur le format des journaux HTTP). Lorsqu’une des cookies n’est pas présente, une tiret (’-’) remplace sa valeur. Ainsi, il est facile de détecter quand un utilisateur passe à une nouvelle session, par exemple, car le serveur lui attribue une nouvelle cookie. Il est également possible de détecter si un serveur définit par erreur une cookie incorrecte pour un client, entraînant une croisement de session.

Exemples :

# capture the first cookie whose name starts with "ASPSESSION"
capture cookie ASPSESSION len 32

# capture the first cookie whose name is exactly "vgnvisitor"
capture cookie vgnvisitor= len 32

Il est possible d’effectuer des captures plus avancées à l’aide des règles « http-request » et « http-response » afin d’attribuer des cookies à des variables de portée « txn ». Les valeurs des cookies peuvent ensuite être extraites à partir de la requête ou de la réponse à l’aide des fonctions d’extraction d’échantillon “req.cook” et “res.cook” (voir section 7.3.6 ) et attribuées à une variable à l’aide des actions « set-var » ou « set-var-fmt » (voir section 4.3 ). Un format de journalisation personnalisé permettra alors de présenter ces variables là où souhaité (voir section 8.2.6 ).

8.8. Capture d’en-têtes HTTP (version ancienne)

Les captures d’en-têtes sont utiles pour suivre des identifiants uniques de requête définis par un proxy supérieur, des noms de virtual host, des user-agents, la longueur du contenu POST, les référents, etc. Dans la réponse, on peut rechercher des informations sur la longueur de la réponse, la manière dont le serveur a demandé au cache de se comporter, ou l’emplacement d’un objet lors d’une redirection.

Il existe deux façons de capturer des en-têtes. La méthode moderne consiste à définir des variables à partir des en-têtes à capturer, ou à partir d’échantillons composés retournés par “req.hdr_names”, “req.hdrs”, “res.hdr_names”, “res.hdrs” (voir section 7.3.6 ) pour toutes les possibilités. Ces variables peuvent être affectées à des variables de portée « txn » à l’aide des actions « set-var » et « set-var-fmt » des règlesets « http-request » et « http-response » (voir section 4.3 ), puis référencées dans des formats de journalisation personnalisés (voir section 8.2.6 ). Cette méthode est recommandée pour capturer les en-têtes HTTP.

Il existe également la méthode héritée, antérieure aux règles et aux variables http-request, qui ne nécessite pas de modifier le format de journalisation et qui a longtemps été utilisée à la fois pour la journalisation et comme moyen artificiel de transmettre des informations sur une requête tout au long de la transaction HTTP, à l’aide des anciens jeux de règles « capture ». C’est ce qui est décrit dans cette section.

Les captures d’en-têtes héritées sont effectuées à l’aide des instructions « capture request header » et « capture response header » dans le frontal. Veuillez consulter leur définition dans la section 4.2 pour plus de détails.

Il est possible d’inclure à la fois des en-têtes de requête et des en-têtes de réponse en même temps. Les en-têtes inexistants sont enregistrés sous forme de chaînes vides, et si un en-tête apparaît plus d’une fois, seul son dernier occurrence est enregistrée. Les en-têtes de requête sont regroupés entre accolades ‘{’ et ‘}’ dans le même ordre que leur déclaration, et séparés par une barre verticale ‘|’ sans espace. Les en-têtes de réponse suivent la même représentation, mais sont affichés après un espace suivant le bloc d’en-têtes de requête. Ces blocs sont affichés juste avant la requête HTTP dans les journaux.

En tant que cas particulier, il est possible de spécifier la capture d’un en-tête HTTP dans un frontend TCP. Le but est d’autoriser la journalisation des en-têtes qui seront analysés dans un backend HTTP si la requête est ensuite acheminée vers ce backend HTTP.

Exemple :

# This instance chains to the outgoing proxy
listen proxy-out
    mode http
    option httplog
    option logasap
    log global
    server cache1 192.168.1.1:3128

    # log the name of the virtual server
    capture request  header Host len 20

    # log the amount of data uploaded during a POST
    capture request  header Content-Length len 10

    # log the beginning of the referrer
    capture request  header Referer len 20

    # server name (useful for outgoing proxies only)
    capture response header Server len 20

    # logging the content-length is useful with "option logasap"
    capture response header Content-Length len 10

    # log the expected cache behavior on the response
    capture response header Cache-Control len 8

    # the Via header will report the next proxy's name
    capture response header Via len 20

    # log the URL location during a redirection
    capture response header Location len 20
    >>> Aug  9 20:26:09 localhost \
          haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \
          proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \
          {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \
          "GET http://fr.adserver.yahoo.com/"
    >>> Aug  9 20:30:46 localhost \
          haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \
          proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \
          {w.ods.org||} {Formilux/0.1.8|3495|||} \
          "GET http://trafic.1wt.eu/ HTTP/1.1"
    >>> Aug  9 20:30:46 localhost \
          haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \
          proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \
          {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \
          {Apache|230|||http://www.sytadin.} \
          "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"

8.9. Exemples de journaux

Voici des exemples concrets de journaux accompagnés d’une explication. Certains ont été créés manuellement. La partie syslog a été supprimée pour faciliter la lecture. Leur unique objectif est d’expliquer comment les décoder.

>>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http &#92;
      px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 &#92;
      "HEAD / HTTP/1.0"

=> requête longue (6,5 s) entrée manuellement via « telnet ». Le serveur a répondu en 147 ms, et la session s'est terminée normalement ('----')

>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http &#92;
      px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 &#92;
      0/9 "HEAD / HTTP/1.0"

=> Idem, mais la requête a été placée en file d'attente dans la file globale derrière 9 autres requêtes, puis a attendu pendant 1230 ms.
    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \
          px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \
          "GET /image.iso HTTP/1.0"
=> requête pour un transfert de données long. L'option « logasap » a été spécifiée, donc le journal a été généré juste avant le transfert des données. Le serveur a répondu en 14 ms, 243 octets d'en-têtes ont été envoyés au client, et le temps total depuis l'acceptation jusqu'à la première octet de données est de 30 ms.

>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http &#92;
      px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 &#92;
      "GET /cgi-bin/bug.cgi? HTTP/1.0"

=> le proxy a bloqué une réponse serveur soit en raison d'une règle « http-response deny », soit parce que la réponse était mal formatée et non conforme au protocole HTTP, soit parce qu'elle contenait des informations sensibles susceptibles d'être mises en cache. Dans ce cas, la réponse est remplacée par un « 502 mauvais passerelle ». Les indicateurs ("PH--") indiquent que c'est HAProxy qui a décidé de renvoyer le code 502 et non le serveur.

>>> haproxy[18113] : 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http &#92;
      px-http/`<NOSRV>` -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""

=> le client n’a pas terminé sa requête et s’est interrompu lui-même ("C---") après 8,5 s, pendant que le proxy attendait les en-têtes de requête ("-R--"). Aucune donnée n’a été envoyée à aucun serveur.

>>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http &#92;
     px-http/`<NOSRV>` -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""

Le client n’a pas terminé sa requête, qui a été interrompue par le délai d’attente ("c---") après 50 s, pendant que le proxy attendait les en-têtes de la requête ("-R--"). Aucune donnée n’a été envoyée à aucun serveur, mais le proxy a pu renvoyer un code de réponse 408 au client.

>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp &#92;
      px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0

=> Ce journal a été généré avec l'option tcplog. Le client a expiré après 5 secondes ("c----").

>>> haproxy[18989] : 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http &#92;
      px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 &#92;
      0/0 "HEAD / HTTP/1.0"

La requête a pris 3 s pour s’achever (probablement un problème réseau), et la connexion au serveur a échoué ('SC--') après 4 tentatives de 2 s chacune (la configuration indique 'retries 3'), sans réacheminement (sinon, nous aurions vu "/+3"). Le code d’état 503 a été renvoyé au client. Il y avait 115 connexions sur ce serveur, 202 connexions sur ce proxy et 205 au niveau du processus global. Il est possible que le serveur ait refusé la connexion en raison d’un nombre trop élevé de connexions déjà établies.

18 - 9. Filtres pris en charge

Trace, compression, SPOE, cache, FastCGI, OpenTracing et filtres de débit

Voici la liste des filtres officiellement pris en charge, accompagnée de la liste des paramètres qu’ils acceptent. En fonction des options de compilation, certains de ces filtres pourraient être indisponibles. La liste des filtres disponibles est indiquée dans HAProxy -vv.

Voir aussi : « filter »

9.1. Trace

filtre trace [nom <name>] [redirection aléatoire] [nombre maximal de redirections <max>] [affichage hexadécimal]

Arguments :

<name>               is an arbitrary name that will be reported in
                     messages. If no name is provided, "TRACE" is used.

<quiet>              inhibits trace messages.

<random-forwarding>  enables the random forwarding of parsed data. By
                     default, this filter forwards all previously parsed
                     data. With this parameter, it only forwards a random
                     amount of the parsed data.

<max>                is the maximum amount of data that can be forwarded at
                     a time. "max-fwd" option can be combined with the
                     random forwarding. <max> must be an positive integer.
                     0 means there is no limit.

<hexdump>             dumps all forwarded data to the server and the client.

Ce filtre peut servir de base pour développer de nouveaux filtres. Il définit toutes les fonctions de rappel et affiche un message sur le flux d’erreur standard (stderr) contenant des informations utiles pour chacune d’elles. Il peut être utile pour déboguer l’activité d’autres filtres ou, tout simplement, l’activité d’HAProxy.

Utiliser les paramètres <random-parsing> et/ou <random-forwarding> est une bonne manière de tester le comportement d’un filtre qui analyse les données échangées entre un client et un serveur en ajoutant des latences dans le traitement.

9.2. Compression HTTP

filtre comp-req

Active le filtre qui tente explicitement de compresser les requêtes HTTP selon les paramètres « compression ». Définit implicitement « compression direction request ».

filtre comp-res

Active le filtre qui tente explicitement de compresser les réponses HTTP selon les paramètres « compression ». Définit implicitement « compression direction response »

filtre de compression (obsolète)

Alias à des fins de compatibilité descendante, équivalent fonctionnellement à l’activation simultanée des filtres « comp-req » et « comp-res ». Le mot-clé « compression » doit être utilisé pour configurer le comportement approprié :

La compression HTTP a été déplacée dans un filtre à partir de HAProxy 1.7. Le mot-clé « compression » doit toujours être utilisé pour activer et configurer la compression HTTP. Et lorsqu’aucun autre filtre n’est utilisé, cela suffit. Lorsqu’il est utilisé avec le cache ou l’application FCGI activés, cela suffit également. Dans ce cas, la compression est toujours effectuée après que la réponse a été stockée dans le cache. Toutefois, il est obligatoire d’utiliser explicitement une ligne de filtre pour activer la compression HTTP lorsqu’au moins un filtre autre que le cache ou l’application FCGI est utilisé pour le même écouteur/frontal/backend. Il est important de connaître l’ordre d’évaluation des filtres.

Voir également : « compression », section 9.4 concernant le filtre de cache et section 9.5 concernant le filtre fcgi-app.

9.3. Moteur de traitement de flux (SPOE)

filtre spoe [moteur <name>] config <file>

Arguments :

<name>      is the engine name that will be used to find the right scope in
            the configuration file. If not provided, all the file will be
            parsed.

<file>      is the path of the engine configuration file. This file can
            contain configuration of several engines. In this case, each
            part must be placed in its own scope.

Le moteur de traitement de flux (SPOE) est un filtre communiquant avec des composants externes. Il permet de déporter certains traitements spécifiques sur les flux dans les applications hiérarchisées. Ces composants externes et les informations échangées avec eux sont configurés dans des fichiers dédiés, pour la majeure partie. Il nécessite également des backends dédiés, définis dans la configuration HAProxy.

SPOE communique avec les composants externes à l’aide d’un protocole binaire interne, le Stream Processing Offload Protocol (SPOP).

Lorsque le SPOE est utilisé sur un flux, un flux dédié est créé pour gérer la communication avec le composant externe. Le flux principal est le flux parent de ce flux « SPOE ». Cela signifie qu’il est possible de récupérer les variables du flux principal depuis le flux « SPOE ». Voir section 2.8 concernant les variables pour plus de détails.

Pour toute information concernant la configuration SPOE et la spécification SPOP, consultez « doc/SPOE.txt ».

9.4. Mise en cache

filtre cache <name>

Arguments :

<name>      is name of the cache section this filter will use.

Le cache utilise un filtre pour stocker les réponses pouvant être mises en cache. Les règles HTTP « cache-store » et « cache-use » doivent être utilisées pour définir comment et quand utiliser un cache. Par défaut, le filtre correspondant est défini implicitement. Lorsqu’aucun autre filtre que fcgi-app ou compression n’est utilisé, cela suffit. Dans ce cas, le filtre de compression est toujours évalué après le filtre de cache. Toutefois, il est obligatoire d’utiliser explicitement une ligne de filtre pour activer un cache lorsqu’au moins un filtre autre que la compression ou fcgi-app est utilisé pour le même écouteur, frontal ou backend. Il est important de connaître l’ordre d’évaluation des filtres.

Voir également : section 9.2 concernant le filtre de compression, section 9.5 concernant le filtre fcgi-app et section 6 concernant le cache.

9.5. Application Fcgi

filtre fcgi-app <name>

Arguments :

<name>      is name of the fcgi-app section this filter will use.

L’application FastCGI utilise un filtre pour évaluer tous les paramètres personnalisés sur le chemin de la requête, et pour traiter les en-têtes sur le chemin de la réponse. Le <name> doit faire référence à une section fcgi-app existante. La directive « use-fcgi-app » doit être utilisée pour définir l’application à utiliser. Par défaut, le filtre correspondant est implicitement défini. Et lorsqu’aucun autre filtre que le cache ou la compression n’est utilisé, cela suffit. Mais il est obligatoire d’utiliser explicitement une ligne de filtre pour une fcgi-app lorsqu’au moins un filtre autre que la compression ou le cache est utilisé pour le même backend. Il est important de connaître l’ordre d’évaluation des filtres.

Voir également : « use-fcgi-app », section 9.2 concernant le filtre de compression, section 9.4 concernant le filtre de mise en cache et section 10 concernant l’application FastCGI.

9.6. OpenTracing

Le filtre OpenTracing ajoute un support natif de la traçabilité distribuée dans HAProxy. Ce support est activé en envoyant une requête conforme à OpenTracing à l’un des traceurs pris en charge, tels que Datadog, Jaeger, Lightstep ou Zipkin. Veuillez noter : les traceurs ne sont pas listés selon une préférence, mais par ordre alphabétique.

Cette fonctionnalité n’est activée que si HAProxy a été compilé avec USE_OT=1.

L’activation du filtre OpenTracing s’effectue de manière explicite en le spécifiant dans la configuration HAProxy. Si cela n’est pas fait, le filtre OpenTracing ne participe en aucune manière au fonctionnement de HAProxy.

filtre opentracing [id <id>] config <file>

Arguments :

<id>        is the OpenTracing filter id that will be used to find the
            right scope in the configuration file. If no filter id is
            specified, 'ot-filter' is used as default.  If scope is not
            specified in the configuration file, it applies to all defined
            OpenTracing filters.

<file>      is the path of the OpenTracing configuration file. The same
            file can contain configurations for multiple OpenTracing
            filters simultaneously. In that case we do not need to define
            scope so the same configuration applies to all filters or each
            filter must have its own scope defined.

Une documentation plus détaillée relative à l’opération, à la configuration et à l’utilisation du filtre est disponible dans le répertoire addons/ot.

Note : Le filtre OpenTracing ne doit pas être utilisé pour de nouveaux designs, car OpenTracing n’est plus maintenu ni soutenu par ses auteurs. En conséquence, OpenTracing sera déprécié à partir de la version 3.3 et supprimé à partir de la version 3.5. Un filtre de remplacement basé sur OpenTelemetry est disponible depuis la version 3.4, avec des instructions de compilation complètes actuellement disponibles à :

https://github.com/haproxytech/haproxy-opentelemetry/

9.7. Limitation de débit

filter bwlim-in <name> limite-par-défaut <size> période-par-défaut <time> [taille-min <sz>] filter bwlim-out <name> limite-par-défaut <size> période-par-défaut <time> [taille-min <sz>] filter bwlim-in <name> limite <size> clé <pattern> [table <table>] [taille-min <sz>] filter bwlim-out <name> limite <size> clé <pattern> [table <table>] [taille-min <sz>]

Arguments :

<name>      is the filter name that will be used by 'set-bandwidth-limit'
            actions to reference a specific bandwidth limitation filter.

<size>      is max number of bytes that can be forwarded over the period.
            The value must be specified for per-stream and shared bandwidth
            limitation filters. It follows the HAProxy size format and is
            expressed in bytes.

<pattern>   is a sample expression rule as described in section 7.3. It
            describes what elements will be analyzed, extracted, combined,
            and used to select which table entry to update the counters. It
            must be specified for shared bandwidth limitation filters only.

<table>     is an optional table to be used instead of the default one,
            which is the stick-table declared in the current proxy. It can
            be specified for shared bandwidth limitation filters only.

<time>      is the default time period used to evaluate the bandwidth
            limitation rate. It can be specified for per-stream bandwidth
            limitation filters only. It follows the HAProxy time format and
            is expressed in milliseconds.

<min-size>  is the optional minimum number of bytes forwarded at a time by
            a stream excluding the last packet that may be smaller. This
            value can be specified for per-stream and shared bandwidth
            limitation filters. It follows the HAProxy size format and is
            expressed in bytes.

Les filtres de limitation de débit doivent être utilisés pour restreindre la vitesse de transfert des données au niveau du flux. Par extension, de tels filtres limitent la bande passante réseau consommée par une ressource. Plusieurs filtres de limitation de débit peuvent être utilisés. Par exemple, il est possible de définir une limite par adresse source afin de garantir qu’un client ne consomme jamais toute la bande passante réseau, ce qui pourrait pénaliser d’autres clients, et une autre limite par flux afin de pouvoir gérer équitablement plusieurs connexions pour un même client.

L’ordre de définition de ces filtres est important. Si plusieurs filtres de limitation de débit sont activés sur un flux, le filtrage s’applique dans l’ordre de leur définition. Il est également important de comprendre que l’ordre de définition des autres filtres a une influence. Par exemple, selon que le filtre de compression HTTP est défini avant ou après un filtre de limitation de débit, la limite s’appliquera sur le contenu compressé ou non. Il en va de même pour le filtre de mise en cache.

Il existe deux types de filtres de limitation de débit. Le premier impose une limite par défaut et est appliqué par flux. Le second utilise une table de persistance pour appliquer une limite répartie également entre tous les flux partageant la même entrée dans la table.

En outre, selon le mot-clé utilisé pour un filtre, la limitation peut s’appliquer aux données entrantes, reçues du client puis transmises au serveur, ou aux données sortantes, reçues du serveur puis envoyées au client. Utilisez « bwlim-in » pour limiter les données entrantes et « bwlim-out » pour les données sortantes. Dans chaque cas, la limitation s’applique aux données transmises, au niveau du flux.

La limitation de débit est appliquée au niveau du flux et non au niveau de la connexion. Pour les protocoles multiplexés (H2, H3 et FastCGI), les flux de la même connexion peuvent avoir des limites différentes.

Pour un filtre de limitation de débit par flux, les valeurs par défaut de la période et de la limite doivent être définies. Comme leur nom l’indique, il s’agit des valeurs par défaut utilisées pour configurer le débit maximal autorisé pour un flux. Toutefois, pour ce type de filtre et uniquement pour celui-ci, il est possible de redéfinir ces valeurs à l’aide d’expressions d’échantillonnage lorsque le filtre est activé par une action TCP/HTTP « set-bandwidth-limit ».

Pour un filtre de limitation de bande passante partagée, selon qu’il est appliqué sur les données entrantes ou sortantes, le tableau de persistance utilisé doit stocker les informations correspondantes sur le débit en octets. Le compteur “bytes_in_rate(<period>)” doit être stocké afin de limiter les données entrantes, et le compteur “bytes_out_rate(<period>)” doit être utilisé afin de limiter les données sortantes.

Enfin, il est possible de définir le nombre minimum d’octets qu’un filtre de limitation de débit peut transmettre à chaque fois pour un flux donné. Cette option doit être utilisée pour éviter de transmettre une quantité trop faible de données, afin de réduire la charge du processeur. Elle doit être définie avec soin. Une valeur trop faible peut augmenter la charge du processeur. Une valeur trop élevée peut augmenter la latence. Elle est également fortement liée à la limite de débit définie. Si elle est trop proche de la limite de débit, des pauses peuvent survenir afin de ne pas dépasser la limite, car trop d’octets seraient consommés à chaque fois. Elle dépend fortement de la configuration du filtre. Une bonne approche consiste à commencer par une valeur d’environ 2 fois la taille maximale d’un segment TCP (MSS), généralement 2896 octets, puis à l’ajuster après quelques expérimentations.

Exemple :

frontend http
    bind *:80
    mode http

    # If this filter is enabled, the stream will share the download limit
    # of 10m/s with all other streams with the same source address.
    filter bwlim-out limit-by-src key src table limit-by-src limit 10m

    # If this filter is enabled, the stream will be limited to download at 1m/s,
    # independently of all other streams.
    filter bwlim-out limit-by-strm default-limit 1m default-period 1s

    # Limit all streams to 1m/s (the default limit) and those accessing the
    # internal API to 100k/s. Limit each source address to 10m/s. The shared
    # limit is applied first. Both are limiting the download rate.
    http-request set-bandwidth-limit limit-by-strm
    http-request set-bandwidth-limit limit-by-strm limit 100k if { path_beg /internal }
    http-request set-bandwidth-limit limit-by-src
    ...

backend limit-by-src
    # The stickiness table used by <limit-by-src> filter
    stick-table type ip size 1m expire 3600s store bytes_out_rate(1s)

Voir également : « tcp-request content set-bandwidth-limit », « tcp-response content set-bandwidth-limit », « http-request set-bandwidth-limit » et « http-response set-bandwidth-limit ».

19 - 10. Applications FastCGI

Configuration, paramètres, exemples et limites d’une application FastCGI

HAProxy est capable d’envoyer des requêtes HTTP vers des applications FastCGI Responder. Cette fonctionnalité a été ajoutée à HAProxy 2.1. Pour cela, les serveurs doivent être configurés pour utiliser le protocole FastCGI (en utilisant le mot-clé « proto fcgi » dans la ligne du serveur) et une application FastCGI doit être configurée et utilisée par le backend gérant ces serveurs (en utilisant le mot-clé « use-fcgi-app » dans la section proxy). Plusieurs applications FastCGI peuvent être définies, mais un seul peut être utilisé à la fois par un backend.

HAProxy implémente toutes les fonctionnalités de la spécification FastCGI pour les applications Répondre. En particulier, il est capable de multiplexer plusieurs requêtes sur une connexion simple.

10.1. Configuration

10.1.1. Section fcgi-app

fcgi-app <name>

fcgi-app <name>

Déclare une application FastCGI nommée <name>. Pour être valide, au moins le répertoire racine du document doit être défini.

acl <aclname> <criterion> [flags] [operator] <value> ...

acl <aclname> <criterion> [flags] [operator] <value> ...

Déclarer ou compléter une liste d’accès.

Voir le mot-clé « acl » dans la section 4.2 et la section 7 pour plus de détails sur l’utilisation des ACL. Les ACL définies pour une application FastCGI sont privées. Elles ne peuvent pas être utilisées par toute autre application ou par tout proxy. De la même manière, les ACL définies dans toute autre section ne sont pas utilisables par une application FastCGI. Toutefois, des ACL prédéfinies sont disponibles.

docroot <path>

docroot <path>

Définir la racine des documents sur l’hôte distant. <path> sera utilisé pour construire la valeur par défaut des paramètres FastCGI SCRIPT_FILENAME et PATH_TRANSLATED. Il s’agit d’un paramètre obligatoire.

index <script-name>

index <script-name>

Définir le nom du script qui sera ajouté après une URI se terminant par une barre oblique ("/") pour définir la valeur par défaut du paramètre FastCGI SCRIPT_NAME. Il s’agit d’un paramètre facultatif.

Exemple :

index index.php

log-stderr global

log-stderr global
log-stderr <target> [len <length>] [format <format>]
    [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]

Activez la journalisation des messages STDERR émis par l’application FastCGI.

Voir le mot-clé « log » dans la section 4.2 pour plus de détails. Il s’agit d’un paramètre facultatif. Par défaut, les messages STDERR sont ignorés.

pass-header <name> [ { if | unless } <condition> ]

pass-header <name> [ { if | unless } <condition> ]

Spécifiez le nom d’un en-tête de requête qui sera transmis à l’application FastCGI. Il peut éventuellement être suivi d’une condition basée sur une ACL, auquel cas il ne sera évalué que si la condition est vraie.

La plupart des en-têtes de requête sont déjà accessibles à l’application FastCGI, préfixés par “HTTP_”. Ce directive n’est donc nécessaire que pour transmettre les en-têtes qui sont volontairement omis. Actuellement, les en-têtes « Authorization », « Proxy-Authorization » et les en-têtes hop-by-hop sont omis.

Notez que les en-têtes « Content-type » et « Content-length » ne sont jamais transmis à l’application FastCGI, car ils sont déjà convertis en paramètres.

path-info <regex>

path-info <regex>

Définir une expression régulière pour extraire le nom du script et le chemin d’information à partir du chemin décodé URL. Ainsi, <regex> peut avoir deux captures : la première pour capturer le nom du script et la deuxième pour capturer le chemin d’information. La première est obligatoire, la deuxième est facultative. Cette approche permet d’extraire le nom du script à partir du chemin en ignorant le chemin d’information. Il s’agit d’un paramètre facultatif. Si ce paramètre n’est pas défini, aucune correspondance n’est effectuée sur le chemin, et les paramètres FastCGI PATH_INFO et PATH_TRANSLATED ne sont pas renseignés.

Pour des raisons de sécurité, lorsque cette expression régulière est définie, les caractères de saut de ligne et de caractère nul sont interdits dans le chemin, une fois décodé en URL. La raison de cette limitation est que, faute de quoi, la correspondance échouerait toujours (en raison d’une limitation dans la manière dont les expressions régulières sont exécutées dans HAProxy). Ainsi, si l’un de ces deux caractères est détecté dans le chemin décodé en URL, une erreur est renvoyée au client. Le principe de moindre étonnement s’applique ici.

Exemple :

path-info ^(/.+\.php)(/.*)?$ # both script-name and path-info may be set
path-info ^(/.+\.php)        # the path-info is ignored

option get-values

option get-values
no option get-values

Active ou désactive la récupération des variables relatives à la gestion des connexions.

HAProxy est capable d’envoyer le champ FCGI_GET_VALUES à l’établissement de la connexion afin de récupérer la valeur des variables suivantes :

* FCGI_MAX_REQS     Nombre maximal de requêtes simultanées que cette application acceptera.

* FCGI_MPXS_CONNS   « 0 » si cette application ne multiplexe pas les connexions,
                    « 1 » dans le cas contraire.

Certains applications FastCGI ne prennent pas en charge cette fonctionnalité. D’autres ferment la connexion immédiatement après avoir envoyé leur réponse. Par conséquent, cette option est désactivée par défaut.

Notez que le nombre maximal de requêtes simultanées acceptées par une application FastCGI est une variable de connexion. Elle limite uniquement le nombre de flux par connexion. Si la charge globale doit être limitée sur l’application, les paramètres serveur « maxconn » et « pool-max-conn » doivent être configurés. En outre, si une application ne prend pas en charge la multiplexion de connexions, le nombre maximal de requêtes simultanées est automatiquement fixé à 1.

option keep-conn

option keep-conn
no option keep-conn

Indiquez à l’application FastCGI de maintenir la connexion ouverte ou non après l’envoi d’une réponse.

Si désactivé, l’application FastCGI ferme la connexion après avoir répondu à cette requête. Par défaut, cette option est activée.

option max-reqs <reqs>

option max-reqs <reqs>

Définir le nombre maximum de requêtes simultanées que cette application acceptera.

Cette option peut être remplacée si la variable FCGI_MAX_REQS est récupérée lors de l’établissement de la connexion. En outre, si l’application ne prend pas en charge le multiplexage des connexions, cette option sera ignorée. Valeur par défaut : 1.

option mpxs-conns

option mpxs-conns
no option mpxs-conns

Active ou désactive la prise en charge du multiplexage de connexions.

Cette option peut être remplacée si la variable FCGI_MPXS_CONNS est récupérée lors de l’établissement de la connexion. Elle est désactivée par défaut.

set-param <name> <fmt> [ { if | unless } <condition> ]

set-param <name> <fmt> [ { if | unless } <condition> ]

Définissez un paramètre FastCGI qui doit être transmis à cette application. Sa valeur, définie par <fmt>, doit respecter les règles du format de journalisation personnalisé (voir la section 8.2.6 « Format de journalisation personnalisé »). Elle peut éventuellement être suivie d’une condition basée sur une ACL, auquel cas elle ne sera évaluée que si la condition est vraie.

Avec cette directive, il est possible de remplacer la valeur des paramètres FastCGI par défaut. Si la valeur est évaluée à une chaîne vide, la règle est ignorée. Ces directives sont évaluées dans l’ordre de leur déclaration.

Exemple :

# PHP only, required if PHP was built with --enable-force-cgi-redirect
set-param REDIRECT_STATUS 200

set-param PHP_AUTH_DIGEST %[req.hdr(Authorization)]

10.1.2. Section proxy

use-fcgi-app <name> Définir l’application FastCGI à utiliser pour le backend.

Arguments :

<name>    is the name of the FastCGI application to use.

Ce mot-clé n’est disponible que pour les proxies HTTP disposant de la capacité backend et comportant au moins un serveur FastCGI. Toutefois, les serveurs FastCGI peuvent être combinés avec des serveurs HTTP. Toutefois, sauf si une bonne raison s’impose, cette configuration n’est pas recommandée (voir section 10.3 pour les détails sur les limitations). Une seule application peut être définie à la fois par backend.

Notez qu’une fois une application FastCGI référencée pour un backend, selon la configuration, un traitement peut être effectué même si la requête n’est pas envoyée à un serveur FastCGI. Les règles permettant de définir des paramètres ou de transmettre des en-têtes à une application sont évaluées.

10.1.3. Exemple

frontend front-http mode http bind *:80 bind *:

  use_backend back-dynamic if { path_reg ^/.+&#92;.php(/.*)?$ }
  default_backend back-static

backend back-static mode http server www A.B.C.D:80

backend back-dynamic mode http use-fcgi-app php-fpm server php-fpm A.B.C.D:9000 proto fcgi

fcgi-app php-fpm log-stderr global option keep-conn

  docroot /var/www/my-app
  index index.php
  path-info ^(/.+&#92;.php)(/.*)?$

10.2. Paramètres par défaut

Un application Répondant FastCGI a le même objectif qu’un programme CGI/1.1. Selon la spécification CGI/1.1 (RFC3875), plusieurs variables doivent être transmises au script. HAProxy les définit donc, ainsi que d’autres variables couramment utilisées par les applications FastCGI. Toutes ces variables peuvent être surchargées, avec prudence toutefois.

  +-------------------+-----------------------------------------------------+
  | AUTH_TYPE         | Identifies the mechanism, if any, used by HAProxy   |
  |                   | to authenticate the user. Concretely, only the      |
  |                   | BASIC authentication mechanism is supported.        |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | CONTENT_LENGTH    | Contains the size of the message-body attached to   |
  |                   | the request. It means only requests with a known    |
  |                   | size are considered as valid and sent to the        |
  |                   | application.                                        |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | CONTENT_TYPE      | Contains the type of the message-body attached to   |
  |                   | the request. It may not be set.                     |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | DOCUMENT_ROOT     | Contains the document root on the remote host under |
  |                   | which the script should be executed, as defined in  |
  |                   | the application's configuration.                    |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | GATEWAY_INTERFACE | Contains the dialect of CGI being used by HAProxy   |
  |                   | to communicate with the FastCGI application.        |
  |                   | Concretely, it is set to "CGI/1.1".                 |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | PATH_INFO         | Contains the portion of the URI path hierarchy      |
  |                   | following the part that identifies the script       |
  |                   | itself. To be set, the directive "path-info" must   |
  |                   | be defined.                                         |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | PATH_TRANSLATED   | If PATH_INFO is set, it is its translated version.  |
  |                   | It is the concatenation of DOCUMENT_ROOT and        |
  |                   | PATH_INFO. If PATH_INFO is not set, this parameters |
  |                   | is not set too.                                     |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | QUERY_STRING      | Contains the request's query string. It may not be  |
  |                   | set.                                                |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | REMOTE_ADDR       | Contains the network address of the client sending  |
  |                   | the request.                                        |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | REMOTE_USER       | Contains the user identification string supplied by |
  |                   | client as part of user authentication.              |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | REQUEST_METHOD    | Contains the method which should be used by the     |
  |                   | script to process the request.                      |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | REQUEST_URI       | Contains the request's URI.                         |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SCRIPT_FILENAME   | Contains the absolute pathname of the script. it is |
  |                   | the concatenation of DOCUMENT_ROOT and SCRIPT_NAME. |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SCRIPT_NAME       | Contains the name of the script. If the directive   |
  |                   | "path-info" is defined, it is the first part of the |
  |                   | URI path hierarchy, ending with the script name.    |
  |                   | Otherwise, it is the entire URI path.               |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SERVER_NAME       | Contains the name of the server host to which the   |
  |                   | client request is directed. It is the value of the  |
  |                   | header "Host", if defined. Otherwise, the           |
  |                   | destination address of the connection on the client |
  |                   | side.                                               |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SERVER_PORT       | Contains the destination TCP port of the connection |
  |                   | on the client side, which is the port the client    |
  |                   | connected to.                                       |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SERVER_PROTOCOL   | Contains the request's protocol.                    |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | SERVER_SOFTWARE   | Contains the string "HAProxy" followed by the       |
  |                   | current HAProxy version.                            |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+
  | HTTPS             | Set to a non-empty value ("on") if the script was   |
  |                   | queried through the HTTPS protocol.                 |
  |                   |                                                     |
  +-------------------+-----------------------------------------------------+

10.3. Limitations

L’implémentation actuelle présente certaines limitations. La première concerne la manière dont certains en-têtes de requête sont masqués aux applications FastCGI. Ce masquage a lieu lors de l’analyse des en-têtes, du côté du backend, avant l’établissement de la connexion. À ce stade, HAProxy sait que le backend utilise une application FastCGI, mais il ne sait pas si la requête sera acheminée vers un serveur FastCGI ou non. Pour masquer les en-têtes de requête, il les supprime simplement du message HTX. Ainsi, si la requête est finalement acheminée vers un serveur HTTP, elle ne les voit jamais. Pour cette raison, il est déconseillé de mixer des serveurs FastCGI et des serveurs HTTP sous le même backend.

De même, les règles « set-param » et « pass-header » sont évaluées lors de l’analyse des en-têtes de requête. L’évaluation est donc toujours effectuée, même si la requête est finalement acheminée vers un serveur HTTP.

À propos des règles « set-param », lorsqu’une règle est appliquée, un en-tête pseudo est ajouté au message HTX. Ainsi, de la même manière que pour les réécritures d’en-têtes HTTP, cela peut échouer si la mémoire tampon est pleine. Les règles « set-param » peuvent entrer en concurrence avec les règles « http-request ».

Enfin, tous les paramètres FastCGI et les en-têtes HTTP sont envoyés dans un enregistrement unique FCGI_PARAM. Le codage de cet enregistrement doit être effectué en une seule passe, faute de quoi une erreur de traitement est renvoyée. Cela signifie que l’enregistrement FCGI_PARAM, une fois encodé, ne doit pas dépasser la taille d’un tampon. Toutefois, aucune réserve n’est à respecter ici.

20 - 11. Tables de persistance et pairs

Déclarations de stockage de table de persistance et de réplication entre pairs

Les tables de persistance dans HAProxy sont un mécanisme qui permet d’associer un certain nombre d’informations et de métriques à une clé d’un type donné, pendant une durée déterminée après la dernière mise à jour. Cela peut être vu comme une ligne à plusieurs colonnes dans un tableau, où le numéro de ligne est défini par la valeur de la clé, et chaque colonne représente un critère distinct.

Les tables de persistance ont été initialement conçues pour stocker des informations de persistance client-serveur afin de maintenir des sessions persistantes entre ces entités. Un client se connecte ou envoie une requête ; ce client est identifié à l’aide d’un discriminateur (adresse source, cookie, paramètre d’URL) et le serveur sélectionné est stocké en association avec ce discriminateur dans une table de persistance pendant une durée configurable, de manière à ce que les accès ultérieurs provenant du même client soient automatiquement acheminés vers le même serveur, où le client a établi sa session d’application.

Aujourd’hui, les tables de stick peuvent stocker davantage qu’un simple numéro de serveur : des métriques d’activité liées à un client spécifique peuvent être conservées (nombre de requêtes/taux, nombre de connexions/taux, nombre d’octets/taux, etc.), ainsi que certains compteurs d’événements arbitraires (“gpc” pour “Compteurs à usage général”) et certaines étiquettes pour marquer un client selon certaines caractéristiques (“gpt” pour “Étiquettes à usage général”).

Les tables de persistance peuvent être référencées par les directives « stick », utilisées pour la persistance client-serveur, par les règles « track-sc », utilisées pour préciser quelle clé suivre dans quelle table afin de collecter des métriques, ainsi que par plusieurs fonctions d’extraction et convertisseurs pouvant effectuer une recherche immédiate d’une clé donnée afin d’obtenir une métrique ou des données spécifiques. Le principe général est que les mises à jour des tables (gpt/gpc/métriques) ainsi que les recherches d’information de persistance rafraîchissent l’entrée accédée et reportent son expiration, tandis que les recherches effectuées uniquement par les fonctions d’extraction et les convertisseurs n’extraient que les données sans reporter l’expiration de l’entrée.

Afin que le mécanisme puisse évoluer et résister aux rechargements HAProxy et aux basculements, il est possible de partager les mises à jour des tables de persistance avec d’autres nœuds appelés « peers » via le mécanisme « Peers » décrit dans section 11.2 . Afin de paramétrer finement la communication avec les peers, il est également possible de décider qu’une table reçoive uniquement des informations provenant des peers, ou que les mises à jour provenant des peers soient au contraire acheminées vers une autre table.

Enfin, les tables de persistance peuvent être déclarées soit dans les sections proxy (frontaux, backaux) à l’aide du mot-clé « stick-table », où une seule table est autorisée par section et qui prendra le nom de cette section, soit dans les sections peers à l’aide du mot-clé « table » suivi du nom de la table, ce qui permet de déclarer plusieurs tables de persistance dans la même section « peers ». Si plusieurs tables de persistance sont nécessaires, la solution recommandée est généralement de les déclarer dans une section peers (si elles doivent être partagées), ou de créer des sections backend supplémentaires, chacune ne contenant qu’une directive « stick-table ».

11.1. déclaration stick-table

La déclaration d’une table de persistance dans une section proxy (“frontend”, “backend”, “listen”) et dans des sections “peers” est très similaire, les différences étant que celle dans la section peers nécessite un nom obligatoire et ne prend pas d’option “peers”.

Dans une section « frontend », « backend » ou « listen » :

stick-table type <type> size <size> [expire <expire>] [nopurge] [recv-only] [write-to <wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>] [peers <peersect>]

Dans une section « peers » :

table <name> type <type> size <size> [expire <expire>] [nopurge] [recv-only] [write-to <wtable>] [srvkey <srvkey>] [store <data_type>]* [brates-factor <factor>]

Arguments : (les obligatoires en premier, puis triés par ordre alphabétique) :

  • type <type> Cet argument obligatoire définit le type de clé à <type>, qui est généralement un mot simple mais peut également avoir ses propres arguments :

    • ip Ce type doit être évité au profit d’une spécification plus explicite, telle que « ipv4 » ou « ipv6 ». Avant la version 3.2, il était la seule manière de configurer IPv4. À partir de la version 3.2, « ip » est un alias de « ipv4 », qui est préféré. Dans une version future, « ip » correspondra à « ipv6 ». Il est destiné uniquement à faciliter la transition entre les versions antérieures à 3.2 et les versions postérieures à 3.2.

    • ipv4 Une table déclarée avec ce type ne stocke que des adresses IPv4. Ce format est très compact (environ 50 octets par entrée) et permet des recherches d’entrée et des opérations de stockage très rapides, avec un surcoût quasi nul. Il est principalement utilisé pour stocker les adresses IP sources des clients.

    • ipv6 Une table déclarée avec “type ipv6” ne stocke que des adresses IPv6. Cette forme est très compacte (environ 60 octets par entrée) et permet des recherches et des écritures d’entrées très rapides, avec un surcoût quasi nul. Elle est principalement utilisée pour stocker les adresses IP sources des clients.

    • integer Une table déclarée avec “type integer” stockera des entiers 32 bits pouvant représenter un identifiant client trouvé dans une requête, par exemple.

    • chaîne [longueur <len>] Une table déclarée avec le type « chaîne » stockera des sous-chaînes d’une longueur maximale de <len> caractères. Si la chaîne fournie par l’extracteur de motif est plus longue que <len>, elle sera tronquée avant d’être stockée. Lors de la correspondance, au plus <len> caractères seront comparés entre la chaîne dans la table et le motif extrait. Si cette valeur n’est pas spécifiée, la chaîne est automatiquement limitée à 32 caractères. Augmenter cette longueur peut avoir un impact non négligeable sur l’utilisation de la mémoire.

    • binary [len <len>] Une table déclarée avec “type binary” stockera des blocs binaires de <len> octets. Si le bloc fourni par l’extracteur de motif est plus grand que <len>, il sera tronqué avant d’être stocké. Si le bloc fourni par l’expression d’échantillonnage est plus court que <len>, il sera complété par des zéros. Par défaut, la taille du bloc est automatiquement limitée à 32 octets. Augmenter cette taille peut avoir un impact non négligeable sur la consommation mémoire.

  • size <size> Cet argument obligatoire définit le nombre maximum d’entrées pouvant être stockées dans la table à <size>. Cette valeur influence directement l’utilisation de la mémoire. Comptez environ 50 octets par entrée, en plus de la taille de la clé, des métriques éventuellement stockées, ainsi que de la taille d’une chaîne si elle est présente. La taille supporte les suffixes « k », « m », « g » pour les facteurs 2^10, 2^20 et 2^30.

  • expire <delay> Définit la durée maximale de validité d’une entrée dans la table depuis sa création, sa mise à jour avec ’track-sc’ ou sa correspondance via une règle ‘stick match’ ou ‘stick on’. Le délai d’expiration <delay> est défini selon le format temporel standard, de la même manière que les divers délais d’expiration, avec une valeur par défaut en millisecondes. La durée maximale est légèrement supérieure à 24 jours. Voir section 2.5 pour plus d’informations. Si ce délai n’est pas spécifié, les sessions ne s’expirent pas automatiquement, mais les entrées les plus anciennes seront supprimées lors de la création une fois la table pleine. Veillez à ne pas utiliser le paramètre “nopurge” si aucun délai d’expiration n’est spécifié. Note : les convertisseurs ’table_*’ effectuent des recherches mais ne mettent pas à jour le délai d’expiration car ils n’exigent pas ’track-sc’.

  • brates-factor <factor> Spécifie un facteur à appliquer au débit d’octets entrants et sortants. Au lieu de compter chaque octet, des blocs d’octets sont comptés. Internement, les débits sont définis sur des compteurs 32 bits, limitant ceux-ci à environ 4 milliards par période. En utilisant ce paramètre, il devient possible de dépasser cette limite de 4G sur la période définie. Le facteur doit être supérieur à 0 et inférieur ou égal à 1024.

  • nopurge indique que les entrées plus anciennes ne seront pas supprimées lorsque la table est pleine. Si ce paramètre n’est pas spécifié et que la table est pleine lorsque HAProxy souhaite y stocker une entrée, celle-ci supprimera un certain nombre des entrées les plus anciennes afin de libérer de l’espace pour les nouvelles. C’est généralement le comportement souhaité. Dans certains cas spécifiques, il peut être préférable de refuser les nouvelles entrées plutôt que de supprimer les anciennes. Cela peut être le cas lorsque la quantité de données à stocker dépasse largement les limites matérielles, et que l’on préfère ne pas accorder de nouvelles connexions plutôt que de rejeter celles déjà établies. Lorsque ce paramètre est utilisé, assurez-vous de définir correctement le paramètre « expire » (voir ci-dessus).

  • recv-only indique que nous ne prévoyons pas d’utiliser la table pour effectuer des mises à jour, mais uniquement pour récupérer des données provenant d’une instance distante dont nous sommes intéressés. En effet, l’utilisation de ce mot-clé permet de récupérer des valeurs locales telles que “conn_cur”, qui ne sont pas apprises par défaut car elles entreraient en conflit avec les mises à jour locales effectuées sur la table par l’instance locale. Cette option n’est pertinente que pour les tables qui ne participent pas à des règles de suivi ou à des méthodes effectuant des opérations de mise à jour sur la table, ou, dit autrement : des tables distantes utilisées uniquement pour récupérer des informations.

  • peers <peersect> Les entrées créées, mises à jour ou actualisées seront envoyées aux pairs dans la section <peersect> afin de synchroniser les données, et les clés apprises auprès des pairs de cette section seront également insérées ou mises à jour dans la table. En outre, au démarrage, une tentative peut être effectuée pour apprendre les entrées à partir d’une ancienne instance du processus, désignée comme le « pair local » via cette section.

  • srvkey <srvkey> Spécifie la manière dont chaque serveur est identifié dans le cadre de la table de persistance. Les valeurs valides sont « name » et « addr ». Si « name » est indiqué, alors l’argument <name> du serveur (peut être généré par un modèle). Si « addr » est indiqué, alors le serveur est identifié par son adresse réseau actuelle, y compris le port. « addr » est particulièrement utile lorsque vous utilisez la découverte de services pour générer les adresses des serveurs avec des tables de persistance jumelées, et que vous souhaitez utiliser de manière cohérente le même hôte pour un jeton de persistance à travers les pairs.

  • store <data_type> Cette directive permet de stocker des informations supplémentaires dans la table de persistance. Elle peut être utilisée par les ACL afin de contrôler divers critères liés à l’activité du client correspondant à la table de persistance. Pour chaque élément spécifié ici, la taille de chaque entrée sera augmentée afin de permettre l’ajout des données supplémentaires. Plusieurs types de données peuvent être stockés avec une même entrée. Plusieurs types de données peuvent être indiqués après le mot-clé « store », sous forme d’une liste séparée par des virgules. À la place, il est également possible de répéter le mot-clé « store » suivi d’un ou plusieurs types de données. À l’exception du type “server_id”, qui est détecté et activé automatiquement, tous les types de données doivent être explicitement déclarés comme étant stockés. Si une ACL référence un type de données non stocké, l’ACL ne correspondra pas. Certains types de données nécessitent un argument, qui doit être fourni immédiatement après le type, entre parenthèses. Voir ci-dessous la liste des types de données pris en charge ainsi que leurs arguments.

  • write-to <wtable> Spécifie le nom d’une autre table de persistance où les mises à jour des pairs seront écrites en plus de la table source. <wtable> doit être du même type que la table définie et avoir la même longueur de clé, et la table source ne peut pas être utilisée elle-même comme table cible. Chaque fois qu’une mise à jour d’entrée sera reçue sur la table source via un pair, HAProxy tentera de rafraîchir l’entrée correspondante dans <wtable>. Si l’entrée n’existe pas encore, elle sera créée ; sinon, ses valeurs seront mises à jour ainsi que son minuteur. Notez que seuls les types n’impliqués dans aucune opération arithmétique, tels que server_id, server_key et gpt, seront écrits dans <wtable> afin d’éviter que les valeurs traitées provenant d’une table distante n’interfèrent avec les opérations arithmétiques effectuées sur la table cible locale. (Par exemple : empêcher un compteur cumulatif partagé de croître indéfiniment.) Un usage courant de cette option consiste à pouvoir utiliser des règles de persistance (pour la persistance des serveurs) dans une configuration de cluster de pairs, car les clés correspondantes seront apprises à partir des tables distantes.

Les types de données pouvant être associés à une entrée via la directive « store » sont indiqués ci-dessous. Il est important de garder à l’esprit que les besoins en mémoire peuvent être significatifs lors du stockage de nombreux types de données. En effet, le stockage de tous les indicateurs ci-dessous en même temps dans chaque entrée peut nécessiter des centaines d’octets par entrée, ou des centaines de mégaoctets pour une table de 1 million d’entrées. Pour cette raison, la taille de stockage approximative est indiquée ci-dessous pour chaque type, entre parenthèses, après l’argument.

Arguments :

  • bytes_in_cnt [4 octets] Il s’agit du décompte des octets envoyés par le client vers le serveur. Il s’agit d’un entier signé 64 bits positif qui compte le nombre cumulé d’octets reçus des clients correspondant à cette entrée. Les en-têtes sont inclus dans le décompte. Ce compteur peut être utilisé pour limiter l’abus des fonctionnalités de téléchargement sur des serveurs photo ou vidéo. Notez que les valeurs sont mesurées au moment où les données entrent dans HAProxy, les comptes ne sont donc pas affectés par la compression.

  • bytes_in_rate(<period>) [12 octets] Ce compteur de débit indique le débit en octets provenant du client vers le serveur. Il prend un paramètre entier <period> qui indique, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Il rapporte le débit moyen d’octets entrants sur cette période, en octets par période. Il peut être utilisé pour détecter les utilisateurs qui téléchargent trop et trop rapidement. Avertissement : lors de transferts importants, il est possible que la quantité de données téléchargées soit comptabilisée une seule fois à la fin, ce qui peut provoquer des pics dans la vitesse moyenne de transfert au lieu d’une courbe lisse. Ce phénomène peut être partiellement atténué avec l’option contstats, bien que cela ne soit pas parfait. Il est recommandé d’utiliser byte_in_cnt pour une meilleure équité.

  • bytes_out_cnt [4 octets] Il s’agit du décompte des octets envoyés par le serveur vers le client. Il s’agit d’un entier signé 64 bits positif qui compte le nombre cumulé d’octets envoyés aux clients correspondant à cette entrée. Les en-têtes sont inclus dans le décompte. Ce compteur peut être utilisé pour limiter l’abus par des bots consommant l’intégralité du site. Notez que les valeurs sont mesurées au moment où les données entrent dans HAProxy, les comptes ne sont donc pas affectés par la compression.

  • bytes_out_rate(<period>) [12 octets] Ce compteur de taux indique le débit en octets envoyés par le serveur vers le client. Il prend un paramètre entier <period> qui indique, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Il signale le débit moyen d’octets sortants sur cette période, en octets par période. Il peut être utilisé pour détecter les utilisateurs qui téléchargeent trop et trop rapidement. Avertissement : lors de transferts importants, il est possible que la quantité de données transférées soit comptabilisée une seule fois à la fin, ce qui peut provoquer des pics dans la vitesse moyenne de transfert au lieu d’une courbe lisse. Ce phénomène peut être partiellement atténué avec l’option contstats, bien que cela ne soit pas encore parfait. Il est recommandé d’utiliser byte_out_cnt pour une équité meilleure.

  • conn_cnt [4 bytes] Il s’agit du nombre de connexions. Il s’agit d’un entier signé 32 bits positif qui compte le nombre absolu de connexions reçues par les clients correspondant à cette entrée. Cela ne signifie pas que les connexions ont été acceptées, mais simplement qu’elles ont été reçues.

  • conn_cur [4 octets] Il s’agit du compteur de connexions actuelles. Il s’agit d’un entier signé 32 bits positif qui stocke le nombre de connexions simultanées pour l’entrée. Ce compteur est incrémenté une fois qu’une connexion entrante correspond à l’entrée, et décrémenté une fois que la connexion se termine. Ainsi, il est possible de connaître à tout moment le nombre exact de connexions simultanées pour une entrée. Ce type n’est pas par défaut appris à partir d’autres pairs, car cela ne représenterait rien étant donné qu’il ignorerait le compteur local. Toutefois, combiné à recv-only, il peut être utilisé pour apprendre le nombre de connexions simultanées observées par les pairs.

  • conn_rate(<period>) [12 octets] Ce compteur mesure la fréquence des connexions. Il prend un paramètre entier <period>, qui indique en millisecondes la durée de la période sur laquelle la moyenne est calculée. Il rapporte le débit moyen de connexions entrantes sur cette période, en connexions par période. Le résultat est un entier pouvant être utilisé dans des listes de contrôle d’accès (ACL). Le fait qu’une connexion soit acceptée ou rejetée n’affecte pas sa mesure.

  • glitch_cnt [4 octets] Il s’agit du nombre de glitchs côté front. Il s’agit d’un entier signé 32 bits positif qui compte le nombre cumulé de glitchs signalés sur une connexion frontale. Les glitchs correspondent à des actions inhabituelles ou inattendues (au niveau du protocole) provenant du client, pouvant indiquer un client défectueux ou éventuellement un attaquant. Ce compteur peut donc aider à déterminer la manière d’agir en cas de telles situations.

  • taux_erreur(<period>) [12 octets] Ce compteur de fréquence mesure les anomalies. Il prend un paramètre entier <period> qui indique, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Il signale le taux moyen d’anomalies frontales sur cette période. Il peut être utilisé pour détecter des clients défectueux ou des attaquants potentiels effectuant des actions inhabituelles ou inattendues du point de vue du protocole, à condition qu’HAProxy les ait identifiés comme tels.

  • gpc(<nb>) [4 * <nb> octets] Il s’agit d’un tableau d’éléments de compteur généralisé <nb>. Il s’agit d’un tableau d’entiers positifs 32 bits pouvant être utilisés pour compter n’importe quoi. En général, ils seront utilisés comme compteurs incrémentaux sur certaines entrées, par exemple pour indiquer qu’une limite est atteinte et déclencher certaines actions. Ce tableau est limité à un maximum de 100 éléments : gpc0 à gpc99, afin de garantir que la construction d’un message de mise à jour de pair puisse tenir dans le tampon. Les utilisateurs doivent tenir compte du fait qu’un grand nombre de compteurs augmente la taille des données et la charge du trafic lors de l’utilisation du protocole pair, car toutes les données/compteurs sont transmises à chaque mise à jour d’un de ces éléments. Ce type de données exclut l’utilisation des types de données hérités « gpc0 » et « gpc1 » sur la même table. Lorsqu’on utilise le type de données tableau « gpc », toutes les fonctions d’extraction d’échantillon et les actions liées à « gpc0 » et « gpc1 » s’appliquent aux deux premiers éléments de ce tableau.

  • gpc_rate(<nb>,<period>) [12 * <nb> octets] Il s’agit d’un tableau de taux d’incrémentation des compteurs généraux sur une période. Ces éléments sont des entiers 32 bits positifs pouvant être utilisés pour n’importe quelle finalité. Tout comme <gpc>, ils comptabilisent les événements, mais au lieu de conserver un nombre cumulé, ils maintiennent le taux auquel le compteur est incrémenté. En général, il est utilisé pour mesurer la fréquence d’apparition d’événements spécifiques (par exemple, les requêtes vers une URL spécifique). Ce tableau est limité à un maximum de 100 éléments : gpt(100), permettant le stockage de gpc0 à gpc99, afin de garantir que la construction d’un message de mise à jour de pair puisse tenir dans le tampon. Le tableau ne peut pas contenir moins d’un élément : utilisez gpc(1) si vous souhaitez stocker uniquement le compteur gpc0. Les utilisateurs doivent prendre en compte qu’un grand nombre de compteurs augmente la taille des données et la charge du trafic lors de l’utilisation du protocole pair, car toutes les données/compteurs sont transmises à chaque mise à jour d’un de ces éléments. Ce type de données exclut l’utilisation des anciens types de données ‘gpc0_rate’ et ‘gpc1_rate’ sur la même table. En utilisant le type de données ‘gpc_rate’ tableau, toutes les opérations de récupération et les actions liées à ‘gpc0’ et ‘gpc1’ s’appliquent aux deux premiers éléments de ce tableau.

  • gpc0 [4 octets] Il s’agit du premier compteur général. Il s’agit d’un entier positif sur 32 bits pouvant être utilisé pour toute finalité. En général, il sera utilisé pour ajouter une étiquette particulière à certaines entrées, par exemple pour indiquer qu’un comportement spécifique a été détecté et doit être pris en compte pour les correspondances ultérieures.

  • gpc0_rate(<period>) [12 octets] Ce paramètre correspond au taux d’incrémentation du premier compteur généralisé sur une période. Il s’agit d’un entier positif sur 32 bits pouvant être utilisé à n’importe quelle fin. Tout comme <gpc0>, il compte les événements, mais au lieu de maintenir un total cumulé, il conserve le taux auquel le compteur est incrémenté. Il est généralement utilisé pour mesurer la fréquence d’apparition d’événements spécifiques (par exemple, les requêtes adressées à une URL précise).

  • gpc1 [4 octets] Il s’agit du deuxième compteur généralisé. Il s’agit d’un entier positif sur 32 bits pouvant être utilisé pour toute finalité. En général, il sera utilisé pour ajouter une étiquette particulière à certaines entrées, par exemple pour indiquer qu’un comportement spécifique a été détecté et doit être pris en compte pour des correspondances ultérieures.

  • gpc1_rate(<period>) [12 octets] Ce paramètre correspond au taux d’incrémentation du deuxième Compteur généralisé sur une période donnée. Il s’agit d’un entier positif sur 32 bits pouvant être utilisé à n’importe quelle fin. Tout comme <gpc1>, il compte les événements, mais au lieu de maintenir un total cumulé, il conserve le taux auquel le compteur est incrémenté. Il est généralement utilisé pour mesurer la fréquence d’apparition d’événements spécifiques (par exemple, les requêtes adressées à une URL précise).

  • gpt(<nb>) [4 * <nb> octets] Il s’agit d’un tableau de <nb> éléments de balises générales. Il s’agit d’un tableau d’entiers signés 32 bits positifs pouvant être utilisés à n’importe quelle fin. En général, ces balises servent à marquer certaines entrées, par exemple pour indiquer qu’un comportement spécifique a été détecté et doit être pris en compte lors de correspondances ultérieures. Ce tableau est limité à un maximum de 100 éléments : gpt(100), permettant de stocker les balises gpt0 à gpt99, afin de garantir que la construction d’un message de mise à jour pair puisse tenir dans le tampon. Le tableau ne peut contenir moins d’un élément : utilisez gpt(1) si vous souhaitez stocker uniquement la balise gpt0. Les utilisateurs doivent tenir compte du fait qu’un grand nombre de compteurs augmentera la taille des données et la charge du trafic lors de l’utilisation du protocole pair, car toutes les données/compteurs sont transmises à chaque mise à jour d’un de ces éléments. Ce type de données exclut l’utilisation du type de données hérité « gpt0 » dans la même table. Lorsque le type de données « gpt » est utilisé, toutes les opérations de récupération et les actions liées à « gpt0 » s’appliquent au premier élément de ce tableau.

  • gpt0 [4 octets] Il s’agit de la première balise générale. Il s’agit d’un entier signé 32 bits positif qui peut être utilisé pour n’importe quelle finalité. En règle générale, il sera utilisé pour ajouter une balise particulière à certaines entrées, par exemple pour indiquer qu’un comportement spécifique a été détecté et doit être pris en compte pour les correspondances futures.

  • http_req_cnt [4 bytes] Ce champ représente le nombre de requêtes HTTP. Il s’agit d’un entier signé 32 bits positif qui compte le nombre absolu de requêtes HTTP reçues depuis les clients correspondant à cette entrée. Il n’est pas tenu compte de la validité de ces requêtes. Notez que cette valeur diffère du nombre de sessions lorsque la fonctionnalité keep-alive est utilisée côté client.

  • http_req_rate(<period>) [12 octets] Ce compteur mesure la fréquence des requêtes. Il prend un paramètre entier <period> qui indique, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Il rapporte le débit moyen de requêtes HTTP sur cette période, en requêtes par période. Le résultat est un entier pouvant être utilisé dans des ACLs. Il n’est pas pertinent qu’il s’agisse de requêtes valides ou non. Notez que cela diffère des sessions lorsque le maintien de connexion (keep-alive) est utilisé côté client.

  • http_err_cnt [4 octets] Ce champ représente le nombre d’erreurs de requête HTTP. Il s’agit d’un entier signé 32 bits positif qui compte le nombre absolu d’erreurs de requêtes HTTP provoquées par des clients correspondant à cette entrée. Les erreurs sont comptabilisées pour les requêtes non valides ou tronquées, ainsi que pour les requêtes refusées ou tarpittées, et pour les échecs d’authentification. Si le serveur répond par un code 4xx, la requête est également comptabilisée comme erreur, car elle est déclenchée par le client (par exemple, une analyse de vulnérabilité).

  • http_err_rate(<period>) [12 octets] Compteur de fréquence des requêtes HTTP. Prend en paramètre un entier <period> indiquant, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Rapporte le taux moyen d’erreurs de requêtes HTTP sur cette période, en requêtes par période (voir http_err_cnt ci-dessus pour la définition des erreurs comptabilisées). Le résultat est un entier pouvant être utilisé dans des ACLs.

  • http_fail_cnt [4 octets] Il s’agit du nombre d’échecs de réponse HTTP. Il s’agit d’un entier signé 32 bits positif qui compte le nombre absolu d’échecs de réponse HTTP provoqués par les serveurs correspondant à cette entrée. Les erreurs sont comptabilisées pour les réponses invalides ou tronquées, ainsi que pour toute réponse 5xx autre que 501 ou 505. Il est destiné à être utilisé en combinaison avec le chemin ou l’URI afin de détecter les pannes de service.

  • http_fail_rate(<period>) [12 octets] Ce compteur mesure la fréquence des échecs de réponse HTTP. Il prend un paramètre entier <period> qui indique, en millisecondes, la durée de la période sur laquelle la moyenne est calculée. Il rapporte le taux moyen d’échecs de réponse HTTP sur cette période, en requêtes par période (voir http_fail_cnt ci-dessus pour la définition d’un échec). Le résultat est un entier pouvant être utilisé dans les ACLs.

  • server_id [4 octets] Il s’agit d’un entier qui contient l’identifiant numérique du serveur vers lequel une requête a été affectée. Il est utilisé par les règles “stick match”, “stick store” et “stick on”. Il est activé automatiquement lorsqu’il est référencé. Il est important de comprendre que la persistance basée sur les informations apprises présente certaines limitations, notamment le fait que toutes les associations apprises sont perdues lors d’un redémarrage, sauf si les pairs sont correctement configurés pour transférer ces informations lors du redémarrage (recommandé). En général, elle peut être utile en complément d’autres mécanismes de persistance, mais pas toujours en tant que mécanisme unique.

  • sess_cnt [4 bytes] Il s’agit du nombre de sessions. Il s’agit d’un entier signé 32 bits positif qui compte le nombre absolu de sessions reçues depuis les clients correspondant à cette entrée. Une session correspond à une connexion acceptée par les règles du niveau 4 (“tcp-request connection”).

  • sess_rate(<period>) [12 octets] Ce compteur mesure la fréquence des sessions. Il prend un paramètre entier <period>, qui indique en millisecondes la durée de la période sur laquelle la moyenne est calculée. Il rapporte le débit moyen des sessions entrantes sur cette période, en sessions par période. Le résultat est un entier pouvant être utilisé dans des listes ACL.

Exemple :

# Keep track of counters of up to 1 million IP addresses over 5 minutes
# and store a general purpose counter and the average connection rate
# computed over a sliding window of 30 seconds.
stick-table type ip size 1m expire 5m store gpc0,conn_rate(30s)

Voir aussi : « stick match », « stick on », « stick store-request », « track-sc », section 2.5 sur le format horaire, section 11.2 sur les pairs, section 9.7 sur les limitations de bande passante, et section 7 sur les listes de contrôle d’accès.

11.2. Déclaration Peers

Il est possible de propager des entrées de tout type de données dans les tables de persistance entre plusieurs instances HAProxy via des connexions TCP, selon une architecture multi-maître. Chaque instance transmet ses mises à jour et insertions locales aux pairs distantes. Les valeurs transmises écrasent celles présentes à distance sans agrégation.

Une exception concerne le type de données “conn_cur”, qui n’est jamais appris auprès des pairs par défaut, car il doit refléter les valeurs locales. Les versions antérieures le synchronisaient par défaut, ce qui était susceptible de provoquer des valeurs négatives dans les configurations actif-actif, ainsi que des valeurs toujours croissantes lors des rechargements ou des basculements actif-passif, car la valeur locale reflétait un nombre de connexions supérieur à celui des connexions locales réelles. Toutefois, certaines configurations peuvent justifier l’apprentissage de cette valeur auprès des pairs, par exemple lorsque la table est une table distante passive utilisée uniquement pour apprendre ou surveiller les données sans en dépendre pour les opérations d’écriture ou les mises à jour. Pour cela, le mot-clé « recv-only » peut être ajouté à la déclaration de la table. Dans tous les cas, les informations “conn_cur” sont toujours transmises afin que les systèmes de surveillance puissent les suivre.

Les échanges interrompus sont automatiquement détectés et récupérés à partir du dernier point connu. En outre, lors d’un redémarrage doux, le processus ancien se connecte au nouveau à l’aide d’une telle connexion TCP pour transmettre toutes ses entrées avant que le nouveau processus ne tente de se connecter aux autres pairs. Cela garantit une réplication très rapide lors d’un rechargement, qui prend généralement une fraction de seconde, même pour de grandes tables.

Notez que les identifiants de serveur sont utilisés pour identifier les serveurs à distance, il est donc important que les configurations soient similaires, ou du moins que les mêmes identifiants soient imposés sur chaque serveur pour tous les participants.

peers <peersect>

peers <peersect>

Crée une nouvelle liste de pairs nommée <peersect>. Il s’agit d’une section indépendante, référencée par une ou plusieurs tables de persistance.

bind [<address>]:port [param*]

bind [<address>]:port [param*]
bind /<path> [param*]

Définit les paramètres de liaison du pair local de cette section « peers ». Ces lignes ne sont pas prises en charge avec une ligne « peer » dans la même section « peers ».

disabled

disabled

Désactive une section peers. Elle désactive à la fois l’écoute et toute synchronisation liée à cette section. Cette option permet de désactiver la synchronisation des tables de persistance sans devoir commenter toutes les références à “peers”.

default-bind [param*]

default-bind [param*]

Définit les paramètres de liaison pour le pair local, à l’exception de son adresse.

default-server [param*]

default-server [param*]

Modifie les options par défaut pour un serveur dans une section « peers ».

Arguments :

<param*>  is a list of parameters for this server. The "default-server"
          keyword accepts an important number of options and has a complete
          section dedicated to it. In a peers section, the transport
          parameters of a "default-server" line are supported. Please refer
          to section 5 for more details, and the "server" keyword below in
          this section for some of the restrictions.

Voir également : « server » et section 5 concernant les options du serveur

enabled

enabled

Cela réactive une section peers qui était précédemment désactivée via le mot-clé « disabled ».

log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]

log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
    <facility> [<level> [<minlevel>]]

Les sections « peers » prennent en charge le mot-clé « log » identique à celui des proxies pour journaliser des informations concernant l’écouteur « peers ». Voir l’option « log » des proxies pour plus de détails.

peer <peername> [<address>]:port [param*]

peer <peername> [<address>]:port [param*]
peer <peername> /<path> [param*]

Définit un pair au sein d’une section peers. Si <peername> est défini sur le nom du pair local (par défaut, hostname, ou forcé à l’aide de l’option en ligne de commande “-L” ou de l’option de configuration globale localpeer), HAProxy écoutera les connexions entrantes du pair distant sur l’adresse fournie. Sinon, l’adresse définit l’emplacement vers lequel se connecter pour rejoindre le pair distant, et <peername> est utilisé au niveau du protocole pour identifier et valider le pair distant côté serveur.

Lors d’un redémarrage doux, l’adresse locale du pair est utilisée par l’instance ancienne pour se connecter à la nouvelle et initier une réplication complète (processus d’enseignement).

Il est fortement recommandé d’avoir une déclaration de pairs identique sur tous les pairs et de ne s’appuyer que sur l’argument en ligne de commande “-L” ou sur le paramètre de configuration globale “localpeer” pour modifier le nom du pair local. Cela facilite la maintenance de fichiers de configuration cohérents sur l’ensemble des pairs.

Vous pouvez souhaiter référencer certaines variables d’environnement dans le paramètre d’adresse, voir section 2.3 concernant les variables d’environnement.

Note : le mot-clé « peer » peut être remplacé de manière transparente par le mot-clé « server » (voir l’explication du mot-clé « server » ci-dessous).

server <peername> [<address>:<port>] [param*]

server <peername> [<address>:<port>] [param*]
server <peername> [/<path>] [param*]

Comme mentionné précédemment, le mot-clé « peer » peut être remplacé par le mot-clé « server », avec prise en charge de tous les paramètres « server » décrits au paragraphe 5.2 qui concernent les paramètres de transport. Si le pair sous-jacent est local, le paramètre address ne doit pas être présent ; il doit être fourni sur une ligne « bind » (voir le mot-clé « bind » de cette section « peers »).

Un certain nombre de paramètres « server » sont sans effet dans les sections « peers ». Par nature, les pairs ne prennent pas en charge la résolution dynamique des noms d’hôte ni les contrôles d’état, aussi les paramètres tels que “init_addr”, « resolvers », « check », « agent-check » ou « track » ne sont pas pris en charge. De même, il n’y a ni répartition de charge ni persistance de session, les paramètres comme « weight » ou « cookie » n’ont donc aucun effet.

Exemple :

 # The old way.
 peers mypeers
     peer haproxy1 192.168.0.1:1024
     peer haproxy2 192.168.0.2:1024
     peer haproxy3 10.2.0.1:1024

 backend mybackend
     mode tcp
     balance roundrobin
     stick-table type ip size 20k peers mypeers
     stick on src

     server srv1 192.168.0.30:80
     server srv2 192.168.0.31:80

Example:
  peers mypeers
     bind 192.168.0.1:1024 ssl crt mycerts/pem
     default-server ssl verify none
     server haproxy1 #local peer
     server haproxy2 192.168.0.2:1024
     server haproxy3 10.2.0.1:1024

shards <shards>

Dans certaines configurations, on souhaite distribuer le contenu de la table de persistance à certains pairs au lieu d’envoyer l’intégralité du contenu de la table à chaque pair déclaré dans la section « peers ». Dans de tels cas, le paramètre « shards » indique le nombre de pairs impliqués dans cette distribution du contenu de la table de persistance. Voir également le paramètre serveur « shard ».

table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]}

table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]}
  size `<size>` [expire `<expire>`] [write-to `<wtable>`] [nopurge] [store `<data_type>`]*
  [recv-only]

Configurez une table de persistance pour la section courante. Cette ligne est analysée exactement de la même manière que le mot-clé « stick-table » dans les autres sections, à l’exception de l’argument « peers » qui n’est pas requis ici et de l’ajout d’un paramètre obligatoire en premier lieu pour désigner la table de persistance. Contrairement aux autres sections, plusieurs lignes « table » peuvent exister dans les sections « peers » (voir également la définition complète des mots-clés « table » et « stick-table » dans la section 11.1 ci-dessus).

Attention également au fait que les sections « peers » disposent d’un espace de noms propre pour les tables de persistance afin d’éviter les conflits entre des noms de tables identiques dans différentes sections « peers ». Ce mécanisme est géré internement en préfixant le nom des tables de persistance par le nom de la section « peers », suivi d’un caractère « / ». Si, ailleurs dans le fichier de configuration, vous devez faire référence à une table de persistance déclarée dans une section « peers », vous devez utiliser la version préfixée du nom de la table, comme suit :

peers mypeers
    peer A ...
    peer B ...
    table t1 ...

frontend fe1
    tcp-request content track-sc0 src table mypeers/t1

Il s’agit également de la version préfixée des noms de tables de persistance, qui doit être utilisée pour faire référence aux tables de persistance via l’interface en ligne de commande.

À propos du protocole « peers », comme seuls les « peers » appartenant à la même section peuvent communiquer entre eux, il n’est pas nécessaire de faire cette distinction. Plusieurs sections « peers » peuvent déclarer des tables de persistance avec le même nom. Il s’agit d’une version raccourcie du nom de la table de persistance transmise sur le réseau. Un seul caractère « / » est utilisé comme préfixe afin d’éviter les conflits de noms entre les tables de persistance déclarées en tant que backends et les tables de persistance déclarées dans les sections « peers », comme illustré dans cette configuration étrange mais prise en charge :

peers mypeers
    peer A ...
    peer B ...
    table t1 type string size 10m store gpc0

backend t1
    stick-table type string size 10m store gpc0 peers mypeers

Ici, la table « t1 » déclarée dans la section « mypeers » a pour nom global « mypeers/t1 ». La table « t1 » déclarée en tant que backend porte également le nom global « t1 ». Toutefois, au niveau du protocole pair, la première table est nommée « /t1 », la seconde est à nouveau nommée « t1 ».

21 - 12. Autres sections

Suivi, utilisateurs, courriels, erreurs, anneaux, certificats, ACME et contrôles d’état globaux

Les sections décrites ci-dessous sont moins couramment utilisées et ne prennent généralement en charge qu’un petit nombre de paramètres. Il n’existe aucune relation implicite entre elles. Elles sont toutes initiales à l’aide d’un mot-clé unique. Aucune d’entre elles n’est autorisée avant une section « global ». Le support de certaines d’entre elles peut être conditionné par des options de compilation (par exemple, tout ce qui est lié au SSL).

12.1. Traces

À des fins de débogage, il est possible d’activer des traces sur un sous-système d’HAProxy. Cela permet d’afficher des messages de débogage relatifs à un sous-système spécifique. Il s’agit d’un outil très puissant pour diagnostiquer les problèmes. Les traces peuvent être configurées dynamiquement via l’interface CLI. Il est également possible de préconfigurer certaines options dans le fichier de configuration, dans des sections dédiées « traces ». Des informations complémentaires sur les traces sont disponibles dans le guide de gestion. Il s’agit d’un outil destiné aux développeurs, utilisé lors de sessions de débogage complexes. Il est très verbeux et coûteux en ressources, donc à utiliser avec précaution. En tant qu’outil destiné aux développeurs, aucune garantie de compatibilité descendante n’est assurée pour cette section.

traces

traces

Démarre une nouvelle section traces. Une ou plusieurs sections « traces » peuvent être utilisées. Toutes les directives sont évaluées dans l’ordre déclaré, les dernières remplaçant les précédentes.

trace <source> <args...>

trace <source> <args...>

Configure le sous-système « trace ». Chacun d’eux peut être trouvé dans le manuel de gestion et suit la même syntaxe exacte. Toute sortie que la commande « trace » produirait sera émise pendant l’étape d’analyse de la section. La plupart du temps, il s’agira d’erreurs et d’avertissements, mais certaines commandes incomplètes peuvent lister les choix autorisés. Cette commande n’est pas destinée à une utilisation régulière ; elle sera généralement proposée uniquement par les développeurs lors de sessions de débogage complexes. Il est important de garder à l’esprit que, selon le niveau de traçage et les détails activés, l’activation des traces peut fortement dégrader les performances globales. Veuillez vous référer au manuel de gestion pour la syntaxe des instructions.

Exemple :

ring buf1
  size 10485760 # 10MB
  format timed
  backing-file /tmp/h1.traces

ring buf2
  size 10485760 # 10MB
  format timed
  backing-file /tmp/h2.traces

traces
  trace h1 sink buf1 level developer verbosity complete start now
  trace h2 sink buf1 level developer verbosity complete start now

12.2. Listes d’utilisateurs

Il est possible de contrôler l’accès aux sections frontend/backend/listen ou à l’interface http stats en n’autorisant que les utilisateurs authentifiés et autorisés. Pour cela, il est nécessaire de créer au moins une liste d’utilisateurs et de définir des utilisateurs.

userlist <listname>

userlist <listname>

Crée une nouvelle liste d’utilisateurs nommée <listname>. Plusieurs listes d’utilisateurs indépendantes peuvent être utilisées pour stocker les données d’authentification et d’autorisation pour des clients indépendants.

group <groupname> [users <user>,<user>,(...)]

group <groupname> [users <user>,<user>,(...)]

Ajoute le groupe <groupname> à la liste d’utilisateurs courante. Il est également possible d’attacher des utilisateurs à ce groupe en utilisant une liste séparée par des virgules de noms précédée du mot-clé « users ».

user <username> [password|insecure-password <password>]

user <username> [password|insecure-password <password>]
                [groups <group>,<group>,(...)]

Ajoute l’utilisateur <username> à la liste des utilisateurs courants. Les mots de passe sécurisés (chiffrés) et les mots de passe non sécurisés (non chiffrés) peuvent être utilisés. Les mots de passe chiffrés sont évalués à l’aide de la fonction crypt(3), ce qui implique que les algorithmes pris en charge dépendent des capacités du système. Par exemple, les systèmes Linux modernes basés sur Glibc prennent en charge MD5, SHA-256, SHA-512, ainsi que bien sûr la méthode classique basée sur DES pour le chiffrement des mots de passe.

Attention : la utilisation de mots de passe chiffrés peut entraîner une augmentation significative de la charge CPU, selon le nombre de requêtes et l’algorithme utilisé. Pour chacune des variantes hachées, le mot de passe de chaque requête doit être traité par l’algorithme choisi avant de pouvoir être comparé à la valeur spécifiée dans le fichier de configuration. La plupart des algorithmes actuels sont délibérément conçus pour être coûteux à calculer afin de résister aux attaques par force brute. Ils ne limitent pas à saler/hacher le mot de passe en clair une seule fois, mais le font des milliers de fois. Cela peut rapidement devenir un facteur majeur de la consommation CPU globale de HAProxy, et même entraîner des crashs d’applications !

Pour réduire l’utilisation élevée du processeur par les fonctions de hachage, une solution consiste à réduire le nombre d’itérations de la fonction de hachage (algorithmes de la famille SHA) ou à diminuer le « coût » de la fonction, si l’algorithme le permet.

En complément, les implémentations basées sur musl (par exemple, Alpine Linux) sont connues pour être plus lentes que leurs homologues glibc lors du calcul des hachages, vous devriez donc également prendre en compte cet aspect.

Tous les mots de passe sont considérés comme des arguments normaux et sont donc soumis à la section 2.2 Quotations et échappements . Il est donc recommandé de citer les mots de passe entre guillemets simples.

Exemple :

userlist L1
  group G1 users tiger,scott
  group G2 users xdb,scott

  user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91
  user scott insecure-password 'elgato'
  user xdb insecure-password 'hello'

userlist L2
  group G1
  group G2

  user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
  user scott insecure-password 'elgato' groups G1,G2
  user xdb insecure-password 'hello' groups G2

Veuillez noter que les deux listes sont fonctionnellement identiques.

12.3. Mailers

Il est possible d’envoyer des alertes par courrier électronique lorsque l’état des serveurs change. Si les alertes par courrier électronique sont configurées, celles-ci sont envoyées à chaque serveur de messagerie défini dans une section mailers. Les courriers sont envoyés aux serveurs de messagerie via Lua (voir examples/lua/mailers.lua).

mailers <mailersect>

mailers <mailersect>

Crée une nouvelle liste de messagerie nommée <mailersect>. Il s’agit d’une section indépendante référencée par un ou plusieurs proxies.

mailer <mailername> <ip>:<port>

mailer <mailername> <ip>:<port>

Définit un serveur de messagerie dans une section mailers.

Exemple :

global
    # mailers.lua file as provided in the git repository
    # adjust path as needed
    lua-load examples/lua/mailers.lua

mailers mymailers
    mailer smtp1 192.168.0.1:587
    mailer smtp2 192.168.0.2:587

backend mybackend
    mode tcp
    balance roundrobin

    email-alert mailers mymailers
    email-alert from test1@horms.org
    email-alert to test2@horms.org

    server srv1 192.168.0.30:80
    server srv2 192.168.0.31:80

timeout mail <time>

timeout mail <time>

Définit le délai disponible pour établir une connexion mail et envoyer les données au serveur de messagerie. Si ce paramètre n’est pas défini, la valeur par défaut est de 10 secondes. Pour permettre l’envoi d’au moins deux paquets SYN-ACK pendant la négociation TCP initiale, il est recommandé de maintenir cette valeur au-dessus de 4 secondes.

Exemple :

mailers mymailers
    timeout mail 20s
    mailer smtp1 192.168.0.1:587

12.4. Erreurs HTTP

Il est possible de déclarer globalement plusieurs groupes d’erreurs HTTP, pouvant être importés ultérieurement dans n’importe quelle section proxy. Un même groupe peut être référencé à plusieurs endroits et être importé entièrement ou partiellement.

http-errors <name>

http-errors <name>

Créez un nouveau groupe d’erreurs HTTP nommé <name>. Il s’agit d’une section indépendante pouvant être référencée par un ou plusieurs proxies à l’aide de son nom.

errorfile <code> <file>

errorfile <code> <file>

Associer le contenu d’un fichier à un code d’erreur HTTP

Arguments :

<code>    is the HTTP status code. Currently, HAProxy is capable of
          generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410,
          425, 429, 500, 501, 502, 503, and 504.

<file>    designates a file containing the full HTTP response. It is
          recommended to follow the common practice of appending ".http" to
          the filename so that people do not confuse the response with HTML
          error pages, and to use absolute paths, since files are read
          before any chroot is performed.

Veuillez vous référer à la directive « errorfile » dans la section 4 pour plus de détails.

Exemple :

http-errors website-1
    errorfile 400 /etc/haproxy/errorfiles/site1/400.http
    errorfile 404 /etc/haproxy/errorfiles/site1/404.http
    errorfile 408 /dev/null  # work around Chrome pre-connect bug

http-errors website-2
    errorfile 400 /etc/haproxy/errorfiles/site2/400.http
    errorfile 404 /etc/haproxy/errorfiles/site2/404.http
    errorfile 408 /dev/null  # work around Chrome pre-connect bug

12.5. Anneaux

Il est possible de déclarer globalement des tampons anneau, destinés à être utilisés comme cible pour les serveurs de journaux ou les traces.

ring <ringname>

ring <ringname>

Crée un nouveau tampon anneau nommé <ringname>.

backing-file <path>

backing-file <path>

Cela remplace l’allocation mémoire régulière par un fichier mappé en mémoire RAM pour stocker l’anneau. Cela peut être utile pour collecter des traces ou des journaux destinés à une analyse post-mortem, sans avoir à connecter un client lent à l’interface CLI. Les nouveaux contenus remplacent automatiquement les anciens, de sorte que les derniers contenus sont toujours disponibles. Les contenus écrits dans l’anneau deviennent visibles dans ce fichier une fois le processus arrêté (ils peuvent même apparaître très rapidement, mais aucune garantie n’est donnée, car les écritures ne sont pas synchrones).

Lorsque cette option est utilisée, la taille totale de l’espace de stockage est réduite de la taille du « struct ring » qui commence au début de la zone et qui est nécessaire pour récupérer le contenu de celle-ci. Le fichier sera créé avec les droits du propriétaire initial, avec les permissions 0600, et de la taille configurée par la directive « size ». Lors de l’analyse de la directive (donc même pendant les vérifications de configuration), tout fichier existant non vide sera renommé en ajoutant le suffixe “.bak”, et tout fichier existant précédemment avec le suffixe “.bak” sera supprimé. Cela garantit qu’un rechargement instantané ou un redémarrage du processus ne supprimera pas d’informations de débogage précieuses, et laissera au administrateur le temps de repérer ce nouveau fichier “.bak” et de l’archiver si nécessaire. Ainsi, après une panne, le fichier désigné par <path> contiendra les informations les plus récentes, et si le service est redémarré, le fichier “<path>.bak” les contiendra à la place. Cela signifie que la capacité de stockage totale requise sera le double de la taille de l’anneau. Les échecs de rotation du fichier sont ignorés silencieusement, de sorte que placer le fichier dans un répertoire sans permissions d’écriture suffira à empêcher la création du fichier de sauvegarde si cela n’est pas souhaité.

AVERTISSEMENT : l’utilisation de cette fonctionnalité comporte des implications en matière de stabilité et de sécurité. Premièrement, le sauvegarde de l’anneau sur un périphérique lent (par exemple, un disque dur physique) peut entraîner des ralentissements perceptibles lors des accès, voire des panneaux blancs si trop de threads s’efforcent d’accéder simultanément. Deuxièmement, une modification de la zone par un processus externe peut provoquer la panne du processus HAProxy ou l’écrasement de certaines parties de sa propre mémoire par des traces. Troisièmement, si le système de fichiers est plein avant l’anneau, les écritures dans l’anneau peuvent provoquer la panne du processus.

Les informations présentes dans cet anneau sont structurées et ne sont PAS directement lisibles à l’aide d’un éditeur de texte (même si la majeure partie d’entre elles semble à peine lisible). La sortie de ce fichier est destinée uniquement aux développeurs.

description <text>

description <text>

La description est une chaîne de caractères facultative décrivant l’anneau. Elle s’affiche en ligne de commande. Par défaut, <name> est réutilisé pour remplir ce champ.

format <format>

format <format>

Format utilisé pour stocker les événements dans le tampon anneau.

Arguments :

<format> is the log format used when generating syslog messages. It may be
         one of the following:

  iso     A message containing only the ISO date, followed by the text.
          The PID, process name and system name are omitted. This is
          designed to be used with a local log server.

  local   Analog to rfc3164 syslog message format except that hostname
          field is stripped. This is the default.
          Note: option "log-send-hostname" switches the default to
          rfc3164.

  raw     A message containing only the text. The level, PID, date, time,
          process name and system name are omitted. This is designed to be
          used in containers or during development, where the severity
          only depends on the file descriptor used (stdout/stderr). This
          is the default.

  rfc3164 The RFC3164 syslog message format.
          (https://tools.ietf.org/html/rfc3164)

  rfc5424 The RFC5424 syslog message format.
          (https://tools.ietf.org/html/rfc5424)

  short   A message containing only a level between angle brackets such as
          '<3>', followed by the text. The PID, date, time, process name
          and system name are omitted. This is designed to be used with a
          local log server. This format is compatible with what the systemd
          logger consumes.

 priority A message containing only a level plus syslog facility between angle
          brackets such as '<63>', followed by the text. The PID, date, time,
          process name and system name are omitted. This is designed to be used
          with a local log server.

  timed   A message containing only a level between angle brackets such as
          '<3>', followed by ISO date and by the text. The PID, process
          name and system name are omitted. This is designed to be
          used with a local log server.

maxlen <length>

maxlen <length>

La longueur maximale d’un message d’événement stocké dans l’anneau, y compris l’en-tête formaté. Si un message d’événement est plus long que <length>, il sera tronqué à cette longueur.

server <name> <address> [param*]

server <name> <address> [param*]

Utilisé pour configurer un serveur syslog TCP afin d’envoyer les messages provenant du tampon circulaire. Cela prend en charge tous les paramètres « server » décrits au paragraphe 5.2. Certains de ces paramètres sont sans effet dans les sections « ring ». Point important : il n’y a peu de raisons d’ajouter plus d’un serveur à un tampon, car tous les serveurs reçoivent une copie identique du contenu du tampon, et le tampon progresse donc à la vitesse du serveur le plus lent. Si un serveur ne répond pas, il empêche la suppression des anciens messages et peut bloquer l’insertion de nouveaux messages dans le tampon. La manière correcte d’envoyer des messages à plusieurs serveurs consiste à utiliser un tampon distinct par serveur de journalisation, et non à attacher plusieurs serveurs au même tampon. Notez que la directive spécifique « log-proto » est utilisée pour définir le protocole utilisé pour envoyer les messages.

size <size>

size <size>

Ce paramètre indique la taille facultative, en octets, du tampon anneau. La valeur par défaut est définie à BUFSIZE.

timeout connect <timeout>

timeout connect <timeout>

Définir le temps maximal d’attente pour qu’une tentative de connexion à un serveur aboutisse.

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

timeout server <timeout>

timeout server <timeout>

Définir le temps maximal pendant lequel les données en attente restent dans le tampon de sortie.

Arguments :

<timeout> is the timeout value specified in milliseconds by default, but
          can be in any other unit if the number is suffixed by the unit,
          as explained at the top of this document.

Exemple :

global
    log ring@myring local7

ring myring
    description "My local buffer"
    format rfc5424
    maxlen 1200
    size 32764
    timeout connect 5s
    timeout server 10s
    server mysyslogsrv 127.0.0.1:6514 log-proto octet-count

12.6. Transmission des journaux

Il est possible de déclarer une ou plusieurs sections de transfert de journaux ; HAProxy transmettra tous les messages de journal reçus à une liste de serveurs de journaux.

log-forward <name>

log-forward <name>

Crée un nouveau proxy de transfert de journaux identifié par <name>.

backlog <conns>

backlog <conns>

Indiquez des indices au système concernant la taille approximative du tampon d’écoute souhaitée pour les connexions acceptées.

bind <addr> [param*]

bind <addr> [param*]

Utilisé pour configurer un écouteur de journalisation en flux afin de recevoir les messages à acheminer. Cela prend en charge les paramètres « bind » décrits au paragraphe 5.1, y compris ceux concernant le ssl, mais certaines directives telles que « alpn » peuvent être sans pertinence pour le protocole syslog sur TCP. Ces écouteurs prennent en charge les deux modes « Comptage d’octets » et « Encadrement non transparent » tels qu’ définis dans le rfc-6587.

dgram-bind <addr> [param*]

dgram-bind <addr> [param*]

Utilisé pour configurer un écouteur de journalisation de datagrammes afin de recevoir les messages à acheminer. Les adresses doivent être au format IPv4 ou IPv6, suivies d’un port. Cette option prend en charge certains paramètres « bind » présents dans le paragraphe 5.1, notamment « interface », « namespace » ou « transparent », les autres étant ignorés silencieusement car sans pertinence dans le cas UDP/syslog.

log global

log global
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>]
    <facility> [<level> [<minlevel>]]

Utilisé pour configurer les serveurs de journalisation cibles. Voir les détails supplémentaires dans la documentation des proxies. Si aucun format n’est spécifié, HAProxy tente de conserver le format de journalisation entrant. L’installation de facility est ignorée, sauf si le message entrant ne contient pas de facility, alors qu’une facility est obligatoire dans le format sortant. Si aucune horodatage n’est disponible dans le format d’entrée, mais que le champ existe dans le format de sortie, HAProxy utilisera la date locale.

Exemple :

global
   log stderr format iso local7

ring myring
    description "My local buffer"
    format rfc5424
    maxlen 1200
    size 32764
    timeout connect 5s
    timeout server 10s
    # syslog tcp server
    server mysyslogsrv 127.0.0.1:514 log-proto octet-count

log-forward sylog-loadb
    dgram-bind 127.0.0.1:1514
    bind 127.0.0.1:1514
    # all messages on stderr
    log global
    # all messages on local tcp syslog server
    log ring@myring local0
    # load balance messages on 4 udp syslog servers
    log 127.0.0.1:10001 sample 1:4 local0
    log 127.0.0.1:10002 sample 2:4 local0
    log 127.0.0.1:10003 sample 3:4 local0
    log 127.0.0.1:10004 sample 4:4 local0

maxconn <conns>

maxconn <conns>

Fixer le nombre maximum de connexions simultanées sur un forwarder de journaux. 10 est la valeur par défaut.

timeout client <timeout>

timeout client <timeout>

Définir le délai maximal d’inactivité du côté client.

option assume-rfc6587-ntf

option assume-rfc6587-ntf

Force HAProxy à traiter les flux d’entrée TCP comme utilisant toujours un encadrement non transparent. Cette option simplifie la logique d’encadrement et garantit un traitement cohérent des messages, ce qui est particulièrement utile lors de la gestion de caractères de départ mal formés.

option dont-parse-log

option dont-parse-log

Active la capacité de HAProxy à acheminer des messages syslog sans tenter de les analyser ni de les reformater, ce qui est utile pour acheminer des messages pouvant ne pas respecter les formats traditionnels. Cette option doit être utilisée avec le paramètre format raw sur les cibles de journalisation destination afin de garantir la préservation du contenu original du message.

option host { replace | fill | keep | append }

option host { replace | fill | keep | append }

Définir la stratégie d’hôte à utiliser dans la section log-forward concernant le champ nom d’hôte syslog pour les messages sortants au format rfc3164 ou rfc5424.

  remplacer Si le message d'entrée contient déjà une valeur pour le champ hostname,
  elle est remplacée par l'adresse IP source de l'expéditeur.
  Si le message d'entrée ne contient pas de valeur pour le champ hostname
  (par exemple : '-' dans un message rfc5424, ou un message non conforme rfc3164 ou rfc5424),
  l'adresse IP source de l'expéditeur est utilisée comme valeur du champ hostname.

  fill    Si le message d'entrée contient déjà une valeur pour le champ hostname,
          nous la conservons.
          Si le message d'entrée ne contient pas de valeur pour le champ hostname
          (par exemple : '-' dans un message rfc5424 ou un message non conforme rfc3164 ou rfc5424),
          nous utilisons l'adresse IP source de l'expéditeur comme valeur du champ hostname.
          (This is the default)

  keep    Si le message d'entrée contient déjà une valeur pour le champ hostname,
          nous la conservons.
          Si le message d'entrée ne contient pas de valeur pour le champ hostname,
          nous la définissons sur « localhost » (rfc3164) ou « - » (rfc5424).

  append  Si le message d'entrée contient déjà une valeur pour le champ hostname,
          nous ajoutons une virgule suivie de l'adresse IP de l'expéditeur.
          Si le message d'entrée ne contient pas de valeur pour le champ hostname,
          nous utilisons l'adresse IP source de l'expéditeur.

Pour toutes les options ci-dessus, si l’adresse IP source de l’expéditeur n’est pas disponible (par exemple : socket UNIX/ABNS), la stratégie résultante est « keep ».

Notez que cette option n’est pertinente que pour les formats de journalisation de destination rfc3164 ou rfc5424. Dans les autres cas, son réglage n’aura aucun effet visible.

12.7. Stockage des certificats

HAProxy utilise un mécanisme de stockage interne pour charger et stocker les certificats utilisés dans la configuration. Ce stockage peut être configuré à l’aide d’une section « crt-store ». Elle permet de définir des certificats et les fichiers à charger dans ce stockage. Une définition de certificat doit être écrite avant d’être utilisée ailleurs dans la configuration.

magasin-crt [<name>]

Le paramètre « crt-store » accepte un nom facultatif en argument. Si un nom est spécifié, chaque certificat de ce magasin doit être référencé à l’aide de « @<name>/<crt> » ou de « @<name>/<alias> ».

Les fichiers du magasin de certificats peuvent également être mis à jour dynamiquement via l’interface CLI. Voir « set ssl cert » dans la section 9.3 du guide d’administration.

Les mots-clés suivants sont pris en charge dans la section « crt-store » :

  • crt-base
  • key-base
  • load

crt-base <dir>

crt-base <dir>

Attribue un répertoire par défaut pour récupérer les certificats SSL lorsqu’un chemin relatif est utilisé avec les directives « crt ». Les emplacements absolus spécifiés prennent priorité et ignorent « crt-base ». Lorsqu’il est utilisé dans un bloc « crt-store », le paramètre « crt-base » de la section globale est ignoré.

key-base <dir>

key-base <dir>

Attribue un répertoire par défaut pour récupérer les clés privées SSL lorsque des chemins relatifs sont utilisés avec les directives « key ». Les emplacements absolus spécifiés ont priorité et ignorent « key-base ». Lorsqu’il est utilisé dans un crt-store, la valeur « key-base » de la section globale est ignorée.

load [crt <filename>] [param*]

load [crt <filename>] [param*]

Charger les fichiers SSL dans le magasin de certificats. Pour la liste des paramètres, voir la section « 12.7.1. Options de chargement ».

Exemple :

crt-store
    load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"
    load crt "site2.crt" key "site2.key"

frontend in2
    bind *:443 ssl crt "@/site1" crt "site2.crt"

crt-store web
    crt-base /etc/ssl/certs/
    key-base /etc/ssl/private/
    load crt "site3.crt" alias "site3"
    load crt "site4.crt" key "site4.key"

frontend in2
    bind *:443 ssl crt "@/site1" crt "site2.crt"  crt "@web/site3" crt "@web/site4.crt"

12.7.1. Options de chargement

Charger les fichiers SSL dans le magasin de certificats. Le mot-clé load peut accepter plusieurs paramètres, listés ci-dessous. Ces mots-clés sont également utilisables dans un crt-list.

crt <filename>

crt <filename>

Cet argument est obligatoire ; il charge un fichier PEM qui doit contenir le certificat public, mais peut également inclure les certificats intermédiaires et la clé privée. Si aucune clé privée n’est fournie dans ce fichier, une clé peut être spécifiée à l’aide du mot-clé « key ».

acme <string>

acme <string>

Cette option permet de configurer le protocole ACME pour un certificat donné. Il s’agit d’une fonctionnalité expérimentale qui nécessite la présence du mot-clé « expose-experimental-directives » dans la section globale.

Lorsqu’on utilise le mot-clé « acme » dans un crt-store, il est possible de démarrer sans certificat existant sur le disque. Un couple de clés temporaire sera alors utilisé jusqu’à la génération du certificat ACME. Ce comportement est propre aux crt-store ; ni une ligne crt-list ni une ligne ssl-f-use ne peuvent produire le même résultat sans avoir déclaré au préalable un crt-store.

Voir également Section 12.8 (“ACME”) et « domains » dans cette section.

alias <string>

alias <string>

Argument facultatif. Permet de nommer le certificat avec un alias, afin de pouvoir le référencer par ce dernier dans la configuration. Un alias doit être précédé de ‘@/’ lorsqu’il est appelé ailleurs dans la configuration.

domains <string>

domains <string>

Configurez la liste des domaines utilisés pour les certificats ACME. Le premier domaine de la liste est utilisé comme CN. Les domaines sont séparés par des virgules dans la liste.

Voir également Section 12.8 (“ACME”) et « acme » dans cette section.

Exemple :

load crt "example.com.pem" acme LE domains "bar.example.com,foo.example.com"

ips <string>

ips <string>

Configurez la liste des adresses IP à inclure en tant que SAN IP dans le certificat ACME. Les adresses IP sont séparées par des virgules dans la liste.

La génération d’un certificat avec des adresses IP peut nécessiter l’utilisation du profil « shortlived ».

Voir également Section 12.8 (“ACME”), les champs « acme » et « domains » dans cette section.

Exemple :

load crt "server.pem" acme LE ips "192.0.2.1,2001:db8::1"

key <filename>

key <filename>

Cet argument est facultatif. Chargez une clé privée au format PEM. Si une clé privée était déjà définie dans « crt », elle sera remplacée.

ocsp <filename>

ocsp <filename>

Cet argument est facultatif ; il charge une réponse OCSP au format DER. Il peut être mis à jour via l’interface en ligne de commande.

issuer <filename>

issuer <filename>

Cet argument est facultatif. Chargez l’émetteur OCSP au format PEM. Pour identifier quel certificat une réponse OCSP concerne, le certificat de l’émetteur est nécessaire. Si le certificat de l’émetteur n’est pas trouvé dans le fichier « crt », il peut être chargé à partir d’un fichier avec cet argument.

sctl <filename>

sctl <filename>

Cet argument est facultatif. Le support de l’extension TLS Certificate Transparency (RFC6962) est activé. Le fichier doit contenir une liste valide de timestamps de certificat signés, comme décrit dans la RFC. Le fichier est analysé pour vérifier la syntaxe de base, mais aucune signature n’est vérifiée.

ocsp-update [ off | on ]

ocsp-update [ off | on ]

Active la mise à jour automatique de la réponse OCSP lorsqu’elle est définie sur « on », désactive-la sinon. Sa valeur par défaut est « off ». Pour activer la mise à jour automatique OCSP sur une ligne bind, vous pouvez utiliser cette option dans un crt-store ou utiliser l’option globale “tune.ocsp-update.mode”. Si un certificat donné est utilisé dans plusieurs crt-lists avec des valeurs différentes pour l’option « ocsp-update », une erreur sera générée. De même, si un certificat hérite de l’option globale sur une ligne bind et qu’une option explicite « ocsp-update » incompatible est définie dans un crt-list, la même erreur sera générée.

Exemples :

Voici une configuration exemple permettant de l’activer avec une liste de certificats :

haproxy.cfg :

frontend fe
    bind:443 ssl crt-list haproxy.list

HAProxy.list:

server_cert.pem [ocsp-update on] foo.bar

Voici une configuration exemple permettant de l’activer avec un crt-store :

haproxy.cfg :

crt-store
  load crt foobar.pem ocsp-update on

frontend fe
    bind:443 ssl crt foobar.pem

Lorsque cette option est définie sur « on », une réponse OCSP est tentée à chaque fois qu’une URI OCSP est trouvée dans le certificat du frontal. La seule limitation de ce mode est que l’émetteur du certificat doit être connu afin de construire le certid OCSP. Chaque réponse OCSP sera mise à jour au moins une fois par heure, et plus fréquemment encore si la date d’expiration d’une réponse OCSP est antérieure à cette limite d’une heure. Un intervalle minimum de mise à jour de 5 minutes est toujours respecté afin d’éviter de mettre à jour trop fréquemment des réponses dont la durée de validité est très courte, voire sans champ « Next Update ». En raison de cette limite stricte, veuillez noter qu’en cas de mise à jour automatique activée sur « on », toute réponse OCSP chargée lors de l’initialisation ne sera pas mise à jour avant au moins 5 minutes, même si sa date d’expiration est antérieure à now+5m. Cela ne devrait pas poser de problème majeur, car une réponse OCSP doit être valide au moment du chargement lors de l’initialisation (sa date d’expiration doit être dans le futur), si bien qu’il est peu probable qu’elle expire si rapidement après l’initialisation. En revanche, si un certificat contient une URI OCSP mais aucune réponse OCSP, définir cette option sur « on » pour ce certificat garantira que la réponse OCSP sera automatiquement récupérée juste après l’initialisation. Les délais minimum et maximum par défaut (5 minutes et 1 heure respectivement) peuvent être configurés à l’aide des options globales “ocsp-update.maxdelay” et “ocsp-update.mindelay”.

Lorsqu’une réponse OCSP est mise à jour par la tâche de mise à jour automatique ou après un appel à la commande CLI « update ssl ocsp-response », une ligne de journalisation dédiée est émise. Elle suit un format dédié contenant l’en-tête “<OCSP-UPDATE>” et est suivie d’informations spécifiques liées à OCSP : - le chemin du certificat frontal correspondant - un statut de mise à jour numérique - un statut de mise à jour textuel - le nombre d’échecs de mise à jour pour la réponse donnée - le nombre de succès de mise à jour pour la réponse donnée

Voir la commande CLI « show ssl ocsp-updates » pour la liste complète des codes d’erreur et des messages d’erreur. Cette ligne est émise indépendamment du succès ou de l’échec de la mise à jour de la réponse OCSP concernée. La requête/réponse OCSP est envoyée et reçue via une instance http_client ayant l’option dontlog-normal activée et utilisant le format de journalisation HTTP régulier en cas d’erreur (par exemple, répondant OCSP inatteignable). Si une telle erreur se produit, une autre ligne de journalisation contenant des informations HTTP sera émise en parallèle de la ligne « normale » OCSP (qui comportera probablement « HTTP error » comme statut textuel). Toutefois, si une erreur purement HTTP survient (par exemple, répondant OCSP inatteignable), une ligne de journalisation supplémentaire suivant le format HTTP régulier sera émise. Voici deux exemples de telles lignes de journalisation, avec d’abord une ligne de journalisation de mise à jour OCSP réussie, puis un exemple d’erreur HTTP avec les deux lignes différentes (les lignes ont été divisées et l’URL raccourcie pour plus de lisibilité) :

<133>Mar  6 11:16:53 haproxy[14872]: <OCSP-UPDATE> /path_to_cert/foo.pem 1 \
        "Update successful" 0 1

<133>Mar  6 11:18:55 haproxy[14872]: <OCSP-UPDATE> /path_to_cert/bar.pem 2 \
        "HTTP error" 1 0
<133>Mar  6 11:18:55 haproxy[14872]: -:- [06/Mar/2023:11:18:52.200] \
        <OCSP-UPDATE> -/- 2/0/-1/-1/3009 503 217 - - SC-- 0/0/0/0/3 0/0 {} \
        "GET http://127.0.0.1:12345/MEMwQT HTTP/1.1"

Dépannage : Une erreur courante pouvant survenir avec les certificats Let’s Encrypt est due à une résolution DNS qui fournit une adresse IPv6, alors que votre système ne dispose pas de route sortante IPv6 valide. Dans ce cas, vous pouvez soit créer la route appropriée, soit définir l’option « httpclient.resolvers.prefer_ipv4 » dans la section globale. En cas d’erreur « échec de vérification de la réponse OCSP », vérifiez que le certificat émetteur que vous avez fourni est valide. Un message d’erreur plus précis peut également être affiché entre parenthèses après le message d’erreur générique. Cela peut se produire pour les erreurs « échec de vérification de la réponse OCSP » ou « erreur lors de l’insertion ».

jwt [ off | on ]

jwt [ off | on ]

Permettre l’utilisation de ce certificat pour la validation ou le déchiffrement JWT via les convertisseurs “jwt_verify_cert”, “jwt_decrypt_cert” ou “jwt_decrypt” lorsque cette option est définie sur « on ». Sa valeur par défaut est « off ».

Lorsqu’il est défini sur « on » pour un certificat donné, la commande CLI « del ssl cert » ne fonctionnera pas. Pour être supprimé, un certificat doit ne pas être utilisé, ni pour les échanges SSL, ni pour la validation JWT.

Cette option peut être modifiée en temps réel à l’aide des commandes CLI « add ssl jwt » et « del ssl jwt ». Voir également la commande CLI « show ssl jwt ».

generate-dummy [ off | on ]

generate-dummy [ off | on ]

Permet la génération d’une clé privée et de son certificat auto-signé au moment de l’analyse lorsque cette option est définie sur « on ». Cela peut être utile si aucun certificat n’est disponible pendant la phase de test, par exemple. Dans ce cas, les options « keytype », « bits » et « curves » peuvent être utilisées pour personnaliser la clé privée. Lorsqu’elle n’est pas utilisée, la valeur par défaut est « off ». (voir également « keytype », « bits » et « curves »).

keytype [ RSA | ECDSA ]

keytype [ RSA | ECDSA ]

Permet la sélection du type de clé privée utilisé pour générer, au moment de l’analyse, un certificat auto-signé. Cela s’applique lorsque « generate-dummy » est défini sur « on » pour ce certificat. En l’absence d’utilisation, la valeur par défaut est « RSA ». (voir également « generate-dummy »).

bits <number>

bits <number>

Configurez le nombre de bits à générer pour un certificat auto-signé RSA lorsque « generate-dummy » est défini sur « on » pour ce certificat auto-signé et que « keytype » est défini sur « RSA ». En l’absence d’utilisation, la valeur par défaut est 2048. (voir également « generate-dummy »).

curves <string>

curves <string>

Configurez les courbes lorsque « generate-dummy » est défini sur « on » et que « keytype » est défini sur « ECDSA » pour ce certificat auto-signé. La valeur par défaut est « P-384 ».

12.8. ACME

acme <name>

Le protocole ACME peut être configuré à l’aide de la section « acme ». Cette section prend un argument “<name>”, utilisé pour lier un certificat à la section.

La section ACME permet de configurer HAProxy en tant que client ACMEv2. Cette fonctionnalité est expérimentale, ce qui signifie que « expose-experimental-directives » doit être présent dans la section global pour pouvoir l’utiliser.

Un guide est disponible sur le wiki HAProxy https://github.com/haproxy/wiki/wiki/ACME:--native-haproxy

Limitations actuelles :

- The feature is limited to the http-01, dns-01 or dns-persist-01 challenges

- The feature is limited to the http-01, dns-01 or dns-persist-01 challenges

Pour l’instant, l’authentification http-01 est entièrement gérée par HAProxy, mais les méthodes dns-01 et dns-persist-01 nécessitent soit l’API dataplane, soit un autre outil tiers pour communiquer avec une API de fournisseur DNS. dns-persist-01 n’exige qu’une seule configuration de l’entrée TXT, qui peut donc être définie manuellement sans outil.

- It is possible to start without an existing certificate on the disk. To do

- It is possible to start without an existing certificate on the disk. To do

Ainsi, le certificat doit être configuré dans un magasin de certificats (crt-store). Lorsqu’on utilise le mot-clé « acme » dans un crt-store, une paire de clés temporaire sera utilisée jusqu’à la génération du certificat ACME.

- The current HAProxy architecture is a non-blocking model, access to the disk

- The current HAProxy architecture is a non-blocking model, access to the disk

n’est pas censé être effectué après le chargement de la configuration, car cela pourrait bloquer la boucle d’événements, bloquant ainsi le trafic sur le même thread. Cela signifie que les certificats et clés générés par HAProxy devront être extraits depuis l’extérieur de HAProxy en utilisant la commande « dump ssl cert » sur le socket de statistiques. Il est possible d’automatiser l’extraction des certificats en utilisant l’API dataplane ou le script HAProxy-dump-certs fourni dans le répertoire admin/cli/.

Le planificateur ACME démarre au démarrage de HAProxy. Il parcourt les certificats et lance une tâche de renouvellement ACME lorsque la date notAfter est passée de curtime + (notAfter - notBefore) / 12, ou 7 jours si notBefore n’est pas défini. Le planificateur s’endort ensuite et se réveille après 12 heures. Il est possible de lancer manuellement une tâche de renouvellement avec la commande « acme renew ». Voir également « acme status » dans le guide d’administration.

Les mots-clés suivants sont utilisables dans la section ACME :

account-key <filename>

account-key <filename>

Configurez le chemin vers la clé du compte. La clé doit être générée avant le lancement de HAProxy. Si le mot-clé account n’est pas utilisé, la section acme tentera de charger un fichier en utilisant le nom de la section “<name>.account.key”. Si le fichier n’existe pas, HAProxy en générera un, en utilisant les paramètres de la section acme.

Vous pouvez également générer manuellement une clé privée RSA avec OpenSSL :

openssl genrsa -out account.key 2048

Ou une clé ecdsa :

openssl ecparam -name secp384r1 -genkey -noout -out account.key

acme-vars <string>

acme-vars <string>

Passer des variables arbitraires à l’outil externe de provisionnement DNS (par exemple, le dataplaneAPI) via le réceptacle « dpapi ». Les sémantiques sont spécifiques à l’outil ; reportez-vous à la documentation de votre outil de provisionnement DNS.

Ce mot-clé n’a d’importance que lorsque le type de défi est « dns-01 » ou « dns-persist-01 ».

Voir aussi : « challenge », « provider-name »

bits <number>

bits <number>

Configurez le nombre de bits à générer pour un certificat RSA. Valeur par défaut : 2048. Une valeur trop élevée peut déclencher un avertissement si votre machine n’est pas suffisamment puissante. (Cela peut être configuré avec « warn-blocked-traffic-after », mais bloquer le trafic trop longtemps pourrait déclencher la surveillance.)

challenge <string>

challenge <string>

Prend en paramètre un type de défi, qui doit être http-01, dns-01 ou dns-persist-01. Si non utilisé, la valeur par défaut est http-01.

dns-persist-01 implémente draft-ietf-acme-dns-persist. Contrairement à dns-01, il utilise un enregistrement TXT statique situé en “_validation-persist.<domain>” qui est défini une fois et ne change jamais entre les renouvellements. Cet enregistrement doit contenir l’URI du compte et une politique facultative. Ce type de défi ne nécessite pas d’accès en écriture à l’API du fournisseur DNS à chaque renouvellement.

challenge-ready <value>[,<value>]*

challenge-ready <value>[,<value>]*

Configurez les conditions qui doivent être remplies avant d’envoyer une notification au serveur ACME indiquant qu’un défi dns-01 est prêt à être validé. Les valeurs acceptées sont :

cli  - wait for an operator to signal readiness via the CLI command
       "acme challenge_ready <crt> domain <domain>" on the master CLI or
       the stats socket. This allows an external DNS provisioning tool to
       confirm that the TXT record has been set before HAProxy proceeds.

dns  - perform a DNS pre-check by resolving the TXT record for
       "_acme-challenge.<domain>" using the configured "default" resolvers
       section, not the authoritative name servers. The challenge is not
       submitted until the TXT record matches the expected token. Results
       may therefore be affected by DNS caching at the resolver level. The
       delay between resolution attempts is controlled by "dns-delay". This
       option is independent of the CLI command, so no human intervention
       is required.

       For dns-01, the TXT record at "_acme-challenge.<domain>" is
       resolved and must match the expected token. For dns-persist-01,
       the TXT record at "_validation-persist.<domain>" is resolved and
       only its presence is checked.

delay - apply an initial wait of "dns-delay" before proceeding. Without
        "dns", the challenge is submitted after the delay expires. When
        combined with "dns", the initial wait is applied before starting
        the DNS pre-checks.

none - no readiness condition; the challenge is submitted to the ACME
       server immediately without waiting for any external confirmation.
       This option cannot be combined with others.

Plusieurs valeurs peuvent être combinées avec une virgule. Lorsque plusieurs conditions sont spécifiées, HAProxy les traite dans l’ordre suivant : il attend d’abord la confirmation CLI (“cli”), puis applique le délai initial (“delay”), puis effectue les vérifications DNS préalables (“dns”).

Cette option n’est compatible qu’avec les types de défis dns-01 et dns-persist-01.

Lorsque « challenge » est défini sur « dns-01 » et que cette option n’est pas configurée, la valeur par défaut est « cli ».

Lorsque « challenge » est défini sur « dns-persist-01 » et que cette option n’est pas configurée, la valeur par défaut est « dns,delay ».

Lorsque « challenge » est défini sur « dns-persist-01 », une vérification DNS opportuniste initiale est toujours effectuée avant l’évaluation des conditions « challenge-ready ». Étant donné que l’enregistrement TXT “_validation-persist.<domain>” est défini une fois et ne change pas entre les renouvellements, HAProxy vérifie à l’heure du renouvellement si l’enregistrement est déjà présent. Si la vérification réussit pour tous les domaines, le défi est soumis immédiatement, sans passer par les étapes « challenge-ready » (cli, délai, dns). Si la vérification échoue, HAProxy reprend le flux normal de « challenge-ready ».

Exemple :

# Wait for CLI confirmation, then verify DNS propagation
challenge-ready cli,dns

contact <string>

contact <string>

L’adresse électronique du contact associée à la clé de compte dans l’Autorité de certification.

curves <string>

curves <string>

Lorsque vous utilisez le type de clé ECDSA, configurez les courbes. La valeur par défaut est P-384.

directory <string>

directory <string>

Ce mot-clé configure l’URL du répertoire de l’autorité de certification utilisée par cette section acme. Ce mot-clé est obligatoire, car aucune URL par défaut n’est définie.

Exemple :

directory https://acme-staging-v02.api.letsencrypt.org/directory

dns-delay <time>

dns-delay <time>

Configurez le délai utilisé par les conditions « challenge-ready » « delay » et « dns ». La valeur est une durée exprimée au format temps HAProxy (par exemple « 5m », « 300s »). La valeur par défaut est de 30 secondes.

Son rôle dépend des conditions « challenge-ready » en vigueur :

delay     - the challenge is submitted after this delay expires, without
            any DNS pre-check.

dns       - the delay between two consecutive DNS resolution attempts.
            The first probe fires immediately without any initial wait.

dns+delay - the initial wait before the first DNS resolution attempt, and
            the delay between subsequent retries.

Notez que la résolution passe par la section « default » des résolveurs configurés, et non par les serveurs de noms autoritatifs. Les résultats peuvent donc encore être affectés par le cache DNS au niveau du résolveur.

dns-timeout <time>

dns-timeout <time>

Lorsque « challenge-ready » inclut « dns », configurez le délai maximal autorisé pour résoudre avec succès le enregistrement TXT avant d’abandonner le défi. La valeur est une durée exprimée au format temps HAProxy (par exemple « 10m », « 600s »). La valeur par défaut est de 600 secondes.

Le délai commence au moment où la première tentative de résolution DNS est déclenchée (après le délai initial « dns-delay »). Si la tentative de résolution suivante devait être déclenchée après l’expiration du délai, le défi est interrompu avec une erreur. Cela empêche une boucle de réessais infinie en cas d’échec de propagation DNS.

Voir également : « dns-delay »

keytype <string>

keytype <string>

Configurez le type de clé qui sera générée. La valeur peut être soit « RSA » soit « ECDSA ». Vous pouvez également configurer les « curves » pour ECDSA et le nombre de « bits » pour RSA. Par défaut, les clés EC384 sont générées.

map <map>

map <map>

Configurez la carte utilisée pour stocker le jeton (clé) et l’empreinte (valeur), ce qui est utile pour répondre à un défi lorsque plusieurs comptes sont utilisés. La tâche ACME ajoutera des entrées avant la validation du défi et supprimera ces entrées à la fin de la tâche.

profile <string>

profile <string>

Demandez un profil de certificat spécifique à l’autorité de certification en incluant un champ « profile » dans la requête newOrder. Cela implémente le brouillon draft-ietf-acme-profiles.

Les noms de profil sont des identificateurs courts spécifiques à l’AC (par exemple, « classic », « shortlived »). Lorsqu’ils sont définis, le nom de profil est envoyé tel quel dans le chargement JSON de newOrder. L’AC est libre d’ignorer la requête ou de renvoyer une erreur si le profil n’est pas pris en charge. Lorsqu’il n’est pas défini, aucun champ de profil n’est inclus, et l’AC utilise sa politique d’émission par défaut.

Voir https://letsencrypt.org/docs/profiles/ pour les profils Let’s Encrypt.

Exemple :

# Request short-lived certificates
profile shortlived

provider-name <string>

provider-name <string>

Spécifiez le nom du fournisseur DNS transmis à l’outil externe de provisionnement DNS (par exemple, l’API dataplane) via le réceptacle « dpapi ». Les valeurs acceptées sont spécifiques à l’outil ; reportez-vous à la documentation de votre outil de provisionnement DNS.

Ce mot-clé n’a d’importance que lorsque le type de défi est « dns-01 » ou « dns-persist-01 ».

Voir aussi : « challenge », « acme-vars »

reuse-key { on | off }

reuse-key { on | off }

Si cette option est définie sur « on », HAProxy ne générera pas de nouveau certificat privé et conservera celui précédemment utilisé. Il est recommandé de renouveler les clés de manière régulière lorsque cette option est activée.

Cette option peut être utile lors de l’utilisation de clés RSA supérieures à 2048 bits, qui peuvent nécessiter du temps pour être générées et risquent de ralentir un thread chargé de cette opération.

Utiliser la même clé peut être utile lorsque vous utilisez le cache de votre serveur ACME, car cela permet de récupérer un certificat valide correspondant à la clé actuelle.

La valeur par défaut est « off ».

Exemple :

global
    expose-experimental-directives
    httpclient.resolvers.prefer ipv4

frontend in
    bind *:80
    bind *:443 ssl
    http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].%[path,field(-1,/),map(virt@acme)]\n" if { path_beg '/.well-known/acme-challenge/' }
    ssl-f-use crt "foo.example.com.pem.rsa"   acme LE1 domains "foo.example.com.pem,bar.example.com"
    ssl-f-use crt "foo.example.com.pem.ecdsa" acme LE2 domains "foo.example.com.pem,bar.example.com"

acme LE1
    directory https://acme-staging-v02.api.letsencrypt.org/directory
    account-key /etc/haproxy/letsencrypt.account.key
    contact john.doe@example.com
    challenge http-01
    keytype RSA
    bits 2048
    map virt@acme

acme LE2
    directory https://acme-staging-v02.api.letsencrypt.org/directory
    account-key /etc/haproxy/letsencrypt.account.key
    contact john.doe@example.com
    challenge http-01
    keytype ECDSA
    curves P-384
    map virt@acme

eab-key-id <filename>

eab-key-id <filename>

Configurez le chemin vers le fichier d’identifiant de clé EAB. Les identifiants sont fournis par l’autorité de certification et doivent être placés au chemin spécifié avant le démarrage de HAProxy. Ils sont utilisés uniquement lors de la création du compte.

Le fichier doit contenir une chaîne ASCII brute.

Les identifiants EAB ne sont requis que lors de la création initiale du compte ACME et peuvent être supprimés par la suite, soit depuis la configuration, soit en vidant les fichiers. Un fichier vide est ignoré sans message d’erreur. Les espaces blancs ne sont pas ignorés, à l’exception de la saut de ligne final.

Voir aussi : « eab-mac-key », « eab-mac-alg »

eab-mac-key <filename>

eab-mac-key <filename>

Configurez le chemin vers le fichier de clé MAC EAB. Credential fourni par l’autorité de certification (CA) et doit être placé au chemin spécifié avant le démarrage de HAProxy. Il est utilisé uniquement lors de la création de compte.

Le fichier doit contenir une clé MAC encodée en base64url.

Les identifiants EAB ne sont requis que lors de la création initiale du compte ACME et peuvent être supprimés par la suite, soit depuis la configuration, soit en vidant les fichiers. Un fichier vide est ignoré sans message d’erreur. Les espaces blancs ne sont pas ignorés, à l’exception de la saut de ligne final.

Voir aussi : « eab-key-id », « eab-mac-alg »

eab-mac-alg { HS256 | HS384 | HS512 }

eab-mac-alg { HS256 | HS384 | HS512 }

Configure l’algorithme MAC utilisé pour la signature EAB. La valeur par défaut est HS256. La clé MAC EAB doit être suffisamment grande pour supporter l’algorithme MAC spécifié. Toutes les autorités de certification ne prennent pas en charge des algorithmes autres que HS256.

Voir aussi : « eab-key-id », « eab-mac-key »

12.9. Vérifications de santé

Il est possible de déclarer globalement plusieurs vérifications de santé pouvant être utilisées par les serveurs dans toute la configuration, en ignorant la configuration locale du proxy.

healthcheck <name>

healthcheck <name>

Créé une nouvelle vérification de santé nommée <name>. Ce nom doit être unique. Il doit être utilisé dans la ligne server pour référencer une section de vérification de santé spécifique.

type <type>

type <type>

Définit le type de vérification de santé. Ce paramètre est obligatoire. Les types de vérification de santé suivants sont pris en charge :

* vérification-tcp
* vérification-http
* vérification-ssl-hello
* vérification-smtp
* vérification-pgsql
* vérification-redis
* vérification-mysql
* vérification-ldap
* vérification-spop

Chaque type utilise les mêmes paramètres, le cas échéant, que l’option correspondante du proxy. Par exemple, la méthode, l’URI… peuvent être spécifiées pour le type « httpchk » :

Exemples :

   healthcheck my-http-check
type httpchk GET /health HTTP/1.1 %[srv_name]

Voir aussi : « option tcp-check », « option httpchk », « option ssl-hello-chk », « option smtpchk », « option mysql-check », « option pgsql-check », « option redis-check », « option ldap-check » et « option spop-check »

http-check comment <string>

http-check comment <string>
http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
                   [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
                   [proto <name>] [comment <msg>]
http-check disable-on-404
http-check expect [min-recv <int>] [comment <msg>]
                  [ok-status <st>] [error-status <st>] [tout-status <st>]
                  [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                  [!] <match> <pattern>
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
                [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
                [comment <msg>]
http-check send-state
http-check set-var(<var-name>[,<cond>...]) <expr>
http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
http-check unset-var(<var-name>)

Ajoutez une règle spécifique http-check pour un contrôle de santé « httpchk ». La syntaxe utilisée est identique à celle des directives du proxy correspondant. Consultez la documentation du proxy correspondant pour plus de détails.

tcp-check comment <string>

tcp-check comment <string>
tcp-check connect [default] [port <expr>] [addr <ip>] [send-proxy] [via-socks4]
                  [ssl] [sni <sni>] [alpn <alpn>] [linger]
                  [proto <name>] [comment <msg>]
tcp-check expect [min-recv <int>] [comment <msg>]
                 [ok-status <st>] [error-status <st>] [tout-status <st>]
                 [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                 [!] <match> <pattern>
tcp-check send <data> [comment <msg>]
tcp-check send-lf <fmt> [comment <msg>]
tcp-check send-binary <hexstring> [comment <msg>]
tcp-check send-binary-lf <hexfmt> [comment <msg>]
tcp-check set-var(<var-name>[,<cond>...]) <expr>
tcp-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
tcp-check unset-var(<var-name>)

Ajoutez une règle tcp-check spécifique pour un contrôle de santé « tcp-check ». La syntaxe utilisée est identique à celle des directives correspondantes du proxy. Consultez la documentation du proxy correspondant pour plus de détails.

22 - 1. Prérequis

Connaissances UNIX attendues en administration et dépannage

Ce document décrit comment démarrer, arrêter, gérer et dépanner HAProxy, ainsi que certaines limitations connues et pièges à éviter. Il ne décrit pas comment le configurer (pour cela, veuillez consulter configuration.txt ).

Dans ce document, il est supposé que le lecteur possède des compétences suffisantes en administration sur un système d’exploitation de type UNIX, utilise quotidiennement l’interpréteur de commandes et maîtrise les outils de dépannage tels que strace et tcpdump.

23 - 2. HAProxy Architecture

Le processus, le multithreading, la boucle d’événements, chroot, les journaux, les horloges et le modèle de proxy TCP

HAProxy est un démon multithreadé, basé sur des événements et non bloquant. Cela signifie qu’il utilise la multiplexion d’événements pour planifier toutes ses activités, plutôt que de dépendre du système pour planifier entre plusieurs activités. La plupart du temps, il s’exécute sous la forme d’un seul processus, de sorte que la sortie de la commande « ps aux » sur un système ne répertorie qu’un seul processus « HAProxy », sauf en cas de rechargement doux en cours, auquel cas un processus ancien peut encore s’exécuter en parallèle du nouveau. Il est donc toujours facile de suivre son activité à l’aide de l’outil strace. Pour s’adapter au nombre de processeurs disponibles, HAProxy démarre, par défaut, un thread worker par processeur sur lequel il est autorisé à s’exécuter. À moins d’être configuré autrement, le trafic entrant est réparti entre tous ces threads, chacun exécutant la même boucle d’événements. Une grande attention est portée à limiter les dépendances entre threads au strict minimum, afin de tenter d’obtenir une scalabilité quasi linéaire. Cela a certaines conséquences, notamment le fait qu’une connexion donnée soit servie par un seul thread. Ainsi, pour utiliser toute la capacité de traitement disponible, il faut disposer d’au moins autant de connexions que de threads, ce qui est presque toujours le cas.

HAProxy est conçu pour s’isoler dans une prison chroot au démarrage, où il ne peut effectuer aucune opération sur le système de fichiers. Cela s’applique également aux bibliothèques sur lesquelles il dépend (par exemple : libc, libssl, etc.). L’effet immédiat est qu’un processus en cours d’exécution ne pourra pas recharger un fichier de configuration pour appliquer des modifications ; au lieu de cela, un nouveau processus sera lancé en utilisant le fichier de configuration mis à jour. Certains autres effets moins évidents sont que certains fichiers de fuseau horaire ou de résolution que libc pourrait tenter d’accéder à l’exécution ne seront pas trouvés, bien que cela devrait généralement ne pas se produire, car ces fichiers ne sont pas nécessaires après le démarrage. Une conséquence agréable de ce principe est que le processus HAProxy est entièrement sans état, et aucune opération de nettoyage n’est requise après sa suppression, aussi bien n’importe quelle méthode de suppression fonctionnera.

HAProxy n’écrit pas de fichiers journaux, mais il s’appuie sur le protocole syslog standard pour envoyer les journaux vers un serveur distant (qui se trouve souvent sur le même système).

HAProxy utilise son horloge interne pour imposer les délais d’expiration, qui est dérivée de l’heure système mais corrigée en cas de dérive imprévue. Cette correction est réalisée en limitant le temps passé en attente dans poll() pour un événement, et en mesurant le temps réellement écoulé. En pratique, il n’attend jamais plus d’une seconde. Cela explique pourquoi, lorsqu’on exécute strace sur un processus complètement inactif, des appels périodiques à poll() (ou à l’une de ses variantes), entourés de deux appels à gettimeofday(), sont observés. Ces appels sont normaux, totalement inoffensifs et si peu coûteux qu’ils sont totalement indétectables à l’échelle du système, il n’y a donc rien d’anormal à cela. Exemple :

16:35:40.002320 gettimeofday({1442759740, 2605}, NULL) = 0
16:35:40.002942 epoll_wait(0, {}, 200, 1000) = 0
16:35:41.007542 gettimeofday({1442759741, 7641}, NULL) = 0
16:35:41.007998 gettimeofday({1442759741, 8114}, NULL) = 0
16:35:41.008391 epoll_wait(0, {}, 200, 1000) = 0
16:35:42.011313 gettimeofday({1442759742, 11411}, NULL) = 0

HAProxy est un proxy TCP, et non un routeur. Il gère les connexions établies, validées par le noyau, et non les paquets de quelque nature que ce soit ni les sockets dans d’autres états (par exemple : aucun SYN_RECV ni TIME_WAIT), bien que leur existence puisse empêcher la liaison d’un port. Il dépend du système pour accepter les connexions entrantes et initier les connexions sortantes. Un effet immédiat de cela est qu’il n’existe aucune relation entre les paquets observés des deux côtés d’une connexion redirigée, qui peuvent différer par taille, nombre, voire famille. Étant donné qu’une connexion ne peut être acceptée qu’à partir d’un socket en état LISTEN, tous les sockets sur lesquels il écoute sont nécessairement visibles à l’aide de l’outil “netstat” pour afficher les sockets d’écoute. Exemple :

# netstat -ltnp

Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1629/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2847/haproxy tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2847/haproxy

24 - 3. Démarrage de HAProxy

Syntaxe de ligne de commande, options, chargement de la configuration et comportement au démarrage

HAProxy est lancé en exécutant le programme « HAProxy » avec un certain nombre d’arguments passés en ligne de commande. La syntaxe réelle est :

$ haproxy [<options>]*

où [<options>]* est un nombre quelconque d’options. Une option commence toujours par ‘-’ suivi d’une ou plusieurs lettres, et peut être suivie d’un ou plusieurs arguments supplémentaires. Sans option, HAProxy affiche la page d’aide avec un rappel des options prises en charge. Les options disponibles peuvent varier légèrement selon le système d’exploitation. Un nombre important de ces options se chevauchent avec une option équivalente dans la section « global ». Dans ce cas, la ligne de commande a toujours priorité sur le fichier de configuration, de sorte que la ligne de commande peut être utilisée pour imposer rapidement certains paramètres sans modifier les fichiers de configuration. La liste actuelle des options est :

-- <cfgfile>*

-- <cfgfile>*

Tous les arguments qui suivent “–” sont des chemins de fichiers ou de répertoires de configuration, chargés et traités dans l’ordre de déclaration. Cette forme est surtout utile lorsque le shell charge de nombreux fichiers ordonnés numériquement. Voir aussi “-f”. Avec “-f”, chaque nom de fichier doit être précédé de l’option, tandis qu’un seul “–” suffit avant l’ensemble des noms. Ces options peuvent être combinées et l’ordre de la ligne de commande continue de s’appliquer. Lorsque plusieurs fichiers sont indiqués, chacun doit commencer à une frontière de section ; son premier mot-clé doit donc être “global”, “defaults”, “peers”, “listen”, “frontend”, “backend”, etc. Un fichier ne peut pas contenir uniquement une liste de serveurs.

-f <cfgfile|cfgdir>

-f <cfgfile|cfgdir>

ajoute <cfgfile> à la liste des fichiers de configuration à charger. Si <cfgdir> est un répertoire, tous les fichiers qu’il contient, et uniquement les fichiers, sont ajoutés à la liste dans l’ordre lexical (avec LC_COLLATE=C). Seuls les fichiers portant l’extension “.cfg” et les fichiers non cachés, sans préfixe “.”, sont ajoutés. Les fichiers de configuration sont chargés et traités dans leur ordre de déclaration. Cette option peut être répétée pour charger plusieurs fichiers. Voir aussi “–”. Avec “-f”, chaque nom de fichier doit être précédé de l’option, tandis qu’un seul “–” suffit avant tous les noms. Ces options peuvent être combinées et l’ordre de la ligne de commande continue de s’appliquer. Lorsque plusieurs fichiers sont indiqués, chacun doit commencer à une frontière de section ; son premier mot-clé doit donc être “global”, “defaults”, “peers”, “listen”, “frontend”, “backend”, etc. Un fichier ne peut pas contenir uniquement une liste de serveurs.

-C <dir>

-C <dir>

Effectuez les changements de répertoire <dir> avant de charger les fichiers de configuration. Cela est utile lorsque l’on utilise des chemins relatifs. Attention à l’utilisation de caractères génériques après “–”, qui sont en réalité remplacés par le shell avant le démarrage de HAProxy.

-D

-D

Démarrer en tant que démon. Le processus se détache du terminal actuel après avoir forké, et les erreurs ne sont plus signalées dans le terminal. Cette option équivaut au mot-clé « daemon » dans la section « global » de la configuration. Il est recommandé de toujours l’activer dans tout script d’initialisation afin qu’une configuration erronée ne bloque pas le démarrage du système.

-L <name>

-L <name>

modifiez le nom du pair local en <name>, qui est par défaut le nom d’hôte local. Cela n’est utilisé que pour la réplication entre pairs. Vous pouvez utiliser la variable $HAPROXY_LOCALPEER dans le fichier de configuration pour faire référence au nom du pair.

-N <limit>

-N <limit>

définit la valeur par défaut de maxconn par proxy à <limit> au lieu de la valeur par défaut intégrée (généralement 2000). Utile uniquement à des fins de débogage.

-V

-V

active le mode verbeux (désactive le mode silencieux). Annule l’effet de “-q” ou de “quiet”.

-W

-W

mode master-worker. Il est équivalent à la clé mot « master-worker » dans la section « global » de la configuration. Ce mode lance un « master » qui surveille les « workers ». En utilisant ce mode, vous pouvez recharger HAProxy directement en envoyant un signal SIGUSR2 au master. Le mode master-worker est compatible avec le mode en premier plan ou en daemon. Il est recommandé d’utiliser ce mode avec le mode multiprocess et systemd.

-Ws

-Ws

Mode master-worker avec prise en charge du type notify de service systemd.

-4

-4

Forcer les résolveurs DNS à interroger et à accepter uniquement des adresses IPv4 (enregistrements « A »). Cela peut être utilisé lorsque des difficultés surviennent dans certains environnements privés de connectivité dual-stack bout en bout. Cette option remplace la directive globale « dns-accept-family » et la force à « ipv4 ».

-c

-c

vérifie uniquement la configuration des fichiers et quitte avant toute tentative de liaison. Le code de sortie est zéro si tout est correct, ou non nul en cas d’erreur. Les avertissements éventuels sont signalés. Par défaut, cette option ne signale pas de message de succès. Associée à “-V”, elle affiche le message « Configuration file is valid » en cas de succès.

Les scripts doivent utiliser le code de sortie pour déterminer la réussite de la commande.

-cc

-cc

évalue une condition telle qu’elle est utilisée dans un bloc conditionnel de la configuration. Le statut de sortie est zéro si la condition est vraie, 1 si la condition est fausse ou 2 en cas d’erreur rencontrée.

-d

-d

activez le mode débogage. Cela désactive le mode démon, force le processus à rester en premier plan et à afficher les événements entrants et sortants. Cette option ne doit jamais être utilisée dans un script d’initialisation.

-dA[file]

-dA[file]

effectue un archive de toutes les dépendances détectées au démarrage dans le fichier désigné au format tar, immédiatement après le chargement de la configuration. Cela équivaut à « set-dumpable libs », mais au lieu de conserver les bibliothèques en mémoire, il les écrit dans un fichier. Cette fonction peut être utilisée après une image mémoire (core dump), afin de fournir à des développeurs toutes les bibliothèques nécessaires pour analyser le core. Cette fonctionnalité n’est pas disponible sur tous les systèmes d’exploitation. Il est fortement recommandé de l’utiliser avec les fichiers de configuration réguliers, et éventuellement avec “-c” lorsqu’elle est utilisée manuellement, afin que HAProxy se termine immédiatement après l’archive, sans démarrer. Exemple :

$ haproxy -dA/tmp/libs.tar -c -f /etc/haproxy/haproxy.cfg

-dC[key]

-dC[key]

Exporter le fichier de configuration. Cette opération est effectuée après le découpage en jetons, de sorte que les commentaires sont supprimés et l’indentation est obligatoire. Si une clé non nulle est spécifiée, les lignes sont tronquées avant les champs sensibles ou confidentiels, et les identifiants et adresses sont émis hachés avec cette clé en utilisant le même algorithme que celui utilisé en mode anonyme sur la ligne de commande. Cela signifie que la sortie peut être partagée en toute sécurité avec un développeur qui en a besoin pour comprendre ce qui se passe dans un dump anonymisé à l’aide de la même clé. Veuillez également consulter la commande « set anon » de la ligne de commande.

-dD

-dD

active le mode diagnostic. Ce mode affiche des avertissements supplémentaires sur les instructions de configuration suspectes. Il n’empêche jamais le démarrage, même en mode « sans avertissement », et ne modifie pas le code de sortie.

-dF

-dF

désactive le transfert accéléré des données. Il s’agit d’un mécanisme d’optimisation du transfert de données qui consiste à acheminer les données directement d’un côté à l’autre sans réveiller le flux. Grâce à cette directive, il est possible de désactiver cette optimisation. Notez qu’elle désactive également tout transfert direct du noyau TCP. Cette commande n’est pas destinée à une utilisation régulière ; elle sera généralement proposée uniquement par les développeurs lors de sessions de débogage complexes.

-dG

-dG

désactive l’utilisation de getaddrinfo() pour résoudre les noms d’hôtes en adresses. Cette option peut être utilisée lorsque l’on suspecte que getaddrinfo() ne fonctionne pas comme prévu. Cette option a été mise à disposition en raison de la présence de nombreuses implémentations incorrectes de getaddrinfo() sur divers systèmes, qui provoquent des anomalies difficiles à diagnostiquer.

-dI

-dI

activez le fork non sécurisé. Ceci équivaut à l’option « insecure-fork-wanted » dans la section globale. Cela peut être utile lors de l’exécution de tous les tests de régularité avec ASAN, qui nécessitent de faire un fork d’addr2line pour résoudre les adresses.

-dK<class[,class]*>

-dK<class[,class]*>

affiche la liste des mots-clés enregistrés dans chaque classe. La liste des classes est disponible avec “-dKhelp”. Toutes les classes peuvent être affichées en utilisant “-dKall”, sinon une sélection parmi celles indiquées dans l’aide peut être spécifiée sous forme d’une liste séparée par des virgules. Le format de sortie varie selon la classe de mots-clés affichée (par exemple, “cfg” affiche les mots-clés de configuration connus dans un format ressemblant au format de fichier de configuration, tandis que “smp” affiche les fonctions d’extraction d’échantillon précédées d’une matrice de compatibilité par ensemble de règles). Ces sorties peuvent rarement être utilisées directement par des humains, mais elles peuvent être très utiles pour des outils externes cherchant à détecter l’apparition de nouveaux mots-clés à certains endroits afin de mettre automatiquement à jour certaines documentation, fichiers de mise en évidence syntaxique, analyseurs de configuration, API, etc. Le format de sortie peut évoluer légèrement au fil du temps, aussi est-il fortement recommandé d’utiliser cette sortie principalement pour détecter les différences par rapport à des archives antérieures. Notez qu’il n’est pas possible de lister tous les mots-clés, car de nombreux mots-clés existaient bien avant la création des différents systèmes d’enregistrement des mots-clés, et ils n’apparaissent donc pas ici. Toutefois, puisque les nouveaux mots-clés ne sont ajoutés que par les mécanismes modernes, il est raisonnablement sûr de supposer que cette sortie peut être utilisée pour détecter les ajouts de langage avec une bonne précision. Les mots-clés ne sont affichés qu’après analyse complète de la configuration, afin que même les mots-clés créés dynamiquement puissent être inclus. Une bonne manière de produire une sortie et de quitter est d’exécuter une vérification silencieuse de configuration sur une configuration existante :

./haproxy -dKall -q -c -f foo.cfg

Si aucun fichier de configuration n’est disponible, l’utilisation de “-f /dev/null” permet également d’extraire tous les mots-clés par défaut, mais le code de retour ne sera pas zéro, car aucun écouteur ne sera présent, et devra être ignoré.

-dL

-dL

affiche la liste des bibliothèques partagées dynamiques chargées à la fin du traitement de la configuration. Celle-ci inclut généralement aussi des dépendances profondes, telles que tout ce qui est chargé depuis du code Lua, ainsi que l’exécutable lui-même. La liste est affichée au format permettant de la nettoyer facilement afin de produire directement un archive tar de toutes les dépendances. Comme cette commande ne bloque pas le démarrage du programme, il est recommandé de ne l’utiliser qu’en combinaison avec “-c” et “-q”, où seule la liste des objets chargés sera affichée (ou rien en cas d’erreur). En outre, gardez à l’esprit que, lors de la fourniture d’un tel package pour aider à l’analyse d’un fichier core, la plupart des bibliothèques sont en réalité des liens symboliques qui doivent être résolus lors de la création de l’archive :

./haproxy -W -q -c -dL -f foo.cfg | tar -T - -hzcf archive.tgz

Lorsqu’il est lancé en mode verbeux (-V), les plages d’adresses des bibliothèques partagées sont également énumérées, à moins que le mode silencieux ne soit activé (-q).

-dM[<byte>[,]][help|options,...]

-dM[<byte>[,]][help|options,...]

active la détection de corruption mémoire, et/ou modifie d’autres options de débogage. La détection de corruption mémoire signifie que chaque région mémoire allouée avec malloc() ou pool_alloc() sera remplie avec <byte> avant d’être renvoyée au demandeur. Lorsque <byte> n’est pas spécifié, sa valeur par défaut est 0x50 (‘P’). Bien que cela ralentisse légèrement les opérations, cela permet de déclencher de manière fiable les problèmes dus à une initialisation manquante dans le code, provoquant des crashs aléatoires. Notez que -dM0 a pour effet de transformer tout appel à malloc() en un appel à calloc(). Dans tous les cas, si un bug apparaît ou disparaît lors de l’utilisation de cette option, cela signifie qu’il y a un bug dans haproxy, veuillez le signaler. Plusieurs autres options sont disponibles, soit seules, soit après une virgule suivant le byte. L’option spéciale « help » affiche la liste des options prises en charge actuellement ainsi que leurs valeurs actuelles. Chaque option de débogage peut être activée ou désactivée. Les options les plus optimales sont généralement choisies au moment de la compilation en fonction du système d’exploitation et n’ont pas besoin d’être ajustées, sauf si suggérées par un développeur. Les options de débogage prises en charge incluent (activer/désactiver) :

  • échec / sans-échec :
This enables randomly failing memory allocations, in conjunction with
the global "tune.fail-alloc" setting. This is used to detect missing
error checks in the code. Setting the option presets the ratio to 1%
failure rate.
  • no-merge / merge :
By default, pools of very similar sizes are merged, resulting in more
efficiency, but this complicates the analysis of certain memory dumps.
This option allows to disable this mechanism, and may slightly increase
the memory usage.
  • froid-d’abord / chaud-d’abord :
In order to optimize the CPU cache hit ratio, by default the most
recently released objects ("hot") are recycled for new allocations.
But doing so also complicates analysis of memory dumps and may hide
use-after-free bugs. This option allows to instead pick the coldest
objects first, which may result in a slight increase of CPU usage.
  • intégrité / sans-intégrité :
When this option is enabled, memory integrity checks are enabled on
the allocated area to verify that it hasn't been modified since it was
last released. This works best with "no-merge", "cold-first" and "tag".
Enabling this option will slightly increase the CPU usage.
  • backup / no-backup :
This option performs a copy of each released object at release time,
allowing developers to inspect them. It also performs a comparison at
allocation time to detect if anything changed in between, indicating a
use-after-free condition. This doubles the memory usage and slightly
increases the CPU usage (similar to "integrity"). If combined with
"integrity", it still duplicates the contents but doesn't perform the
comparison (which is performed by "integrity"). Just like "integrity",
it works best with "no-merge", "cold-first" and "tag".
  • no-global / global :
Depending on the operating system, a process-wide global memory cache
may be enabled if it is estimated that the standard allocator is too
slow or inefficient with threads. This option allows to forcefully
disable it or enable it. Disabling it may result in a CPU usage
increase with inefficient allocators. Enabling it may result in a
higher memory usage with efficient allocators.
  • no-cache / cache :
Each thread uses a very fast local object cache for allocations, which
is always enabled by default. This option allows to disable it. Since
the global cache also passes via the local caches, this will
effectively result in disabling all caches and allocating directly from
the default allocator. This may result in a significant increase of CPU
usage, but may also result in small memory savings on tiny systems.
  • appelant / sans-appelant :
Enabling this option reserves some extra space in each allocated object
to store the address of the last caller that allocated or released it.
This helps developers go back in time when analysing memory dumps and
to guess how something unexpected happened.
  • tag / sans-tag :
Enabling this option reserves some extra space in each allocated object
to store a tag that allows to detect bugs such as double-free, freeing
an invalid object, and buffer overflows. It offers much stronger
reliability guarantees at the expense of 4 or 8 extra bytes per
allocation. It usually is the first step to detect memory corruption.
  • poison / no-poison :
Enabling this option will fill allocated objects with a fixed pattern
that will make sure that some accidental values such as 0 will not be
present if a newly added field was mistakenly forgotten in an
initialization routine. Such bugs tend to rarely reproduce, especially
when pools are not merged. This is normally enabled by directly passing
the byte's value to -dM but using this option allows to disable/enable
use of a previously set value.

-dR

-dR

désactive l’option de socket SO_REUSEPORT sur les ports d’écoute. Cela équivaut à la directive “noreuseport” de la section “global”. Cette option peut être appliquée dans les scénarios à multi-threading lorsque des problèmes de répartition de charge sont observés entre les threads HAProxy (pouvant être surveillés avec top).

-dS

-dS

désactive l’utilisation de l’appel système splice(). Cela équivaut à la directive “nosplice” dans la section “global”. Cette option peut être utilisée lorsque splice() est suspecté de se comporter de manière incorrecte ou de provoquer des problèmes de performance, ou lorsqu’on utilise strace pour visualiser les données transférées (lesquelles ne sont pas visibles lorsqu’on utilise splice()).

-dT

-dT

désactive l’utilisation de ktls. Cela équivaut à la directive « noktls » de la section « global ». Cela est principalement utile lorsqu’un bug lié à ktls est suspecté.

-dV

-dV

Désactive la vérification SSL du côté serveur. Cela équivaut à la directive « ssl-server-verify none » dans la section « global ». Cela est utile pour reproduire des problèmes de production en dehors de l’environnement de production. Ne jamais utiliser cela dans un script d’initialisation, car cela réduit la sécurité SSL des serveurs.

-dW

-dW

Si défini, HAProxy refusera de démarrer si un avertissement a été émis lors du traitement de la configuration. Cela permet de détecter des erreurs subtiles et de maintenir la configuration propre et portable entre les versions. Il est recommandé de définir cette option dans les scripts de service lorsque les configurations sont gérées par des humains, mais il est recommandé de ne pas l’utiliser avec des configurations générées, qui ont tendance à émettre plus d’avertissements. Elle peut être combinée avec “-c” pour faire échouer les configurations vérifiées en cas d’avertissement. Cela équivaut à l’option globale “zero-warning”.

-dZ

-dZ

désactive le transfert des données en mode « zero-copy ». Cela équivaut à la directive “tune.disable-zero-copy-forwarding” de la section « global ». Cela peut être utile en cas de problèmes de perte de données ou d’intégrité des données, ou lors de l’utilisation de strace pour observer les données transférées, car cela désactive également le splice TCP du noyau.

-db

-db

Désactivez le mode en arrière-plan et le mode multi-processus. Le processus reste en premier plan. Ce paramètre est principalement utilisé pendant le développement ou lors de petits tests, car l’envoi de Ctrl-C suffit à arrêter le processus. Ne l’utilisez jamais dans un script d’initialisation.

-dc

-dc

Activer le débogage de l’affinité CPU. La liste des CPUs sélectionnés et évacués ainsi que leur topologie seront rapportées avant le démarrage.

-de

-de

désactive l’utilisation du poller « epoll ». Cela équivaut à la directive « noepoll » de la section « global ». Il est principalement utile lorsque l’on suspecte un bug lié à ce poller. Sur les systèmes prenant en charge epoll, le mécanisme de secours sera généralement le poller « poll ».

-dk

-dk

désactive l’utilisation du poller « kqueue ». Cela équivaut à la directive du secteur « global » « nokqueue ». Cela est principalement utile lorsqu’un bug lié à ce poller est suspecté. Sur les systèmes prenant en charge kqueue, le mécanisme de secours sera généralement le poller « poll ».

-dp

-dp

désactive l’utilisation du poller « poll ». Cela équivaut à la directive « nopoll » de la section « global ». Il est principalement utile lorsque l’on suspecte un bogue lié à ce poller. Sur les systèmes prenant en charge poll, le mécanisme de secours sera généralement le poller « select », qui ne peut pas être désactivé et est limité à 1024 descripteurs de fichiers.

-dr

-dr

ignorer les échecs de résolution d’adresse du serveur. Il est fréquent, lors de la validation d’une configuration en dehors d’un environnement de production, de ne pas avoir accès aux mêmes serveurs de résolution, ce qui entraîne l’échec de la résolution d’adresse du serveur, rendant ainsi difficile le test d’une configuration. Cette option ajoute simplement la méthode « none » à la liste des méthodes de résolution d’adresse pour tous les serveurs, garantissant que, même si la bibliothèque libc échoue à résoudre une adresse, la séquence de démarrage n’est pas interrompue.

-dt [<trace_desc>,...]

-dt [<trace_desc>,...]

active les traces sur stderr. Sans argument, cela active toutes les sources de trace au niveau d’erreur. Cela peut notamment être utile pour détecter des violations de protocole provenant de clients ou de serveurs. Un argument facultatif peut être utilisé pour spécifier une liste de configurations de trace différentes, séparées par une virgule. Chaque élément active une ou toutes les sources de trace. En outre, le niveau et la verbosité peuvent être spécifiés de manière facultative pour chaque élément en utilisant deux-points comme séparateur interne avec le nom de la trace. En cas d’entrée d’une verbosité ou d’un nom de niveau invalide, la liste des mots-clés disponibles est affichée. Par exemple, il peut être pratique de passer « help » pour chaque champ afin de consulter la liste en premier.

-dv

-dv

désactive l’utilisation du poller « evports ». Cela équivaut à la directive du secteur « global » « noevports ». Cela est principalement utile lorsque l’on soupçonne un bogue lié à ce poller. Sur les systèmes prenant en charge les event ports (SunOS dérivé de Solaris 10 et ultérieur), le mécanisme de secours sera généralement le poller « poll ».

-m <limit>

-m <limit>

limite la mémoire allouable, utilisée pour stocker les données du processus, à <limit> mégaoctets. Cela peut entraîner des refus de connexion ou des ralentissements, selon la quantité de mémoire nécessaire pour les opérations normales. Cette option est principalement utilisée pour forcer le processus HAProxy à fonctionner dans un scénario de consommation de ressources contrainte. Il est important de noter que la mémoire n’est pas partagée entre les processus haproxy, et un processus fils créé via l’appel système fork() hérite des limites de ressources de son processus parent. Ainsi, en mode maître-travailleur, cette limite de mémoire est appliquée séparément au maître et à son processus travailleur forké.

-n <limit>

-n <limit>

limite la limite de connexions par processus à <limit>. Cela équivaut à la directive « maxconn » de la section globale. Elle a une priorité supérieure à cette directive. Cela peut être utilisé pour imposer rapidement des limites inférieures afin d’éviter une interruption de service sur des systèmes où les limites de ressources sont trop faibles.

-p <file>

-p <file>

Écrivez les PID de tous les processus dans <file> au démarrage. Cela équivaut à la directive “pidfile” de la section “global”. Le fichier est ouvert avant d’entrer dans la jail chroot, et après avoir exécuté le chdir() implicite par “-C”. Chaque PID apparaît sur une ligne distincte.

-q

-q

activer le mode « quiet ». Cela désactive les messages de sortie. Peut être utilisé en combinaison avec “-c” pour vérifier uniquement si un fichier de configuration est valide ou non.

-S <bind>[,bind_options...]

-S <bind>[,bind_options...]

En mode master-worker, liez une interface CLI maître, qui permet l’accès à tous les processus, qu’ils soient en cours d’exécution ou en cours de terminaison. Pour des raisons de sécurité, il est recommandé de lier l’interface CLI maître à une socket UNIX locale. Les options de liaison sont les mêmes que le mot-clé « bind » dans le fichier de configuration, avec les mots séparés par des virgules au lieu d’espaces.

Notez que ce socket ne peut pas être utilisé pour récupérer les sockets d’écoute d’un ancien processus lors d’un rechargement sans interruption.

-sf <pid>*

-sf <pid>*

envoyer le signal « finish » (SIGUSR1) aux processus anciens après la fin du démarrage, afin de leur demander de terminer leur traitement et de quitter. <pid> est une liste d’identifiants de processus à signaler (un par argument). La liste se termine à la première option commençant par un « - ». Il n’est pas problématique que la liste des identifiants de processus soit vide, de sorte qu’elle puisse être construite dynamiquement à partir du résultat d’une commande comme « pidof » ou « pgrep ».

-st <pid>*

-st <pid>*

envoyer le signal « terminate » (SIGTERM) aux processus anciens après la fin du démarrage pour les interrompre immédiatement sans terminer ce qu’ils étaient en train de faire. <pid> est une liste d’identifiants de processus à signaler (un par argument). La liste se termine à tout argument commençant par un « - ». Il n’est pas problématique que la liste des identifiants de processus soit vide, de sorte qu’elle puisse être construite dynamiquement à partir du résultat d’une commande comme « pidof » ou « pgrep ».

-v

-v

Indiquez la version et la date de compilation.

-vv

-vv

affiche la version, les options de compilation, les versions des bibliothèques et les pollers disponibles. Cette sortie est systématiquement demandée lors de la soumission d’un rapport de bug.

-x <unix_socket>

-x <unix_socket>

se connecter au socket spécifié et essayer de récupérer les sockets d’écoute de l’ancien processus, puis les utiliser à la place de tenter de lier de nouveaux sockets. Cela est utile pour éviter de manquer toute nouvelle connexion lors du rechargement de la configuration sous Linux.

Sans mode master-worker, la fonctionnalité doit être activée sur le socket de statistiques en utilisant « expose-fd listeners » dans votre configuration.

En mode master-worker, il n’est pas nécessaire d’utiliser des « écouteurs expose-fd », le master utilisera automatiquement cette option lors d’un rechargement avec la syntaxe « sockpair@ », ce qui permet au master de se connecter directement à un worker sans avoir recours à une socket de statistiques déclarée dans la configuration. Si vous souhaitez désactiver cette fonctionnalité, vous pouvez passer -x /dev/null.

Une manière sûre de lancer HAProxy à partir d’un fichier d’initialisation consiste à forcer le mode démon, à stocker les PID existants dans un fichier de PID, puis à utiliser ce fichier pour avertir les processus anciens de se terminer avant de quitter :

haproxy -f /etc/haproxy.cfg \
        -D -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)

Lorsque la configuration est répartie entre plusieurs fichiers spécifiques (par exemple : tcp versus http), il est recommandé d’utiliser l’option “-f” :

haproxy -f /etc/haproxy/global.cfg -f /etc/haproxy/stats.cfg \
        -f /etc/haproxy/default-tcp.cfg -f /etc/haproxy/tcp.cfg \
        -f /etc/haproxy/default-http.cfg -f /etc/haproxy/http.cfg \
        -D -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)

Lorsqu’un nombre inconnu de fichiers est attendu, par exemple des fichiers spécifiques à un client, il est recommandé de leur attribuer un nom commençant par un numéro de séquence de taille fixe, puis de les charger à l’aide de “–”, éventuellement après avoir chargé certains paramètres par défaut :

haproxy -f /etc/haproxy/global.cfg -f /etc/haproxy/stats.cfg \
        -f /etc/haproxy/default-tcp.cfg -f /etc/haproxy/tcp.cfg \
        -f /etc/haproxy/default-http.cfg -f /etc/haproxy/http.cfg \
        -D -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid) \
        -f /etc/haproxy/default-customers.cfg -- /etc/haproxy/customers/*

Parfois, une erreur de démarrage peut survenir pour une raison quelconque. Il est alors important de vérifier que la version d’HAProxy que vous lancez est bien celle attendue et qu’elle prend en charge les fonctionnalités que vous attendez (par exemple : SSL, PCRE, compression, Lua, etc.). Cette vérification peut être effectuée à l’aide de la commande « HAProxy -vv ». Certains éléments importants, tels que certaines options de compilation, le système cible et les versions des bibliothèques utilisées, y sont indiqués. C’est également ce que vous serez systématiquement invité à fournir lors de la soumission d’un rapport de bug :

$ haproxy -vv

HAProxy version 1.6-dev7-a088d3-4 2015/10/08 Copyright 2000-2015 Willy Tarreau willy@haproxy.org

Build options:

TARGET  = linux2628
CPU     = generic
CC      = gcc
CFLAGS  = -pg -O0 -g -fno-strict-aliasing -Wdeclaration-after-statement \
          -DBUFSIZE=8030 -DMAXREWRITE=1030 -DSO_MARK=36 -DTCP_REPAIR=19
OPTIONS = USE_ZLIB=1 USE_DLMALLOC=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1

Default settings:

maxconn = 2000, bufsize = 8030, maxrewrite = 1030, maxpollevents = 200

Encrypted password support via crypt(3): yes Built with zlib version: 1.2.6 Compression algorithms supported: identity(“identity”), deflate(“deflate”), \ raw-deflate(“deflate”), gzip(“gzip”) Built with OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 Running on OpenSSL version: OpenSSL 1.0.1o 12 Jun 2015 OpenSSL library supports TLS extensions: yes OpenSSL library supports SNI: yes OpenSSL library supports prefer-server-ciphers: yes Built with PCRE version: 8.12 2011-01-15 PCRE library supports JIT: no (USE_PCRE_JIT not set) Built with Lua version: Lua 5.3.1 Built with transparent proxy support using: IP_TRANSPARENT IP_FREEBIND

Available polling systems:

 epoll: pref=300,  test result OK
  poll: pref=200,  test result OK
select: pref=150,  test result OK

Total: 3 (3 usable), will use epoll.

Les informations pertinentes que de nombreux utilisateurs non développeurs peuvent vérifier ici sont :

- the version

- the version

1.6-dev7-a088d3-4 signifie que le code est actuellement au commit ID « a088d3 », qui est le 4e après la version officielle “1.6-dev7”. La version 1.6-dev7 s’afficherait sous la forme “1.6-dev7-8c1ad7”. Ce qui compte ici, c’est en réalité “1.6-dev7”. Il s’agit de la 7e version de développement de ce qui deviendra ultérieurement la version 1.6. Une version de développement non adaptée à une utilisation en production (sauf si vous savez exactement ce que vous faites). Une version stable s’affiche sous la forme d’une version à trois nombres, comme “1.5.14-16f863”, indiquant le 14e correctif appliqué sur la version 1.5. Il s’agit d’une version prête à être utilisée en production.

- the release date

- the release date

2015/10/08. Il est représenté au format universel année/mois/jour. Ici, cela signifie le 8 août 2015. Étant donné que les versions stables sont publiées tous les quelques mois (1 à 2 mois au début, parfois 6 mois une fois le produit très stable), si vous voyez une date ancienne ici, cela signifie probablement que vous êtes touché par un certain nombre de bogues ou de problèmes de sécurité qui ont depuis été corrigés, et qu’il pourrait être utile de vérifier le site officiel.

- build options

- build options

Ils concernent les personnes qui construisent elles-mêmes leurs paquets ; ils peuvent expliquer pourquoi certaines fonctionnalités ne se comportent pas comme prévu. Par exemple, la version de développement ci-dessus a été compilée pour Linux 2.6.28 ou ultérieur, ciblant un processeur générique (sans optimisations spécifiques au processeur), et ne contient aucune optimisation de code (-O0), ce qui entraîne une performance médiocre.

- libraries versions

- libraries versions

La version de zlib est indiquée comme étant présente dans la bibliothèque elle-même. En général, zlib est considéré comme un produit très stable et les mises à jour sont presque jamais nécessaires. OpenSSL indique deux versions : celle utilisée au moment de la compilation et celle actuellement utilisée, telle qu’elle est présente sur le système. Ces versions peuvent différer uniquement par la dernière lettre, mais jamais par les chiffres. La date de compilation est également indiquée, car la plupart des bugs d’OpenSSL sont liés à la sécurité et doivent être pris au sérieux ; cette bibliothèque doit donc absolument être tenue à jour. Un version âgée de quatre mois est hautement suspecte, et en effet, une mise à jour a été manquée. PCRE fournit des expressions régulières très rapides et est fortement recommandé. Certaines de ses extensions, comme le JIT, ne sont pas présentes dans toutes les versions et restent encore jeunes, si bien que certaines personnes préfèrent ne pas les activer lors de la compilation, ce qui explique pourquoi l’état de compilation est également indiqué. En ce qui concerne le langage de script Lua, HAProxy attend la version 5.3, qui est très récente, étant sortie peu avant HAProxy 1.6. Il est important de vérifier sur le site web de Lua si des correctifs sont proposés pour cette branche.

- Available polling systems will affect the process's scalability when

- Available polling systems will affect the process's scalability when

gestion de plus d’environ mille connexions simultanées. Ces mécanismes ne sont disponibles que lorsque le système approprié a été indiqué dans la variable TARGET lors de la compilation. Le mécanisme « epoll » est fortement recommandé sous Linux, et le mécanisme « kqueue » est fortement recommandé sous BSD. En leur absence, la fonction poll() ou même select() sera utilisée, entraînant une utilisation élevée du CPU lors de la gestion d’un grand nombre de connexions.

25 - 4. Arrêt et redémarrage de HAProxy

Signaux, arrêts doux, rechargements et redémarrages en mode maître-worker

HAProxy prend en charge une interruption douce et une interruption brutale. L’interruption brutale est simple : lorsqu’un signal SIGTERM est envoyé au processus HAProxy, celui-ci quitte immédiatement et toutes les connexions établies sont fermées. L’interruption douce est déclenchée lorsqu’un signal SIGUSR1 est envoyé au processus HAProxy. Elle consiste à ne plus se lier aux ports d’écoute, tout en continuant à traiter les connexions existantes jusqu’à leur fermeture. Une fois la dernière connexion fermée, le processus se termine.

La méthode d’arrêt rigide est utilisée pour les actions « stop » ou « restart » du script de gestion du service. L’arrêt graduel est utilisé pour l’action « reload », qui tente de recharger en douceur une nouvelle configuration dans un nouveau processus.

Ces signaux peuvent être envoyés par le nouveau processus HAProxy lui-même pendant un rechargement ou un redémarrage, afin de ne les émettre qu’au dernier moment et seulement s’ils sont indispensables. C’est ce que font respectivement les options “-st” (arrêt brutal) et “-sf” (arrêt gracieux).

En mode master-worker, il n’est pas nécessaire de lancer un nouveau processus haproxy pour recharger la configuration. Le processus master réagit au signal SIGUSR2 en s’exécutant à nouveau avec le paramètre -sf suivi des PID des workers. Le master analysera alors le fichier de configuration et créera de nouveaux workers.

Pour mieux comprendre l’utilisation de ces signaux, il est essentiel de maîtriser l’ensemble du mécanisme de redémarrage.

Tout d’abord, un processus HAProxy existant est en cours d’exécution. L’administrateur utilise une commande spécifique au système, telle que « /etc/init.d/haproxy reload », pour indiquer qu’il souhaite appliquer le nouveau fichier de configuration. Ce qui se produit ensuite est le suivant. Tout d’abord, le script de service (/etc/init.d/haproxy ou équivalent) vérifiera que le fichier de configuration est correctement parsé à l’aide de la commande « HAProxy -c ». Ensuite, il tentera de démarrer HAProxy avec ce fichier de configuration, en utilisant « -st » ou « -sf ».

Ensuite, HAProxy tente de se lier à tous les ports d’écoute. Si des erreurs critiques se produisent (par exemple : adresse non présente sur le système, accès refusé), le processus se termine avec une erreur. Si la liaison d’une socket échoue car un port est déjà utilisé, le processus envoie d’abord un signal SIGTTOU à tous les PID spécifiés dans la liste de PID “-st” ou “-sf”. Ce signal est appelé le « signal de pause ». Il invite tous les processus haproxy existants à interrompre temporairement l’écoute de leurs ports afin que le nouveau processus puisse réessayer la liaison. Pendant cette période, le processus ancien continue à traiter les connexions existantes. Si la liaison échoue toujours (par exemple parce qu’un port est partagé avec un autre démon), le nouveau processus envoie un signal SIGTTIN aux anciens processus pour leur demander de reprendre leurs opérations comme si rien ne s’était produit. Les anciens processus reprennent alors l’écoute des ports et continuent à accepter les connexions. Notez que ce mécanisme dépend du système et que certains systèmes d’exploitation ne le supportent pas en mode multi-processus.

Si le nouveau processus parvient à se lier correctement à tous les ports, il envoie soit le SIGTERM (arrêt forcé en cas de “-st”), soit le SIGUSR1 (arrêt graduel en cas de “-sf”) à tous les processus pour leur notifier qu’il est désormais chargé des opérations et que les anciens processus doivent quitter, soit immédiatement, soit une fois leur tâche terminée.

Il est important de noter qu’au cours de cette période, deux courtes fenêtres de quelques millisecondes chacune peuvent entraîner une légère augmentation du nombre de défaillances de connexion, notamment sous forte charge. Les taux de défaillance observés sont généralement d’environ 1 défaillance par rechargement pour chaque 10 000 nouvelles connexions par seconde, ce qui signifie qu’un site fortement sollicité fonctionnant à 30 000 nouvelles connexions par seconde peut connaître environ 3 défaillances de connexion à chaque rechargement. Ces deux situations se produisent lorsque :

  • si le nouveau processus échoue à se lier en raison de la présence du processus ancien, il devra d’abord passer par la séquence SIGTTOU+SIGTTIN, qui dure généralement environ un milliseconde pour quelques dizaines de frontaux, pendant laquelle certaines ports ne seront ni liés au processus ancien ni encore liés au nouveau. HAProxy contourne ce problème sur les systèmes qui prennent en charge les options de socket SO_REUSEPORT, car elles permettent au nouveau processus de se lier sans devoir d’abord demander au processus ancien de se délier. La plupart des systèmes BSD ont pris en charge cela depuis longtemps. Linux l’a pris en charge à partir de la version 2.0, puis l’a supprimé vers la version 2.2, bien que des correctifs aient été disponibles à l’époque. Il a été réintroduit dans le noyau 3.9 ; si vous constatez un taux d’échec de connexion supérieur à celui mentionné ci-dessus, veillez à ce que votre noyau soit la version 3.9 ou ultérieure, ou que les correctifs pertinents aient été appliqués à votre noyau (moins probable).

  • lorsque les anciens processus ferment les ports d’écoute, le noyau ne redistribue pas toujours les connexions en attente restantes dans la file d’attente du socket. En cas de charge élevée, un paquet SYN peut survenir juste avant la fermeture du socket, ce qui entraîne l’envoi d’un paquet RST au client. Dans certains environnements critiques où même une seule perte est inacceptable, ces pertes sont parfois gérées à l’aide de règles de pare-feu bloquant les paquets SYN pendant le redémarrage, forçant ainsi le client à réessayer. Cette solution dépend entièrement du système, car certains systèmes peuvent accéder à d’autres files d’attente d’écoute et éviter ainsi ce RST. Un deuxième cas concerne l’ACK du client sur un socket local qui était en état SYN_RECV juste avant la fermeture. Cet ACK entraîne l’envoi d’un paquet RST alors que le processus haproxy n’est pas encore au courant. Ce cas est plus difficile à éliminer, bien que les règles de filtrage du pare-feu mentionnées ci-dessus fonctionnent bien si elles sont appliquées une seconde environ avant le redémarrage du processus.

Pour la grande majorité des utilisateurs, de tels écarts ne se produiront jamais, car ils n’ont pas une charge suffisante pour déclencher les conditions de concurrence. Et pour la plupart des utilisateurs à fort trafic, le taux d’échec reste encore raisonnablement dans la marge de bruit, à condition qu’au moins SO_REUSEPORT soit correctement pris en charge sur leurs systèmes.

26 - 5. Limites des descripteurs de fichiers

Limites des descripteurs, dimensionnement, contraintes du système et dépannage

Afin de garantir que toutes les connexions entrantes soient correctement servies, HAProxy calcule au moment du chargement le nombre total de descripteurs de fichiers nécessaires durant la durée de vie du processus. Un processus Unix classique reçoit généralement 1024 descripteurs de fichiers par défaut, et un processus privilégié peut augmenter lui-même cette limite. C’est une des raisons de lancer HAProxy en tant que root et de lui permettre d’ajuster cette limite. La limite par défaut de 1024 descripteurs de fichiers permet approximativement 500 connexions simultanées. Ce calcul repose sur le paramètre global maxconn, qui limite le nombre total de connexions par processus, le nombre d’écouteurs, le nombre de serveurs ayant un contrôle d’état activé, les vérifications d’agent, les pairs, les enregistreurs et éventuellement quelques autres exigences techniques. Une estimation simple de ce nombre consiste à doubler la valeur de maxconn et à ajouter quelques dizaines pour obtenir une approximation du nombre de descripteurs de fichiers nécessaires.

HAProxy ne savait initialement pas calculer cette valeur, et il était nécessaire de la spécifier à l’aide de l’option « ulimit-n » dans la section globale. C’est pourquoi, même aujourd’hui, de nombreuses configurations incluent encore cette option. Malheureusement, cette valeur était souvent mal calculée, entraînant des échecs de connexion lorsque la limite maxconn était atteinte, au lieu de limiter les connexions entrantes en attendant la disponibilité des ressources nécessaires. Pour cette raison, il est important de supprimer toute option « ulimit-n » résiduelle provenant de versions très anciennes.

Augmenter le nombre de descripteurs de fichiers pour accepter des charges modérées est obligatoire, mais nécessite des ajustements spécifiques au système d’exploitation. Tout d’abord, le système de sondage select() est limité à 1024 descripteurs de fichiers. En réalité, sur Linux, il était autrefois capable de gérer davantage, mais certains systèmes d’exploitation livrent des politiques SELinux excessivement restrictives interdisant l’utilisation de select() avec plus de 1024 descripteurs de fichiers. HAProxy refuse désormais de démarrer dans ce cas afin d’éviter tout problème à l’exécution. Sur tous les systèmes d’exploitation pris en charge, poll() est disponible et ne souffre pas de cette limitation. Il est automatiquement sélectionné, donc aucune action n’est requise pour obtenir une configuration fonctionnelle. Toutefois, poll() devient très lent lorsque le nombre de descripteurs de fichiers augmente. Bien que HAProxy fasse tout son possible pour limiter cet impact sur les performances (par exemple grâce à la mise en cache interne des descripteurs de fichiers et au traitement par lots), une règle empirique consiste à dire qu’utiliser poll() avec plus d’un millier de connexions simultanées consommera beaucoup de CPU.

Pour les systèmes Linux basés sur les noyaux 2.6 et ultérieurs, l’appel système epoll() sera utilisé. Il s’agit d’un mécanisme bien plus évolutif, fondé sur des rappels dans le noyau, garantissant un temps de réveil constant, quel que soit le nombre de descripteurs de fichiers surveillés. Il est utilisé automatiquement lorsqu’il est détecté, à condition que HAProxy ait été compilé pour l’une des variantes Linux. Sa présence et son support peuvent être vérifiés à l’aide de la commande « HAProxy -vv ».

Pour les systèmes BSD qui le supportent, kqueue() est disponible en tant qu’alternative. Il est bien plus rapide que poll() et légèrement plus rapide que epoll(), grâce à sa gestion par lots des modifications. Au moins FreeBSD et OpenBSD le supportent. Tout comme pour epoll() sous Linux, son support et sa disponibilité sont indiqués dans la sortie de la commande « HAProxy -vv ».

Disposer d’un bon poller est une chose, mais il est obligatoire que le processus puisse atteindre les limites. Lorsque HAProxy démarre, il définit immédiatement les limites des descripteurs de fichiers du nouveau processus et vérifie si cette opération réussit. En cas d’échec, il le signale avant le fork afin que l’administrateur puisse détecter le problème. Tant que le processus est lancé en tant que root, il ne devrait pas y avoir de raison que ce paramétrage échoue. Toutefois, il peut échouer si le processus est lancé par un utilisateur non privilégié. Si une raison impérieuse existe pour ne pas lancer HAProxy en tant que root (par exemple : lancé par des utilisateurs finaux ou par un compte dédié à une application), alors l’administrateur système peut augmenter la limite des descripteurs de fichiers pour cet utilisateur spécifique. L’efficacité de ce paramétrage peut être vérifiée en exécutant « ulimit -n » depuis la ligne de commande de l’utilisateur. Elle doit refléter la nouvelle limite.

Avertissement : lorsque les limites d’un utilisateur non privilégié sont modifiées dans son compte, il est fréquent que ces valeurs ne soient prises en compte que lors de la connexion de l’utilisateur, et non du tout dans certains scripts exécutés au démarrage du système ou dans des crontabs. Cela dépend entièrement du système d’exploitation ; veillez à vérifier la commande « ulimit -n » avant de lancer haproxy dans ce cas. Il est généralement conseillé de ne jamais lancer haproxy en tant qu’utilisateur non privilégié dans un environnement de production. Une autre bonne raison est qu’il empêche haproxy d’activer certaines protections de sécurité.

Une fois certain que le système autorise le processus HAProxy à utiliser le nombre demandé de descripteurs de fichiers, deux nouvelles limites propres au système peuvent apparaître. La première est la limite globale du nombre de descripteurs ouverts sur le système, tous processus confondus. Lorsqu’elle est atteinte, accept() ou socket() renvoie généralement ENFILE. La seconde est la limite stricte par processus, qui empêche setrlimit() de fixer une valeur supérieure. Ces limites dépendent fortement du système d’exploitation. Sous Linux, la limite globale est fixée au démarrage en fonction de la mémoire et peut être modifiée avec le sysctl “fs.file-max”. La limite stricte par processus vaut 1048576 par défaut et peut être modifiée avec le sysctl “fs.nr_open”.

Les limites des descripteurs de fichiers peuvent être observées sur un processus en cours d’exécution lorsque celles-ci sont trop faibles. L’outil strace signalera que les appels système accept() et socket() retournent “-1 EMFILE” lorsque les limites du processus ont été atteintes. Dans ce cas, il suffit de relever la valeur de “ulimit-n” (ou de la supprimer) pour résoudre le problème. Si ces appels système retournent “-1 ENFILE”, cela signifie que les limites du noyau ont été atteintes et qu’une action doit être entreprise sur un paramètre système global. Ces problèmes doivent absolument être traités, car ils entraînent une utilisation élevée du CPU (lorsque accept() échoue) et des échecs de connexion généralement perceptibles par l’utilisateur. Une solution consiste également à réduire la valeur maxconn globale afin d’imposer une sérialisation, et éventuellement à désactiver la réutilisation persistante HTTP afin de forcer la libération et la réutilisation plus rapide des connexions.

27 - 6. Gestion de la mémoire

Allocation mémoire, limites, pools, tampons et dimensionnement des processus

HAProxy utilise une gestion mémoire basée sur des pools, simple et rapide. Étant donné qu’il repose sur un nombre réduit de types d’objets différents, il est bien plus efficace de tirer de nouveaux objets depuis un pool déjà contenant des objets de la taille appropriée que d’appeler malloc() pour chaque taille différente. Les pools sont organisés selon une structure de pile ou LIFO, de sorte que les objets nouvellement alloués proviennent d’objets récemment libérés, encore présents dans les caches CPU. Les pools de tailles similaires sont regroupés afin de limiter la fragmentation mémoire.

Par défaut, le focus étant mis sur les performances, chaque objet libéré est remis dans le pool d’où il provient, et les objets alloués ne sont jamais libérés, car ils sont censés être réutilisés très bientôt.

Sur la ligne de commande, il est possible de vérifier l’utilisation de la mémoire dans les pools grâce à la commande « show pools » :

> show pools
Dumping pools usage. Use SIGQUIT to flush them.
  - Pool cache_st (16 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccc40=03 [SHARED]
  - Pool pipe (32 bytes): 5 allocated (160 bytes), 5 used, 0 failures, 2 users, @0x9ccac0=00 [SHARED]
  - Pool comp_state (48 bytes): 3 allocated (144 bytes), 3 used, 0 failures, 5 users, @0x9cccc0=04 [SHARED]
  - Pool filter (64 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 3 users, @0x9ccbc0=02 [SHARED]
  - Pool vars (80 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccb40=01 [SHARED]
  - Pool uniqueid (128 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9cd240=15 [SHARED]
  - Pool task (144 bytes): 55 allocated (7920 bytes), 55 used, 0 failures, 1 users, @0x9cd040=11 [SHARED]
  - Pool session (160 bytes): 1 allocated (160 bytes), 1 used, 0 failures, 1 users, @0x9cd140=13 [SHARED]
  - Pool h2s (208 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccec0=08 [SHARED]
  - Pool h2c (288 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cce40=07 [SHARED]
  - Pool spoe_ctx (304 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 2 users, @0x9ccf40=09 [SHARED]
  - Pool connection (400 bytes): 2 allocated (800 bytes), 2 used, 0 failures, 1 users, @0x9cd1c0=14 [SHARED]
  - Pool hdr_idx (416 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cd340=17 [SHARED]
  - Pool dns_resolut (480 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccdc0=06 [SHARED]
  - Pool dns_answer_ (576 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9ccd40=05 [SHARED]
  - Pool stream (960 bytes): 1 allocated (960 bytes), 1 used, 0 failures, 1 users, @0x9cd0c0=12 [SHARED]
  - Pool requri (1024 bytes): 0 allocated (0 bytes), 0 used, 0 failures, 1 users, @0x9cd2c0=16 [SHARED]
  - Pool buffer (8030 bytes): 3 allocated (24090 bytes), 2 used, 0 failures, 1 users, @0x9cd3c0=18 [SHARED]
  - Pool trash (8062 bytes): 1 allocated (8062 bytes), 1 used, 0 failures, 1 users, @0x9cd440=19
Total: 19 pools, 42296 bytes allocated, 34266 used.

Le nom du pool n’est indiquatif que, il correspond au nom du premier type d’objet utilisant ce pool. La taille entre parenthèses est la taille des objets dans ce pool. Les tailles d’objets sont toujours arrondies à l’entier multiple de 16 octets le plus proche. Le nombre d’objets actuellement alloués et le nombre équivalent d’octets sont indiqués afin de faciliter l’identification du pool responsable de la plus forte utilisation mémoire. Le nombre d’objets actuellement en cours d’utilisation est également indiqué dans le champ « used ». La différence entre « allocated » et « used » correspond aux objets qui ont été libérés et sont disponibles pour une utilisation immédiate. L’adresse en fin de ligne est l’adresse du pool, et le nombre suivant est l’indice du pool lorsqu’il existe, ou est indiqué comme -1 s’aucun indice n’a été attribué.

Il est possible de limiter la quantité de mémoire allouée par processus à l’aide de l’option en ligne de commande “-m”, suivie d’un nombre de mégaoctets. Cette limite s’applique à l’ensemble de l’espace adressable du processus, ce qui inclut la mémoire utilisée par certaines bibliothèques ainsi que la pile, mais constitue une limite fiable lors de la construction d’un système à ressources contraintes. Elle fonctionne de la même manière que “ulimit -v” sur les systèmes qui la supportent, ou “ulimit -d” sur les autres.

Si une allocation mémoire échoue en raison d’un dépassement de la limite mémoire ou du fait que le système ne dispose d’aucune mémoire disponible, HAProxy tente d’abord de libérer tous les objets disponibles de toutes les pools avant de tenter une nouvelle allocation mémoire. Ce mécanisme de libération de la mémoire inutilisée peut être déclenché en envoyant le signal SIGQUIT au processus HAProxy.

Pendant une opération de rechargement, le processus passe également en état d’arrêt gracieux, ce qui entraîne automatiquement certaines vidanges après avoir libéré toute connexion, afin de libérer toute mémoire possible et la préserver pour le nouveau processus.

28 - 7. Utilisation du CPU

Threads, affinité CPU, saturation, profilage et comportement des performances

HAProxy passe normalement la majeure partie de son temps en mode noyau et une part plus faible en mode utilisateur. Un processeur 3,5 GHz correctement optimisé peut supporter un débit d’environ 80 000 établissements et fermetures de connexions bout-en-bout par seconde à 100 % d’utilisation sur un seul cœur. Lorsqu’un cœur est saturé, les valeurs typiques sont :

  • 95 % système, 5 % utilisateur pour des connexions TCP longues ou de grands objets HTTP
  • 85 % système et 15 % utilisateur pour des connexions TCP courtes ou de petits objets HTTP en mode fermé
  • 70 % système et 30 % utilisateur pour de petits objets HTTP en mode keep-alive

Le nombre de règles traitées et d’expressions régulières augmente la partie en espace utilisateur. La présence de règles de pare-feu, du suivi des connexions et de tables de routage complexes dans le système augmente quant à elle la partie noyau.

Sur la plupart des systèmes, le temps CPU observé lors des transferts réseau peut être divisé en 4 parties :

  • la partie d’interruption, qui concerne tout traitement effectué lors de la réception d’E/S, avant même que le processus cible ne soit connu. En général, les paquets Rx sont comptabilisés dans l’interruption. Sur certains systèmes, comme Linux, où le traitement d’interruption peut être différé vers un thread dédié, celui-ci peut apparaître sous la forme d’un softirq, et le thread s’appelle ksoftirqd/0 (pour le CPU 0). Le CPU chargé de cette charge est généralement défini par les paramètres matériels, bien qu’en cas de softirq il soit souvent possible de rediriger le traitement vers un autre CPU. Cette partie d’interruption est souvent perçue comme parasite, car elle n’est associée à aucun processus, mais elle correspond en réalité à un traitement effectué pour préparer le travail du processus.

  • la partie système, qui concerne tout traitement effectué à l’aide de code noyau appelé depuis l’espace utilisateur. Les appels système sont comptabilisés comme du temps système, par exemple. Tous les paquets Tx livrés de manière synchrone seront comptabilisés comme du temps système. Si certains paquets doivent être différés en raison de la saturation des files d’attente, ils pourront être traités ultérieurement dans le contexte d’interruption (par exemple : à la réception d’un ACK ouvrant une fenêtre TCP).

  • la partie utilisateur, qui exécute exclusivement du code d’application en espace utilisateur. HAProxy s’exécute exclusivement dans cette partie, bien qu’il utilise abondamment les appels système. Le traitement des règles, les expressions régulières, la compression et le chiffrement ajoutent à la consommation de CPU attribuée à la partie utilisateur.

  • la partie inactif, c’est-à-dire ce que fait le processeur lorsqu’il n’a rien à faire. Par exemple, HAProxy attend qu’une connexion entrante arrive, ou attend qu’une donnée soit envoyée, ce qui signifie que le système attend une accusé de réception (ACK) du client pour transmettre ces données.

En pratique, concernant l’activité d’HAProxy, il est généralement raisonnable (mais totalement inexact) de considérer que les interruptions/softirq sont dues au traitement Rx dans les pilotes noyau, que le temps utilisateur est dû au traitement au niveau 7 dans HAProxy, et que le temps système est dû au traitement réseau sur le chemin Tx.

Étant donné que HAProxy s’exécute autour d’une boucle d’événements, il attend de nouveaux événements à l’aide de poll() (ou d’une alternative quelconque) et traite tous ces événements aussi rapidement que possible avant de retourner à poll() pour attendre de nouveaux événements. Il mesure le temps passé en attente dans poll() par rapport au temps consacré au traitement des événements. Le rapport entre le temps passé en attente et le temps total est appelé le temps « idle », c’est-à-dire la durée passée à attendre qu’une action se produise. Ce rapport est affiché dans la page de statistiques sur la ligne « idle », ou “Idle_pct” en ligne de commande. Lorsqu’il est proche de 100 %, cela signifie que la charge est extrêmement faible. Lorsqu’il est proche de 0 %, cela indique qu’il y a constamment une activité. Bien qu’il ne puisse pas être très précis sur un système surchargé en raison de la préemption éventuelle du processeur par d’autres processus, il fournit tout de même une bonne estimation du travail perçu par HAProxy : si la charge est faible et que le taux d’« idle » est également faible, cela peut indiquer que HAProxy a beaucoup de travail à accomplir, probablement à cause de règles très coûteuses à traiter. À l’inverse, si HAProxy indique un taux d’« idle » proche de 100 % alors que les performances sont lentes, cela signifie qu’il ne peut rien faire pour accélérer les choses car il attend déjà des données entrantes à traiter. Dans l’exemple ci-dessous, HAProxy est complètement inactif :

$ echo "show info" | socat - /var/run/haproxy.sock | grep ^Idle
Idle_pct: 100

Lorsque le taux d’inactivité commence à devenir très faible, il est important de configurer le système et de positionner correctement les processus et les interruptions afin de préserver au maximum les ressources CPU pour toutes les tâches. Si un pare-feu est présent, il peut être utile d’essayer de le désactiver ou de le configurer pour s’assurer qu’il n’est pas à l’origine d’une grande partie de la limitation des performances. Il convient de noter que le déchargement d’un pare-feu étatique réduit généralement à la fois le nombre d’interruptions/softirq et l’utilisation du système, car de tels pare-feux agissent à la fois sur les chemins Rx et Tx. Sous Linux, le déchargement des modules nf_conntrack et ip_conntrack permettra de vérifier s’il y a un gain à tirer. Si tel est le cas, le module fonctionne avec les paramètres par défaut, et il faudra déterminer comment le configurer pour une meilleure performance. En général, cela consiste à augmenter considérablement la taille du tableau de hachage. Sous FreeBSD, la commande “pfctl -d” désactive à la fois le pare-feu “pf” et son moteur étatique.

Si une grande partie du temps est consacrée aux interruptions et softirq, assurez-vous qu’elles ne s’exécutent pas sur le même processeur. La plupart des systèmes fixent les tâches sur le processeur qui reçoit le trafic réseau, car cela améliore certaines charges. Pour les charges très liées au réseau, c’est l’inverse : le processus HAProxy doit concurrencer la pile noyau. Fixer HAProxy sur un cœur et les interruptions sur un autre, partageant le même cache L3, améliore sensiblement les performances réseau. En pratique, HAProxy et la pile réseau ont des quantités de travail proches et peuvent presque saturer chacun un cœur. Sous Linux, utilisez taskset pour HAProxy ou cpu-map dans sa configuration ; les interruptions sont affectées sous /proc/irq. De nombreuses interfaces réseau prennent en charge plusieurs files et interruptions. Il est généralement utile de les répartir sur quelques cœurs partageant le même cache L3. Arrêtez toujours irq_balance, qui effectue le pire choix pour ce type de charge.

Pour les charges de travail intensives en CPU, telles que de nombreuses connexions SSL ou une compression importante, il peut être pertinent d’utiliser plusieurs processus dédiés à certaines tâches, bien qu’aucune règle universelle ne s’applique ici et qu’une expérimentation s’impose.

Afin d’augmenter la capacité du processeur, il est possible de faire exécuter HAProxy en plusieurs processus, en utilisant la directive « nbproc » dans la section globale. Toutefois, certaines limitations s’appliquent :

  • Les contrôles d’état sont exécutés par processus, les serveurs cibles reçoivent donc autant de contrôles qu’il y a de processus en cours d’exécution ;
  • Les valeurs maxconn et les files d’attente sont par processus, il faut donc définir la valeur correcte afin d’éviter de surcharger les serveurs ;
  • Les connexions sortantes doivent éviter d’utiliser des plages de ports pour éviter les conflits ;
  • Les tables de persistance sont par processus et ne sont pas partagées entre les processus ;
  • Chaque section peers ne peut être exécutée que sur un seul processus à la fois ;
  • Les opérations en ligne de commande n’agissent que sur un seul processus à la fois.

En gardant cela à l’esprit, la configuration la plus simple consiste souvent à faire fonctionner une première couche sur plusieurs processus, chargée du traitement intensif, qui transfère le trafic vers une deuxième couche exécutée dans un seul processus. Ce mécanisme convient particulièrement au chiffrement SSL et à la compression, qui sont les deux fonctionnalités les plus exigeantes en ressources CPU. Les instances peuvent facilement être chaînées via des sockets UNIX (plus économiques que les sockets TCP et qui n’occupent pas de ports), ainsi que via le protocole proxy, utile pour transmettre les informations client à l’étape suivante. Lors de cette configuration, il est généralement préférable de lier toutes les tâches exécutées dans un seul processus au processus numéro 1, et les tâches supplémentaires aux processus suivants, afin de faciliter la génération de configurations similaires pour différentes machines.

Sur les versions Linux 3.9 et ultérieures, exécuter HAProxy en mode multi-processus est beaucoup plus efficace lorsque chaque processus utilise un socket d’écoute distinct sur le même IP:port ; cela permet au noyau de répartir uniformément la charge entre tous les processus au lieu de les réveiller tous. Veuillez consulter l’option « process » des lignes de mot-clé « bind » dans le manuel de configuration pour plus d’informations.

29 - 8. Journalisation

Intégration Syslog, journaux de démarrage, journaux d’exécution et dépannage des journaux

Pour la journalisation, HAProxy s’appuie toujours sur un serveur syslog, car il ne réalise aucune opération sur le système de fichiers. La méthode standard consiste à envoyer les journaux via UDP vers le serveur de journalisation (par défaut sur le port 514). Il est très courant de le configurer sur 127.0.0.1, où s’exécute le démon syslog local, mais il peut aussi être utilisé sur le réseau pour journaliser sur un serveur central. Ce dernier offre des avantages supplémentaires, notamment dans les scénarios actif-actif où il est souhaitable de conserver les journaux fusionnés dans l’ordre d’arrivée. HAProxy peut également utiliser une socket UNIX pour envoyer ses journaux au démon syslog local, mais cela n’est pas recommandé, car si le serveur syslog est redémarré pendant que HAProxy est en cours d’exécution, la socket sera remplacée et les nouveaux journaux seront perdus. Étant donné que HAProxy sera isolé dans une prison chroot, il ne pourra pas se reconnecter à la nouvelle socket. Des observations sur le terrain ont également montré que les tampons utilisés sur les sockets UNIX sont très petits et entraînent la perte de messages même à des charges très faibles. Cela peut toutefois convenir pour les tests.

Il est recommandé d’ajouter la directive suivante à la section « global » afin que HAProxy écrive ses journaux dans le démon local en utilisant l’installation « local0 » :

log 127.0.0.1:514 local0

puis ajouter la ligne suivante à chaque section « defaults » ou à chaque section « frontend » et « backend » :

log global

Ainsi, tous les journaux seront centralisés grâce à la définition globale de l’emplacement du serveur de journaux.

Certains démons syslog n’écoutent pas par défaut les connexions UDP, si bien que, selon le démon utilisé, la syntaxe pour activer cette fonctionnalité varie :

  • sur sysklogd, vous devez passer l’argument “-r” dans la ligne de commande du démon afin qu’il écoute un socket UDP pour les journaux distants ; notez qu’il n’existe aucun moyen de le limiter à l’adresse 127.0.0.1, il recevra donc également les journaux provenant d’autres systèmes distants ;

  • sur rsyslogd, les lignes suivantes doivent être ajoutées au fichier de configuration :

$ModLoad imudp
$UDPServerAddress *
$UDPServerRun 514
  • sur syslog-ng, une nouvelle source peut être créée de la manière suivante ; elle doit ensuite être ajoutée en tant que source valide dans l’une des directives “log” :
source s_udp {
  udp(ip(127.0.0.1) port(514));
};

Veuillez consulter le manuel de votre daemon syslog pour plus d’informations. Si aucun journal n’apparaît dans les fichiers de journalisation du système, veuillez envisager les tests suivants :

  • redémarrez HAProxy. Chaque frontal et backend journalise une ligne indiquant son démarrage. Si ces journaux sont reçus, cela signifie que la journalisation fonctionne.

  • exécutez la commande « strace -tt -s100 -etrace=sendmsg -p <haproxy’s pid> » et effectuez une activité que vous attendez être journalisée. Vous devez voir les messages de journalisation envoyés via sendmsg(). S’ils ne s’affichent pas, redémarrez avec strace en surimpression sur HAProxy. Si vous ne voyez toujours aucun journal, cela signifie certainement qu’il y a une erreur dans votre configuration.

  • exécutez tcpdump pour surveiller le port 514, par exemple sur l’interface boucle locale si le trafic est envoyé localement : « tcpdump -As0 -ni lo port 514 ». Si les paquets apparaissent, cela prouve qu’ils sont envoyés, et le démon syslogd doit être dépanné.

Bien que les journaux de trafic soient envoyés depuis les frontaux (où les connexions entrantes sont acceptées), les backends doivent également être capables d’envoyer des journaux afin de signaler un changement d’état du serveur consécutif à un contrôle d’état. Veuillez consulter le manuel de configuration de HAProxy pour plus d’informations concernant toutes les options de journalisation possibles.

Il est pratique de choisir une facility qui n’est pas utilisée par d’autres démons. Les exemples HAProxy suggèrent souvent « local0 » pour les journaux de trafic et « local1 » pour les journaux d’administration, car ils ne sont jamais observés en production. Une seule facility suffirait également. Avoir des journaux séparés est pratique pour l’analyse, mais il est également important de se souvenir que les journaux peuvent parfois contenir des informations confidentielles, et qu’ils ne doivent donc pas être mélangés à d’autres journaux qui pourraient être accidentellement transmis à des personnes non autorisées.

Pour le dépannage sur site sans trop impacter la capacité du serveur, il est recommandé d’utiliser l’outil « halog » fourni avec HAProxy. Il s’agit d’un utilitaire similaire à grep, conçu pour traiter les fichiers de journaux HAProxy à un débit de données très élevé. Les performances typiques s’établissent entre 1 et 2 Go de journaux par seconde. Il permet d’extraire uniquement certains journaux (par exemple : rechercher des codes d’état HTTP de certaines catégories, l’état de terminaison des connexions, rechercher par plages de temps de réponse, ne montrer que les erreurs), de compter les lignes, de limiter la sortie à un nombre de lignes, et d’effectuer certaines statistiques avancées telles que trier les serveurs par temps de réponse ou nombre d’erreurs, trier les URL par temps ou nombre d’accès, trier les adresses clientes par nombre d’accès, etc. Il est particulièrement pratique pour repérer rapidement des anomalies telles qu’un robot effectuant des boucles sur le site, et le bloquer.

30 - 9. Statistiques et surveillance

Statistiques CSV et typées, commandes CLI d’exécution, CLI principale et fichiers de statistiques

Il est possible de consulter l’état de HAProxy. Le mécanisme le plus couramment utilisé est la page de statistiques HTTP. Cette page expose également un format de sortie CSV alternatif destiné aux outils de surveillance. Le même format est disponible via le socket Unix.

Les statistiques sont regroupées par catégories désignées sous le nom de domaines, correspondant aux différents composants d’HAProxy. Deux domaines sont disponibles : proxy et resolvers. Si aucun domaine n’est précisé, le domaine proxy est sélectionné. Notez que seules les statistiques du proxy sont affichées sur la page HTTP.

9.1. Format CSV

Les statistiques peuvent être consultées soit via le socket Unix, soit via la page HTTP. Les deux méthodes fournissent un format CSV dont les champs sont décrits ci-dessous. La première ligne commence par un dièse (’#’) et contient un mot par champ séparé par des virgules, représentant le titre de la colonne. Toutes les lignes suivantes, à partir de la deuxième, utilisent un format CSV classique avec une virgule comme délimiteur, et la guillemet double (’"’) comme délimiteur textuel facultatif, uniquement si le texte enclos est ambigu (s’il contient une guillemet ou une virgule). Le caractère guillemet double (’"’) présent dans le texte est doublé (’""’), ce qui correspond au format reconnu par la plupart des outils. Veuillez ne pas insérer de colonne avant celles-ci afin de ne pas rompre les outils utilisant des positions de colonne codées en dur.

Pour les statistiques du proxy, après chaque nom de champ, les types pouvant avoir une valeur pour ce champ sont indiqués entre parenthèses. Les types sont L (écouteurs), F (frontaux), B (backends) et S (serveurs). Un ensemble fixe de champs statiques est toujours disponible dans le même ordre. Une colonne contenant le caractère ‘-’ délimite la fin des champs statiques, après laquelle la présence ou l’ordre des champs n’est pas garanti.

Voici la liste des champs statiques utilisant le domaine de statistiques du proxy :

 0. pxname [LFBS]: proxy name
 1. svname [LFBS]: service name (FRONTEND for frontend, BACKEND for backend,
    any name for server/listener)
 2. qcur [..BS]: current queued requests. For the backend this reports the
    number queued without a server assigned.
 3. qmax [..BS]: max value of qcur
 4. scur [LFBS]: current sessions
 5. smax [LFBS]: max sessions
 6. slim [LFBS]: configured session limit
 7. stot [LFBS]: cumulative number of sessions
 8. bin [LFBS]: bytes in
 9. bout [LFBS]: bytes out
10. dreq [LFB.]: requests denied because of security concerns.
    - For tcp this is because of a matched tcp-request content rule.
    - For http this is because of a matched http-request or tarpit rule.
11. dresp [LFBS]: responses denied because of security concerns.
    - For http this is because of a matched http-request rule, or
      "option checkcache".
12. ereq [LF..]: request errors. Some of the possible causes are:
    - early termination from the client, before the request has been sent.
    - read error from the client
    - client timeout
    - client closed connection
    - various bad requests from the client.
    - request was tarpitted.
13. econ [..BS]: number of requests that encountered an error trying to
    connect to a backend server. The backend stat is the sum of the stat
    for all servers of that backend, plus any connection errors not
    associated with a particular server (such as the backend having no
    active servers).
14. eresp [..BS]: response errors. srv_abrt will be counted here also.
    Some other errors are:
    - write error on the client socket (won't be counted for the server stat)
    - failure applying filters to the response.
15. wretr [..BS]: number of times a connection to a server was retried.
16. wredis [..BS]: number of times a request was redispatched to another
    server. The server value counts the number of times that server was
    switched away from.
17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)/MAINT(resolution)...)
18. weight [..BS]: total effective weight (backend), effective weight (server)
19. act [..BS]: number of active servers (backend), server is active (server)
20. bck [..BS]: number of backup servers (backend), server is backup (server)
21. chkfail [...S]: number of failed checks. (Only counts checks failed when
    the server is up.)
22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts
    transitions to the whole backend being down, rather than the sum of the
    counters for each server.
23. lastchg [..BS]: number of seconds since the last UP<->DOWN transition
24. downtime [..BS]: total downtime (in seconds). The value for the backend
    is the downtime for the whole backend, not the sum of the server downtime.
25. qlimit [...S]: configured maxqueue for the server, or nothing in the
    value is 0 (default, meaning no limit)
26. pid [LFBS]: process id (0 for first instance, 1 for second, ...)
27. iid [LFBS]: unique proxy id
28. sid [L..S]: server id (unique inside a proxy)
29. throttle [...S]: current throttle percentage for the server, when
    slowstart is active, or no value if not in slowstart.
30. lbtot [..BS]: total number of times a server was selected, either for new
    sessions, or when re-dispatching. The server counter is the number
    of times that server was selected.
31. tracked [...S]: id of proxy/server if tracking is enabled.
32. type [LFBS]: (0=frontend, 1=backend, 2=server, 3=socket/listener)
33. rate [.FBS]: number of sessions per second over last elapsed second
34. rate_lim [.F..]: configured limit on new sessions per second
35. rate_max [.FBS]: max number of new sessions per second
36. check_status [...S]: status of last health check, one of:
       UNK     -> unknown
       INI     -> initializing
       SOCKERR -> socket error
       L4OK    -> check passed on layer 4, no upper layers testing enabled
       L4TOUT  -> layer 1-4 timeout
       L4CON   -> layer 1-4 connection problem, for example
                  "Connection refused" (tcp rst) or "No route to host" (icmp)
       L6OK    -> check passed on layer 6
       L6TOUT  -> layer 6 (SSL) timeout
       L6RSP   -> layer 6 invalid response - protocol error
       L7OK    -> check passed on layer 7
       L7OKC   -> check conditionally passed on layer 7, for example 404 with
                  disable-on-404
       L7TOUT  -> layer 7 (HTTP/SMTP) timeout
       L7RSP   -> layer 7 invalid response - protocol error
       L7STS   -> layer 7 response error, for example HTTP 5xx
    Notice: If a check is currently running, the last known status will be
    reported, prefixed with "* ". e. g. "* L7OK".
37. check_code [...S]: layer5-7 code, if available
38. check_duration [...S]: time in ms took to finish last health check
39. hrsp_1xx [.FBS]: http responses with 1xx code
40. hrsp_2xx [.FBS]: http responses with 2xx code
41. hrsp_3xx [.FBS]: http responses with 3xx code
42. hrsp_4xx [.FBS]: http responses with 4xx code
43. hrsp_5xx [.FBS]: http responses with 5xx code
44. hrsp_other [.FBS]: http responses with other codes (protocol error)
45. hanafail [...S]: failed health checks details
46. req_rate [.F..]: HTTP requests per second over last elapsed second
47. req_rate_max [.F..]: max number of HTTP requests per second observed
48. req_tot [.FB.]: total number of HTTP requests received
49. cli_abrt [..BS]: number of data transfers aborted by the client
50. srv_abrt [..BS]: number of data transfers aborted by the server
    (inc. in eresp)
51. comp_in [.FB.]: number of HTTP response bytes fed to the compressor
52. comp_out [.FB.]: number of HTTP response bytes emitted by the compressor
53. comp_byp [.FB.]: number of bytes that bypassed the HTTP compressor
    (CPU/BW limit)
54. comp_rsp [.FB.]: number of HTTP responses that were compressed
55. lastsess [..BS]: number of seconds since last session assigned to
    server/backend
56. last_chk [...S]: last health check contents or textual error
57. last_agt [...S]: last agent check contents or textual error
58. qtime [..BS]: the average queue time in ms over the 1024 last requests
59. ctime [..BS]: the average connect time in ms over the 1024 last requests
60. rtime [..BS]: the average response time in ms over the 1024 last requests
    (0 for TCP)
61. ttime [..BS]: the average total session time in ms over the 1024 last
    requests
62. agent_status [...S]: status of last agent check, one of:
       UNK     -> unknown
       INI     -> initializing
       SOCKERR -> socket error
       L4OK    -> check passed on layer 4, no upper layers testing enabled
       L4TOUT  -> layer 1-4 timeout
       L4CON   -> layer 1-4 connection problem, for example
                  "Connection refused" (tcp rst) or "No route to host" (icmp)
       L7OK    -> agent reported "up"
       L7STS   -> agent reported "fail", "stop", or "down"
63. agent_code [...S]: numeric code reported by agent if any (unused for now)
64. agent_duration [...S]: time in ms taken to finish last check
65. check_desc [...S]: short human-readable description of check_status
66. agent_desc [...S]: short human-readable description of agent_status
67. check_rise [...S]: server's "rise" parameter used by checks
68. check_fall [...S]: server's "fall" parameter used by checks
69. check_health [...S]: server's health check value between 0 and rise+fall-1
70. agent_rise [...S]: agent's "rise" parameter, normally 1
71. agent_fall [...S]: agent's "fall" parameter, normally 1
72. agent_health [...S]: agent's health parameter, between 0 and rise+fall-1
73. addr [L..S]: address:port or "unix". IPv6 has brackets around the address.
74: cookie [..BS]: server's cookie value or backend's cookie name
75: mode [LFBS]: proxy mode (tcp, http, health, unknown)
76: algo [..B.]: load balancing algorithm
77: conn_rate [.F..]: number of connections over the last elapsed second
78: conn_rate_max [.F..]: highest known conn_rate
79: conn_tot [.F..]: cumulative number of connections
80: intercepted [.FB.]: cum. number of intercepted requests (monitor, stats)
81: dcon [LF..]: requests denied by "tcp-request connection" rules
82: dses [LF..]: requests denied by "tcp-request session" rules
83: wrew [LFBS]: cumulative number of failed header rewriting warnings
84: connect [..BS]: cumulative number of connection establishment attempts
85: reuse [..BS]: cumulative number of connection reuses
86: cache_lookups [.FB.]: cumulative number of cache lookups
87: cache_hits [.FB.]: cumulative number of cache hits
88: srv_icur [...S]: current number of idle connections available for reuse
89: src_ilim [...S]: limit on the number of available idle connections
90. qtime_max [..BS]: the maximum observed queue time in ms
91. ctime_max [..BS]: the maximum observed connect time in ms
92. rtime_max [..BS]: the maximum observed response time in ms (0 for TCP)
93. ttime_max [..BS]: the maximum observed total session time in ms
94. eint [LFBS]: cumulative number of internal errors
95. idle_conn_cur [...S]: current number of unsafe idle connections
96. safe_conn_cur [...S]: current number of safe idle connections
97. used_conn_cur [...S]: current number of connections in use
98. need_conn_est [...S]: estimated needed number of connections
99. uweight [..BS]: total user weight (backend), server user weight (server)
100. agg_server_status [..B.]: backend aggregated gauge of server's status
101. agg_server_status_check [..B.]: (deprecated)
102. agg_check_status [..B.]: backend aggregated gauge of server's state check
     status
103. srid [...S]: server id revision
104. sess_other [.F..]: total number of sessions other than HTTP since process
     started
105. h1_sess [.F..]: total number of HTTP/1 sessions since process started
106. h2_sess [.F..]: total number of HTTP/2 sessions since process started
107. h3_sess [.F..]: total number of HTTP/3 sessions since process started
108. req_other [.F..]: total number of sessions other than HTTP processed by
     this object since the worker process started
109. h1req [.F..]: total number of HTTP/1 sessions processed by this object
     since the worker process started
110. h2req [.F..]: total number of hTTP/2 sessions processed by this object
     since the worker process started
111. h3req [.F..]: total number of HTTP/3 sessions processed by this object
     since the worker process started
112. proto [L...]: protocol
113. priv_idle_cur [...S]: current number of private idle connections
114. reqbin [LFBS]: total number of request bytes received since the worker
     process started
115. reqbout [LFBS]: total number of request bytes sent since the worker
     process started
116. resbin [LFBS]: total number of response bytes received since the worker
     process started
117. resbout [LFBS]: total number of response bytes sent since the worker
     process started

Pour tous les autres domaines de statistiques, la présence ou l’ordre des champs n’est pas garantie. Dans ce cas, la ligne d’en-tête doit toujours être utilisée pour analyser les données CSV.

9.2. Format de sortie typé

Les commandes « show info » et « show stat » prennent en charge un mode où chaque valeur de sortie est accompagnée de son type et d’informations suffisantes pour déterminer comment la valeur doit être agrégée entre les processus et comment elle évolue.

Dans tous les cas, la sortie se compose d’une seule valeur par ligne, avec toutes les informations séparées en champs délimités par des deux-points (’:’).

La première colonne indique l’objet ou la métrique dont la sortie est générée. Son format est spécifique à la commande produisant cette sortie et ne sera pas décrit dans cette section. En général, il se compose d’une série d’identifiants et de noms de champs.

La deuxième colonne contient 4 caractères indiquant respectivement l’origine, la nature, la portée et l’état de persistance de la valeur signalée. Le premier caractère (l’origine) indique l’emplacement d’où la valeur a été extraite. Les caractères possibles sont :

M   The value is a metric. It is valid at one instant any may change depending
    on its nature .

S   The value is a status. It represents a discrete value which by definition
    cannot be aggregated. It may be the status of a server ("UP" or "DOWN"),
    the PID of the process, etc.

K   The value is a sorting key. It represents an identifier which may be used
    to group some values together because it is unique among its class. All
    internal identifiers are keys. Some names can be listed as keys if they
    are unique (eg: a frontend name is unique). In general keys come from the
    configuration, even though some of them may automatically be assigned. For
    most purposes keys may be considered as equivalent to configuration.

C   The value comes from the configuration. Certain configuration values make
    sense on the output, for example a concurrent connection limit or a cookie
    name. By definition these values are the same in all processes started
    from the same configuration file.

P   The value comes from the product itself. There are very few such values,
    most common use is to report the product name, version and release date.
    These elements are also the same between all processes.

Le deuxième caractère (la nature) indique la nature de l’information transportée par le champ afin de permettre à un agrégateur de déterminer quelle opération utiliser pour agréger plusieurs valeurs. Les caractères possibles sont :

A   The value represents an age since a last event. This is a bit different
    from the duration in that an age is automatically computed based on the
    current date. A typical example is how long ago did the last session
    happen on a server. Ages are generally aggregated by taking the minimum
    value and do not need to be stored.

a   The value represents an already averaged value. The average response times
    and server weights are of this nature. Averages can typically be averaged
    between processes.

C   The value represents a cumulative counter. Such measures perpetually
    increase until they wrap around. Some monitoring protocols need to tell
    the difference between a counter and a gauge to report a different type.
    In general counters may simply be summed since they represent events or
    volumes. Examples of metrics of this nature are connection counts or byte
    counts.

D   The value represents a duration for a status. There are a few usages of
    this, most of them include the time taken by the last health check and
    the time a server has spent down. Durations are generally not summed,
    most of the time the maximum will be retained to compute an SLA.

G   The value represents a gauge. It's a measure at one instant. The memory
    usage or the current number of active connections are of this nature.
    Metrics of this type are typically summed during aggregation.

L   The value represents a limit (generally a configured one). By nature,
    limits are harder to aggregate since they are specific to the point where
    they were retrieved. In certain situations they may be summed or be kept
    separate.

M   The value represents a maximum. In general it will apply to a gauge and
    keep the highest known value. An example of such a metric could be the
    maximum amount of concurrent connections that was encountered in the
    product's life time. To correctly aggregate maxima, you are supposed to
    output a range going from the maximum of all maxima and the sum of all
    of them. There is indeed no way to know if they were encountered
    simultaneously or not.

m   The value represents a minimum. In general it will apply to a gauge and
    keep the lowest known value. An example of such a metric could be the
    minimum amount of free memory pools that was encountered in the product's
    life time. To correctly aggregate minima, you are supposed to output a
    range going from the minimum of all minima and the sum of all of them.
    There is indeed no way to know if they were encountered simultaneously
    or not.

N   The value represents a name, so it is a string. It is used to report
    proxy names, server names and cookie names. Names have configuration or
    keys as their origin and are supposed to be the same among all processes.

O   The value represents a free text output. Outputs from various commands,
    returns from health checks, node descriptions are of such nature.

R   The value represents an event rate. It's a measure at one instant. It is
    quite similar to a gauge except that the recipient knows that this measure
    moves slowly and may decide not to keep all values. An example of such a
    metric is the measured amount of connections per second. Metrics of this
    type are typically summed during aggregation.

T   The value represents a date or time. A field emitting the current date
    would be of this type. The method to aggregate such information is left
    as an implementation choice. For now no field uses this type.

Le troisième caractère (la portée) indique l’étendue à laquelle la valeur est représentative. Certains éléments peuvent être propres à un processus, tandis que d’autres peuvent être propres à une configuration ou à un système. Cette distinction est importante pour déterminer si une seule valeur doit être conservée lors de l’agrégation, ou si les valeurs doivent être agrégées. Les caractères suivants sont actuellement pris en charge :

C   The value is valid for a whole cluster of nodes, which is the set of nodes
    communicating over the peers protocol. An example could be the amount of
    entries present in a stick table that is replicated with other peers. At
    the moment no metric use this scope.

P   The value is valid only for the process reporting it. Most metrics use
    this scope.

S   The value is valid for the whole service, which is the set of processes
    started together from the same configuration file. All metrics originating
    from the configuration use this scope. Some other metrics may use it as
    well for some shared resources (eg: shared SSL cache statistics).

s   The value is valid for the whole system, such as the system's hostname,
    current date or resource usage. At the moment this scope is not used by
    any metric.

Le quatrième caractère (état de persistance) indique que la valeur (la métrique) est volatile ou persistante lors des rechargements. Les caractères suivants sont attendus :

V   The metric is volatile because it is local to the current process so
    the value will be lost when reloading.

P   The metric is persistent because it may be shared with other co-processes
    so that the value is preserved across reloads.

Les consommateurs de ces informations auront généralement besoin de ces 4 caractères pour déterminer avec précision comment rapporter les informations agrégées issues de plusieurs processus.

Après cette colonne, la troisième colonne indique le type du champ, parmi « s32 » (entier signé 32 bits), « s64 » (entier signé 64 bits), « u32 » (entier non signé 32 bits), « u64 » (entier non signé 64 bits), « str » (chaîne de caractères). Il est important de connaître le type avant d’analyser la valeur afin de la lire correctement. Par exemple, une chaîne ne contenant que des chiffres reste une chaîne et non un entier (par exemple, un code d’erreur extrait par une vérification).

Ensuite, la quatrième colonne est la valeur elle-même, encodée selon son type. Les chaînes sont écrites telles quelles immédiatement après les deux-points, sans espace initial. Si une chaîne contient un deux-points, il s’affiche normalement. Cela signifie que la sortie ne doit pas être divisée exclusivement autour des deux-points, sinon certaines sorties de vérification ou des adresses de serveur pourraient être tronquées.

9.3. Commandes Unix Socket

Le socket de statistiques n’est pas activé par défaut. Pour l’activer, il est nécessaire d’ajouter une ligne dans la section globale de la configuration haproxy. Une deuxième ligne est recommandée afin de définir un délai d’expiration plus élevé, toujours apprécié lors de l’émission de commandes manuellement :

global
    stats socket /var/run/haproxy.sock mode 600 level admin
    stats timeout 2m

Il est également possible d’ajouter plusieurs instances de socket de statistiques en répétant la ligne, et de les faire écouter sur un port TCP au lieu d’une socket UNIX. Cela n’est jamais fait par défaut car cela présente un risque, mais peut s’avérer utile dans certaines situations :

global
    stats socket /var/run/haproxy.sock mode 600 level admin
    stats socket ipv4@192.168.0.1:9999 level admin
    stats timeout 2m

Pour accéder à la socket, une utilitaire externe tel que « socat » est nécessaire. Socat est un outil polyvalent permettant de connecter n’importe quoi à n’importe quoi. Nous l’utilisons pour connecter des terminaux à la socket, ou des canaux stdin/stdout à celle-ci pour les scripts. Les deux syntaxes principales que nous utiliserons sont les suivantes :

# socat /var/run/haproxy.sock stdio
# socat /var/run/haproxy.sock readline

Le premier est utilisé avec des scripts. Il est possible d’envoyer la sortie d’un script vers HAProxy, et de transmettre la sortie d’haproxy à un autre script. Cela est utile, par exemple, pour récupérer des compteurs ou des traces d’attaque.

Le second est utile uniquement pour émettre des commandes manuellement. Il présente l’avantage que le terminal est géré par la bibliothèque readline, qui prend en charge l’édition de ligne et l’historique, ce qui est très pratique lors de l’émission de commandes répétées (par exemple : surveiller un compteur).

La socket prend en charge trois modes de fonctionnement :

  • non interactif, silencieux
  • interactif, silencieux
  • interactif avec invite

Le mode non interactif est le mode par défaut lorsque socat se connecte à la socket. Dans ce mode, une seule ligne peut être envoyée. Elle est traitée en entier, les réponses sont renvoyées, puis la connexion se ferme après la fin de la réponse. C’est le mode utilisé par les scripts et les outils de surveillance. Il est possible d’envoyer plusieurs commandes dans ce mode, à condition de les séparer par un point-virgule (’;’). Par exemple :

# echo "show info;show stat;show table" | socat /var/run/haproxy stdio

Si une commande doit utiliser un point-virgule ou une barre oblique inverse (par exemple, dans une valeur), elle doit être précédée d’une barre oblique inverse (’\’).

Le mode interactif permet d’envoyer de nouvelles commandes après la fin des commandes des lignes précédentes. Il existe deux variantes : l’une silencieuse, qui fonctionne comme le mode non interactif, sauf que le socket attend une nouvelle commande au lieu de se fermer, et une autre où une invite est affichée (’>’) au début de la ligne. Le mode interactif est préféré pour les outils avancés, tandis que le mode invite est préféré pour les humains.

Le mode peut être modifié à l’aide de la commande « prompt ». Par défaut, il bascule entre les modes interactif et prompt. Saisir « prompt » en mode interactif active le mode prompt. La commande accepte optionnellement un mode spécifique parmi les suivants :

  • “n” : mode non interactif (exécution d’une seule commande, puis arrêt)
  • “i” : mode interactif (exécution de plusieurs commandes, sans invite)
  • “p” : mode invite (exécution de plusieurs commandes avec invite)

Étant donné que le mode par défaut est non interactif, la commande « prompt » doit être utilisée en premier afin de basculer le mode, faute de quoi la commande précédente entraînera la fermeture de la connexion. Le basculement vers le mode non interactif entraîne la fermeture de la connexion après la finalisation de toutes les commandes de la même ligne.

Pour cette raison, lors du débogage manuel, il est courant de commencer par la commande « prompt » :

# socat /var/run/haproxy readline
prompt

afficher les informations…

Les outils interactifs peuvent préférer commencer par « prompt i » pour passer en mode interactif sans le prompt.

Optionnellement, le temps de fonctionnement du processus peut être affiché dans l’invite. Pour activer cette fonctionnalité, la commande « prompt timed » active l’invite et bascule l’affichage de l’heure. Le temps de fonctionnement est affiché au format « d:hh:mm:ss », où « d » représente le nombre de jours, et « hh », « mm », « ss » le nombre d’heures, de minutes et de secondes, chacun sur deux chiffres :

# socat /var/run/haproxy readline
prompt timed

[23:03:34:39]> show version 2.8-dev9-e5e622-18

[23:03:34:41]> quit

Lorsque l’invite temporelle est définie sur l’interface CLI principale, l’invite affiche le temps de fonctionnement du processus actuellement sélectionné, ce qui fonctionne pour le maître, le worker actuel ou un worker plus ancien :

master> prompt timed
[0:00:00:50] master> show proc
(...)
[0:00:00:58] master> @!11955     <-- master, switch to current worker
[0:00:01:03] 11955> @!11942      <-- current worker, switch to older worker
[0:00:02:17] 11942> @            <-- older worker, switch back to master
[0:00:01:10] master>

Étant donné qu’il est possible d’envoyer plusieurs commandes en même temps, HAProxy utilise la ligne vide comme délimiteur pour marquer la fin de la sortie de chaque commande, et veille à ce qu’aucune commande ne produise de ligne vide en sortie. Un script peut donc parser facilement la sortie, même lorsque plusieurs commandes ont été enchaînées sur une seule ligne.

Certains commandes peuvent accepter un chargement optionnel. Pour ajouter un chargement à une commande, la première ligne doit se terminer par le motif “<<\n”. Les lignes suivantes seront traitées comme le chargement et peuvent contenir autant de lignes que nécessaire. Pour valider une commande avec un chargement, celle-ci doit se terminer par une ligne vide.

Le motif du payload peut être personnalisé afin de modifier la manière dont le payload se termine. Pour terminer un payload par autre chose qu’une ligne vide, un motif personnalisé peut être défini entre ‘<<’ et ‘\n’. Jusqu’à 64 caractères peuvent être utilisés en plus de ‘<<’, sinon cela ne sera pas considéré comme un payload. Il devrait suffire d’utiliser des motifs de payload aléatoires. Par exemple, pour utiliser un fichier PEM contenant des lignes vides et des commentaires :

# echo -e "set ssl cert common.pem <<%EOF%\n$(cat common.pem)\n%EOF%\n" | \
socat /var/run/haproxy.stat -

Des limitations existent : le motif “<<” ne doit pas être collé au dernier mot de la ligne. La longueur d’une ligne de commande ne doit pas dépasser tune.bufsize, y compris le motif marquant le début du payload, mais en excluant le payload lui-même. La taille du payload est limitée par défaut à 128 Ko. Cette valeur peut être modifiée en configurant le paramètre global “tune.cli.max-payload-size”, avec certaines précautions. Notez que le motif marquant la fin du payload fait partie de cette limite.

Lorsqu’un payload est saisi en mode interactif, l’invite change de « > » à « + ».

Il est important de comprendre qu’en lançant plusieurs processus HAProxy sur les mêmes sockets, n’importe quel processus peut traiter la requête et produire ses propres statistiques.

La liste des commandes actuellement prises en charge sur le socket de statistiques est fournie ci-dessous. Si une commande inconnue est envoyée, HAProxy affiche le message d’utilisation, qui rappelle toutes les commandes prises en charge. Certaines commandes supportent une syntaxe plus complexe ; en cas d’erreur, le message indique généralement quelle partie de la commande est invalide.

Certaines commandes nécessitent un niveau de privilège supérieur pour fonctionner. Si vous ne disposez pas des privilèges suffisants, vous obtiendrez une erreur « Permission denied ». Veuillez consulter l’option « level » des lignes keyword « bind » dans le manuel de configuration pour plus d’informations.

abort ssl ca-file <cafile>

abort ssl ca-file <cafile>

Abandonner et supprimer une transaction de mise à jour temporaire du fichier CA.

Voir également « set ssl ca-file » et « commit ssl ca-file ».

abort ssl cert <filename>

abort ssl cert <filename>

Annuler et supprimer une transaction de mise à jour de certificat SSL temporaire.

Voir également « set ssl cert » et « commit ssl cert ».

abort ssl crl-file <crlfile>

abort ssl crl-file <crlfile>

Abandonner et supprimer une transaction de mise à jour temporaire d’un fichier CRL.

Voir également « set ssl crl-file » et « commit ssl crl-file ».

acme renew <certificate>

acme renew <certificate>

Démarre une tâche de génération de certificat ACME avec le nom de certificat fourni. Le certificat doit être lié à une section acme, voir la section 12.8 « ACME » du manuel de configuration. Voir également « acme status ».

acme status

acme status

Affiche l’état de chaque certificat configuré avec ACME.

Cette commande affiche, séparés par une tabulation :

  • Le nom du certificat configuré dans HAProxy
  • La section acme utilisée dans la configuration
  • L’état de la tâche acme, soit « Running », soit « Scheduled » ou soit « Stopped »
  • La date d’expiration UTC du certificat au format ISO8601
  • Le temps restant avant expiration (0d si expiré)
  • La date planifiée UTC du certificat au format ISO8601
  • Le temps restant avant planification (0d si Running)

Exemple :

$ echo "@1; acme status" | socat /tmp/master.sock - | column -t -s $'\t'
# certificate   section  state      expiration date (UTC)  expires in        scheduled date (UTC)  scheduled in
ecdsa.pem       LE       Running    2020-01-18T09:31:12Z   0d 0h00m00s       2020-01-15T21:31:12Z  0d 0h00m00s
foobar.pem.rsa  LE       Scheduled  2025-08-04T11:50:54Z   89d 23h01m13s     2025-07-27T23:50:55Z  82d 11h01m14s

add acl [@<ver>] <acl> <pattern>

add acl [@<ver>] <acl> <pattern>

Ajoutez une entrée dans la liste de contrôle d’accès <acl>. <acl> correspond au #<id> ou au <name> retourné par la commande « show acl ». Cette commande ne vérifie pas si l’entrée existe déjà. Les entrées sont ajoutées à la version courante de la liste de contrôle d’accès, sauf si une version spécifique est précisée avec “@<ver>”. Ce numéro de version doit avoir été préalablement alloué par la commande « prepare acl », et se situer entre les versions indiquées dans “curr_ver” et “next_ver” dans la sortie de la commande « show acl ». Les entrées ajoutées avec un numéro de version spécifique ne seront pas prises en compte avant une opération « commit acl » sur celles-ci. Elles peuvent toutefois être consultées à l’aide de la commande « show acl @<ver> », et effacées à l’aide de la commande « clear acl @<ver> ». Cette commande ne peut pas être utilisée si la référence <acl> est un nom également utilisé avec une carte. Dans ce cas, la commande « add map » doit être utilisée à la place.

add backend <name> from <defproxy> [mode <mode>] [guid <guid>]

add backend <name> from <defproxy> [mode <mode>] [guid <guid>]

Instanciez un nouveau proxy backend nommé <name>.

Seuls les proxies TCP ou HTTP peuvent être créés. Toutes les paramètres sont hérités de l’instance de proxy par défaut <defproxy>. Par défaut, il est obligatoire de préciser le mode backend via l’argument du même nom, sauf si <defproxy> le définit explicitement. Il est également possible d’utiliser un argument GUID facultatif si nécessaire.

Les serveurs peuvent être ajoutés via la commande « add server ». Le backend est initialisé dans l’état non publié. Une fois prêt à recevoir le trafic, utilisez la commande « publish backend » pour exposer l’instance nouvellement créée.

Tous les proxies par défaut nommés peuvent être utilisés, à condition qu’ils respectent les mêmes règles d’héritage appliquées lors de l’analyse de la configuration. Toutefois, certaines exceptions s’appliquent, par exemple lorsque le mode n’est ni TCP ni HTTP.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

add map [@<ver>] <map> <key> <value>

add map [@<ver>] <map> <key> <value>
add map [@<ver>] <map> <payload>

Ajoutez une entrée dans la carte <map> pour associer la valeur <value> à la clé <key>. Cette commande ne vérifie pas si l’entrée existe déjà. Elle est principalement utilisée pour remplir une carte après une opération « clear » ou « prepare ». Les entrées sont ajoutées à la version courante de la liste ACL, sauf si une version spécifique est indiquée avec « @<ver> ». Ce numéro de version doit avoir été préalablement alloué par « prepare acl », et se situe entre les versions indiquées dans “curr_ver” et “next_ver” dans la sortie de « show acl ». Les entrées ajoutées avec un numéro de version spécifique ne seront pas prises en compte avant une opération « commit map » sur celles-ci. Elles peuvent toutefois être consultées à l’aide de la commande « show map @<ver> », et effacées à l’aide de la commande « clear acl @<ver> ». Si la carte désignée est également utilisée comme une ACL, celle-ci ne correspondra qu’à la partie <key> et ignora la partie <value>. En utilisant la syntaxe du payload, il est possible d’ajouter plusieurs paires clé/valeur en les entrant sur des lignes séparées. Sur chaque nouvelle ligne, le premier mot est la clé et le reste de la ligne est considéré comme la valeur, qui peut même contenir des espaces.

Exemple :

# socat /tmp/sock1 -
prompt

> add map #-1 <<
+ key1 value1
+ key2 value2 with spaces
+ key3 value3 also with spaces
+ key4 value4

>

add server <backend>/<server> [args]*

add server <backend>/<server> [args]*

Instanciez un nouveau serveur attaché au backend <backend>.

Le nom <server> ne doit pas déjà être utilisé dans le backend. Une restriction particulière s’applique au backend, qui doit utiliser un algorithme de répartition de charge dynamique. Un sous-ensemble de mots-clés issus de l’instruction de configuration du serveur peut être utilisé pour configurer le comportement du serveur (voir « add server help » pour obtenir la liste). Notez également qu’aucun paramètre ne sera réutilisé à partir d’une éventuelle instruction « default-server » dans le même backend.

Actuellement, un serveur dynamique est initialisé de manière statique avec la méthode d’initialisation « none ». Cela signifie qu’aucune résolution ne sera effectuée si un nom FQDN est spécifié comme adresse, même si la création du serveur sera validée.

Pour prendre en charge les opérations de rechargement, il est nécessaire que le serveur créé via l’interface en ligne de commande soit également inséré manuellement dans le fichier de configuration HAProxy pertinent. Un serveur dynamique absent de la configuration ne sera pas restauré après une opération de rechargement.

Un serveur dynamique peut utiliser le mot-clé « track » pour suivre l’état de vérification d’un autre serveur défini dans la configuration. Toutefois, il n’est pas possible de suivre un autre serveur dynamique. Cela garantit que la chaîne de suivi reste cohérente, même en cas de suppression de serveurs dynamiques.

Utilisez le mot-clé « check » pour activer la prise en charge des vérifications de santé. Notez que la vérification de santé est désactivée par défaut et doit être activée indépendamment du serveur à l’aide de la commande « enable health ». Pour les vérifications d’agent, utilisez le mot-clé « agent-check » et la commande « enable agent ». Notez que, dans ce cas, le serveur peut être activé par l’agent en fonction de l’état rapporté, sans commande explicite « enable server ». Cela signifie également qu’une attention particulière est requise lors de la suppression d’un serveur dynamique avec vérification d’agent. L’agent doit d’abord être désactivé à l’aide de la commande « disable agent » afin de pouvoir placer le serveur en mode maintenance requis avant sa suppression.

Il se peut que la limite de descripteurs de fichiers (fd) soit atteinte lors de l’utilisation d’un grand nombre de serveurs dynamiques. Veuillez vous référer à la documentation du mot-clé global « u-limit » dans ce cas.

add server help

add server help

Liste des mots-clés pris en charge pour les serveurs dynamiques par la version actuelle de HAProxy. La syntaxe des mots-clés est similaire à celle de la ligne server du fichier de configuration ; reportez-vous à leur documentation respective pour plus de détails.

add ssl ca-file <cafile> <payload>

add ssl ca-file <cafile> <payload>

Ajoutez un nouveau certificat à un fichier ca. Cette commande est utile lorsque vous avez atteint la limite de taille de tampon sur l’interface en ligne de commande et que vous souhaitez ajouter plusieurs certificats. Au lieu d’utiliser une commande « set » avec tous les certificats, vous pouvez ajouter chaque certificat individuellement. Une commande « set ssl ca-file » réinitialise le fichier ca.

Exemple :

echo -e "set ssl ca-file cafile.pem <<\n$(cat rootCA.crt)\n" | \
socat /var/run/haproxy.stat -
echo -e "add ssl ca-file cafile.pem <<\n$(cat intermediate1.crt)\n" | \
socat /var/run/haproxy.stat -
echo -e "add ssl ca-file cafile.pem <<\n$(cat intermediate2.crt)\n" | \
socat /var/run/haproxy.stat -
echo "commit ssl ca-file cafile.pem" | socat /var/run/haproxy.stat -

add ssl crt-list <crtlist> <certificate>

add ssl crt-list <crtlist> <certificate>
add ssl crt-list <crtlist> <payload>

Ajoutez un certificat à une liste de certificats (crt-list). Cette commande peut également être utilisée avec des répertoires, puisque les répertoires sont désormais chargés de la même manière que les listes de certificats. Cette commande permet d’utiliser un nom de certificat en paramètre ; pour utiliser des options SSL ou des filtres, une ligne de crt-list doit être envoyée en charge utile au lieu de paramètre. Une seule ligne de crt-list est prise en charge dans la charge utile. Cette commande charge le certificat pour toutes les lignes bind utilisant la crt-list. Pour ajouter un nouveau certificat à HAProxy, les commandes « new ssl cert » et « set ssl cert » doivent être utilisées.

Exemple :

$ echo "new ssl cert foobar.pem" | socat /tmp/sock1 -
$ echo -e "set ssl cert foobar.pem <<\n$(cat foobar.pem)\n" | socat
/tmp/sock1 -
$ echo "commit ssl cert foobar.pem" | socat /tmp/sock1 -
$ echo "add ssl crt-list certlist1 foobar.pem" | socat /tmp/sock1 -

$ echo -e 'add ssl crt-list certlist1 <<\nfoobar.pem [allow-0rtt] foo.bar.com
!test1.com\n' | socat /tmp/sock1 -

add ssl ech <bind> <payload>

add ssl ech <bind> <payload>

Ajoutez une clé ECH à une ligne <bind>. Le contenu doit être au format PEM pour ECH. (https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni )

Le format de la ligne bind est <frontend>/@<filename>:<linenum> (exemple : frontend1/@haproxy.conf :19) ou <frontend>/<name> si la ligne bind a été nommée avec le mot-clé « name ».

Exige une version d’OpenSSL qui prend en charge ECH, et HAProxy doit être compilé avec USE_ECH=1. Cette commande n’est prise en charge que sur une connexion CLI en mode expérimental (voir « experimental-mode on »).

Voir également « show ssl ech » et « ech » dans la Section 5.1 du manuel de configuration.

Exemple :

$ openssl ech -public_name foobar.com -out foobar3.com.ech
$ echo -e "experimental-mode on; add ssl ech frontend1/@haproxy.conf:19 <<%EOF%\n$(cat foobar3.com.ech)\n%EOF%\n" | \
  socat /tmp/haproxy.sock -
added a new ECH config to frontend1

add ssl jwt <filename>

add ssl jwt <filename>

Ajoutez un certificat déjà chargé à la liste des certificats pouvant être utilisés pour la validation JWT (voir le convertisseur “jwt_verify_cert”). Cette commande ne fonctionne pas sur les transactions en cours. Voir également les commandes « del ssl jwt » et « show ssl jwt ». Voir l’option de certificat « jwt » pour plus d’informations.

clear counters

clear counters

Réinitialise les valeurs maximales des compteurs de statistiques dans chaque proxy (frontal et backend) et dans chaque serveur. Les compteurs accumulés ne sont pas affectés. Les compteurs d’activité internes rapportés par la commande « show activity » sont également réinitialisés. Cette commande peut être utilisée pour obtenir des compteurs propres après un incident, sans avoir à redémarrer ni à réinitialiser les compteurs de trafic. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés pour les niveaux « operator » ou « admin ».

clear counters all

clear counters all

Réinitialise tous les compteurs de statistiques dans chaque proxy (frontal et backend) ainsi que dans chaque serveur. Cette opération a le même effet qu’un redémarrage. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés au niveau « admin ».

clear acl [@<ver>] <acl>

clear acl [@<ver>] <acl>

Supprimez toutes les entrées de la liste de contrôle d’accès <acl>. <acl> correspond au #<id> ou au <name> retourné par la commande « show acl ». Notez que si la référence <acl> est un nom partagé avec une carte, cette dernière sera également vidée. Par défaut, seule la version courante de la liste de contrôle d’accès est vidée (celle en cours de correspondance). Toutefois, il est possible de préciser une autre version en utilisant ‘@’ suivi de cette version.

clear map [@<ver>] <map>

clear map [@<ver>] <map>

Supprimez toutes les entrées de la carte <map>. <map> est le #<id> ou le <name> retourné par la commande « show map ». Notez que si la référence <map> est un nom partagé avec une liste de contrôle d’accès (acl), cette dernière sera également vidée. Par défaut, seule la version actuelle de la carte est vidée (celle en cours de correspondance). Toutefois, il est possible de spécifier une autre version en utilisant ‘@’ suivi de cette version.

clear table <table> [ data.<type> <operator> <value> ] | [ key <key> ] |

clear table <table> [ data.<type> <operator> <value> ] | [ key <key> ] |
                    [ ptr <ptr> ]

Supprimez les entrées de la table de persistance <table>.

Cela est généralement utilisé pour débloquer certains utilisateurs qui se plaignent d’avoir été abusivement privés d’accès à un service, mais cela peut aussi servir à supprimer des entrées de persistance correspondant à un serveur qui va être remplacé (voir « show table » ci-dessous pour plus de détails). Notez qu’il arrive parfois que la suppression d’une entrée soit refusée car elle est actuellement suivie par une session. Il est courant de réessayer quelques secondes plus tard, après la fin de la session.

Dans le cas où aucun argument d’option n’est fourni, toutes les entrées seront supprimées.

Lorsque le formulaire “data.” est utilisé, les entrées correspondant à un filtre appliqué à l’aide des données stockées (voir « stick-table » dans la section 4.2) sont supprimées. Un type de données stockées doit être spécifié dans <type>, et ce type de données doit être stocké dans la table, sinon une erreur est signalée. Les données sont comparées selon <operator> avec l’entier 64 bits <value>. Les opérateurs sont les mêmes qu’avec les ACLs :

- eq : correspond aux entrées dont les données sont égales à cette valeur
- ne : correspond aux entrées dont les données sont différentes de cette valeur
- le : correspond aux entrées dont les données sont inférieures ou égales à cette valeur
- ge : correspond aux entrées dont les données sont supérieures ou égales à cette valeur
- lt : correspond aux entrées dont les données sont inférieures à cette valeur
- gt : correspond aux entrées dont les données sont supérieures à cette valeur

Lorsque la forme clé est utilisée, l’entrée <key> est supprimée. La clé doit être du même type que la table, ce qui est actuellement limité à IPv4, IPv6, entier et chaîne.

Lorsque la forme ptr est utilisée, l’entrée <ptr> est supprimée. <ptr> est écrit sous la forme 0xffff et doit correspondre à l’adresse renvoyée par une commande précédente « show table ». Correspondre à une entrée à l’aide de son pointeur peut être pertinent si l’entrée ne peut pas être identifiée à l’aide de sa clé en raison d’une clé vide ou de caractères incompatibles sur le CLI.

Si data.<type> est de type tableau, on peut utiliser « [] » pour accéder à un index spécifique du tableau, comme ceci : data.gpt[1]

Exemple :

    $ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a4c: key=127.0.0.1 use=0 exp=3594729 gpc0=0 conn_rate(30000)=1 \
      bytes_out_rate(60000)=187
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191
>>> 0x80e6b40: key=127.0.0.3 use=0 exp=3594743 gpc0=2 conn_rate(30000)=10 \
      bytes_out_rate(60000)=200

    $ echo "clear table http_proxy key 127.0.0.1" | socat stdio /tmp/sock1

    $ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:1
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
>>> 0x80e6b40: key=127.0.0.3 use=0 exp=3594743 gpc0=2 conn_rate(30000)=10 \
      bytes_out_rate(60000)=200
      bytes_out_rate(60000)=191
    $ echo "clear table http_proxy data.gpc0 eq 1" | socat stdio /tmp/sock1
    $ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:1
>>> 0x80e6b40: key=127.0.0.3 use=0 exp=3594743 gpc0=2 conn_rate(30000)=10 \
      bytes_out_rate(60000)=200

    $ echo "clear table http_proxy ptr 0x80e6b40" | socat stdio /tmp/sock1
    $ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:0

commit acl @<ver> <acl>

commit acl @<ver> <acl>

Validez tous les changements apportés à la version <ver> de la liste de contrôle d’accès <acl>, et supprimez toutes les versions antérieures. <acl> est le numéro #<id> ou le <name> retourné par la commande « show acl ». Le numéro de version doit être compris entre “curr_ver”+1 et “next_ver” tel que rapporté par la commande « show acl ». Le contenu à valider dans la liste de contrôle d’accès peut être consulté à l’aide de la commande « show acl @<ver> <acl> » si nécessaire. Le numéro de version spécifié a normalement été créé à l’aide de la commande « prepare acl ». La substitution est atomique. Elle consiste à mettre à jour atomiquement la version courante vers la version spécifiée, ce qui rend instantanément invisibles toutes les entrées des autres versions et rend visibles toutes les entrées de la nouvelle version. Il est également possible d’utiliser cette commande pour supprimer atomiquement toutes les entrées visibles d’une liste de contrôle d’accès en appelant d’abord « prepare acl », puis en validant sans ajouter d’entrée. Cette commande ne peut pas être utilisée si la référence <acl> est un nom également utilisé comme carte. Dans ce cas, la commande « commit map » doit être utilisée à la place.

commit map @<ver> <map>

commit map @<ver> <map>

Validez toutes les modifications apportées à la version <ver> de la carte <map>, et supprimez toutes les versions antérieures. <map> est le #<id> ou le <name> retourné par la commande « show map ». Le numéro de version doit être compris entre “curr_ver”+1 et “next_ver”, tel que rapporté par la commande « show map ». Le contenu à valider dans la carte peut être consulté à l’aide de la commande « show map @<ver> <map> », si nécessaire. Le numéro de version spécifié a normalement été créé à l’aide de la commande « prepare map ». La substitution est atomique. Elle consiste à mettre à jour atomiquement la version courante vers la version spécifiée, ce qui entraîne instantanément la disparition de toutes les entrées des autres versions, et la visibilité immédiate de toutes les entrées de la nouvelle version. Il est également possible d’utiliser cette commande pour supprimer atomiquement toutes les entrées visibles d’une carte en exécutant d’abord « prepare map », puis en validant sans ajouter d’entrée.

commit ssl ca-file <cafile>

commit ssl ca-file <cafile>

Valider une transaction de mise à jour temporaire du fichier CA SSL.

Dans le cas d’un fichier CA existant (dans un état « Used » dans « show ssl ca-file »), la nouvelle entrée d’arbre de fichier CA est insérée dans l’arbre de fichiers CA, et toutes les instances utilisant cette entrée de fichier CA sont reconstruites, ainsi que les contextes SSL qu’elles nécessitent. Tous les contextes précédemment utilisés par les instances reconstruites sont supprimés. En cas de succès, l’entrée de fichier CA précédente est supprimée de l’arbre. En cas d’échec, rien n’est supprimé ni supprimé, et tous les contextes SSL d’origine sont conservés et utilisés. Une fois la transaction temporaire validée, elle est détruite.

Dans le cas d’un nouveau fichier CA (après une commande « new ssl ca-file » et dans un état « Unused » affiché par « show ssl ca-file »), le fichier CA sera inséré dans l’arbre des fichiers CA, mais ne sera utilisé nulle part dans HAProxy. Pour l’utiliser et générer des contextes SSL qui l’utilisent, vous devrez l’ajouter à une liste de certificats avec la commande « add ssl crt-list ».

Voir également « new ssl ca-file », « set ssl ca-file », « add ssl ca-file », « abort ssl ca-file » et « add ssl crt-list ».

commit ssl cert <filename>

commit ssl cert <filename>

Validez une transaction de mise à jour temporaire du certificat SSL.

Dans le cas d’un certificat existant (dans un état « Used » dans « show ssl cert »), génère tous les contextes SSL et les SNIs dont il a besoin, insère-les, puis supprime les anciens. Remplace en mémoire les anciens certificats SSL partout où <filename> était utilisé dans la configuration. En cas d’échec, rien n’est supprimé ni inséré. Une fois la transaction temporaire validée, elle est détruite.

Dans le cas d’un nouveau certificat (après une commande « new ssl cert » et dans un état « Unused » affiché par « show ssl cert »), le certificat sera enregistré dans un stockage de certificats, mais ne sera utilisé nulle part dans haproxy. Pour l’utiliser et générer ses SNI, il faudra l’ajouter à une liste de certificats (crt-list) ou à un répertoire via la commande « add ssl crt-list ».

Voir également « new ssl cert », « set ssl cert », « abort ssl cert » et « add ssl crt-list ».

commit ssl crl-file <crlfile>

commit ssl crl-file <crlfile>

Valider une transaction de mise à jour temporaire d’un fichier CRL SSL.

Dans le cas d’un fichier CRL existant (dans un état « Used » dans « show ssl crl-file »), la nouvelle entrée de fichier CRL est insérée dans l’arbre des fichiers CA (qui contient à la fois les fichiers CA et les fichiers CRL) et chaque instance utilisant l’entrée de fichier CRL est reconstruite, ainsi que les contextes SSL qu’elle nécessite. Tous les contextes précédemment utilisés par les instances reconstruites sont supprimés. En cas de succès, l’entrée de fichier CRL précédente est supprimée de l’arbre. En cas d’échec, rien n’est supprimé ni supprimé, et tous les contextes SSL d’origine sont conservés et utilisés. Une fois la transaction temporaire validée, elle est détruite.

Dans le cas d’un nouveau fichier CRL (après une commande « new ssl crl-file » et en état « Unused » dans « show ssl crl-file »), le fichier CRL sera inséré dans l’arbre des fichiers CRL, mais ne sera utilisé nulle part dans HAProxy. Pour l’utiliser et générer des contextes SSL qui l’utilisent, vous devrez l’ajouter à une liste de certificats avec la commande « add ssl crt-list ».

Voir également « new ssl crl-file », « set ssl crl-file », « abort ssl crl-file » et « add ssl crt-list ».

debug counters [reset|show|on|off|all|bug|chk|cnt|glt|?]*

debug counters [reset|show|on|off|all|bug|chk|cnt|glt|?]*

Liste les compteurs internes placés dans le code, qui peuvent varier selon certaines options de compilation. Certains dépendent de DEBUG_STRICT, d’autres de DEBUG_COUNTERS. La commande prend une combinaison d’arguments multiples, certains définissant des actions et d’autres des filtres : - bug active l’affichage des compteurs des requêtes BUG_ON() - cnt active l’affichage des compteurs des requêtes COUNT_IF() - chk active l’affichage des compteurs des requêtes CHECK_IF() - glt active l’affichage des compteurs des requêtes COUNT_GLITCH() - all active l’affichage des compteurs qui n’ont jamais été déclenchés (valeur 0) - off action : désactive la mise à jour des compteurs COUNT_IF() - on action : active la mise à jour des compteurs COUNT_IF() - reset action : réinitialise tous les compteurs spécifiés - show action : affiche tous les compteurs spécifiés

Par défaut, l’action est « show » afin d’afficher les compteurs, et les compteurs listés sont tous des types ayant une valeur non nulle. La commande « show » est implicite lorsqu’aucune autre action n’est spécifiée, et n’est présente que pour faciliter la génération de commandes à partir de scripts.

La sortie commence par un compteur entier, suivi du type du compteur en majuscules, puis de son emplacement dans le code (fichier:ligne), du nom de la fonction, et éventuellement de « : » suivi d’une description. Veuillez noter que le format de sortie peut évoluer entre les versions majeures, et que de nouveaux types et entrées peuvent être rétroportés vers les versions stables dans le but d’améliorer les capacités de débogage. Tout suivi effectué sur ces éléments doit être réalisé de manière très permissive et ne devrait, idéalement, pas être effectué.

En règle générale, les utilisateurs finaux n’utilisent pas cette commande, mais ils peuvent être invités à la faire par un développeur cherchant à diagnostiquer une anomalie ou à rechercher des entrées CNT ou GLT. À noter que des entrées « CHK » non nulles ne devraient pas se produire et doivent être signalées aux développeurs, car elles pourraient indiquer des hypothèses incorrectes dans le code.

debug dev <command> [args]*

debug dev <command> [args]*

Appelle une commande spécifique au développeur. Prise en charge uniquement sur une connexion CLI en mode expert (voir « expert-mode on »). Ces commandes sont extrêmement dangereuses et sans tolérance ; toute utilisation incorrecte peut entraîner un plantage du processus. Elles sont destinées aux experts uniquement et doivent absolument ne pas être utilisées sauf instruction explicite. Certaines d’entre elles ne sont disponibles que lorsque haproxy est compilé avec DEBUG_DEV défini, car elles peuvent avoir des implications de sécurité. Toutes ces commandes exigent des privilèges d’administration et sont délibérément non documentées afin d’éviter d’encourager leur utilisation par des personnes non familières avec le code source.

del acl <acl> [<key>|#<ref>]

del acl <acl> [<key>|#<ref>]

Supprimez toutes les entrées ACL de l’ACL <acl> correspondant à la clé <key>. <acl> est le #<id> ou le <name> retourné par la commande « show acl ». Si <ref> est utilisé, cette commande supprime uniquement la référence indiquée. La référence peut être trouvée en listant le contenu de l’ACL. Notez que si la référence <acl> est un nom partagé avec une map, l’entrée sera également supprimée dans la map.

del backend <name>

del backend <name>

Supprime le proxy backend nommé <name>.

Cette opération n’est possible que pour les proxies TCP ou HTTP. Pour réussir, l’instance backend doit avoir été précédemment dépubliée. En outre, tous ses serveurs doivent avoir été supprimés en premier lieu (via la commande CLI « del server »). Enfin, aucune connexion active ne doit encore être associée à l’instance backend.

Il existe des restrictions supplémentaires qui empêchent la suppression d’un backend. Premièrement, un backend ne peut pas être supprimé s’il est explicitement référencé par des éléments de configuration, par exemple via une règle use_backend ou dans des expressions sample. Certains paramètres de proxy sont également incompatibles avec la suppression en temps d’exécution. Actuellement, cela concerne l’utilisation des options dépréciées dispatch ou transparent. En outre, un backend ne peut pas être supprimé s’il contient une table de persistance (stick-table) déclarée. Enfin, il est actuellement impossible de supprimer un backend si des serveurs QUIC étaient présents dedans.

Il peut être utile d’utiliser « wait be-removable » avant cette commande pour vérifier les prérequis mentionnés ci-dessus. Cela fournit également une méthode pour attendre la fermeture définitive des flux associés au backend cible.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

del map <map> [<key>|#<ref>]

del map <map> [<key>|#<ref>]

Supprime toutes les entrées de la carte <map> correspondant à la clé <key>. <map> est le #<id> ou le <name> retourné par la commande « show map ». Si l’option <ref> est utilisée, cette commande supprime uniquement la référence indiquée. La référence peut être identifiée en listant le contenu de la carte. Notez que si la référence <map> est un nom partagé avec une liste de contrôle d’accès (acl), l’entrée sera également supprimée de la carte.

del ssl ca-file <cafile>

del ssl ca-file <cafile>

Supprimez une entrée d’arbre de fichier CA depuis HAProxy. Le fichier CA doit être inutilisé et retiré de toute liste crt-list. La commande « show ssl ca-file » affiche l’état des fichiers CA. La suppression ne fonctionne pas si un certificat est référencé directement via les directives « ca-file » ou « ca-verify-file » dans la configuration.

del ssl cert <certfile>

del ssl cert <certfile>

Supprimez un magasin de certificats depuis HAProxy. Le certificat doit être inutilisé (inclus pour la validation JWT) et retiré de toute liste crt-list ou répertoire. La commande « show ssl cert » affiche l’état du certificat. La suppression ne fonctionne pas avec un certificat référencé directement via la directive « crt » dans la configuration.

del ssl crl-file <crlfile>

del ssl crl-file <crlfile>

Supprime une entrée de l’arborescence des fichiers CRL de HAProxy. Le fichier CRL doit être inutilisé et retiré de toute crt-list. La commande « show ssl crl-file » affiche l’état des fichiers CRL. La suppression ne fonctionne pas avec un certificat référencé directement par la directive « crl-file » dans la configuration.

del ssl crt-list <filename> <certfile[:line]>

del ssl crt-list <filename> <certfile[:line]>

Supprime une entrée dans une liste de certificats. Cette opération supprime tous les SNIs utilisés pour cette entrée dans les frontaux. Si un certificat est utilisé plusieurs fois dans une liste de certificats, vous devez préciser quelle ligne vous souhaitez supprimer. Pour afficher les numéros de ligne, utilisez la commande « show ssl crt-list -n <crtlist> ».

del ssl ech <bind>

del ssl ech <bind>

Supprime les clés ECH d’une ligne bind.

Le format de la ligne bind est <frontend>/@<filename>:<linenum> (exemple : frontend1/@haproxy.conf :19) ou <frontend>/<name> si la ligne bind a été nommée avec le mot-clé « name ».

Exige une version d’OpenSSL qui prend en charge ECH, et HAProxy doit être compilé avec USE_ECH=1. Cette commande n’est prise en charge que sur une connexion CLI en mode expérimental (voir « experimental-mode on »).

Voir également « show ssl ech », « add ssl ech » et « ech » dans la Section 5.1 du manuel de configuration.

Exemple :

$ echo "experimental-mode on; del ssl ech frontend1/@haproxy.conf:19" | socat /tmp/haproxy.sock -
deleted all ECH configs from frontend1/@haproxy.conf:19

del ssl jwt <filename>

del ssl jwt <filename>

Supprime un certificat déjà chargé de la liste des certificats pouvant être utilisés pour la validation JWT (voir le convertisseur “jwt_verify_cert”). Cette commande ne fonctionne pas sur les transactions en cours. Voir également les commandes « add ssl jwt » et « show ssl jwt ». Voir l’option de certificat « jwt » pour plus d’informations.

del server <backend>/<server>

del server <backend>/<server>

Supprimez un serveur supprimable attaché au backend <backend>. Un serveur supprimable est le serveur qui satisfait à toutes ces conditions :

  • non référencé par d’autres éléments de configuration
  • doit déjà être en maintenance (voir « disable server »)
  • ne doit pas avoir de connexion active ou inactif

Si l’une de ces conditions n’est pas remplie, la commande échouera.

Les connexions actives sont celles ayant au moins une requête en cours. Il est possible d’accélérer leur fermeture en utilisant « shutdown sessions server ». Il est fortement recommandé d’utiliser « wait srv-removable » avant « del server » afin de garantir que toutes les connexions actives ou inactives sont fermées et que la commande aboutit.

disable agent <backend>/<server>

disable agent <backend>/<server>

Marquez le contrôle de l’agent auxiliaire comme temporairement arrêté.

Dans le cas où une vérification d’agent est exécutée en tant que vérification auxiliaire, en raison du paramètre agent-check d’une directive server, de nouvelles vérifications ne sont initialisées que lorsque l’agent est activé. Ainsi, désactiver l’agent empêchera toute nouvelle vérification d’agent de démarrer jusqu’à ce que l’agent soit réactivé à l’aide de enable agent.

Lorsqu’un agent est désactivé, le traitement d’une vérification d’agent auxiliaire initiée pendant que l’agent était activé se déroule comme suit : toutes les valeurs qui modifieraient le poids, en particulier « drain » ou un poids retourné par l’agent, sont ignorées. Le traitement de la vérification d’agent reste inchangé dans les autres cas.

La motivation de cette fonctionnalité est de permettre de suspendre les effets de modification du poids provenant des vérifications d’agent, afin de configurer le poids d’un serveur à l’aide de set weight sans que celui-ci ne soit annulé par l’agent.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

disable dynamic-cookie backend <backend>

disable dynamic-cookie backend <backend>

Désactiver la génération de cookies dynamiques pour le backend <backend>

disable frontend <frontend>

disable frontend <frontend>

Marquez le frontal comme arrêté temporairement. Cela correspond au mode utilisé lors d’un redémarrage doux : le frontal libère le port mais peut être réactivé si nécessaire. Utilisez cette option avec précaution, car certains systèmes d’exploitation non Linux ne parviennent pas à le réactiver. Cette fonction est destinée à être utilisée dans des environnements où l’arrêt d’un proxy n’est tout simplement pas envisageable, mais où un proxy mal configuré doit tout de même être corrigé. Ainsi, il devient possible de libérer le port et de le réaffecter à un autre processus afin de restaurer les opérations. Le frontal apparaîtra avec le statut « STOP » sur la page de statistiques.

Le frontal peut être spécifié soit par son nom, soit par son identifiant numérique, précédé d’un dièse (’#’).

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

disable health <backend>/<server>

disable health <backend>/<server>

Marquez le contrôle d’état principal comme étant temporairement arrêté. Cela désactivera l’envoi des contrôles d’état, et le dernier résultat de contrôle d’état sera ignoré. Le serveur sera en état non contrôlé et considéré comme UP, sauf si un contrôle d’état auxiliaire le force à descendre.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

disable server <backend>/<server>

disable server <backend>/<server>

Marquez le serveur comme INDISPONIBLE pour maintenance. En ce mode, aucune vérification supplémentaire n’est effectuée sur le serveur jusqu’à ce qu’il quitte la maintenance. Si le serveur est suivi par d’autres serveurs, ceux-ci seront également marqués comme INDISPONIBLE pendant la maintenance.

Dans la page des statistiques, un serveur en maintenance apparaîtra avec un statut « MAINT », ses serveurs de suivi affichant quant à eux le statut « MAINT(via) ».

Le backend et le serveur peuvent chacun être spécifiés soit par leur nom, soit par leur identifiant numérique, précédé d’un dièse (’#’).

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

dump ssl cert <certfile>

dump ssl cert <certfile>

Affiche un certificat chargé en mémoire HAProxy. Cela affichera le certificat au format PEM, suivi de la clé privée, puis du certificat feuille, enfin de la chaîne sera affichée. Vous pouvez également afficher une transaction en préfixant le nom de fichier par un astérisque. Cela est utile pour sauvegarder des certificats sur le système de fichiers lorsqu’ils ont été mis à jour via l’interface CLI et non sur le système de fichiers.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

Exemples :

$ echo "dump ssl cert cert1.pem" | socat /tmp/sock1 -

$ echo "dump ssl cert cert1.pem" | socat /tmp/sock1 - | openssl storeutl -noout -text /dev/stdin

dump stats-file

dump stats-file

Génère un fichier de statistiques pouvant être utilisé pour charger les valeurs des compteurs HAProxy au démarrage. Consultez la section « Stats-file » pour plus de détails.

echo <text>

echo <text>

Affiche du texte avec l’interface en ligne de commande. Peut être utile pour écrire des commentaires entre les commandes lors de l’exportation du résultat de plusieurs commandes.

Exemple :

echo "expert-mode on; echo FDs from fdtab; show fd; echo wild FDs; debug dev fd" | socat /var/run/haproxy.sock -

enable agent <backend>/<server>

enable agent <backend>/<server>

Reprendre le contrôle auxiliaire de l’agent qui avait été temporairement arrêté.

Voir « désactiver l’agent » pour obtenir les détails sur l’effet de la mise en marche et de l’arrêt temporaire d’un agent auxiliaire.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

enable dynamic-cookie backend <backend>

enable dynamic-cookie backend <backend>

Activez la génération de cookies dynamiques pour le backend <backend>. Une clé secrète doit également être fournie.

enable frontend <frontend>

enable frontend <frontend>

Reprendre un frontal qui a été temporairement arrêté. Il se peut que certains ports d’écoute ne puissent plus être bindés (par exemple, si un autre processus les a pris depuis l’opération « désactiver le frontal »). Dans ce cas, une erreur est affichée. Certains systèmes d’exploitation ne peuvent pas reprendre un frontal qui a été désactivé.

Le frontal peut être spécifié soit par son nom, soit par son identifiant numérique, précédé d’un dièse (’#’).

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

enable health <backend>/<server>

enable health <backend>/<server>

Reprendre un contrôle d’état principal qui a été temporairement arrêté. Cela permettra à nouveau l’envoi de contrôles d’état. Voir « disable health » pour plus de détails.

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

enable server <backend>/<server>

enable server <backend>/<server>

Si le serveur était précédemment marqué comme DOWN pour maintenance, cela le marque comme UP et réactive les vérifications.

Le backend et le serveur peuvent chacun être spécifiés soit par leur nom, soit par leur identifiant numérique, précédé d’un dièse (’#’).

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

experimental-mode [on|off]

experimental-mode [on|off]

Sans option, cela indique si le mode expérimental est activé ou désactivé sur la connexion actuelle. En spécifiant « on », il active le mode expérimental pour la connexion CLI actuelle uniquement. Avec « off », il le désactive.

Le mode expérimental est utilisé pour accéder à des fonctionnalités supplémentaires encore en développement. Ces fonctionnalités sont actuellement instables et doivent être utilisées avec précaution. Elles peuvent faire l’objet de modifications infructueuses entre les versions.

Lorsqu’il est utilisé depuis l’interface CLI principale, cette commande ne doit pas être préfixée, car elle définira le mode pour tout worker lors de sa connexion à son interface CLI.

Exemple :

echo "@1; experimental-mode on; <experimental_cmd>..." | socat /var/run/haproxy.master -
echo "experimental-mode on; @1 <experimental_cmd>..." | socat /var/run/haproxy.master -

expert-mode [on|off]

expert-mode [on|off]

Cette commande est similaire à experimental-mode, mais elle sert à activer ou désactiver le mode expert.

Le mode expert permet d’afficher des commandes experts qui peuvent être extrêmement dangereuses pour le processus et qui peuvent parfois aider les développeurs à recueillir des informations importantes sur des bogues complexes. Toute utilisation incorrecte de ces fonctionnalités entraîne probablement une panne du processus. N’utilisez pas cette option sans y être invité. Notez que cette commande est volontairement omise dans le message d’aide. Cette commande n’est accessible qu’au niveau administrateur. Passer à un autre niveau réinitialise automatiquement le mode expert.

Lorsqu’il est utilisé depuis l’interface CLI principale, cette commande ne doit pas être préfixée, car elle définira le mode pour tout worker lors de sa connexion à son interface CLI.

Exemple :

echo "@1; expert-mode on; debug dev exit 1" | socat /var/run/haproxy.master -
echo "expert-mode on; @1 debug dev exit 1" | socat /var/run/haproxy.master -

get map <map> <value>

get map <map> <value>
get acl <acl> <value>

Recherchez la valeur <value> dans la carte <map> ou dans la liste ACL <acl>. <map> ou <acl> correspondent au(s) <id> ou au <name> retourné(s) par la commande « show map » ou « show acl ». Cette commande renvoie tous les modèles correspondants associés à cette carte. Elle est utile pour le débogage des cartes et des listes ACL. Le format de sortie est composé d’une ligne par type correspondant. Chaque ligne est composée d’une série de mots séparés par des espaces.

Les deux premiers mots sont :

<match method>:   The match method applied. It can be "found", "bool",
                  "int", "ip", "bin", "len", "str", "beg", "sub", "dir",
                  "dom", "end" or "reg".

<match result>:   The result. Can be "match" or "no-match".

Les mots suivants ne sont retournés que si le motif correspond à une entrée.

 `<index type>` : « tree » ou « list ». Algorithme interne de recherche.

 `<case>` : « case-insensitive » ou « case-sensitive ». Interprétation de la casse.

 `<entry matched>` : match="`<entry>`". Retourne le motif correspondant. Utile avec les expressions régulières.

Les deux derniers mots servent à indiquer la valeur renvoyée et son type. Dans le cas « acl », le modèle n’existe pas.

 return=nothing : Aucun retour, car aucune « map » n'est définie.
 return="`<value>`" : La valeur retournée au format chaîne.
 return=cannot-display : La valeur ne peut pas être convertie en chaîne.

 type="`<type>`":         Le type de l'échantillon renvoyé.

get var <name>

get var <name>

Affiche l’existence, le type et le contenu de la variable globale du processus « name ». Seules les variables globales du processus sont lisibles, donc le nom doit commencer par ‘proc.’, sinon aucune variable ne sera trouvée. Cette commande nécessite les niveaux « operator » ou « admin ».

get weight <backend>/<server>

get weight <backend>/<server>

Rapporte le poids actuel et le poids initial du serveur <server> dans le backend <backend> ou une erreur si l’un des deux n’existe pas. Le poids initial est celui qui apparaît dans le fichier de configuration. Les deux sont normalement égaux sauf si le poids actuel a été modifié. Le backend et le serveur peuvent chacun être spécifiés soit par leur nom, soit par leur identifiant numérique, précédé d’un dièse (’#’).

help [<command>]

help [<command>]

Affiche la liste des mots-clés connus ainsi que leur utilisation basique, ou les commandes correspondant à celle demandée. L’écran d’aide est également affiché pour les commandes inconnues.

httpclient [--htx] <method> <URI>

httpclient [--htx] <method> <URI>

Lancez une requête HTTP et affichez la réponse sur la CLI. Pris en charge uniquement sur une connexion CLI en mode expert (voir « expert-mode on »). Destiné uniquement au débogage. L’outil httpclient est capable de résoudre un nom de serveur dans l’URL à l’aide de la section de résolution « default », qui est remplie par défaut avec les serveurs DNS de votre /etc/resolv.conf. Toutefois, il ne pourra pas résoudre un hôte provenant de /etc/hosts si vous n’utilisez pas un démon DNS local capable de résoudre ces noms.

L’option –htx permet d’utiliser la représentation interne HAProxy htx via la fonction htx_dump(), principalement utilisée pour le débogage.

new ssl ca-file <cafile>

new ssl ca-file <cafile>

Créez une nouvelle entrée vide dans l’arborescence de fichier de certificats CA, à remplir avec un ensemble de certificats CA et à ajouter à une liste crt. Cette commande doit être utilisée en combinaison avec « set ssl ca-file », « add ssl ca-file » et « add ssl crt-list ».

new ssl cert <filename>

new ssl cert <filename>

Créez un nouveau magasin de certificats SSL vide à remplir avec un certificat et à ajouter à un répertoire ou à une liste de certificats. Cette commande doit être utilisée en combinaison avec « set ssl cert » et « add ssl crt-list ».

new ssl crl-file <crlfile>

new ssl crl-file <crlfile>

Créez une nouvelle entrée vide dans l’arborescence de fichier CRL, destinée à être remplie par un ensemble de CRLs et ajoutée à une liste de certificats. Cette commande doit être utilisée en combinaison avec « set ssl crl-file » et « add ssl crt-list ».

prepare acl <acl>

prepare acl <acl>

Allouez un nouveau numéro de version dans la liste de contrôle d’accès <acl> pour une substitution atomique. <acl> est le #<id> ou le <name> retourné par la commande « show acl ». Le nouveau numéro de version est indiqué dans la réponse après « Nouvelle version créée : ». Ce numéro pourra ensuite être utilisé pour préparer l’ajout de nouvelles entrées dans la liste de contrôle d’accès, qui remplaceront atomiquement les entrées actuelles une fois validées. Il est indiqué comme “next_ver” dans la commande « show acl ». L’allocation de nouvelles versions n’a aucun impact, car les versions non utilisées sont automatiquement supprimées dès qu’une version plus récente est validée. Les numéros de version sont des valeurs non signées sur 32 bits, qui bouclent en fin de plage, il convient donc de porter une attention particulière lors de leur comparaison dans un programme externe. Cette commande ne peut pas être utilisée si la référence <acl> est un nom également utilisé comme carte. Dans ce cas, la commande « prepare map » doit être utilisée à la place.

prepare map <map>

prepare map <map>

Allouez un nouveau numéro de version dans la carte <map> pour une substitution atomique. <map> est le #<id> ou le <name> retourné par la commande « show map ». Le nouveau numéro de version est indiqué dans la réponse après « New version created: ». Ce numéro pourra ensuite être utilisé pour préparer l’ajout de nouvelles entrées dans la carte, qui remplaceront atomiquement les entrées actuelles une fois validées. Il est indiqué comme “next_ver” dans la commande « show map ». L’allocation de nouvelles versions n’a aucun impact, car les versions non utilisées sont automatiquement supprimées dès qu’une version plus récente est validée. Les numéros de version sont des valeurs non signées sur 32 bits, qui bouclent en fin de plage, il convient donc de porter une attention particulière lors de leur comparaison dans un programme externe.

prompt [help | n | i | p | timed]*

prompt [help | n | i | p | timed]*

Modifie le comportement du mode interactif et l’invite affichée au début de la ligne en mode interactif : - « help » : affiche l’utilisation de la commande - « n » : passe en mode non interactif - « i » : passe en mode interactif - « p » : passe en mode interactif + invite - « timed » : active ou désactive l’affichage de l’heure dans l’invite

Sans option, le mode d’interaction passe successivement en mode interactif, puis en mode non interactif. En mode non interactif, la connexion est fermée après la fin de la dernière commande de la ligne courante. En mode interactif, la connexion n’est pas fermée après la fin d’une commande, afin de permettre l’entrée d’une nouvelle commande. En mode invite, le mode interactif est toujours utilisé, et une invite apparaît au début de la ligne, indiquant à l’utilisateur que l’interpréteur attend une nouvelle commande. L’invite se compose d’un angle droit suivi d’un espace « > ».

Le mode interactif convient davantage aux utilisateurs humains, le mode interactif avancé aux scripts complexes, et le mode non interactif (par défaut) aux scripts basiques. Notez que le mode non interactif n’est pas disponible pour la socket principale.

publish backend <backend>

publish backend <backend>

Active le commutateur de contenu vers une instance backend. Il s’agit de l’opération inverse de la commande « unpublish backend ». Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés pour les niveaux « operator » ou « admin ».

quit

quit

Fermer la connexion en mode interactif.

set anon [on|off] [<key>]

set anon [on|off] [<key>]

Cette commande permet d’activer ou de désactiver le « mode anonymisé » pour la session CLI en cours, qui remplace certains champs jugés sensibles ou confidentiels dans les sorties de commandes par des hachages conservant une cohérence suffisante entre les éléments afin d’aider les développeurs à repérer des relations entre éléments lors de la recherche de bogues, tout en disposant d’un nombre de bits faible (24) pour rendre les hachages non réversibles en raison du grand nombre de correspondances possibles. Lorsqu’il est activé, si aucune clé n’est spécifiée, la clé globale sera utilisée (soit définie dans le fichier de configuration via « anonkey », soit définie via la commande CLI « set anon global-key »). Si aucune telle clé n’a été définie, une clé aléatoire sera générée. Sinon, il est possible de spécifier la clé 32 bits à utiliser pour la session en cours, par exemple pour réutiliser la clé utilisée dans un dump précédent afin de faciliter la comparaison des sorties. Les développeurs n’auront jamais besoin de cette clé, et il est recommandé de ne jamais la partager, car elle pourrait permettre de confirmer ou infirmer certaines hypothèses sur ce que certains hachages pourraient cacher.

set dynamic-cookie-key backend <backend> <value>

set dynamic-cookie-key backend <backend> <value>

Modifiez la clé secrète utilisée pour générer les cookies persistants dynamiques. Cela interrompra les sessions en cours.

set anon global-key <key>

set anon global-key <key>

Cela définit la clé d’anonymisation globale sur <key>, qui doit être un entier 32 bits compris entre 0 et 4294967295 (0 désactive la clé globale). Cette commande nécessite des privilèges d’administrateur.

set map <map> [<key>|#<ref>] <value>

set map <map> [<key>|#<ref>] <value>

Modifiez la valeur correspondant à chaque clé <key> dans une carte <map>. <map> est le #<id> ou <name> retourné par la commande « show map ». Si <ref> est utilisé à la place de <key>, seule l’entrée pointée par <ref> est modifiée. La nouvelle valeur est <value>.

set maxconn frontend <frontend> <value>

set maxconn frontend <frontend> <value>

Modifiez dynamiquement la valeur maxconn du frontend spécifié. Toute valeur positive est autorisée, y compris zéro, mais définir une valeur supérieure à maxconn global n’a guère de sens. Si la limite est augmentée et qu’il y a des connexions en attente, celles-ci seront immédiatement acceptées. Si elle est réduite à une valeur inférieure au nombre actuel de connexions, l’acceptation de nouvelles connexions sera reportée jusqu’à atteinte du seuil. Le frontend peut être spécifié soit par son nom, soit par son identifiant numérique précédé d’un dièse (’#’).

set maxconn server <backend/server> <value>

set maxconn server <backend/server> <value>

Modifiez dynamiquement le paramètre maxconn du serveur spécifié. Toute valeur positive est autorisée, y compris zéro, mais définir une valeur supérieure au maxconn global n’a guère de sens.

set maxconn global <maxconn>

set maxconn global <maxconn>

Modifiez dynamiquement le paramètre global maxconn dans la plage définie par la valeur initiale de maxconn. Si cette valeur est augmentée et qu’il y a des connexions en attente, celles-ci seront immédiatement acceptées. Si elle est réduite à une valeur inférieure au nombre actuel de connexions, l’acceptation des nouvelles connexions sera retardée jusqu’à atteinte du seuil. Une valeur nulle restaure le paramètre initial.

set profiling memory { on | off }

set profiling memory { on | off }
set profiling tasks { auto | on | off | lock | no-lock | memory | no-memory }

Active ou désactive le profilage CPU ou mémoire pour le sous-système indiqué. Cela équivaut à définir ou supprimer les paramètres « profiling » dans la section « global » du fichier de configuration. Voir également « show profiling ». Notez qu’une activation manuelle du profilage des tâches sur « on » réinitialise automatiquement les statistiques du planificateur, permettant ainsi de mesurer l’activité sur une période donnée. Le profilage mémoire est limité à certains systèmes d’exploitation (fonctionne notamment sur la cible linux-glibc) et nécessite que USE_MEMORY_PROFILING soit défini au moment de la compilation.

Pour le profilage des tâches, il est possible d’activer ou de désactiver en temps réel la collecte des mesures de verrouillage et de mémoire par tâche, mais le changement n’est pris en compte qu’à la prochaine transition du profilage de « désactivé »/« auto » vers « activé » (soit automatiquement, soit manuellement). Ainsi, lorsqu’on utilise « no-lock » pour désactiver le profilage du verrouillage par tâche et économiser des cycles CPU, il est recommandé de désactiver puis réactiver le profilage des tâches afin de valider le changement.

set rate-limit connections global <value>

set rate-limit connections global <value>

Modifiez la limite de débit de connexions à l’échelle du processus, définie par le paramètre global « maxconnrate ». Une valeur nulle désactive la limitation. Cette limite s’applique à tous les frontaux et le changement prend effet immédiatement. La valeur est exprimée en nombre de connexions par seconde.

set rate-limit http-compression global <value>

set rate-limit http-compression global <value>

Modifiez le taux maximal de compression d’entrée, défini par le paramètre global « maxcomprate ». Une valeur nulle désactive la limitation. La valeur est exprimée en kilo-octets par seconde. Elle est disponible dans la commande « show info », sur la ligne « CompressBpsRateLim », en octets.

set rate-limit sessions global <value>

set rate-limit sessions global <value>

Modifiez la limite de taux de sessions au niveau du processus, définie par le paramètre global « maxsessrate ». Une valeur nulle désactive la limitation. Cette limite s’applique à tous les frontaux et le changement prend effet immédiatement. La valeur est exprimée en nombre de sessions par seconde.

set rate-limit ssl-sessions global <value>

set rate-limit ssl-sessions global <value>

Modifiez la limite de débit des sessions SSL à l’échelle du processus, définie par le paramètre global « maxsslrate ». Une valeur nulle désactive la limitation. Cette limite s’applique à tous les frontaux et prend effet immédiatement. La valeur est exprimée en nombre de sessions par seconde envoyées à la pile SSL. Elle s’applique avant l’établissement de la connexion afin de protéger la pile contre les abus liés à l’établissement de connexion.

set server <backend>/<server> addr <ip4 or ip6 address> [port <port>]

set server <backend>/<server> addr <ip4 or ip6 address> [port <port>]

Remplacez l’adresse IP actuelle d’un serveur par celle fournie. Le port peut éventuellement être modifié à l’aide du paramètre « port ». Notez qu’un changement de port permet également de basculer entre le mappage de port (notation avec +X ou -Y), à condition qu’un port soit configuré pour le contrôle d’état.

set server <backend>/<server> agent [ up | down ]

set server <backend>/<server> agent [ up | down ]

Forcer l’agent d’un serveur à un nouvel état. Cela peut être utile pour basculer immédiatement l’état d’un serveur, indépendamment de vérifications d’agent lentes, par exemple. Notez que le changement est propagé aux serveurs de suivi, le cas échéant.

set server <backend>/<server> agent-addr <addr> [port <port>]

set server <backend>/<server> agent-addr <addr> [port <port>]

Modifie l’adresse des vérifications d’agent des serveurs. Permet de migrer les vérifications d’agent vers une autre adresse en temps réel. Vous pouvez spécifier à la fois une adresse IP et un nom d’hôte, qui sera résolu. Facultativement, modifiez le port de l’agent.

set server <backend>/<server> agent-port <port>

set server <backend>/<server> agent-port <port>

Modifiez le port utilisé pour les vérifications de l’agent.

set server <backend>/<server> agent-send <value>

set server <backend>/<server> agent-send <value>

Modifie la chaîne d’agent envoyée à la cible de vérification de l’agent. Permet de mettre à jour la chaîne tout en modifiant l’adresse du serveur afin de maintenir les deux synchronisées.

set server <backend>/<server> health [ up | stopping | down ]

set server <backend>/<server> health [ up | stopping | down ]

Forcer l’état de contrôle d’état d’un serveur à une nouvelle valeur. Cela peut être utile pour modifier immédiatement l’état d’un serveur, indépendamment de contrôles d’état lents, par exemple. Notez que le changement est propagé aux serveurs de suivi, le cas échéant.

set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]

set server <backend>/<server> check-addr <ip4 | ip6> [port <port>]

Modifiez l’adresse IP utilisée pour les contrôles d’état des serveurs. Facultativement, modifiez le port utilisé pour les contrôles d’état des serveurs.

set server <backend>/<server> check-port <port>

set server <backend>/<server> check-port <port>

Modifiez le port utilisé pour le contrôle d’état en <port>

set server <backend>/<server> state [ ready | drain | maint ]

set server <backend>/<server> state [ ready | drain | maint ]

Forcer l’état administratif d’un serveur vers un nouvel état. Cela peut être utile pour désactiver la répartition de charge et/ou tout trafic vers un serveur. Définir l’état sur « ready » place le serveur en mode normal, et la commande équivaut à la commande « enable server ». Définir l’état sur « maint » désactive tout trafic vers le serveur ainsi que tout contrôle d’état. Cela équivaut à la commande « disable server ». Définir le mode sur « drain » retire uniquement le serveur de la répartition de charge, mais permet toujours son contrôle d’état et l’acceptation de nouvelles connexions persistantes. Les modifications sont propagées aux serveurs de suivi s’il y en a.

set server <backend>/<server> weight <weight>[%]

set server <backend>/<server> weight <weight>[%]

Modifie le poids d’un serveur par la valeur passée en argument. Cela correspond exactement à la commande « set weight » ci-dessous.

set server <backend>/<server> fqdn <FQDN>

set server <backend>/<server> fqdn <FQDN>

Modifie le nom DNS complet (FQDN) d’un serveur par la valeur passée en argument. Cela nécessite que le résolveur DNS interne soit configuré et activé pour ce serveur.

set server <backend>/<server> ssl [ on | off ] (deprecated)

set server <backend>/<server> ssl [ on | off ]  (deprecated)

Cette option configure le chiffrement SSL des connexions sortantes vers le serveur. Lorsqu’elle est désactivée, tout le trafic devient en clair ; le chemin de contrôle d’état n’est pas modifié.

Cette commande est obsolète. Créez un serveur dynamiquement, avec ou sans SSL, à l’aide de la commande « add server » à la place.

set severity-output [ none | number | string ]

set severity-output [ none | number | string ]

Modifie le format de sortie de la sévérité du socket de statistiques connecté pour la durée de la session en cours.

set ssl ca-file <cafile> <payload>

set ssl ca-file <cafile> <payload>

Cette commande fait partie d’un système de transactions : les commandes « commit ssl ca-file » et « abort ssl ca-file » peuvent être requises. Si aucune transaction en cours n’existe, une entrée de fichier CA sera créée dans l’arborescence des fichiers CA, dans laquelle les certificats contenus dans le chargement seront stockés. L’entrée de fichier CA ne sera pas conservée dans l’arborescence des fichiers CA et ne sera stockée que dans une transaction temporaire. Si une transaction portant le même nom de fichier existe déjà, l’entrée de fichier CA précédente sera supprimée et remplacée par la nouvelle. Une fois les modifications effectuées, vous devez valider la transaction à l’aide d’un appel à « commit ssl ca-file ». Si vous souhaitez ajouter plusieurs certificats séparément, vous pouvez utiliser la commande « add ssl ca-file ».

Exemple :

echo -e "set ssl ca-file cafile.pem <<\n$(cat rootCA.crt)\n" | \
socat /var/run/haproxy.stat -
echo "commit ssl ca-file cafile.pem" | socat /var/run/haproxy.stat -

set ssl cert <filename> <payload>

set ssl cert <filename> <payload>

Cette commande fait partie d’un système de transaction : les commandes « commit ssl cert » et « abort ssl cert » peuvent être nécessaires. Ce système de transaction fonctionne sur n’importe quel certificat affiché par la commande « show ssl cert », c’est-à-dire sur n’importe quel certificat frontal ou backend. Si aucune transaction en cours n’existe, elle dupliquerait le certificat <filename> en mémoire vers une transaction temporaire, puis mettrait à jour cette transaction avec le fichier PEM contenu dans le payload. Si une transaction existe déjà avec le même nom de fichier, elle mettra à jour cette transaction. Il est également possible de mettre à jour les fichiers liés à un certificat (.issuer, .sctl, .oscp, etc.). Une fois les modifications effectuées, vous devez « commit ssl cert » la transaction.

L’injection de fichiers via la ligne de commande doit se faire avec précaution, car une ligne vide est utilisée pour signaler la fin du contenu. Il est recommandé d’injecter un fichier PEM ayant été nettoyé. Une méthode simple consiste à supprimer toutes les lignes vides et à ne conserver que les sections PEM. Cette opération peut être réalisée à l’aide d’une commande sed.

Exemple :

# With some simple sanitizing
 echo -e "set ssl cert localhost.pem <<\n$(sed -n '/^$/d;/-BEGIN/,/-END/p' 127.0.0.1.pem)\n" | \
 socat /var/run/haproxy.stat -

 # Complete example with commit
 echo -e "set ssl cert localhost.pem <<\n$(cat 127.0.0.1.pem)\n" | \
 socat /var/run/haproxy.stat -
 echo -e \
 "set ssl cert localhost.pem.issuer <<\n $(cat 127.0.0.1.pem.issuer)\n" | \
 socat /var/run/haproxy.stat -
 echo -e \
 "set ssl cert localhost.pem.ocsp <<\n$(base64 -w 1000 127.0.0.1.pem.ocsp)\n" | \
 socat /var/run/haproxy.stat -
 echo "commit ssl cert localhost.pem" | socat /var/run/haproxy.stat -

set ssl crl-file <crlfile> <payload>

set ssl crl-file <crlfile> <payload>

Cette commande fait partie d’un système de transactions : les commandes « commit ssl crl-file » et « abort ssl crl-file » peuvent être nécessaires. Si aucune transaction en cours n’existe, une entrée d’arborescence de fichier CRL sera créée, dans laquelle les listes de révocation contenues dans le payload seront stockées. L’entrée de fichier CRL ne sera pas conservée dans l’arborescence de fichiers CRL et ne sera stockée que dans une transaction temporaire. Si une transaction portant le même nom de fichier existe déjà, l’entrée de fichier CRL précédente sera supprimée et remplacée par la nouvelle. Une fois les modifications effectuées, vous devez valider la transaction à l’aide d’un appel à « commit ssl crl-file ».

Exemple :

echo -e "set ssl crl-file crlfile.pem <<\n$(cat rootCRL.pem)\n" | \
socat /var/run/haproxy.stat -
echo "commit ssl crl-file crlfile.pem" | socat /var/run/haproxy.stat -

set ssl ech <bind> <payload>

set ssl ech <bind> <payload>

Remplacez les clés ECH d’une ligne bind par celle-ci. Le contenu doit être au format PEM pour ECH. (https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni )

Le format de la ligne bind est <frontend>/@<filename>:<linenum> (exemple : frontend1/@haproxy.conf :19) ou <frontend>/<name> si la ligne bind a été nommée avec le mot-clé « name ».

Exige une version d’OpenSSL qui prend en charge ECH, et HAProxy doit être compilé avec USE_ECH=1. Cette commande n’est prise en charge que sur une connexion CLI en mode expérimental (voir « experimental-mode on »).

Voir également « show ssl ech », « add ssl ech » et « ech » dans la Section 5.1 du manuel de configuration.

$ openssl ech -public_name foobar.com -out foobar3.com.ech
$ echo -e "experimental-mode on;
           set ssl ech frontend1/@haproxy.conf:19 <<%EOF%&#92;n$(cat foobar3.com.ech)&#92;n%EOF%&#92;n" | &#92;
  socat /tmp/haproxy.sock -
set new ECH configs for frontend1/@haproxy.conf:19

set ssl ocsp-response <response | payload>

set ssl ocsp-response <response | payload>

Cette commande permet de mettre à jour une réponse OCSP pour un certificat (voir « crt » dans les lignes « bind »). Les mêmes contrôles sont effectués qu’à l’initialisation du chargement de la réponse. Le <response> doit être transmis sous forme d’une chaîne encodée en base64 de la réponse encodée en DER provenant du serveur OCSP. Cette commande n’est pas prise en charge avec BoringSSL.

Exemple :

openssl ocsp -issuer issuer.pem -cert server.pem \
             -host ocsp.issuer.com:80 -respout resp.der
echo "set ssl ocsp-response $(base64 -w 10000 resp.der)" | \
             socat stdio /var/run/haproxy.stat

using the payload syntax:
echo -e "set ssl ocsp-response <<\n$(base64 resp.der)\n" | \
             socat stdio /var/run/haproxy.stat

set ssl tls-key <id> <tlskey>

set ssl tls-key <id> <tlskey>

Définissez la prochaine clé TLS pour l’écouteur <id> sur <tlskey>. Cette clé devient la clé finale, tandis que la clé précédente est utilisée pour le chiffrement (les autres ne servent qu’à déchiffrer). La clé TLS la plus ancienne présente est remplacée. <id> est soit un entier #<id>, soit <file>, renvoyé par la commande « show tls-keys ». <tlskey> est une clé de billet TLS codée en base64 sur 48 ou 80 bits (par exemple : OpenSSL rand 80 | OpenSSL base64 -A).

set table <table> key <key> [data.<data_type> <value>]*

set table <table> key <key> [data.<data_type> <value>]*
set table <table> ptr <ptr> [data.<data_type> <value>]*

Crée ou met à jour une entrée dans la table de persistance. Si la clé n’est pas présente, une entrée est insérée. Consultez stick-table dans la section 4.2 pour obtenir la liste de toutes les valeurs possibles pour <data_type>. L’utilisation la plus courante consiste à insérer dynamiquement des entrées pour les adresses IP sources, avec un indicateur dans gpc0 afin de bloquer dynamiquement une adresse IP ou d’en modifier la qualité de service. Il est possible de transmettre plusieurs data_types dans un appel unique.

Une recherche par pointeur peut être utilisée à la place de la recherche par clé pour une entrée existante : <ptr> doit être spécifié sous la forme 0xffff et correspond au pointeur retourné par une commande précédente « show table ». Une correspondance par pointeur peut être pertinente si l’entrée ne peut pas être identifiée par sa clé en raison d’une clé vide ou de caractères incompatibles sur le CLI.

Si data.<data_type> est de type tableau, les crochets « [] » peuvent être utilisés pour accéder à un index spécifique du tableau, comme ceci : data.gpt[1]

set timeout cli <delay>

set timeout cli <delay>

Modifie le délai d’expiration de l’interface CLI pour la connexion actuelle. Cela peut être utile lors de sessions de débogage longues, où l’utilisateur doit inspecter continuellement certains indicateurs sans être déconnecté. Le délai est spécifié en secondes.

set var <name> <expression>

set var <name> <expression>
set var <name> expr <expression>
set var <name> fmt <format>

Permet de définir ou de remplacer la variable globale « name » par le résultat de l’expression <expression> ou de la chaîne de format <format>. Seules les variables globales peuvent être utilisées, donc le nom doit commencer par ‘proc.’, sinon aucune variable ne sera définie. Les <expression> et <format> ne peuvent impliquer que des mots-clés d’extraction d’échantillon « internes » et des convertisseurs, même si les plus utiles seront probablement str(‘quelque chose’), int(), des chaînes simples ou des références à d’autres variables. Notez que le parseur de ligne de commande ne connaît pas les guillemets, donc tout espace dans l’expression doit être précédé d’une barre oblique inverse. Cette commande nécessite les niveaux « operator » ou « admin ». Cette commande n’est prise en charge que sur une connexion CLI en mode expérimental (voir « experimental-mode on »).

set weight <backend>/<server> <weight>[%]

set weight <backend>/<server> <weight>[%]

Modifie le poids d’un backend au valeur passée en argument. Si la valeur se termine par le signe ‘%’, le nouveau poids sera relatif au poids initialement configuré. Les poids absolus sont autorisés entre 0 et 256. Les poids relatifs doivent être positifs, et le poids absolu résultant est plafonné à 256. Les backends faisant partie d’une ferme utilisant un algorithme de répartition de charge statique ont des limitations plus strictes, car le poids ne peut pas être modifié une fois fixé. Pour ces backends, les seules valeurs acceptées sont 0 et 100 % (ou 0 et le poids initial). Les modifications prennent effet immédiatement, bien que certains algorithmes de répartition de charge nécessitent un certain nombre de requêtes pour prendre en compte les changements. Une utilisation typique de cette commande consiste à désactiver un backend pendant une mise à jour en lui attribuant un poids de zéro, puis à le réactiver après la mise à jour en le ramenant à 100 %. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés au niveau “admin”. Le backend et le backend peuvent être spécifiés soit par leur nom, soit par leur identifiant numérique, précédé d’un dièse (’#’).

show acl [[@<ver>] <acl>]

show acl [[@<ver>] <acl>]

Informations sur les convertisseurs d’ACL. Sans argument, la liste de toutes les ACL disponibles est renvoyée. Si un <acl> est spécifié, son contenu est affiché. <acl> est le #<id> ou <name>. Par défaut, la version actuelle de l’ACL est affichée (la version actuellement en cours de correspondance et signalée comme ‘curr_ver’ dans la liste des ACL). Il est possible de plutôt afficher d’autres versions en préfixant ‘@<ver>’ à l’identifiant de l’ACL. La version agit comme un filtre et les versions inexistantes ne renvoient simplement aucun résultat. Le format de sortie est identique à celui des cartes, y compris pour les valeurs d’exemple. Les données renvoyées ne constituent pas une liste des ACL disponibles, mais la liste de tous les modèles composant n’importe quelle ACL. Beaucoup de ces modèles peuvent être partagés avec les cartes. La valeur ’entry_cnt’ représente le nombre total d’entrées ACL, pas seulement les entrées actives, ce qui signifie qu’elle inclut également les entrées actuellement en cours d’ajout.

show anon

show anon

Affiche l’état actuel du mode d’anonymisation (activé ou désactivé) ainsi que la clé de la session en cours.

show backend

show backend

Affiche la liste des backends disponibles dans le processus en cours d’exécution

show cli level

show cli level

Affiche le niveau CLI de la session CLI en cours. Le résultat peut être « admin », « operator » ou « user ». Voir également les commandes « operator » et « user ».

Exemple :

$ socat /tmp/sock1 readline
prompt
> operator
> show cli level
operator
> user
> show cli level
user
> operator
Permission denied

operator

operator

Réduit le niveau CLI de la session CLI en cours à opérateur. Ce niveau ne peut pas être augmenté. Désactive également les modes expert et expérimental. Voir également « show cli level ».

unpublish backend <backend>

unpublish backend <backend>

Marque le backend comme non qualifié pour la sélection du trafic futur. En pratique, les règles use_backend / default_backend qui le référencent sont ignorées et les règles de commutation de contenu suivantes sont évaluées. Contrairement aux backends désactivés, les contrôles d’état des serveurs restent actifs. Cette commande est restreinte et ne peut être émise que sur les sockets configurés pour les niveaux « operator » ou « admin ».

user

user

Réduit le niveau CLI de la session CLI en cours à l’utilisateur. Ce niveau ne peut pas être augmenté. Désactive également les modes expert et expérimental. Voir également « show cli level ».

show activity [-1 | 0 | thread_num]

show activity [-1 | 0 | thread_num]

Rapporte certains compteurs relatifs aux événements internes qui aideront les développeurs et plus généralement toute personne suffisamment familière avec HAProxy à diagnostiquer les causes de comportements anormaux. Un exemple typique serait un processus correctement exécuté qui ne s’endort jamais et consomme 100 % du CPU. Les champs de sortie seront composés d’une ligne par métrique, avec les compteurs par thread sur la même ligne. Ces compteurs sont sur 32 bits et peuvent déborder au cours de la durée de vie du processus, ce qui n’est pas problématique car les appels à cette commande seront typiquement effectués deux fois. Les champs ne sont pas documentés intentionnellement afin que leur signification exacte soit vérifiée dans le code où les compteurs sont mis à jour. Ces valeurs sont également réinitialisées par la commande « clear counters ». Dans les déploiements multi-thread, la première colonne indiquera la valeur agrégée (ou la moyenne selon la nature de la métrique) pour tous les threads, et la liste des valeurs de chaque thread sera affichée entre crochets dans l’ordre des threads. Un numéro de thread optionnel peut être spécifié en argument. La valeur spéciale « 0 » rapportera uniquement la valeur agrégée (première colonne), et « -1 », qui est la valeur par défaut, affichera toutes les colonnes. Notez qu’à l’instar du mode mono-thread, il n’y aura pas de crochets lorsque seule une colonne est demandée.

show cli sockets

show cli sockets

Liste les sockets CLI. Le format de sortie est composé de 3 champs séparés par des espaces. Le premier champ est l’adresse de la socket, qui peut être une socket Unix, un couple adresse IPv4:port ou une adresse IPv6. Les sockets de types autres ne seront pas affichées. Le deuxième champ décrit le niveau de la socket : « admin », « user » ou « operator ». Le dernier champ liste les processus auxquels la socket est liée, séparés par des virgules, pouvant être des numéros ou « all ».

Exemple :

$ echo 'show cli sockets' | socat stdio /tmp/sock1
# socket lvl processes
/tmp/sock1 admin all
127.0.0.1:9999 user 2,3,4
127.0.0.2:9969 user 2
[::1]:9999 operator 2

show cache

show cache

Listez les caches configurés et les objets stockés dans chaque arbre de cache.

$ echo ‘show cache’ | socat stdio /tmp/sock1 0x7f6ac6c5b03a: foobar (shctx:0x7f6ac6c5b000, available blocks:3918) 1 2 3 4

  1. pointeur vers la structure de cache
  2. nom du cache
  3. pointeur vers la zone mmap (shctx)
  4. nombre de blocs disponibles pour être réutilisés dans le shctx

0x7f6ac6c5b4cc hachage:286881868 variante:0x0011223344556677 taille:39114 (39 blocs), compteur:9, expiration:237 1 2 3 4 5 6 7

  1. pointeur vers l’entrée du cache
  2. premiers 32 bits du hachage
  3. hachage secondaire de l’entrée en cas de variation
  4. taille de l’objet en octets
  5. nombre de blocs utilisés pour l’objet
  6. nombre de transactions utilisant l’entrée
  7. heure d’expiration, peut être négatif si déjà expiré

show dev

show dev

Cette commande a pour objectif de centraliser certaines informations que les développeurs HAProxy pourraient nécessiter pour mieux comprendre les causes d’un problème donné. Elle ne fournit généralement pas d’information utile à l’utilisateur, mais ces données permettent aux développeurs d’éliminer certaines hypothèses. Le format est approximativement une série de sections contenant des lignes indentées, une seule valeur par ligne, comme le type et la version du système d’exploitation, le type de processeur ou les limites de descripteurs d’ouverture au démarrage, par exemple. Certains champs seront omis afin d’éviter la répétition ou la pollution de la sortie lorsqu’ils ne contribuent pas à la valeur (par exemple, les valeurs illimitées). D’autres champs pourront apparaître à l’avenir, et certains pourront évoluer. Cette sortie n’est pas destinée à être analysée par des scripts, et ne doit pas être considérée avec un haut degré de fiabilité ; elle vise essentiellement à économiser du temps pour ceux qui peuvent la lire.

Techniquement parlant, ces informations sont prises telles quelles à partir d’une structure interne qui les stocke ensemble au démarrage, afin qu’elles puissent également être trouvées dans un fichier core après un plantage. Il peut donc arriver que les développeurs demandent une sortie précoce sur un processus bien comporté afin de la comparer avec ce qui est trouvé dans un dump core, ou de la comparer entre plusieurs rechargements (par exemple, certaines limites pourraient changer). Si l’anonymisation est activée, toute valeur potentiellement sensible sera également anonymisée (par exemple, le nom du nœud).

Exemple de sortie :

$ socat stdio /tmp/sock1 <<< "show dev"
Platform info
  machine vendor: To be filled by O.E.M
  machine family: Altra
  cpu model: Impl 0x41 Arch 8 Part 0xd0c r3p1
  virtual machine: no
  container: no
  OS name: Linux
  OS release: 6.2.0-36-generic
  OS version: #37~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Oct  9 18:01:07 UTC 2
  OS architecture: aarch64
  node name: 489aaf
Process info
  pid: 1735846
  boot uid: 509
  boot gid: 1002
  fd limit (soft): 1024
  fd limit (hard): 1048576

show env [<name>]

show env [<name>]

Affiche une ou toutes les variables d’environnement connues par le processus. Sans argument, toutes les variables sont affichées. Avec un argument, seule la variable spécifiée est affichée si elle existe. Sinon, le message « Variable non trouvée » est émis. Les variables sont affichées au format utilisé pour les stocker ou les renvoyer par l’outil « env », à savoir « <name>=<value> ». Cette commande peut être utile lors du débogage de certains fichiers de configuration utilisant abondamment des variables d’environnement afin de vérifier qu’elles contiennent les valeurs attendues. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés pour les niveaux « operator » ou « admin ».

show errors [<iid>|<proxy>] [request|response]

show errors [<iid>|<proxy>] [request|response]

Dump les dernières erreurs de requête et de réponse HTTP/1.x collectées par les frontaux et les backaux. Si <iid> est spécifié, limiter le dump aux erreurs concernant soit le frontend, soit le backend dont l’ID est <iid>. L’ID de proxy “-1” provoquera le dump de toutes les instances. Si un nom de proxy est spécifié à la place, son ID sera utilisé comme filtre. Si “request” ou “response” est ajouté après le nom de proxy ou son ID, seules les erreurs de requête ou de réponse seront dumpées. Cette commande est restreinte et ne peut être exécutée que sur des sockets configurés pour les niveaux “operator” ou “admin”.

Les erreurs qui peuvent être collectées sont les erreurs de requête et de réponse ultimes provoquées par des violations de protocole, souvent dues à des caractères non valides dans les noms d’en-tête. Le rapport indique précisément quel caractère exact a violé le protocole. D’autres informations importantes, telles que la date exacte à laquelle l’erreur a été détectée, les noms du frontal et du backend, le nom du serveur (lorsqu’il est connu), l’identifiant de transaction interne et l’adresse source ayant initié la session, sont également rapportées.

Tous les caractères sont renvoyés, et les caractères non imprimables sont encodés. Les plus courants (\t = 9, \n = 10, \r = 13 et \e = 27) sont encodés sous la forme d’une lettre suivie d’une barre oblique inverse. La barre oblique inverse elle-même est encodée par ‘\\’ afin d’éviter toute confusion. Les autres caractères non imprimables sont encodés sous la forme ‘\xNN’, où NN représente la représentation hexadécimale sur deux chiffres du code ASCII du caractère.

Les lignes sont précédées de la position de leur premier caractère, à partir de 0 pour le début du tampon. Au plus une ligne d’entrée est affichée par ligne, et les lignes longues sont divisées en plusieurs lignes de sortie consécutives afin que la sortie n’excède jamais 79 caractères de large. Il est facile de détecter si une ligne a été coupée, car elle ne se termine pas par ‘\n’ et l’offset de la ligne suivante est suivi d’un signe ‘+’, indiquant qu’elle est une continuation de la ligne précédente.

Exemple :

    $ echo "show errors -1 response" | socat stdio /tmp/sock1
>>> [04/Mar/2009:15:46:56.081] backend http-in (#2): invalid response
      src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)
      response length 213 bytes, error at position 23:

      00000  HTTP/1.0 200 OK\r\n
      00017  header/bizarre:blah\r\n
      00038  Location: blah\r\n
      00054  Long-line: this is a very long line which should b
      00104+ e broken into multiple lines on the output buffer,
      00154+  otherwise it would be too large to print in a ter
      00204+ minal\r\n
      00211  \r\n

In the example above, we see that the backend "http-in" which has internal
ID 2 has blocked an invalid response from its server s2 which has internal
ID 1. The request was on transaction 54 (called "session" here) initiated
by source 127.0.0.1 and received by frontend fe-eth0 whose ID is 1. The
total response length was 213 bytes when the error was detected, and the
error was at byte 23. This is the slash ('/') in header name
"header/bizarre", which is not a valid HTTP character for a header name.

show events [<sink>] [-w] [-n] [-0]

show events [<sink>] [-w] [-n] [-0]

Sans option, cette commande liste tous les réceptacles d’événements connus ainsi que leurs types. Avec une option, elle affiche tous les événements disponibles dans le réceptacle désigné, si celui-ci est de type tampon. Si l’option “-w” est passée après le nom du réceptacle, une fois la fin du tampon atteinte, la commande attend de nouveaux événements et les affiche. Il est possible d’interrompre l’opération en saisissant une entrée (qui sera ignorée) ou en fermant la session. Enfin, l’option “-n” permet de se positionner directement à la fin du tampon, ce qui est souvent pratique lorsqu’elle est combinée à “-w” pour ne rapporter que les événements nouveaux. Pour plus de commodité, les options “-wn” ou “-nw” peuvent être utilisées pour activer les deux options simultanément. Par défaut, tous les événements sont délimités par un caractère de saut de ligne (’\n’ ou 10 ou 0x0A). Il est possible de modifier cette valeur par le caractère NUL (’\0’ ou 0) en passant l’argument “-0”.

show fd [-!plcfbsd]* [[<tgid>]/[<fd>] | <fd>]

show fd [-!plcfbsd]* [[<tgid>]/[<fd>] | <fd>]

Affiche la liste de tous les descripteurs de fichiers ou uniquement le nombre <fd> s’il est spécifié. La forme “<tgid>/<fd>” est également acceptée, où l’un des côtés peut être vide comme un joker ("/<fd>" pour le descripteur <fd> à travers les groupes de threads, “<tgid>/” pour tous les descripteurs de <tgid>). Le <tgid> est actuellement analysé mais ignoré, en attente d’une future prise en charge des tables de descripteurs par groupe de threads. Un ensemble d’indicateurs peut éventuellement être passé pour limiter le dump à certains types de FD ou en exclure d’autres. Lorsqu’on rencontre ‘-’ ou ‘!’, la sélection est inversée pour les caractères suivants dans le même argument. L’inversion est réinitialisée avant chaque mot d’argument délimité par des espaces. Les types de FD sélectionnables incluent ‘p’ pour les tubes, ’l’ pour les écouteurs, ‘c’ pour les connexions (de tout type), ‘f’ pour les connexions frontales, ‘b’ pour les connexions backend (de tout type), ’s’ pour les connexions aux serveurs, ’d’ pour les connexions à l’adresse “dispatch” ou à l’adresse transparente du backend. Avec cela, ‘b’ est un raccourci pour ‘sd’ et ‘c’ pour ‘fb’ ou ‘fsd’. ‘c!f’ est équivalent à ‘b’ (“toutes les connexions sauf les connexions frontales” sont bien des connexions backend). Cette fonction est destinée uniquement aux développeurs qui doivent observer des états internes afin de déboguer des problèmes complexes tels qu’une utilisation anormale du CPU. Un descripteur est rapporté par ligne, et pour chacun, son état dans le poller est indiqué avec des lettres majuscules pour les indicateurs activés et minuscules pour les désactivés, en utilisant “P” pour “polled”, “R” pour “ready”, “A” pour “active”, l’état des événements avec “H” pour “hangup”, “E” pour “error”, “O” pour “output”, “P” pour “priority” et “I” pour “input”, quelques autres indicateurs comme “N” pour “new” (ajouté récemment dans le cache des descripteurs), “U” pour “updated” (reçu une mise à jour dans le cache des descripteurs), “L” pour “linger_risk”, “C” pour “cloned”, puis la position de l’entrée mise en cache, le pointeur vers le propriétaire interne, le pointeur vers la fonction de rappel d’E/S et son nom lorsqu’il est connu. Lorsque le propriétaire est une connexion, les indicateurs de connexion et la cible sont rapportés (frontal, proxy ou serveur). Lorsque le propriétaire est un écouteur, l’état de l’écouteur et son frontal sont rapportés. Il n’y a aucun intérêt à utiliser cette commande sans une bonne connaissance des internes. Il convient de noter que le format de sortie peut évoluer au fil du temps, de sorte que cette sortie ne doit pas être analysée par des outils conçus pour être durables. Certains états internes peuvent sembler suspects à la fonction les listant ; dans ce cas, la ligne de sortie sera suffixée par un point d’exclamation (’!’). Cela peut aider à trouver un point de départ lors de la diagnostic d’un incident.

show info [typed|json] [desc] [float]

show info [typed|json] [desc] [float]

Affiche les informations sur l’état de haproxy dans le processus actuel. Si l’argument facultatif « typed » est fourni, les numéros de champ, les noms et les types sont également émis afin que les outils de surveillance externes puissent facilement récupérer, éventuellement agréger, puis rapporter les informations contenues dans les champs qu’ils ne connaissent pas. Chaque champ est affiché sur une ligne distincte. Si l’argument facultatif « json » est fourni, les informations fournies par la sortie « typed » sont fournies au format JSON sous forme d’une liste d’objets JSON. Par défaut, le format ne contient que deux colonnes séparées par deux points (’:’). La colonne de gauche est le nom du champ et la colonne de droite est la valeur. Il est très important de noter que, dans le format de sortie « typed », la sortie pour un objet unique est contiguë, de sorte qu’il n’est pas nécessaire pour le consommateur de stocker l’ensemble des données en même temps. Si l’argument facultatif « float » est fourni, certains champs habituellement émis sous forme d’entiers peuvent être émis sous forme de flottants pour une plus grande précision. Il n’est pas spécifié de manière explicite quels champs sont concernés, car cela pourrait évoluer au fil du temps. L’utilisation de cette option implique que le consommateur est capable de traiter les flottants. Le format de sortie utilisé est sprintf("%f").

Lorsque le format de sortie typé est utilisé, chaque ligne est composée de 4 colonnes séparées par des deux-points (’:’). La première colonne est une série de 3 éléments séparés par des points. Le premier élément est la position numérique du champ dans la liste (commençant à zéro). Cette position ne doit pas évoluer au fil du temps, mais des trous sont à prévoir, selon les options de compilation ou si certains champs sont supprimés à l’avenir. Le deuxième élément est le nom du champ tel qu’il apparaît dans la sortie par défaut de « show info ». Le troisième élément est le numéro relatif du processus, commençant à 1.

Le reste de la ligne, à partir du premier deux-points, suit le format de sortie typé décrit dans la section précédente. En résumé, la deuxième colonne (après le premier « : ») indique l’origine, la nature et la portée de la variable. La troisième colonne précise le type du champ, parmi « s32 », « s64 », « u32 », « u64 » ou « str ». La quatrième colonne contient la valeur elle-même, que le consommateur sait interpréter grâce à la colonne 3 et traiter grâce à la colonne 2.

Ainsi, le format global de ligne en mode typé est :

<field_pos>.<field_name>.<process_num>:<tags>:<type>:<value>

Lorsque « desc » est ajouté à la commande, une deuxième virgule suivie d’une chaîne entre guillemets est ajoutée pour inclure une description de la métrique. Au moment de la rédaction, cette fonctionnalité n’est prise en charge que pour les formats de sortie « typed » et par défaut.

Exemple :

> show info
Name: HAProxy
Version: 1.7-dev1-de52ea-146
Release_date: 2016/03/11
Nbproc: 1
Process_num: 1
Pid: 28105
Uptime: 0d 0h00m04s
Uptime_sec: 4
Memmax_MB: 0
PoolAlloc_MB: 0
PoolUsed_MB: 0
PoolFailed: 0
(...)

> show info typed
0.Name.1:POSV:str:HAProxy
1.Version.1:POSV:str:3.1-dev0-7c653d-2466
2.Release_date.1:POSV:str:2025/07/01
3.Nbthread.1:CGSV:u32:1
4.Nbproc.1:CGSV:u32:1
5.Process_num.1:KGPV:u32:1
6.Pid.1:SGPV:u32:638069
7.Uptime.1:MDPV:str:0d 0h00m07s
8.Uptime_sec.1:MDPV:u32:7
9.Memmax_MB.1:CLPV:u32:0
10.PoolAlloc_MB.1:MGPV:u32:0
11.PoolUsed_MB.1:MGPV:u32:0
12.PoolFailed.1:MCPV:u32:0
(...)

Dans le format typé, la présence de l’identifiant de processus à la fin de la première colonne permet de regrouper visuellement les sorties de plusieurs processus de manière très simple. Exemple :

$ ( echo show info typed | socat /var/run/haproxy.sock1;    \
    echo show info typed | socat /var/run/haproxy.sock2 ) |  \
  sort -t . -k 1,1n -k 2,2 -k 3,3n
0.Name.1:POS:str:HAProxy
0.Name.2:POS:str:HAProxy
1.Version.1:POS:str:1.7-dev1-868ab3-148
1.Version.2:POS:str:1.7-dev1-868ab3-148
2.Release_date.1:POS:str:2016/03/11
2.Release_date.2:POS:str:2016/03/11
3.Nbproc.1:CGS:u32:2
3.Nbproc.2:CGS:u32:2
4.Process_num.1:KGP:u32:1
4.Process_num.2:KGP:u32:2
5.Pid.1:SGP:u32:30120
5.Pid.2:SGP:u32:30121
6.Uptime.1:MDP:str:0d 0h01m28s
6.Uptime.2:MDP:str:0d 0h01m28s
(...)

Le format de la sortie JSON est décrit dans un schéma qui peut être affiché à l’aide de la commande « show schema json ».

La sortie JSON ne contient aucun espace blanc supplémentaire afin de réduire le volume de sortie. Pour une lecture humaine, il peut être utile de passer la sortie through un formatteur de code. Exemple :

$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool

La sortie JSON ne contient aucun espace blanc supplémentaire afin de réduire le volume de sortie. Pour une lecture humaine, il peut être utile de passer la sortie through un formatteur de code. Exemple :

$ echo “show info json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool

show libs

show libs

Affiche la liste des bibliothèques dynamiques partagées et des fichiers objets chargés, sur les systèmes qui le supportent. Lorsqu’elles sont disponibles, pour chaque objet partagé, la plage d’adresses virtuelles, la taille et le chemin d’accès à l’objet seront indiqués. Cette commande peut par exemple servir à estimer quelle bibliothèque fournit une fonction apparaissant dans un dump. Notez que sur de nombreux systèmes, les adresses changent à chaque redémarrage (randomisation de l’espace d’adressage), de sorte que cette liste doit être récupérée au démarrage si elle est destinée à être utilisée pour analyser un fichier core. Cette commande ne peut être exécutée que sur les sockets configurés pour les niveaux « operator » ou « admin ». Notez que le format de sortie peut varier selon les systèmes d’exploitation, les architectures et même les versions de HAProxy, et ne doit pas être utilisé dans les scripts.

show map [[@<ver>] <map>]

show map [[@<ver>] <map>]

Informations sur les convertisseurs de cartes. Sans argument, la liste de toutes les cartes disponibles est retournée. Si un <map> est spécifié, son contenu est affiché. <map> est le numéro de <id> ou <name>. Par défaut, la version actuelle de la carte est affichée (la version actuellement utilisée pour les correspondances et signalée comme ‘curr_ver’ dans la liste des cartes). Il est possible de plutôt afficher d’autres versions en préfixant ‘@<ver>’ à l’identifiant de la carte. La version agit comme un filtre et les versions inexistantes ne renvoient simplement aucun résultat. La valeur ’entry_cnt’ représente le nombre total d’entrées de la carte, y compris celles qui ne sont pas actives, ce qui signifie qu’elle inclut également les entrées actuellement en cours d’ajout.

Dans la sortie, la première colonne est un identifiant unique d’entrée, utilisable comme référence pour les opérations « del map » et « set map ». La deuxième colonne est le motif et la troisième colonne est l’exemple, le cas échéant. Les données renvoyées ne constituent pas directement une liste des cartes disponibles, mais la liste de tous les motifs composant une carte. De nombreux de ces motifs peuvent être partagés avec les ACL.

show peers [dict|-] [<peers section>]

show peers [dict|-] [<peers section>]

Informations sur les pairs configurés dans les sections « peers ». Sans argument, la liste des pairs appartenant à toutes les sections « peers » est affichée. Si <peers section> est spécifié, seules les informations relatives aux pairs appartenant à cette section « peers » sont affichées. Lorsque « dict » est précisé avant le nom de la section « peers », les caches entiers des dictionnaires Tx/Rx sont également affichés (très volumineux). L’utilisation de « - » peut être nécessaire pour afficher une section « peers » nommée « dict ».

Voici deux exemples de sorties où les pairs hostA, hostB et hostC appartiennent à la section « sharedlb ». Seulement hostA et hostB sont connectés. Seulement hostA a envoyé des données à hostB.

$ echo “show peers” | socat - /tmp/hostA 0x55deb0224320 : [15/Apr/2019:11:28:01] id=sharedlb state=0 flags=0x3 \ resync_timeout=<PAST> task_calls=45122 0x55deb022b540 : id=hostC(remote) addr=127.0.0.12:10002 status=CONN \ reconnect=4s confirm=0 flags=0x0 0x55deb022a440 : id=hostA(local) addr=127.0.0.10:10000 status=NONE \ reconnect=<NEVER> confirm=0 flags=0x0 0x55deb0227d70 : id=hostB(remote) addr=127.0.0.11:10001 status=ESTA reconnect=2s confirm=0 flags=0x20000200 appctx:0x55deb028fba0 st0=7 st1=0 task_calls=14456 \ state=EST xprt=RAW src=127.0.0.1:37257 addr=127.0.0.10:10000 remote_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1 last_local_table:0x55deb0224a10 id=stkt local_id=1 remote_id=1 shared tables:

0x55deb0224a10 local_id=1 remote_id=1 flags=0x0 remote_data=0x65
  last_acked=0 last_pushed=3 last_get=0 teaching_origin=0 update=3
  table:0x55deb022d6a0 id=stkt update=3 localupdate=3 \
    commitupdate=3 syncing=0

$ echo “show peers” | socat - /tmp/hostB 0x55871b5ab320 : [15/Apr/2019:11:28:03] id=sharedlb état=0 drapeaux=0x3 \ délai_d_expiration_re synchronisation=<PAST> appels_tâche=3 0x55871b5b2540 : id=hostC(à distance) addr=127.0.0.12:10002 statut=CONN \ reconnexion=3s confirmation=0 drapeaux=0x0 0x55871b5b1440 : id=hostB(local) addr=127.0.0.11:10001 statut=NONE \ reconnexion=<NEVER> confirmation=0 drapeaux=0x0 0x55871b5aed70 : id=hostA(à distance) addr=127.0.0.10:10000 statut=ESTA \ reconnexion=2s confirmation=0 drapeaux=0x20000200 contexte_application:0x7fa46800ee00 st0=7 st1=0 appels_tâche=62356 \ état=EST table_à_distance:0x55871b5ab960 id=stkt id_local=1 id_à_distance=1 dernière_table_locale:0x55871b5ab960 id=stkt id_local=1 id_à_distance=1 tables partagées :

0x55871b5ab960 local_id=1 remote_id=1 flags=0x0 remote_data=0x65
  last_acked=3 last_pushed=0 last_get=3 teaching_origin=0 update=0
  table:0x55871b5b46a0 id=stkt update=1 localupdate=0 \
    commitupdate=0 syncing=0

show pools [byname|bysize|byusage] [detailed] [match <pfx>] [<nb>]

show pools [byname|bysize|byusage] [detailed] [match <pfx>] [<nb>]

Effectue un dump de l’état des pools mémoire internes. Cela est utile pour suivre l’utilisation mémoire lorsqu’un fuite de mémoire est suspectée, par exemple. Il effectue exactement la même opération que SIGQUIT lorsqu’exécuté en mode frontal, sauf qu’il ne vide pas les pools. La sortie n’est pas triée par défaut. Si « byname » est spécifié, elle est triée par nom de pool ; si « bysize » est spécifié, elle est triée par taille d’élément dans l’ordre inverse ; si « byusage » est spécifié, elle est triée par utilisation totale dans l’ordre inverse, et seuls les éléments utilisés sont affichés. Il est également possible de limiter la sortie aux <nb> premiers éléments (par exemple, lors du tri par utilisation). Il est possible d’afficher également des détails internes supplémentaires, y compris la liste de tous les pools fusionnés, en spécifiant « detailed ». Enfin, si « match » est suivi d’un préfixe, seuls les pools dont le nom commence par ce préfixe seront affichés. Le total rapporté concerne uniquement les pools correspondant aux critères de filtrage. Exemple :

$ socat - /tmp/haproxy.sock <<< "show pools match quic byusage"
Dumping pools usage. Use SIGQUIT to flush them.
  - Pool quic_conn_r (65560 bytes): 1337 allocated (87653720 bytes), ...
  - Pool quic_crypto (1048 bytes): 6685 allocated (7005880 bytes), ...
  - Pool quic_conn (4056 bytes): 1337 allocated (5422872 bytes), ...
  - Pool quic_rxbuf (262168 bytes): 8 allocated (2097344 bytes), ...
  - Pool quic_conne (184 bytes): 9359 allocated (1722056 bytes), ...
  - Pool quic_frame (184 bytes): 7938 allocated (1460592 bytes), ...
  - Pool quic_tx_pac (152 bytes): 6454 allocated (981008 bytes), ...
  - Pool quic_tls_ke (56 bytes): 12033 allocated (673848 bytes), ...
  - Pool quic_rx_pac (408 bytes): 1596 allocated (651168 bytes), ...
  - Pool quic_tls_se (88 bytes): 6685 allocated (588280 bytes), ...
  - Pool quic_cstrea (88 bytes): 4011 allocated (352968 bytes), ...
  - Pool quic_tls_iv (24 bytes): 12033 allocated (288792 bytes), ...
  - Pool quic_dgram (344 bytes): 732 allocated (251808 bytes), ...
  - Pool quic_arng (56 bytes): 4011 allocated (224616 bytes), ...
  - Pool quic_conn_c (152 bytes): 1337 allocated (203224 bytes), ...
Total: 15 pools, 109578176 bytes allocated, 109578176 used ...

show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_lines>]*

show profiling [{all | status | tasks | memory}] [byaddr|bytime|byctx|aggr|<max_lines>]*

Affiche les paramètres de profilage actuels, un par ligne, ainsi que la commande nécessaire pour les modifier. Lorsque le profilage des tâches est activé, certaines statistiques par fonction collectées par l’horloge seront également émises, accompagnées d’un résumé indiquant le nombre d’appels, le temps CPU total/moyen et la latence totale/moyenne. Lorsque le profilage mémoire est activé, certaines informations telles que le nombre d’allocations/libérations et leurs tailles seront rapportées. Il est possible de limiter la sortie à l’état de profilage uniquement, aux tâches ou au profilage mémoire en spécifiant les mots-clés correspondants ; par défaut, toutes les informations de profilage sont affichées. Il est également possible de limiter le nombre de lignes de sortie de chaque catégorie en spécifiant une limite numérique. Il est possible de demander que la sortie soit triée par adresse, par temps d’exécution total ou par contexte d’appel au lieu de l’utilisation, par exemple pour faciliter les comparaisons entre appels successifs ou vérifier ce qui doit être optimisé, et pour agréger l’activité des tâches par fonction appelée au lieu de voir les détails. Veuillez noter que le profilage est essentiellement destiné aux développeurs, car il fournit des indices sur l’endroit où les cycles CPU ou la mémoire sont gaspillés dans le code. Il n’y a rien d’utilisable à surveiller là-dedans.

show resolvers [<resolvers section id>]

show resolvers [<resolvers section id>]

Affiche les statistiques pour la section de résolveurs indiquée, ou pour toutes les sections de résolveurs si aucune section n’est fournie.

Pour chaque serveur de noms, les compteurs suivants sont rapportés :

sent: number of DNS requests sent to this server
valid: number of DNS valid responses received from this server
update: number of DNS responses used to update the server's IP address
cname: number of CNAME responses
cname_error: CNAME errors encountered with this server
any_err: number of empty response (IE: server does not support ANY type)
nx: non existent domain response received from this server
timeout: how many time this server did not answer in time
refused: number of requests refused by this server
other: any other DNS errors
invalid: invalid DNS response (from a protocol point of view)
too_big: too big response
outdated: number of response arrived too late (after another name server)

show quic [<format>] [<filter>]

show quic [<format>] [<filter>]

Affiche les informations sur toutes les connexions frontend QUIC actives. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés avec les niveaux « operator » ou « admin ».

Un argument facultatif peut être spécifié pour contrôler le niveau de détail. Sa valeur peut être interprétée de différentes manières. La première possibilité consiste à utiliser des valeurs prédéfinies : « oneline » pour le format par défaut, « stream » pour lister tous les flux actifs, ou « full » pour afficher toutes les informations. En alternative, une liste de champs séparés par des virgules peut être spécifiée afin de restreindre la sortie. Les valeurs actuellement prises en charge sont « tp », « sock », « pktns », « cc » et « mux ». Enfin, la valeur « help » dans le format affiche à la place un message d’aide plus détaillé.

L’argument final sert à restreindre ou étendre la liste des connexions. Par défaut, seules les connexions frontend actives sont affichées. Utilisez l’argument supplémentaire « clo » pour afficher les connexions frontend en cours de fermeture, « be » pour les connexions backend ou « all » pour toutes les catégories. Il est également possible de restreindre à une seule connexion en spécifiant son adresse hexadécimale.

show servers conn [<backend>]

show servers conn [<backend>]

Affiche l’état des connexions actives et inactives des serveurs appartenant au backend spécifié (ou de tous les backends si aucun n’est précisé). Un nom ou un identifiant de backend peut être utilisé.

La sortie se compose d’une ligne d’en-tête affichant les titres des champs, suivie d’une ligne par serveur, contenant pour chaque serveur le nom et l’ID du backend, le nom et l’ID du serveur, l’adresse, le port et une série de valeurs. Le nombre de champs varie selon le nombre de threads. Le format exact de la sortie peut légèrement varier d’une version à l’autre et selon le nombre de threads. Il est nécessaire de prêter attention à la ligne d’en-tête pour aligner correctement les colonnes lors de l’extraction des valeurs, ainsi qu’au nombre de threads, car les dernières colonnes sont par thread :

bkname/svname         Backend name '/' server name
bkid/svid             Backend ID '/' server ID
addr                  Server's IP address
port                  Server's port (or zero if none)
-                     Unused field, serves as a visual delimiter
purge_delay           Interval between connection purges, in milliseconds
served                Number of connections currently in use
used_cur              Number of connections currently in use
                      note that this excludes conns attached to a session
used_max              Highest value of used_cur since the process started
need_est              Floating estimate of total needed connections
idle_sess             Number of idle connections flagged as private
unsafe_nb             Number of idle connections considered as "unsafe"
safe_nb               Number of idle connections considered as "safe"
idle_lim              Configured maximum number of idle connections
idle_cur              Total of the per-thread currently idle connections
idle_per_thr[NB]      Idle conns per thread for each one of the NB threads

HAProxy tue une partie de <idle_cur> toutes les <purge_delay> lorsque la somme de <idle_cur> + <used_cur> dépasse l’estimation <need_est>. Cette estimation varie en fonction de l’activité des connexions.

Étant donné la nature threadée des connexions inactives, il est important de comprendre que certaines valeurs peuvent évoluer après lecture, et qu’aucune cohérence au sein d’une ligne n’est garantie. Cette sortie est principalement destinée à la débogage et ne doit pas être surveillée ni visualisée de manière régulière.

show servers state [<backend>]

show servers state [<backend>]

Affiche l’état des serveurs présents dans la configuration en cours d’exécution. Un nom ou un identifiant de backend peut être fourni pour limiter la sortie à ce backend uniquement.

Dumper a le format suivant :

  • première ligne contient la version du format (1 dans cette spécification) ;
  • deuxième ligne contient les en-têtes de colonne, précédés d’un dièse (’#’) ;
  • troisième ligne et les lignes suivantes contiennent les données ;
  • chaque ligne commençant par un dièse (’#’) est considérée comme un commentaire.

Étant donné que plusieurs versions de la sortie peuvent coexister, voici la liste des champs et leur ordre par version de format de fichier :

1:
  be_id:                       Backend unique id.
  be_name:                     Backend label.
  srv_id:                      Server unique id (in the backend).
  srv_name:                    Server label.
  srv_addr:                    Server IP address.
  srv_op_state:                Server operational state (UP/DOWN/...).
                                 0 = SRV_ST_STOPPED
                                   The server is down.
                                 1 = SRV_ST_STARTING
                                   The server is warming up (up but
                                   throttled).
                                 2 = SRV_ST_RUNNING
                                   The server is fully up.
                                 3 = SRV_ST_STOPPING
                                   The server is up but soft-stopping
                                   (eg: 404).
  srv_admin_state:             Server administrative state (MAINT/DRAIN/...).
                               The state is actually a mask of values:
                                 0x01 = SRV_ADMF_FMAINT
                                   The server was explicitly forced into
                                   maintenance.
                                 0x02 = SRV_ADMF_IMAINT
                                   The server has inherited the maintenance
                                   status from a tracked server.
                                 0x04 = SRV_ADMF_CMAINT
                                   The server is in maintenance because of
                                   the configuration.
                                 0x08 = SRV_ADMF_FDRAIN
                                   The server was explicitly forced into
                                   drain state.
                                 0x10 = SRV_ADMF_IDRAIN
                                   The server has inherited the drain status
                                   from a tracked server.
                                 0x20 = SRV_ADMF_RMAINT
                                   The server is in maintenance because of an
                                   IP address resolution failure.
                                 0x40 = SRV_ADMF_HMAINT
                                   The server FQDN was set from stats socket.

  srv_uweight:                 User visible server's weight.
  srv_iweight:                 Server's initial weight.
  srv_time_since_last_change:  Time since last operational change.
  srv_check_status:            Last health check status.
  srv_check_result:            Last check result (FAILED/PASSED/...).
                                 0 = CHK_RES_UNKNOWN
                                   Initialized to this by default.
                                 1 = CHK_RES_NEUTRAL
                                   Valid check but no status information.
                                 2 = CHK_RES_FAILED
                                   Check failed.
                                 3 = CHK_RES_PASSED
                                   Check succeeded and server is fully up
                                   again.
                                 4 = CHK_RES_CONDPASS
                                   Check reports the server doesn't want new
                                   sessions.
  srv_check_health:            Checks rise / fall current counter.
  srv_check_state:             State of the check (ENABLED/PAUSED/...).
                               The state is actually a mask of values:
                                 0x01 = CHK_ST_INPROGRESS
                                   A check is currently running.
                                 0x02 = CHK_ST_CONFIGURED
                                   This check is configured and may be
                                   enabled.
                                 0x04 = CHK_ST_ENABLED
                                   This check is currently administratively
                                   enabled.
                                 0x08 = CHK_ST_PAUSED
                                   Checks are paused because of maintenance
                                   (health only).
  srv_agent_state:             State of the agent check (ENABLED/PAUSED/...).
                               This state uses the same mask values as
                               "srv_check_state", adding this specific one:
                                 0x10 = CHK_ST_AGENT
                                   Check is an agent check (otherwise it's a
                                   health check).
  bk_f_forced_id:              Flag to know if the backend ID is forced by
                               configuration.
  srv_f_forced_id:             Flag to know if the server's ID is forced by
                               configuration.
  srv_fqdn:                    Server FQDN.
  srv_port:                    Server port.
  srvrecord:                   DNS SRV record associated to this SRV.
  srv_use_ssl:                 use ssl for server connections.
  srv_check_port:              Server health check port.
  srv_check_addr:              Server health check address.
  srv_agent_addr:              Server health agent address.
  srv_agent_port:              Server health agent port.

show sess [<options>*]

show sess [<options>*]

Affiche tous les flux actifs connus (anciennement appelés « sessions »). Évitez d’exécuter cette commande sur des connexions lentes, car cela peut générer une sortie très volumineuse. Cette commande est restreinte et ne peut être exécutée que sur les sockets configurés pour les niveaux « operator » ou « admin ». Notez qu’ sur des machines avec des connexions recyclées rapidement, il se peut que la sortie affiche moins d’entrées que le nombre réellement existant, car seuls les flux existants au moment de l’entrée de la commande sont répertoriés ; ceux qui se ferment entre-temps ne seront pas inclus. Pour les options prises en charge, voir ci-dessous.

show sess [<id> | all | help] [<options>*]

show sess [<id> | all | help] [<options>*]

Affichez beaucoup d’informations internes sur les flux correspondants. La commande connaît deux formats de sortie : un format court, qui est le par défaut lorsqu’aucun identifiant de flux spécifique n’est demandé, et un format étendu lors de la liste de flux désignés. Le format court, utilisé par défaut avec « show sess », n’affiche qu’un flux par ligne, avec quelques informations, et l’identifiant du flux au début de la ligne en format hexadécimal (il correspond à l’adresse mémoire du flux).

Dans sa forme étendue, utilisée par « show sess <id> » ou « show sess all », les flux sont affichés avec une quantité importante de détails de débogage sur plusieurs lignes (environ 20 par flux), tout en commençant toujours par leur identifiant. Le délimiteur entre les flux est l’identifiant situé au début de la ligne ; les lignes supplémentaires appartenant au même flux commencent par un ou plusieurs espaces (le flux est affiché avec un retrait). L’affichage de nombreux flux peut générer une sortie très volumineuse, prendre beaucoup de temps et être très coûteux en ressources CPU, il est donc toujours préférable de n’afficher que le minimum nécessaire. Ces informations sont inutiles pour la majorité des utilisateurs, mais peuvent être utilisées par les développeurs HAProxy pour diagnostiquer un bug complexe. Le format exact de la sortie n’est pas documenté intentionnellement afin qu’il puisse évoluer librement selon les besoins, y compris dans les branches stables. Cette sortie est destinée à être interprétée en consultant la fonction strm_dump_to_buffer() dans src/stream.c afin de comprendre la signification exacte de certains champs.

L’argument « help » affichera l’utilisation détaillée de la commande au lieu de déverser les flux.

Il est possible de définir certaines options afin de personnaliser la sauvegarde ou d’appliquer des filtres. Voici les options prises en charge : - backend <b> : n’afficher que les flux attachés à ce backend - frontend <f> : n’afficher que les flux attachés à ce frontal - older <age> : n’afficher que les flux plus anciens que <age> secondes - server <b/s> : n’afficher que les flux attachés à ce couple backend+serveur - show-uri : sauvegarder l’URI de la transaction, tel qu’il a été capturé lors de l’analyse de la requête. Il n’est affiché que s’il a été capturé. - susp : n’afficher que les flux considérés comme suspects par les développeurs, selon des critères qui peuvent évoluer dans le temps ou varier selon les versions.

show stat [domain <resolvers|proxy>] [{<iid>|<proxy>} <type> <sid>] \

show stat [domain <resolvers|proxy>] [{<iid>|<proxy>} <type> <sid>] \
          [typed|json] [desc] [up|no-maint]

Dump des statistiques. Le domaine est utilisé pour sélectionner les statistiques à afficher ; les résolveurs et les proxies sont actuellement disponibles. Par défaut, le format CSV est utilisé ; vous pouvez activer le format d’affichage étendu typé décrit dans la section précédente en passant « typed » après les autres arguments ; ou au format JSON en passant « json » après les autres arguments. En passant <id>, <type> et <sid>, il est possible de n’afficher que des éléments sélectionnés : - <iid> est un identifiant de proxy, -1 pour tout afficher. En alternative, un nom de proxy <proxy> peut être spécifié. Dans ce cas, l’identifiant de ce proxy sera utilisé comme sélecteur d’identifiant. - <type> sélectionne le type d’objets pouvant être dumpés : 1 pour les frontaux, 2 pour les backends, 4 pour les serveurs, -1 pour tout. Ces valeurs peuvent être combinées par opération OU, par exemple :

1 + 2     = 3   -> frontend + backend.
1 + 2 + 4 = 7   -> frontend + backend + server.
- `<sid>` est un identifiant de serveur, -1 pour exporter l'intégralité du proxy sélectionné.

Exemple :

    $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock1
>>> Name: HAProxy
    Version: 1.4-dev2-49
    Release_date: 2009/09/23
    Nbproc: 1
    Process_num: 1
    (...)

    # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,  (...)
    stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
    stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...)
    (...)
    www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)

    $

Dans cet exemple, deux commandes ont été émises simultanément. Cela permet de déterminer facilement quel processus les statistiques concernent en mode multi-processus. Cette information n’est pas nécessaire dans le format de sortie typée, car le numéro de processus est indiqué sur chaque ligne. Notez la ligne vide suivant la sortie d’information, qui marque la fin du premier bloc. Une ligne vide similaire apparaît à la fin du second bloc (stats), afin que l’utilisateur sache que la sortie n’a pas été tronquée.

Lorsque « typed » est spécifié, le format de sortie est plus adapté aux outils de surveillance, car il fournit des positions numériques et indique le type de chaque champ de sortie. Chaque valeur apparaît sur une ligne distincte, accompagnée du numéro de processus, du numéro d’élément, de sa nature, de son origine et de son champ d’application. Ce même format est également disponible via les statistiques HTTP en ajoutant « ;typed » à l’URI. Il est très important de noter que, dans le format de sortie typé, les données d’un objet unique sont contiguës, de sorte qu’il n’est pas nécessaire pour le consommateur de stocker l’ensemble des données en même temps.

Le modificateur « up » entraîne l’affichage uniquement des serveurs signalés comme étant actifs ou non vérifiés. Les serveurs inactifs, non résolus ou en maintenance ne seront pas affichés. Cela correspond à l’option « ;up » dans les statistiques HTTP. De même, le modificateur « no-maint » agit comme le modificateur HTTP « ;no-maint » et empêche l’affichage des serveurs désactivés. La différence réside dans le fait que les serveurs activés mais inactifs ne seront pas exclus.

Lorsqu’on utilise le format de sortie typé, chaque ligne est composée de 4 colonnes séparées par des deux-points (’:’). La première colonne est une série de 5 éléments séparés par des points. Le premier élément est une lettre indiquant le type de l’objet décrit. Actuellement, les types d’objets suivants sont connus : « F » pour un frontal, « B » pour un backend, « L » pour un écouteur, et « S » pour un serveur. Le deuxième élément est un entier positif représentant l’identifiant unique du proxy auquel appartient l’objet. Il correspond à la colonne « iid » de la sortie CSV et correspond à la valeur située devant la directive optionnelle « id » présente dans la section frontal ou backend. Le troisième élément est un entier positif contenant l’identifiant unique de l’objet à l’intérieur du proxy, et correspond à la colonne « sid » de la sortie CSV. La valeur 0 est utilisée lors du dump d’un frontal ou d’un backend. Pour un écouteur ou un serveur, cela correspond à son identifiant respectif à l’intérieur du proxy. Le quatrième élément est la position numérique du champ dans la liste (comptée à partir de zéro). Cette position ne doit pas évoluer au fil du temps, mais des trous sont à prévoir, selon les options de compilation ou si certains champs sont supprimés à l’avenir. Le cinquième élément est le nom du champ tel qu’il apparaît dans la sortie CSV. Le sixième élément est un entier positif et correspond au numéro relatif du processus, commençant à 1.

Le reste de la ligne, à partir du premier deux-points, suit le format de sortie typé décrit dans la section précédente. En résumé, la deuxième colonne (après le premier « : ») indique l’origine, la nature, la portée et l’état de persistance de la variable. La troisième colonne indique le type de champ, parmi « s32 », « s64 », « u32 », « u64 », « flt » et « str ». La quatrième colonne contient la valeur elle-même, que le consommateur sait interpréter grâce à la colonne 3 et traiter grâce à la colonne 2.

Lorsque « desc » est ajouté à la commande, une deuxième virgule suivie d’une chaîne entre guillemets est ajoutée pour inclure une description de la métrique. Au moment de la rédaction, cette fonctionnalité n’est prise en charge que pour le format de sortie « typed ».

Ainsi, le format global de ligne en mode typé est :

<obj>.<px_id>.<id>.<fpos>.<fname>.<process_num>:<tags>:<type>:<value>

Voici un exemple de format de sortie typé :

$ echo "show stat typed" | socat stdio unix-connect:/tmp/sock1
F.2.0.0.pxname.1:KNSV:str:dummy
F.2.0.1.svname.1:KNSV:str:FRONTEND
F.2.0.4.scur.1:MGPV:u32:0
F.2.0.5.smax.1:MMPV:u32:0
F.2.0.6.slim.1:CLPV:u32:524269
F.2.0.7.stot.1:MCPP:u64:0
F.2.0.8.bin.1:MCPP:u64:0
F.2.0.9.bout.1:MCPP:u64:0
F.2.0.10.dreq.1:MCPP:u64:0
F.2.0.11.dresp.1:MCPP:u64:0
F.2.0.12.ereq.1:MCPP:u64:0
F.2.0.17.status.1:SGPV:str:OPEN
F.2.0.26.pid.1:KGPV:u32:1
F.2.0.27.iid.1:KGSV:u32:2
F.2.0.28.sid.1:KGSV:u32:0
F.2.0.32.type.1:CGSV:u32:0
F.2.0.33.rate.1:MRPP:u32:0
F.2.0.34.rate_lim.1:CLPV:u32:0
F.2.0.35.rate_max.1:MMPV:u32:0
F.2.0.46.req_rate.1:MRPP:u32:0
F.2.0.47.req_rate_max.1:MMPV:u32:0
F.2.0.48.req_tot.1:MCPP:u64:0
F.2.0.51.comp_in.1:MCPP:u64:0
F.2.0.52.comp_out.1:MCPP:u64:0
F.2.0.53.comp_byp.1:MCPP:u64:0
F.2.0.54.comp_rsp.1:MCPP:u64:0
(...)

Dans le format typé, la présence de l’identifiant de processus à la fin de la première colonne permet de regrouper visuellement les sorties de plusieurs processus, comme illustré dans l’exemple ci-dessous où chaque ligne s’affiche pour chaque processus :

$ ( echo show stat typed | socat /var/run/haproxy.sock1 -; \
    echo show stat typed | socat /var/run/haproxy.sock2 - ) | \
  sort -t . -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5 -k 6,6n
B.3.0.0.pxname.1:KNSV:str:private-backend
B.3.0.0.pxname.2:KNSV:str:private-backend
B.3.0.1.svname.1:KNSV:str:BACKEND
B.3.0.1.svname.2:KNSV:str:BACKEND
B.3.0.2.qcur.1:MGPV:u32:0
B.3.0.2.qcur.2:MGPV:u32:0
B.3.0.3.qmax.1:MMPV:u32:0
B.3.0.3.qmax.2:MMPV:u32:0
B.3.0.4.scur.1:MGPV:u32:0
B.3.0.4.scur.2:MGPV:u32:0
B.3.0.5.smax.1:MMPV:u32:0
B.3.0.5.smax.2:MMPV:u32:0
B.3.0.6.slim.1:CLPV:u32:1000
B.3.0.6.slim.2:CLPV:u32:1000
(...)

Le format de la sortie JSON est décrit dans un schéma qui peut être affiché à l’aide de la commande « show schema json ».

La sortie JSON ne contient aucun espace blanc supplémentaire afin de réduire le volume de sortie. Pour une lecture humaine, il peut être utile de passer la sortie through un formatteur de code. Exemple :

$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool

La sortie JSON ne contient aucun espace blanc supplémentaire afin de réduire le volume de sortie. Pour une lecture humaine, il peut être utile de passer la sortie through un formatteur de code. Exemple :

$ echo “show stat json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool

show ssl ca-file [[*][\]<cafile>[:<index>]]

show ssl ca-file [[*][\]<cafile>[:<index>]]

Affiche la liste des fichiers de certificats autorités de certification (CA) chargés dans le processus ainsi que le nombre de certificats correspondants. Les certificats ne sont pas utilisés par aucun frontal ou backend tant que leur statut n’est pas « Utilisé ». Une entrée “@system-ca” peut apparaître dans la liste ; elle est chargée par défaut par httpclient et contient la liste des autorités de certification fiables de votre système, renvoyée par OpenSSL. Si un nom de fichier est précédé d’un astérisque, il s’agit d’une transaction non encore validée. Si un <cafile> est spécifié sans <index>, il affichera l’état du fichier CA (“Utilisé”/“Non utilisé”) suivi des détails de tous les certificats contenus dans ce fichier. Les détails affichés pour chaque certificat sont identiques à ceux affichés par la commande “show ssl cert”. Si un <cafile> est spécifié suivi d’un <index>, seuls les détails du certificat ayant l’index spécifié seront affichés. Les index commencent à 1. Si l’index est invalide (par exemple trop élevé), rien ne sera affiché. Cette commande peut être utile pour vérifier qu’un fichier CA a été correctement mis à jour. Vous pouvez également afficher les détails d’une transaction en cours en précédant le nom de fichier par un ‘’. Si le premier caractère du nom de fichier est un ‘’, il peut être échappé avec ‘\*’.

Exemple :

$ echo "show ssl ca-file" | socat /var/run/haproxy.master -
# transaction
*cafile.crt - 2 certificate(s)
# filename
cafile.crt - 1 certificate(s)

$ echo "show ssl ca-file cafile.crt" | socat /var/run/haproxy.master -
Filename: /home/tricot/work/haproxy/reg-tests/ssl/set_cafile_ca2.crt
Status: Used

Certificate #1:
Serial: 11A4D2200DC84376E7D233CAFF39DF44BF8D1211
notBefore: Apr  1 07:40:53 2021 GMT
notAfter: Aug 17 07:40:53 2048 GMT
Subject Alternative Name:
Algorithm: RSA4096
SHA1 FingerPrint: A111EF0FEFCDE11D47FE3F33ADCA8435EBEA4864
Subject: /C=FR/ST=Some-State/O=HAProxy Technologies/CN=HAProxy Technologies CA
Issuer: /C=FR/ST=Some-State/O=HAProxy Technologies/CN=HAProxy Technologies CA

$ echo "show ssl ca-file *cafile.crt:2" | socat /var/run/haproxy.master -
Filename: */home/tricot/work/haproxy/reg-tests/ssl/set_cafile_ca2.crt
Status: Unused

Certificate #2:
Serial: 587A1CE5ED855040A0C82BF255FF300ADB7C8136
[...]

show ssl cert [[*][\]<filename>]

show ssl cert [[*][\]<filename>]

Affiche la liste des certificats chargés dans le processus. Ils ne sont pas utilisés par aucun frontal ou backend tant que leur statut n’est pas « Utilisé ». Si un nom de fichier est précédé d’un astérisque, il s’agit d’une transaction non encore validée. Si un nom de fichier est spécifié, les détails concernant le certificat seront affichés. Cette commande peut être utile pour vérifier qu’un certificat a bien été mis à jour. Vous pouvez également afficher les détails d’une transaction en précédant le nom de fichier par un ‘’. Si le premier caractère du nom de fichier est un ‘’, il peut être échappé avec ‘\*’. Cette commande peut également être utilisée pour afficher les détails de la réponse OCSP d’un certificat en ajoutant à la fin du nom de fichier une extension “.ocsp”. Elle fonctionne aussi bien pour les certificats validés que pour les transactions en cours. Pour un certificat validé, cette commande est équivalente à l’appel de « show ssl ocsp-response » avec l’identifiant correspondant de la réponse OCSP.

Exemple :

$ echo "@1 show ssl cert" | socat /var/run/haproxy.master -
# transaction
*test.local.pem
# filename
test.local.pem

$ echo "@1 show ssl cert test.local.pem" | socat /var/run/haproxy.master -
Filename: test.local.pem
Status: Used
Serial: 03ECC19BA54B25E85ABA46EE561B9A10D26F
notBefore: Sep 13 21:20:24 2019 GMT
notAfter: Dec 12 21:20:24 2019 GMT
Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Subject: /CN=test.local
Subject Alternative Name: DNS:test.local, DNS:imap.test.local
Algorithm: RSA2048
SHA1 FingerPrint: 417A11CAE25F607B24F638B4A8AEE51D1E211477

$ echo "@1 show ssl cert *test.local.pem" | socat /var/run/haproxy.master -
Filename: *test.local.pem
Status: Unused
[...]

$ echo "@1 show ssl cert \*.local.pem" | socat /var/run/haproxy.master -
Filename: *.local.pem
Status: Used
[...]

show ssl crl-file [[*][\]<crlfile>[:<index>]]

show ssl crl-file [[*][\]<crlfile>[:<index>]]

Affiche la liste des fichiers CRL chargés dans le processus. Ils ne sont pas utilisés par aucun frontal ou backend tant que leur statut n’est pas « Utilisé ». Si un nom de fichier est précédé d’un astérisque, il s’agit d’une transaction non encore validée. Si un <crlfile> est spécifié sans <index>, il affiche l’état du fichier CRL (“Utilisé”/“Non utilisé”) suivi des détails relatifs à toutes les listes de révocation contenues dans le fichier CRL. Les détails affichés pour chaque liste sont basés sur la sortie de la commande « openssl crl -text -noout -in <file> ». Si un <crlfile> est spécifié suivi d’un <index>, seul le détail de la liste ayant l’index spécifié est affiché. Les index commencent à 1. Si l’index est invalide (par exemple trop élevé), rien n’est affiché. Cette commande peut être utile pour vérifier qu’un fichier CRL a été correctement mis à jour. Vous pouvez également afficher les détails d’une transaction en cours en précédant le nom de fichier d’un ‘’. Si le premier caractère du nom de fichier est un ‘’, il peut être échappé avec ‘\*’.

Exemple :

$ echo "show ssl crl-file" | socat /var/run/haproxy.master -
# transaction
*crlfile.pem
# filename
crlfile.pem

$ echo "show ssl crl-file crlfile.pem" | socat /var/run/haproxy.master -
Filename: /home/tricot/work/haproxy/reg-tests/ssl/crlfile.pem
Status: Used

Certificate Revocation List #1:
Version 1
Signature Algorithm: sha256WithRSAEncryption
Issuer: /C=FR/O=HAProxy Technologies/CN=Intermediate CA2
Last Update: Apr 23 14:45:39 2021 GMT
Next Update: Sep  8 14:45:39 2048 GMT
Revoked Certificates:
    Serial Number: 1008
        Revocation Date: Apr 23 14:45:36 2021 GMT

Certificate Revocation List #2:
Version 1
Signature Algorithm: sha256WithRSAEncryption
Issuer: /C=FR/O=HAProxy Technologies/CN=Root CA
Last Update: Apr 23 14:30:44 2021 GMT
Next Update: Sep  8 14:30:44 2048 GMT
No Revoked Certificates.

show ssl crt-list [-n] [<filename>]

show ssl crt-list [-n] [<filename>]

Affiche la liste des crt-list et des répertoires utilisés dans la configuration HAProxy. Si un nom de fichier est spécifié, affiche le contenu d’un crt-list ou d’un répertoire. Une fois affiché, la sortie peut être utilisée comme fichier crt-list. L’option ‘-n’ permet d’afficher le numéro de ligne, ce qui est utile lors de l’utilisation combinée avec l’option ‘del ssl crt-list’ en cas de duplication d’entrée. La sortie avec l’option ‘-n’ n’est pas compatible avec le format crt-list et ne peut pas être chargée par HAProxy.

Exemple :

echo "show ssl crt-list -n localhost.crt-list" | socat /tmp/sock1 -
# localhost.crt-list
common.pem:1 !not.test1.com *.test1.com !localhost
common.pem:2
ecdsa.pem:3 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3] localhost !www.test1.com
ecdsa.pem:4 [verify none allow-0rtt ssl-min-ver TLSv1.0 ssl-max-ver TLSv1.3]

show ssl ech [<name>]

show ssl ech [<name>]

Affichez la liste des clés ECH chargées dans le processus HAProxy.

Lorsque <name> est spécifié, affiche les clés correspondant à une ligne de liaison spécifique. Le format de la ligne de liaison est <frontend>/@<filename>:<linenum> (par exemple : frontend1/@haproxy.conf :19) ou <frontend>/<name> si la ligne de liaison a été nommée à l’aide du mot-clé « name ».

L’entrée « age » représente le temps, en secondes, écoulé depuis que la clé a été chargée dans la ligne bind. Cette valeur est réinitialisée lors du démarrage, du rechargement ou de la redémarrage de HAProxy.

Exige une version d’OpenSSL qui prend en charge ECH, et HAProxy doit être compilé avec USE_ECH=1. Cette commande n’est prise en charge que sur une connexion CLI en mode expérimental (voir « experimental-mode on »).

Voir également « ech » dans la Section 5.1 du manuel de configuration.

Exemple :

$ echo "experimental-mode on; show ssl ech" | socat /tmp/haproxy.sock -
 ***
 frontend: frontend1

 bind: frontend1/@haproxy.conf:19

 ECH entry: 0 public_name: example.com age: 557 (has private key)
      [fe0d,94,example.com,[0020,0001,0001],c39285b774bf61c071864181c5292a012b30adaf767e39369a566af05573ef2b,00,00]

 ECH entry: 1 public_name: example.com age: 557 (has private key)
      [fe0d,ee,example.com,[0020,0001,0001],6572191131b5cabba819f8cacf2d2e06fa0b87b30d9b793644daba7b8866d511,00,00]

 bind: frontend1/@haproxy.conf:20

 ECH entry: 0 public_name: example.com age: 557 (has private key)
      [fe0d,94,example.com,[0020,0001,0001],c39285b774bf61c071864181c5292a012b30adaf767e39369a566af05573ef2b,00,00]

 ECH entry: 1 public_name: example.com age: 557 (has private key)
      [fe0d,ee,example.com,[0020,0001,0001],6572191131b5cabba819f8cacf2d2e06fa0b87b30d9b793644daba7b8866d511,00,00]

$ echo "experimental-mode on; show ssl ech frontend1/@haproxy.conf:19" | socat /tmp/haproxy.sock -
***
ECH for frontend1/@haproxy.conf:19
ECH entry: 0 public_name: example.com age: 786 (has private key)
      [fe0d,94,example.com,[0020,0001,0001],c39285b774bf61c071864181c5292a012b30adaf767e39369a566af05573ef2b,00,00]

ECH entry: 1 public_name: example.com age: 786 (has private key)
      [fe0d,ee,example.com,[0020,0001,0001],6572191131b5cabba819f8cacf2d2e06fa0b87b30d9b793644daba7b8866d511,00,00]

show ssl jwt

show ssl jwt

Affiche la liste des certificats pouvant être utilisés pour la validation JWT. Voir également les commandes « add ssl jwt » et « del ssl jwt ». Voir l’option de certificat « jwt » pour plus d’informations.

Exemple :

echo "show ssl jwt"  | socat /tmp/sock1 -
#filename
jwt.pem

show ssl ocsp-response [[text|base64] <id|path>]

show ssl ocsp-response [[text|base64] <id|path>]

Affichez les identifiants des entrées de l’arbre OCSP correspondant à toutes les réponses OCSP utilisées par HAProxy, ainsi que le chemin du certificat frontal correspondant, le nom de l’autorité émettrice et son hachage de clé, et le numéro de série du certificat pour lequel la réponse OCSP a été générée. Si un <id> valide ou le <path> d’un certificat frontal valide est fourni, affichez le contenu de la réponse OCSP correspondante. Lorsqu’un <id> est fourni, il est possible de définir le format dans lequel les données sont exportées. L’option « text » est la valeur par défaut et permet d’afficher des informations détaillées sur la réponse OCSP de la même manière qu’avec une commande « OpenSSL ocsp -respin <ocsp-response> -text ». Le format « base64 » permet d’exporter le contenu d’une réponse OCSP au format base64.

Exemple :

$ echo "show ssl ocsp-response" | socat /var/run/haproxy.master -
# Certificate IDs
  Certificate ID key: 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100a
  Certificate path: /path_to_cert/foo.pem
    Certificate ID:
      Issuer Name Hash: 8A83E0060FAFF709CA7E9B95522A2E81635FDA0A
      Issuer Key Hash: F652B0E435D5EA923851508F0ADBE92D85DE007A
      Serial Number: 100A

$ echo "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100a" | socat /var/run/haproxy.master -
OCSP Response Data:
  OCSP Response Status: successful (0x0)
  Response Type: Basic OCSP Response
  Version: 1 (0x0)
  Responder Id: C = FR, O = HAProxy Technologies, CN = ocsp.haproxy.com
  Produced At: May 27 15:43:38 2021 GMT
  Responses:
  Certificate ID:
    Hash Algorithm: sha1
    Issuer Name Hash: 8A83E0060FAFF709CA7E9B95522A2E81635FDA0A
    Issuer Key Hash: F652B0E435D5EA923851508F0ADBE92D85DE007A
    Serial Number: 100A
  Cert Status: good
  This Update: May 27 15:43:38 2021 GMT
  Next Update: Oct 12 15:43:38 2048 GMT
  [...]

$ echo "show ssl ocsp-response base64 /path_to_cert/foo.pem" | socat /var/run/haproxy.sock -
  MIIB8woBAKCCAewwggHoBgkrBgEFBQcwAQEEggHZMIIB1TCBvqE[...]

show ssl ocsp-updates

show ssl ocsp-updates

Affiche des informations sur les entrées concernées par le mécanisme de mise à jour OCSP. La commande affiche une ligne par réponse OCSP et inclut l’heure prévue de mise à jour de la réponse, ainsi que l’heure de la dernière mise à jour réussie et les compteurs de mises à jour réussies et échouées. Elle indique également le statut de la dernière mise à jour (réussie ou non) sous forme numérique et textuelle. Consultez la liste complète des erreurs possibles ci-dessous. Les lignes sont triées par heure croissante de « Next Update ». Chaque ligne contient également le chemin vers le premier certificat frontal utilisant la réponse OCSP. Pour plus d’informations sur la mise à jour automatique OCSP, reportez-vous à la commande « show ssl ocsp-response » et à l’option « ocsp-update ».

Les codes d’erreur et les chaînes d’erreur de mise à jour peuvent être les suivants :

  +----+-------------------------------------+
  | ID | message                             |
  +----+-------------------------------------+
  |  0 | "Unknown"                           |
  |  1 | "Update successful"                 |
  |  2 | "HTTP error"                        |
  |  3 | "Missing \"ocsp-response\" header"  |
  |  4 | "OCSP response check failure"       |
  |  5 | "Error during insertion"            |
  +----+-------------------------------------+

Exemple :

$ echo "show ssl ocsp-updates" | socat /tmp/haproxy.sock -
  OCSP Certid | Path | Next Update | Last Update | Successes | Failures | Last Update Status | Last Update Status (str)
      303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a02021015 | /path_to_cert/cert.pem | 30/Jan/2023:00:08:09 +0000 | - | 0 | 1 | 2 | HTTP error
      304b300906052b0e03021a0500041448dac9a0fb2bd32d4ff0de68d2f567b735f9b3c40414142eb317b75856cbae500940e61faf9d8b14c2c6021203e16a7aa01542f291237b454a627fdea9c1 | /path_to_cert/other_cert.pem | 30/Jan/2023:01:07:09 +0000 | 30/Jan/2023:00:07:09 +0000 | 1 | 0 | 1 | Update successful

show ssl providers

show ssl providers

Affiche les noms des fournisseurs chargés par OpenSSL lors de l’initialisation. Le chargement des fournisseurs peut effectivement être configuré via le fichier de configuration OpenSSL, et cette option permet de vérifier que les bons fournisseurs ont été chargés. Cette commande n’est disponible que sous OpenSSL v3.

Exemple :

$ echo "show ssl providers" | socat /var/run/haproxy.master -
Loaded providers:
    - fips
    - base

show ssl sni [-f <frontend>] [-A] [-t <offset>]

show ssl sni [-f <frontend>] [-A] [-t <offset>]

Affiche chaque SNI configuré pour le frontal désigné, ou tous les frontaux si aucun frontal n’a été spécifié. Cela permet de visualiser quels SNI sont proposés pour un frontal, et d’identifier si un SNI est défini plusieurs fois par plusieurs certificats pour le même frontal.

L’option -A permet de filtrer la liste et n’affiche que les certificats dont la date notAfter est dépassée, permettant ainsi d’afficher uniquement les certificats expirés.

L’option -t prend un décalage en secondes, ou avec une unité de temps (s, m, h, d), qui est ajouté à l’heure courante, permettant de vérifier quels certificats ont expiré après le décalage lorsqu’elle est combinée avec -A.. Par exemple, si vous souhaitez vérifier quels certificats seraient expirés dans 30d, il suffit d’exécuter « show ssl sni -A -t 30d ».

Les colonnes sont séparées par un unique \t, permettant une analyse simple.

La colonne « Frontend/Bind » indique le nom du frontal suivi de la position de la ligne de liaison dans la configuration (frontend/fichier:numero_ligne).

La colonne « SNI » affiche le SNI, qui peut être un CN, un SAN ou un filtre provenant d’une liste de certificats (crt-list). Les certificats par défaut d’une ligne bind (qui sont soit déclarés explicitement via default-crt, soit implicites, à savoir le premier certificat d’une ligne bind lorsque strict-sni n’est pas utilisé) affichent le caractère « * » dans la colonne SNI.

La colonne « Filtrage négatif » contient la liste des filtres négatifs associés à un joker. Elle affiche tous les filtres négatifs présents sur la même ligne de la liste crt. Un trait de soulignement est affiché s’il n’y en a aucun.

La colonne « Type » indique le type d’algorithme de chiffrement, qui peut être « rsa », « ecdsa » ou « dsa ».

La colonne « Filename » peut être soit un nom de fichier provenant de la configuration, soit un alias déclaré dans un crt-store.

Les colonnes « NotAfter » et « NotBefore » sont extraites directement du certificat X509 feuille.

Exemple :

$ echo "@1 show ssl sni -A -t 30d" | socat /var/run/haproxy-master.sock - | column -t -s $'\t'
# Frontend/Bind        SNI        Negative Filter  Type   Filename             NotAfter                  NotBefore
li1/haproxy.cfg:10021  *.ex.lan   !m1.ex.lan       rsa    example.lan.pem      Jun 13 13:37:21 2024 GMT  May 14 13:37:21 2024 GMT
li1/haproxy.cfg:10021  machine10  -                ecdsa  machine10.pem.ecdsa  Jun 13 13:37:21 2024 GMT  May 14 13:37:21 2024 GMT
li1/haproxy.cfg:10021  machine10  -                rsa    machine10.pem.rsa    Jun 13 13:37:21 2024 GMT  May 14 13:37:21 2024 GMT
li1/haproxy.cfg:10021  machine10  -                ecdsa  machine10.pem.ecdsa  Jun 13 13:37:21 2024 GMT  May 14 13:37:21 2024 GMT
li1/haproxy.cfg:10021  localhost  -                rsa    localhost.pem.rsa    Jun 13 13:37:11 2024 GMT  May 14 13:37:11 2024 GMT
li1/haproxy.cfg:10021  localhost  -                ecdsa  localhost.pem.ecdsa  Jun 13 13:37:10 2024 GMT  May 14 13:37:10 2024 GMT
li1/haproxy.cfg:10021  *          -                rsa    localhost.pem.rsa    Jun 13 13:37:11 2024 GMT  May 14 13:37:11 2024 GMT

show startup-logs

show startup-logs

Affiche tous les messages émis pendant le démarrage du processus HAProxy actuel, chaque tampon startup-logs étant unique à son worker HAProxy.

Ce mot-clé existe également sur l’interface CLI principale, qui affiche la dernière tentative de démarrage ou de rechargement.

show table

show table

Affiche des informations générales sur toutes les tables de persistance connues. Leur nom est retourné (le nom du proxy qui les contient), leur type (actuellement toujours zéro, toujours IP), leur taille maximale en nombre d’entrées possible, ainsi que le nombre d’entrées actuellement utilisées.

Exemple :

    $ echo "show table" | socat stdio /tmp/sock1
>>> # table: front_pub, type: ip, size:204800, used:171454
>>> # table: back_rdp, type: ip, size:204800, used:0

show table <name> [ data.<type> <operator> <value> [data.<type> ...]] |

show table <name> [ data.<type> <operator> <value> [data.<type> ...]] |
                  [ key <key> ] | [ ptr <ptr> ]

Affiche le contenu de la table de persistance <name>. En ce mode, une première ligne d’information générique sur la table est affichée, comme avec la commande « show table », suivie de l’affichage de toutes les entrées. Étant donné que cela peut être très lourd, il est possible de spécifier un filtre afin de préciser les entrées à afficher.

Lorsque le formulaire “data.” est utilisé, le filtre s’applique aux données stockées (voir « stick-table » dans la section 4.2). Un type de données stockées doit être spécifié dans <type>, et ce type de données doit être stocké dans la table, sinon une erreur est signalée. Les données sont comparées selon <operator> avec l’entier 64 bits <value>. Les opérateurs sont les mêmes qu’avec les ACLs :

- eq : correspond aux entrées dont les données sont égales à cette valeur
- ne : correspond aux entrées dont les données sont différentes de cette valeur
- le : correspond aux entrées dont les données sont inférieures ou égales à cette valeur
- ge : correspond aux entrées dont les données sont supérieures ou égales à cette valeur
- lt : correspond aux entrées dont les données sont inférieures à cette valeur
- gt : correspond aux entrées dont les données sont supérieures à cette valeur

Dans cette forme, vous pouvez utiliser plusieurs entrées de filtre de données, jusqu’à un maximum défini au moment de la compilation (4 par défaut).

Lorsque la forme clé est utilisée, l’entrée <key> est affichée. La clé doit être du même type que la table, ce qui est actuellement limité à IPv4, IPv6, entier et chaîne.

Lorsque la forme ptr est utilisée, l’entrée <ptr> est affichée. <ptr> est écrite sous la forme 0xffff et doit correspondre à l’adresse renvoyée par une commande précédente « show table ». Correspondre à une entrée à l’aide de son pointeur peut être pertinent si l’entrée ne peut pas être identifiée à l’aide de sa clé en raison d’une clé vide ou de caractères incompatibles sur le CLI.

Si data.<type> est de type tableau, on peut utiliser « [] » pour accéder à un index spécifique du tableau, comme ceci : data.gpt[1]

Exemple :

    $ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a4c: key=127.0.0.1 use=0 exp=3594729 gpc0=0 conn_rate(30000)=1  \
      bytes_out_rate(60000)=187
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191

    $ echo "show table http_proxy data.gpc0 gt 0" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191

    $ echo "show table http_proxy data.conn_rate gt 5" | \
        socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191

    $ echo "show table http_proxy key 127.0.0.2" | \
        socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191

    $ echo "show table http_proxy ptr 0x80e6a80" | \
        socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
>>> 0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
      bytes_out_rate(60000)=191

Lorsque le critère de données s’applique à une valeur dynamique dépendante du temps, comme un débit en octets, la valeur est calculée dynamiquement pendant l’évaluation de l’entrée afin de déterminer si elle doit être envoyée ou non. Cela signifie qu’un tel filtre peut correspondre pendant une certaine période, puis ne plus correspondre, car au fil du temps, le débit moyen des événements diminue.

Il est possible d’utiliser cette fonctionnalité pour extraire des listes d’adresses IP abuseuses du service, afin de les surveiller ou même de les bloquer dans un pare-feu. Exemple :

$ echo "show table http_proxy data.gpc0 gt 0" \
  | socat stdio /tmp/sock1 \
  | fgrep 'key=' | cut -d' ' -f2 | cut -d= -f2 > abusers-ip.txt
  ( or | awk '/key/{ print a[split($2,a,"=")]; }' )

Lorsque la table de persistance est synchronisée avec une section peers prenant en charge le fractionnement, le numéro de fraction sera affiché pour chaque clé (sinon, « 0 » est indiqué). Cela permet de savoir quels peers recevront cette clé. Exemple :

$ echo "show table http_proxy" | socat stdio /tmp/sock1 | fgrep shard=
  0x7f23b0c822a8: key=10.0.0.2 use=0 exp=296398 shard=9 gpc0=0
  0x7f23a063f948: key=10.0.0.6 use=0 exp=296075 shard=12 gpc0=0
  0x7f23b03920b8: key=10.0.0.8 use=0 exp=296766 shard=1 gpc0=0
  0x7f23a43c09e8: key=10.0.0.12 use=0 exp=295368 shard=8 gpc0=0

show tasks

show tasks

Affiche le nombre de tâches actuellement dans la file d’exécution, le nombre d’occurrences pour chaque fonction, ainsi que leur latence moyenne lorsqu’elle est connue (pour les tâches pures avec le profilage des tâches activé). La capture est un instantané de l’instant où elle est effectuée, et peut présenter des variations selon les tâches restantes dans la file au moment de l’opération, notamment en mode mono-thread où il y a moins de chances que les opérations d’E/S reconstituent la file (sauf si celle-ci est pleine). Cette commande accède exclusivement au processus et peut provoquer des latences mineures mais mesurables lorsqu’elle est exécutée sur un processus fortement sollicité, elle ne doit donc pas être utilisée de manière abusive par des bots de surveillance.

show threads

show threads

Affiche certains états internes et structures pour chaque thread, ce qui peut aider les développeurs à comprendre un problème. La sortie est conçue pour être lisible en affichant un bloc par thread. Lorsque HAProxy est compilé avec USE_THREAD_DUMP=1, un mécanisme avancé de dump utilisant des signaux de thread est employé afin que chaque thread puisse afficher son propre état tour à tour. Sans cette option, le thread traitant la commande affiche tous ses détails, tandis que les autres sont moins détaillés. Un astérisque (’*’) est affiché devant le thread gérant la commande. Un angle droit (’>’) peut également être affiché devant les threads qui n’ont fait aucune progression depuis la dernière invocation de cette commande, indiquant un bogue dans le code qui doit absolument être signalé. Lorsque cela se produit entre deux threads, cela indique généralement un blocage. Si un seul thread est concerné, il s’agit d’un autre type de bogue, comme une liste corrompue. Dans tous les cas, le processus n’est plus entièrement fonctionnel et doit être redémarré.

Le format de sortie n’est pas documenté intentionnellement afin de permettre une évolution facile en fonction des besoins identifiés, sans devoir maintenir une compatibilité descendante, tout comme pour « show activity », les valeurs n’ont pas de sens sans le code à portée de main.

show tls-keys [id|*]

show tls-keys [id|*]

Affiche toutes les références de clés TLS chargées. L’identifiant de référence de la clé de ticket TLS et le fichier à partir duquel les clés ont été chargées sont indiqués. Ces deux éléments peuvent être utilisés pour mettre à jour les clés TLS à l’aide de la commande « set ssl tls-key ». Si un identifiant est spécifié en paramètre, les tickets correspondants seront affichés ; en utilisant *, tous les tickets de toutes les références seront affichés.

show schema json

show schema json

Affichez le schéma utilisé pour la sortie de « show info json » et « show stat json ».

Il ne contient aucun espace supplémentaire afin de réduire le volume de sortie. Pour une lecture humaine, passer la sortie through un formatteur élégant peut être utile. Exemple :

$ echo “show schema json” | socat /var/run/haproxy.sock stdio | \ python -m json.tool

Le schéma suit la spécification « JSON Schema » (json-schema.org), et les vérificateurs peuvent ainsi être utilisés pour valider la sortie des commandes « show info json » et « show stat json » par rapport au schéma.

show trace [<source>]

show trace [<source>]

Affiche l’état actuel du traçage. Pour chaque source, une ligne est affichée avec un caractère unique indiquant si le traçage est arrêté, en attente ou en cours. Le réceptacle de sortie utilisé par le traçage est indiqué (ou « none » s’il n’a pas été défini), suivi du nombre d’événements perdus dans ce réceptacle, puis d’une brève description de la source. Si un nom de source est spécifié, une liste détaillée de tous les événements pris en charge par la source est affichée, ainsi que leur état pour chaque action (report, start, pause, stop), indiqué par un “+” s’ils sont activés, ou un “-” sinon. Tous ces événements sont indépendants, et un événement peut déclencher un démarrage sans être rapporté, et inversement.

show version

show version

Affiche la version du processus HAProxy en cours d’exécution. Cette fonctionnalité est disponible depuis l’interface CLI du processus principal et des processus workers. Exemple :

$ echo "show version" | socat /var/run/haproxy.sock stdio
2.4.9

$ echo "show version" | socat /var/run/haproxy-master.sock stdio
2.5.0

shutdown frontend <frontend>

shutdown frontend <frontend>

Supprime complètement le frontal spécifié. Toutes les ports auxquels il était lié seront libérées. Il ne sera plus possible d’activer ce frontal après cette opération. Cette fonction est destinée à être utilisée dans des environnements où l’arrêt d’un proxy n’est tout simplement pas envisageable, mais où un proxy mal configuré doit être corrigé. Ainsi, il devient possible de libérer le port et de le réaffecter à un autre processus afin de restaurer les opérations. Une fois terminé, le frontal n’apparaîtra plus du tout sur la page de statistiques.

Le frontal peut être spécifié soit par son nom, soit par son identifiant numérique, précédé d’un dièse (’#’).

Cette commande est restreinte et ne peut être émise que sur les sockets configurés au niveau « admin ».

shutdown session <id>

shutdown session <id>

Interrompre immédiatement le flux correspondant à l’identifiant de flux spécifié. Cet identifiant est le premier champ au début des lignes des dumps de la commande « show sess » (il correspond au pointeur de flux). Cette commande peut être utilisée pour interrompre un flux en cours depuis longtemps sans attendre l’expiration du délai d’expiration, ou lorsqu’une transmission infinie est en cours. Les flux ainsi interrompus sont signalés dans les journaux avec un indicateur « K ».

shutdown sessions server <backend>/<server>

shutdown sessions server <backend>/<server>

Interrompre immédiatement tous les flux associés au serveur spécifié. Cette fonction peut être utilisée pour interrompre les flux longs après qu’un serveur a été placé en mode maintenance, par exemple. Les flux ainsi interrompus sont signalés dans les journaux avec un indicateur « K ».

Les connexions backend restent en état inactif, sauf si le serveur est déjà en mode maintenance, auquel cas elles seront immédiatement planifiées pour suppression.

trace

trace

La commande « trace » seule affiche les sources de traçage, leur état actuel et leurs courtes descriptions. Elle n’est destinée qu’à servir de menu pour accéder aux niveaux suivants ; consultez les autres commandes « trace » ci-dessous.

trace 0

trace 0

Arrête immédiatement toutes les traces. Cette commande est destinée à être utilisée comme solution rapide pour terminer une session de débogage ou comme action d’urgence en cas d’activation de traces complexes sur plusieurs sources ayant un impact sur le service.

trace <source> [<args...>]

trace <source> [<args...>]

Configure les traces pour la source <source>. Sans argument, cela affiche la liste de toutes les commandes secondaires prises en charge par la source donnée. Plusieurs commandes secondaires peuvent être enchaînées. Les commandes suivantes sont prises en charge :

event [ [+|-|!]<name> ] Sans argument, cette commande affiche la liste de tous les événements pris en charge par la source désignée. Ils sont précédés d’un “-” si ils ne sont pas activés, ou d’un “+” s’ils sont activés. Il est important de noter qu’une seule trace peut être étiquetée avec plusieurs événements, et tant qu’un des événements activés correspond à l’un des événements étiquetés sur la trace, cet événement sera transmis au sous-système de traçage. Par exemple, la réception d’un cadre HTTP/2 de type HEADERS peut déclencher un événement cadre et un événement flux, car le cadre crée un nouveau flux. Si l’événement cadre ou l’événement flux est activé pour cette source, le cadre sera transmis au cadre de traçage.

Avec un argument, il est possible de basculer l'état de chaque événement et de les activer ou désactiver individuellement. Deux mots-clés spéciaux sont pris en charge : « none », qui ne correspond à aucun événement et est utilisé pour désactiver tous les événements en une seule fois, et « any », qui correspond à tous les événements et est utilisé pour activer tous les événements en une seule fois. Les autres événements sont spécifiques à la source d'événements. Il est possible d'activer un événement en spécifiant son nom, éventuellement précédé du signe « + » pour une meilleure lisibilité. Il est possible de désactiver un événement en spécifiant son nom précédé du signe « - » ou « ! ».

Une façon de désactiver complètement une source de traçage consiste à passer « event none », et cette source sera instantanément entièrement ignorée.

suivre <other_source> Cela permet à la source <source> d’émettre également des traces lorsque la source autre <other_source> est verrouillée sur un critère et que le même critère correspond également à la source actuelle. Par exemple, si une source est verrouillée sur une session, suivre cette source depuis une autre en fera émettre des traces pour toutes les occurrences liées à cette session. Cela peut être utilisé, dans une certaine mesure, pour suivre les requêtes backend associées aux connexions frontend. La source « session » facilite cette opération en fournissant des événements « new » et « end » utilisables pour le traitement de verrouillage. Notez que la source <source> n’a pas besoin d’avoir ses traces activées dans ce cas, et son état de traçage ne sera pas non plus affecté. Il se peut toutefois que certains événements soient manquants s’ils ne contiennent pas d’informations permettant de les corrélater avec l’élément suivi. Le meta-source « all » peut également être utilisé avec cette commande : dans ce cas, toutes les sources suivront <other_source>.

Exemple :

trace h1 lock session start sess_new pause sess_end follow session

niveau [<level>] Sans argument, cette commande affiche tous les niveaux de traçage pour cette source, le niveau actuel étant indiqué par une étoile (’*’) placée en tête. Avec un argument, ce niveau de traçage est modifié en fonction du niveau spécifié. Les niveaux de détail constituent une forme de filtres appliqués avant la remontée des événements. Ces filtres permettent d’inclure ou d’exclure sélectivement les événements selon leur niveau d’importance. Par exemple, un développeur peut avoir besoin de connaître précisément l’emplacement dans le code où un en-tête HTTP a été jugé invalide, tandis qu’un utilisateur final peut ne pas s’intéresser du tout à la validité de cet en-tête. Actuellement, il existe 5 niveaux distincts de traçage :

user       this will report information that are suitable for use by a
           regular haproxy user who wants to observe his traffic.
           Typically some HTTP requests and responses will be reported
           without much detail. Most sources will set this as the
           default level to ease operations.

proto      in addition to what is reported at the "user" level, it also
           displays protocol-level updates. This can for example be the
           frame types or HTTP headers after decoding.

state      in addition to what is reported at the "proto" level, it
           will also display state transitions (or failed transitions)
           which happen in parsers, so this will show attempts to
           perform an operation while the "proto" level only shows
           the final operation.

data       in addition to what is reported at the "state" level, it
           will also include data transfers between the various layers.

developer  it reports everything available, which can include advanced
           information such as "breaking out of this loop" that are
           only relevant to a developer trying to understand a bug that
           only happens once in a while in field. Function names are
           only reported at this level.
Il est fortement recommandé d'utiliser uniquement le niveau « user » et de ne passer à d'autres niveaux que si un développeur vous y invite. Il est également conseillé de configurer les événements en premier lieu avant de passer à des niveaux supérieurs, afin d'éviter d'obtenir de nombreuses lignes si aucune filtration n'est appliquée. Le meta-source « all » peut également être utilisé avec cette commande : dans ce cas, le niveau sera appliqué à toutes les sources existantes simultanément.

lock [critère] Sans argument, cette commande affiche la liste de tous les critères pris en charge par cette source pour le traitement en verrouillage, et indique le choix actuel par une étoile (’*’) en tête de celui-ci. Le verrouillage signifie que la source se concentre sur le premier événement correspondant et ne conserve que le critère qui a déclenché cet événement, tout en ignorant les autres jusqu’à l’arrêt de la trace. Cela permet par exemple de capturer une trace sur une connexion unique ou sur un flux unique. Les critères suivants sont pris en charge par certaines traces, pas nécessairement par toutes, car certains pourraient ne pas être disponibles pour la source :

backend      lock on the backend that started the trace
connection   lock on the connection that started the trace
frontend     lock on the frontend that started the trace
listener     lock on the listener that started the trace
nothing      do not lock on anything
server       lock on the server that started the trace
session      lock on the session that started the trace
thread       lock on the thread that started the trace
En complément de cela, chaque source peut fournir jusqu'à 4 critères spécifiques, tels que des états internes ou des identifiants de connexion. Par exemple, dans HTTP/2, il est possible de s'ancrer sur un flux H2 et d'ignorer les autres flux une fois qu'une trace a commencé.

Lorsqu'un critère est passé en argument, celui-ci est utilisé à la place des autres, et tout suivi existant est immédiatement interrompu afin de pouvoir redémarrer avec le nouveau critère. Le mot-clé spécial « nothing » est pris en charge par toutes les sources pour désactiver définitivement le suivi.

{ pause | start | stop } [ [+|-|!]événement ] Sans argument, cette commande affiche la liste des événements activés pour mettre automatiquement en pause, démarrer ou arrêter une trace pour cette source. Ces événements sont spécifiques à chaque source de trace. Avec un argument, elle active l’événement pour l’action indiquée (si précédé optionnellement par un ‘+’) ou le désactive (si précédé d’un ‘-’ ou d’un ‘!’). Le mot-clé spécial « now » n’est pas un événement et demande d’exécuter l’action immédiatement. Les mots-clés « none » et « any » sont pris en charge de la même manière qu’avec « trace event ».

Les trois actions prises en charge sont respectivement « pause », « start » et « stop ».
L’action « pause » énumère les événements qui feront arrêter une trace en cours et attendront un nouvel événement de démarrage pour la reprendre.
L’action « start » énumère les événements qui mettent la trace en mode d’attente jusqu’à l’apparition d’un de ces événements de démarrage.
L’action « stop » énumère les événements qui arrêtent définitivement la trace jusqu’à ce qu’elle soit réactivée manuellement.

En pratique, il est pertinent de démarrer manuellement une trace avec « start now » sans tenir compte des événements, et de l’arrêter avec « stop now ».
Pour capturer des séquences d’événements plus subtiles, il est utile de définir « start » sur un événement normal (comme la réception d’une requête HTTP) et « stop » sur un événement très rare (comme l’émission d’une erreur spécifique), afin de garantir que les derniers événements capturés correspondent aux critères souhaités.
L’événement « pause » est utile pour détecter la fin d’une séquence, désactiver le verrouillage et attendre une nouvelle opportunité de capturer.
Dans ce cas, il peut être pertinent d’activer le verrouillage pour ne repérer qu’un critère spécifique (par exemple, un flux), de définir « start » sur n’importe quel événement qui déclenche ce critère (par exemple, tous les événements qui créent un flux), « stop » sur l’anomalie attendue, et « pause » sur n’importe quel événement qui met fin à ce critère (par exemple, n’importe quel événement de fin de flux).
Dans ce cas, le journal de trace contiendra des séquences complètes de séries parfaitement propres affectant un seul objet, jusqu’à la dernière séquence contenant tout, depuis le début jusqu’à l’anomalie.

sink [<sink>] Sans argument, cette commande affiche la liste de tous les réceptacles d’événements disponibles pour cette source, et le réceptacle actuellement configuré est précédé d’une étoile (’*’). Le réceptacle « none » est toujours disponible et signifie que tous les événements sont simplement ignorés, bien que leur traitement ne soit pas ignoré (par exemple, les verrous sont toujours appliqués). D’autres réceptacles sont disponibles selon la configuration et les options de compilation, mais en général « stdout » et « stderr » sont utilisables en mode débogage, et des tampons en mémoire en anneau devraient également être disponibles. Lorsqu’un nom est spécifié, le réceptacle est immédiatement changé pour la source indiquée. Les événements ne sont pas modifiés pendant un changement de réceptacle. Dans le pire des cas, certains peuvent être perdus si un réceptacle invalide (ou « none ») est utilisé, mais les opérations continuent vers une destination différente. Le meta-réceptacle « all » peut également être utilisé avec cette commande : dans ce cas, le réceptacle est appliqué à toutes les sources existantes en même temps.

verbosity [<level>] Sans argument, cette commande affiche tous les niveaux de verbosité disponibles pour cette source, le niveau actuel étant indiqué par une étoile (’*’) placée devant. Avec un argument, cette commande change le niveau de verbosité vers celui spécifié.

Les niveaux de verbosité indiquent jusqu'où le décodeur de trace doit aller pour fournir des informations détaillées. Cela dépend de la source de trace, car certaines sources ne fournissent même pas de décodeur spécifique. Le niveau « quiet » est toujours disponible et désactive toute décodage. Il peut être utile pour comprendre ce qui se passe avant d'analyser les détails, car il a un impact très faible sur les performances et la taille de la trace. Lorsqu'une source ne déclare aucun niveau de verbosité, le niveau « default » est disponible et entraîne l'appel d'un décodeur lorsqu'il est spécifié dans les traces. Il s'agit d'un décodage opportuniste. Lorsque la source déclare des niveaux de verbosité, ceux-ci sont listés avec une description de leur signification. Dans ce cas, le décodeur de trace fourni par la source sera aussi précis que possible, en fonction des informations disponibles au point de trace. Le premier niveau au-dessus de « quiet » est défini par défaut.

update ssl ocsp-response <certfile>

update ssl ocsp-response <certfile>

Créez une requête OCSP pour le <certfile> spécifié et envoyez-la au répondant OCSP dont l’URI doit être indiqué dans la section « Authority Information Access » du certificat. Seul le premier URI est pris en compte. La réponse OCSP reçue en retour est ensuite vérifiée et insérée dans l’arbre local des réponses OCSP. Cette commande ne fonctionne que pour les certificats qui ont déjà une réponse OCSP stockée, soit parce qu’elle a été fournie lors de l’initialisation, soit si elle a été définie précédemment à l’aide des commandes « set ssl cert » ou « set ssl ocsp-response ». Si la réponse OCSP reçue est valide et a été correctement insérée dans l’arbre local, son contenu est affiché sur la sortie standard. Le format est identique à celui décrit dans « show ssl ocsp-response ».

wait { -h | <delay> } [<condition> [<args>...]]

wait { -h | <delay> } [<condition> [<args>...]]

Dans sa forme la plus simple, sans condition, cette directive attend simplement le délai demandé avant de poursuivre. Elle peut être utilisée pour collecter des métriques sur un intervalle spécifique.

Avec une condition et des arguments facultatifs, la commande attend que la condition spécifiée soit remplie, qu’elle échoue de manière irréversible, ou qu’elle reste non remplie pendant toute la durée <delay>. Les conditions prises en charge sont :

  • be-removable <proxy> : attend que le backend proxy spécifié soit supprimable par la commande « del backend ». Certaines conditions ne seront jamais acceptées (par exemple, un backend non encore désindexé ou comportant des serveurs) et entraîneront l’affichage d’un message d’erreur précis indiquant la condition non remplie. Si tout est correct avant l’expiration du délai, un succès est retourné et l’opération est terminée.

  • srv-removable <proxy>/<server> : cette directive attend que le serveur spécifié soit éligible à la suppression par la commande « del server », c’est-à-dire qu’il soit en maintenance et ne possède plus aucune connexion (ni active ni inactif). Certaines conditions ne seront jamais acceptées (par exemple, le serveur non en maintenance) et entraîneront la remontée d’un message d’erreur spécifique indiquant la condition non remplie. Le serveur pourrait même avoir été supprimé en parallèle et ne plus exister. Si tout est correct avant l’expiration du délai, un succès est retourné et l’opération est terminée.

L’unité par défaut pour le délai est les millisecondes, bien que d’autres unités soient acceptées si elles sont suffixées par les unités de temporisation usuelles (us, ms, s, m, h, d). Lorsqu’il est utilisé avec l’utilitaire ‘socat’, n’oubliez pas d’élargir le délai d’expiration de socat afin de couvrir le temps d’attente. Passer “-h” en premier ou en second argument fournit la syntaxe de la commande. Exemple :

$ socat -t20 /path/to/socket - <<< "show activity; wait 10s; show activity"

$ socat -t5 /path/to/socket - <<< "
    disable server px/srv1
    shutdown sessions server px/srv1
    wait 2s srv-removable px/srv1
    del server px/srv1"

9.4. CLI principale

L’interface CLI principale est une socket liée au processus principal en mode principal-worker. Cette interface CLI permet d’accéder aux commandes de socket Unix depuis tous les processus en cours d’exécution ou en cours de terminaison, et permet une supervision basique de ces processus.

L’interface CLI principale ne peut être configurée qu’à partir des arguments du programme HAProxy, via l’option -S. Cette option accepte également des options bind, séparées par des virgules.

Exemple :

# haproxy -W -S 127.0.0.1:1234 -f test1.cfg
# haproxy -Ws -S /tmp/master-socket,uid,1000,gid,1000,mode,600 -f test1.cfg
# haproxy -W -S /tmp/master-socket,level,user -f test1.cfg

9.4.1. Commandes CLI principales

@<[!]pid>

@<[!]pid>

L’interface CLI principale utilise une notation de préfixe spéciale pour accéder aux processus multiples. Cette notation est facilement identifiable car elle commence par un @.

Un préfixe @ peut être suivi d’un numéro de processus relatif ou d’un point d’exclamation suivi d’un PID. (Par exemple : @1 ou @!1271). Un @ seul peut être utilisé pour spécifier le processus principal. Les processus restants ne sont accessibles qu’avec le PID comme numéro de processus relatif, et ne sont utilisables qu’avec les processus actuels.

Ce préfixe peut être utilisé comme enveloppe avant une commande, indiquant que cette commande uniquement sera envoyée au processus désigné. Dans ce cas, la commande complète se termine à la fin de la ligne ou à la point-virgule, comme toute commande régulière.

Bugs : le protocole sockpair@ utilisé pour implémenter la communication entre le processus principal et le worker est connu pour ne pas être fiable sous macOS en raison d’un problème dans l’implémentation de sendmsg(2) de macOS. Une commande pourrait ne pas obtenir de réponse à cause de cela.

Exemples :

$ socat /var/run/haproxy-master.sock readline
prompt
master> @1 show info; @2 show info
[...]
Process_num: 1
Pid: 1271
[...]
Process_num: 2
Pid: 1272
[...]
master>

$ echo '@!1271 show info; @!1272 show info' | socat /var/run/haproxy-master.sock -
[...]

Le préfixe peut également être utilisé comme commande autonome pour basculer le contexte d’exécution par défaut vers le processus désigné, indiquant que toutes les commandes ultérieures seront exécutées dans ce processus, jusqu’à ce qu’une nouvelle commande ‘@’ change à nouveau le contexte d’exécution.

Exemples :

$ socat /var/run/haproxy-master.sock readline
prompt
master> @1
1271> show info
[...]
1271> show stat
[...]
1271> @
master>

$ echo '@1; show info; show stat; @2; show info; show stat' | socat /var/run/haproxy-master.sock -
[...]

Remarque sur les limitations : quelques rares commandes modifient l’état d’une session CLI (par exemple, « set anon », « set timeout ») et peuvent ne pas se comporter exactement de la même manière lorsqu’elles sont exécutées depuis la CLI principale, en raison de l’envoi individuel des commandes sur des sessions CLI distinctes. De même, quelques rares commandes (« show events », « wait ») surveillent activement l’entrée ou la fermeture de la CLI et sont immédiatement interrompues lorsque la CLI est fermée. Ces commandes ne fonctionneront pas comme prévu via la CLI principale, car l’entrée de la commande est fermée après chaque exécution. Dans de tels cas rares, la variante « @@ » ci-dessous pourrait être plus adaptée.

@@<[!]pid> [command...]

@@<[!]pid> [command...]

Ce préfixe ou commande est très similaire au préfixe “@” documenté ci-dessus, à ceci près qu’il entre dans le processus worker, transmet la ligne de commande entière tel quelle à ce dernier et reste connecté jusqu’à la fin de l’exécution de la commande. Les points-virgules sont également transmis, permettant d’exécuter une commande en pipeline complète dans un processus worker. La connexion avec le worker reste ouverte jusqu’à la fin de l’exécution de la liste des commandes. Toute donnée envoyée après les commandes sera acheminée vers l’interface CLI du worker et pourra être consommée par les commandes en cours d’exécution, mais sera perdue pour l’interface CLI du master, offrant ainsi une connexion véritablement bidirectionnelle avec le processus worker. En conséquence, les utilisateurs de ces commandes doivent être extrêmement prudents et attendre la fin de l’exécution d’une commande avant d’envoyer de nouvelles commandes à l’interface CLI du master.

Au lieu d’exécuter une seule commande, il est également possible d’ouvrir une session entièrement interactive sur le processus worker en ne spécifiant aucune commande (c’est-à-dire « @@1 » sur une ligne seule). Cette session peut être terminée soit en fermant la connexion, soit en quittant le processus worker (à l’aide de la commande « quit »). Dans ce cas, le mode d’invite du socket principal (interactif, invite, temporisé) est propagé au processus worker.

Bugs : le protocole sockpair@ utilisé pour implémenter la communication entre le processus principal et le worker est connu pour ne pas être fiable sous macOS en raison d’un problème dans l’implémentation de sendmsg(2) de macOS. Une commande pourrait ne pas obtenir de réponse à cause de cela.

Exemples :

# gracefully close connections and delete a server once idle (wait max 10s)
$ socat -t 11 /var/run/haproxy-master.sock - <<< \
   "@@1 disable server app2/srv36; \
   wait 10000 srv-removable app2/srv36; \
   del server app2/srv36"

# forcefully close connections and quickly delete a server
$ socat /var/run/haproxy-master.sock - <<< \
   "@@1 disable server app2/srv36; \
   shutdown sessions server app2/srv36; \
   wait 100 srv-removable app2/srv36; \
   del server app2/srv36"

# show messages arriving to this ring in real time ("tail -f" equivalent)
$ (echo "show events buf0 -w"; read) | socat /var/run/haproxy-master.sock -

expert-mode [on|off]

expert-mode [on|off]

Cette commande active le mode « expert » pour chaque worker accédé depuis l’interface CLI principale. En combinaison avec « mcli-debug-mode », elle active également la commande sur le maître. Affiche le drapeau « e » dans l’invite de l’interface CLI principale.

Voir également « expert-mode » dans Section 9.3 et « mcli-debug-mode » dans 9.4.1.

experimental-mode [on|off]

experimental-mode [on|off]

Cette commande active le mode expérimental pour chaque worker accédé depuis l’interface CLI principale. En combinaison avec « mcli-debug-mode », elle active également la commande sur le maître. Affiche le drapeau « x » dans l’invite de l’interface CLI principale.

Voir également « experimental-mode » dans Section 9.3 et « mcli-debug-mode » dans 9.4.1.

hard-reload

hard-reload

Cette commande agit de la même manière que la commande « reload » sur l’interface CLI principale, à ceci près qu’elle effectue une interruption brutale (-st) au lieu d’une interruption douce (-sf) du processus précédent. Cela signifie que le processus précédent ne s’arrête pas en attendant la réalisation de quoi que ce soit, de sorte que toutes les connexions seront fermées.

Voir également la commande « reload ».

mcli-debug-mode [on|off]

mcli-debug-mode [on|off]

Ce mot-clé permet d’activer un mode spécial dans l’interface CLI principale, qui permet d’utiliser sur l’interface CLI principale toutes les commandes destinées à l’interface CLI des workers, ce qui permet de déboguer le processus principal. Une fois activé, listez les nouvelles commandes disponibles à l’aide de « help ». En combinaison avec « experimental-mode » ou « expert-mode », il active encore plus de commandes. Affichez le drapeau « d » dans l’invite de l’interface CLI principale.

prompt

prompt

Lorsque l’invite est activée (via la commande « prompt »), le contexte sur lequel le CLI opère est affiché dans l’invite. Le processus principal est identifié par la chaîne « master », tandis que les autres processus sont identifiés par leur PID. En cas d’échec du dernier rechargement, l’invite du processus principal est modifiée en « master[ReloadFailed]> », afin de rendre visible le fait que le processus continue de fonctionner avec la configuration précédente et que la nouvelle configuration n’est pas opérationnelle.

L’invite de la CLI principale est capable d’afficher plusieurs indicateurs correspondant aux modes activés. « d » pour mcli-debug-mode, « e » pour expert-mode, « x » pour experimental-mode.

Exemple :

$ socat /var/run/haproxy-master.sock -
prompt
master> expert-mode on
master(e)> experimental-mode on
master(xe)> mcli-debug-mode on
master(xed)> @1
95191(xed)>

reload

reload

Vous pouvez également recharger le processus principal HAProxy à l’aide de la commande « reload », qui produit le même effet qu’un kill -USR2 sur le processus principal, à condition que l’utilisateur dispose au moins des privilèges « operator » ou « admin ».

Cette commande permet d’effectuer un rechargement synchrone ; la commande renvoie un statut de rechargement une fois celui-ci effectué. Prenez garde au délai d’expiration si un outil est utilisé pour l’analyser, car il n’est renvoyé qu’après analyse de la configuration et création du nouveau processus worker. La commande « socat » utilise un délai d’expiration par défaut de 0,5 s, donc elle se termine avant d’afficher le message si le rechargement dure trop longtemps. « ncat » ne dispose pas de délai d’expiration par défaut. Lorsqu’il est compilé avec USE_SHM_OPEN=1, la commande de rechargement peut également exporter les journaux de démarrage du processus principal.

Exemple :

$ echo "reload" | socat -t300 /var/run/haproxy-master.sock stdin
Success=1
--
[NOTICE]   (482713): haproxy version is 2.7-dev7-4827fb-69
[NOTICE]   (482713): path to executable is ./haproxy
[WARNING]  (482713): config: 'http-request' rules ignored for proxy 'frt1' as they require HTTP mode.
[NOTICE]   (482713): New worker (482720) forked
[NOTICE]   (482713): Loading success.

$ echo "reload" | socat -t300 /var/run/haproxy-master.sock stdin
Success=0
--
[NOTICE]   (482886): haproxy version is 2.7-dev7-4827fb-69
[NOTICE]   (482886): path to executable is ./haproxy
[ALERT]    (482886): config: parsing [test3.cfg:1]: unknown keyword 'Aglobal' out of section.
[ALERT]    (482886): config: Fatal errors found in configuration.
[WARNING]  (482886): Loading failure!

$

La commande reload est la dernière exécutée sur l’interface CLI principale ; toutes les autres commandes suivantes sont ignorées. Dès que la commande reload a renvoyé son statut, la connexion à l’interface CLI est fermée.

Notez qu’un rechargement fermera toutes les connexions vers l’interface CLI principale. Voir également la commande « hard-reload ».

show proc [debug]

show proc [debug]

L’interface CLI principale introduit une commande « show proc » pour surveiller les processus.

Exemple :

$ echo 'show proc' | socat /var/run/haproxy-master.sock -
#<PID>          <type>          <reloads>       <uptime>        <version>
1162            master          5 [failed: 0]   0d00h02m07s     2.5-dev13
# workers
1271            worker          1               0d00h00m00s     2.5-dev13
# old workers
1233            worker          3               0d00h00m43s     2.0-dev3-6019f6-289

Dans cet exemple, le maître a été rechargé 5 fois, mais un des anciens workers est toujours en cours d’exécution et a survécu à 3 rechargements. Vous pouvez accéder à l’interface CLI de ce worker pour comprendre ce qui se passe.

Le paramètre « debug » est utile pour afficher les détails de débogage ; il affiche actuellement les descripteurs de fichiers (FDs) utilisés pour la communication IPC. Notez que la sortie de débogage n’est pas garantie stable entre les versions de HAProxy.

show startup-logs

show startup-logs

HAProxy doit être compilé avec USE_SHM_OPEN=1 pour être utilisé correctement sur l’interface CLI principale ou tous les messages ne seront pas visibles.

Comme son homologue sur la socket de statistiques, cette commande est capable d’afficher les messages de démarrage de HAProxy. Toutefois, elle ne fournit pas les messages de démarrage du worker actuel, mais ceux de la dernière initialisation ou rechargement, ce qui permet de récupérer les messages d’analyse d’un rechargement échoué.

Ces messages sont également affichés avec la commande « reload ».

9.5. Fichier de statistiques

Un fichier appelé stats-file peut être utilisé pour charger au démarrage du processus des compteurs internes de HAProxy avec des valeurs non nulles. Son usage principal consiste à préserver les statistiques des processus workers lors des rechargements. Seule une partie des statistiques exposées par HAProxy est présente dans un fichier stats-file, car il n’a de sens que de charger des valeurs de type métrique.

Pour l’instant, seuls les compteurs de proxy sont pris en charge dans stats-file. Cela permet de précharger des valeurs pour les frontaux, les backends, les serveurs et les écouteurs. Toutefois, seuls les objets dont l’identifiant GUID n’est pas vide sont stockés dans un fichier stats-file. Cela garantit que les valeurs seront préchargées pour les objets ayant un type et un GUID correspondants, même si d’autres paramètres diffèrent.

La commande CLI « dump stats-file » a pour but de générer un fichier de statistiques. Le format de ce fichier est défini internement et peut faire l’objet de modifications ou d’extensions futures sans préavis. Il est conçu pour être compatible au moins entre les versions stables adjacentes de HAProxy, mais peut nécessiter une configuration optionnelle supplémentaire lors du chargement d’un fichier de statistiques dans un processus exécutant une version plus ancienne.

31 - 10. Gestion de configuration simplifiée

Techniques pour rendre les configurations HAProxy volumineuses plus faciles à maintenir

Il est très courant que deux nœuds HAProxy constituant un cluster partagent exactement la même configuration, à l’exception de quelques adresses. Au lieu de devoir maintenir une configuration dupliquée pour chaque nœud, ce qui entraînera inévitablement une divergence, il est possible d’inclure des variables d’environnement dans la configuration. Ainsi, plusieurs configurations peuvent partager exactement le même fichier, en ne modifiant que quelques variables d’environnement système. Cette fonctionnalité a été introduite à partir de la version 1.5, où seules les adresses pouvaient inclure des variables d’environnement, et la version 1.6 va plus loin en permettant l’utilisation de variables d’environnement partout. La syntaxe est identique à celle du shell UNIX : une variable commence par un signe dollar (’$’), suivi d’une accolade ouvrante (’{’), puis le nom de la variable, terminé par une accolade fermante (’}’). À l’exception des adresses, les variables d’environnement ne sont interprétées que dans les arguments entourés de guillemets doubles (ce qui était nécessaire pour ne pas rompre les configurations existantes utilisant des expressions régulières impliquant le symbole dollar).

Les variables d’environnement permettent également d’écrire des configurations destinées à fonctionner sur différents sites, où seul l’adresse change. Elles peuvent aussi permettre de supprimer les mots de passe de certaines configurations. Exemple ci-dessous où le fichier “site1.env” est chargé par le script d’initialisation au démarrage :

$ cat site1.env
LISTEN=192.168.1.1
CACHE_PFX=192.168.11
SERVER_PFX=192.168.22
LOGGER=192.168.33.1
STATSLP=admin:pa$$w0rd
ABUSERS=/etc/haproxy/abuse.lst
TIMEOUT=10s

$ cat haproxy.cfg
global
    log "${LOGGER}:514" local0

defaults
    mode http
    timeout client "${TIMEOUT}"
    timeout server "${TIMEOUT}"
    timeout connect 5s

frontend public
    bind "${LISTEN}:80"
    http-request reject if { src -f "${ABUSERS}" }
    stats uri /stats
    stats auth "${STATSLP}"
    use_backend cache if { path_end .jpg .css .ico }
    default_backend server

backend cache
    server cache1 "${CACHE_PFX}.1:18080" check
    server cache2 "${CACHE_PFX}.2:18080" check

backend server
    server cache1 "${SERVER_PFX}.1:8080" check
    server cache2 "${SERVER_PFX}.2:8080" check

32 - 11. Pièges courants à éviter

Erreurs opérationnelles et comportements surprenants à éviter

Parfois, une personne signale que, après un redémarrage du système, le service HAProxy n’est pas démarré automatiquement, et qu’une fois lancé manuellement, il fonctionne correctement. La plupart de ces utilisateurs exécutent un mécanisme d’adresse IP regroupée, comme keepalived, afin d’attribuer l’adresse IP du service uniquement au nœud principal, et alors qu’il fonctionnait auparavant lorsqu’ils liaient HAProxy à l’adresse 0.0.0.0, il a cessé de fonctionner après avoir lié celui-ci à l’adresse IP virtuelle. Ce qui se produit ici, c’est que, lors du démarrage du service, l’adresse IP virtuelle n’est pas encore détenu par le nœud local, si bien que lorsque HAProxy tente de se lier à cette adresse, le système la rejette car elle n’est pas une adresse locale. La solution ne consiste pas à retarder le démarrage du service HAProxy (car cela ne résisterait pas à un redémarrage), mais plutôt à configurer correctement le système afin de permettre la liaison à des adresses non locales. Cela peut être facilement réalisé sous Linux en définissant le paramètre sysctl net.ipv4.ip_nonlocal_bind à 1. Cette configuration est également nécessaire pour intercepter de manière transparente le trafic IP qui traverse HAProxy pour une adresse cible spécifique.

Les configurations multi-processus utilisant des plages de ports sources peuvent sembler fonctionner mais entraîneront des échecs aléatoires sous charge élevée, car plusieurs processus pourraient tenter d’utiliser le même port source pour se connecter au même serveur, ce qui n’est pas possible. Le système signalera une erreur, puis effectuera une nouvelle tentative en choisissant un autre port. Une valeur élevée du paramètre « retries » peut atténuer cet effet à un certain point, mais cela entraîne également une utilisation accrue du CPU et un temps de traitement plus long. Les journaux rapporteront également un certain nombre de tentatives. Pour cette raison, les plages de ports doivent être évitées dans les configurations multi-processus.

Étant donné qu’HAProxy utilise SO_REUSEPORT et prend en charge l’exécution de plusieurs processus indépendants liés au même IP:port, il peut arriver pendant le dépannage qu’un ancien processus n’ait pas été arrêté avant le lancement d’un nouveau. Cela peut entraîner des résultats de test absurdes, qui semblent indiquer que toute modification de la configuration est ignorée. La raison est que, même si le nouveau processus est effectivement redémarré avec une nouvelle configuration, l’ancien processus continue également à recevoir des connexions entrantes et à les traiter, produisant ainsi des résultats inattendus. En cas de doute, arrêtez simplement le nouveau processus et réessayez. Si cela fonctionne toujours, il est très probable qu’un ancien processus soit toujours en cours d’exécution et doive être arrêté. La commande Linux « netstat -lntp » s’avère ici particulièrement utile.

Lors d’ajout d’entrées à une liste de contrôle d’accès (ACL) depuis la ligne de commande (par exemple, lors du blocage d’une adresse source), il est important de garder à l’esprit que ces entrées ne sont pas synchronisées avec le fichier et qu’en cas de rechargement de la configuration, ces modifications seront perdues. Bien que ce comportement soit souvent souhaité (par exemple, pour le blocage), il peut ne pas correspondre aux attentes lorsque le changement a été effectué en tant que correction d’un problème. Voir l’action « add acl » de l’interface CLI.

33 - 12. Problèmes de débogage et de performance

Méthodes d’investigation des crashs, blocages, latences et problèmes de débit

Lorsque HAProxy est lancé avec l’option “-d”, il reste en premier plan et affiche une ligne par événement, tel qu’une connexion entrante, la fin d’une connexion, ou chaque ligne d’en-tête de requête ou de réponse observée. Cette sortie de débogage est émise avant le traitement des contenus, aussi ne tiennent-elles pas compte des modifications locales. Son usage principal consiste à afficher les requêtes et réponses sans avoir à exécuter un analyseur réseau. La lecture de la sortie devient moins aisée lorsque plusieurs connexions sont gérées en parallèle, mais les scripts “debug2ansi” et “debug2html” présents dans le répertoire examples/ aident certainement dans ce cas en colorant la sortie.

Si une requête ou une réponse HTTP/1.x est rejetée parce que HAProxy détecte qu’elle est mal formée, la meilleure action consiste à se connecter à l’interface CLI et à exécuter la commande « show errors », qui rapporte la dernière requête ou réponse HTTP/1.x incorrecte capturée pour chaque frontal et backend, accompagnée de toutes les informations nécessaires pour indiquer précisément le premier caractère du flux d’entrée rejeté. Cette information est parfois nécessaire pour prouver à des clients ou à des développeurs qu’une erreur est présente dans leur code. Dans ce cas, il est souvent possible de relâcher les vérifications (tout en conservant les captures) en utilisant l’option « option accept-unsafe-violations-in-http-request » ou son équivalent pour les réponses provenant du serveur « option accept-unsafe-violations-in-http-response ». Voir le manuel de configuration pour plus de détails.

Exemple :

> show errors
Total events captured on [13/Oct/2015:13:43:47.169]: 1

[13/Oct/2015:13:43:40.918] frontend HAProxyLocalStats (#2): invalid request
  backend <NONE> (#-1), server <NONE> (#-1), event #0
  src 127.0.0.1:51981, session #0, session flags 0x00000080
  HTTP msg state 26, msg flags 0x00000000, tx flags 0x00000000
  HTTP chunk len 0 bytes, HTTP body len 0 bytes
  buffer flags 0x00808002, out 0 bytes, total 31 bytes
  pending 31 bytes, wrapping at 8040, error at position 13:

  00000  GET /invalid request HTTP/1.1\r\n

La sortie de la commande « show info » en ligne de commande fournit plusieurs informations utiles concernant le débit maximal de connexions atteint, le débit maximal de clés SSL atteint, et, en général, toutes les informations pouvant aider à expliquer des problèmes temporaires liés à l’utilisation du CPU ou de la mémoire. Exemple :

> show info
Name: HAProxy
Version: 1.6-dev7-e32d18-17
Release_date: 2015/10/12
Nbproc: 1
Process_num: 1
Pid: 7949
Uptime: 0d 0h02m39s
Uptime_sec: 159
Memmax_MB: 0
Ulimit-n: 120032
Maxsock: 120032
Maxconn: 60000
Hard_maxconn: 60000
CurrConns: 0
CumConns: 3
CumReq: 3
MaxSslConns: 0
CurrSslConns: 0
CumSslConns: 0
Maxpipes: 0
PipesUsed: 0
PipesFree: 0
ConnRate: 0
ConnRateLimit: 0
MaxConnRate: 1
SessRate: 0
SessRateLimit: 0
MaxSessRate: 1
SslRate: 0
SslRateLimit: 0
MaxSslRate: 0
SslFrontendKeyRate: 0
SslFrontendMaxKeyRate: 0
SslFrontendSessionReuse_pct: 0
SslBackendKeyRate: 0
SslBackendMaxKeyRate: 0
SslCacheLookups: 0
SslCacheMisses: 0
CompressBpsIn: 0
CompressBpsOut: 0
CompressBpsRateLim: 0
ZlibMemUsage: 0
MaxZlibMemUsage: 0
Tasks: 5
Run_queue: 1
Idle_pct: 100
node: wtap
description:

Lorsqu’un problème semble apparaître de manière aléatoire sur une nouvelle version de HAProxy (par exemple, chaque deuxième requête est interrompue, crash occasionnel, etc.), il peut être utile d’activer le polluage mémoire afin que chaque appel à malloc() soit immédiatement suivi du remplissage de la zone mémoire avec un octet configurable. Par défaut, cet octet est 0x50 (caractère ‘P’ en ASCII), mais tout autre octet peut être utilisé, y compris zéro (ce qui aura le même effet qu’un calloc() et qui peut faire disparaître certains problèmes). Le polluage mémoire est activé en ligne de commande à l’aide de l’option “-dM”. Cela impacte légèrement les performances et n’est pas recommandé en production. Si un problème survient systématiquement avec cette option ou ne se produit jamais lorsque l’octet zéro est utilisé, cela indique clairement la présence d’un bug, que vous devez absolument signaler. Sinon, si aucun changement clair n’est observé, le problème n’est pas lié.

Lors du débogage de certains problèmes de latence, il est important d’utiliser à la fois strace et tcpdump sur la machine locale, ainsi qu’un autre tcpdump sur le système distant. La raison en est que des délais sont présents à chaque étape de la chaîne de traitement, et il est essentiel de déterminer celui qui cause la latence afin de savoir où intervenir. En pratique, le tcpdump local indiquera quand les données d’entrée arrivent. Strace indiquera quand haproxy reçoit ces données (via recv/recvfrom). Attention, openssl utilise des appels système read()/write() au lieu de recv()/send(). Strace indiquera également quand haproxy envoie les données, et tcpdump indiquera quand le système les envoie à l’interface. Ensuite, le tcpdump externe indiquera quand les données envoyées sont réellement reçues (puisqu’un tcpdump local ne montre que quand les paquets sont mis en file d’attente). L’avantage de capturer sur la machine locale est que strace et tcpdump utiliseront la même horloge de référence. Strace doit être utilisé avec “-tts200” pour obtenir des horodatages complets et rapporter des tronçons de données suffisamment grands pour être lus. Tcpdump doit être utilisé avec “-nvvttSs0” pour rapporter des paquets complets, des numéros de séquence réels et des horodatages complets.

En pratique, les données reçues sont presque toujours immédiatement prises en charge par HAProxy (sauf si le processeur est saturé ou si ces données sont invalides et non livrées). Si ces données sont reçues mais non envoyées, cela provient généralement d’un tampon de sortie saturé (c’est-à-dire que le destinataire ne consomme pas les données assez rapidement). Cela peut être confirmé en constatant que la surveillance ne signale pas la possibilité d’écrire sur le descripteur de fichier de sortie pendant un certain temps (il est souvent plus facile de repérer cela dans la sortie de strace lorsque les données finissent par partir, puis en remontant pour voir quand l’événement d’écriture a été signalé). Cela correspond généralement à un accusé de réception (ACK) reçu du destinataire, détecté par tcpdump. Une fois les données envoyées, elles peuvent passer un certain temps dans le système sans action. Là encore, la fenêtre de congestion TCP peut être limitée et empêcher ces données de sortir, en attendant un ACK pour ouvrir la fenêtre. Si le trafic est inactif et que les données mettent 40 ms ou 200 ms à sortir, il s’agit d’un autre problème (qui n’est pas un problème), à savoir que l’algorithme de Nagle empêche les paquets vides de sortir immédiatement, dans l’espoir qu’ils soient fusionnés avec des données ultérieures. HAProxy désactive automatiquement Nagle en mode TCP pur et dans les tunnels. Toutefois, il reste activé lors du transfert d’un corps HTTP (ce qui contribue à l’amélioration des performances en réduisant le nombre de paquets). Certains applications HTTP non conformes peuvent être sensibles à la latence lors de la livraison de messages de réponse HTTP incomplets. Dans ce cas, vous devrez activer « option http-no-delay » pour désactiver Nagle afin de contourner leur conception, tout en gardant à l’esprit que tout autre proxy de la chaîne peut être affecté de manière similaire. Si tcpdump indique que les données partent immédiatement mais que l’autre extrémité ne les voit pas rapidement, cela peut signifier qu’il y a une liaison WAN saturée, un LAN saturé avec le contrôle de flux activé empêchant les données de sortir, ou plus couramment que HAProxy fonctionne effectivement dans une machine virtuelle et que, pour une raison quelconque, l’hyperviseur a décidé que les données n’avaient pas besoin d’être envoyées immédiatement. Dans les environnements virtualisés, les problèmes de latence sont presque toujours dus à la couche de virtualisation, aussi vaut-il la peine, pour gagner du temps, de comparer tout d’abord les sorties tcpdump dans la machine virtuelle et sur les composants externes. Toute différence doit être attribuée à l’hyperviseur et à ses pilotes associés.

Lorsque des segments TCP SACK apparaissent dans les traces tcpdump (en utilisant -vv), cela signifie toujours que le côté émetteur dispose de la preuve de la perte d’un paquet. Le fait de ne pas les voir ne signifie pas qu’il n’y a pas de pertes, mais leur présence indique clairement que le réseau est sujet aux pertes. Les pertes sont normales sur un réseau, mais à un taux tel que les SACK ne sont pas perceptibles à l’œil nu. Si elles apparaissent fréquemment dans les traces, il est recommandé d’investiguer précisément ce qui se passe et où les paquets sont perdus. HTTP ne gère pas bien les pertes TCP, qui entraînent des latences importantes.

La commande « netstat -i » affiche les statistiques par interface. Une interface dont le compteur Rx-Ovr augmente indique que le système ne dispose pas de ressources suffisantes pour recevoir tous les paquets entrants, qui sont perdus avant d’être traités par le pilote réseau. Rx-Drp indique que certains paquets reçus ont été perdus dans la pile réseau parce que l’application ne les traite pas assez rapidement. Cela peut survenir également lors de certaines attaques. Tx-Drp signifie que les files de sortie étaient pleines et que des paquets ont dû être abandonnés. En utilisant TCP, cela devrait être très rare, mais peut indiquer une liaison sortante saturée.

34 - 13. Considérations de sécurité

Isolation des privilèges, surface d’attaque, capacités Linux et fonctionnement sécurisé

HAProxy est conçu pour s’exécuter avec des privilèges très limités. La méthode standard consiste à l’isoler dans une prison chroot et à supprimer ses privilèges pour qu’il s’exécute en tant qu’utilisateur non root, sans aucun droit à l’intérieur de cette prison, afin qu’en cas de découverte d’une vulnérabilité future, son compromis n’affecte pas le reste du système.

Pour effectuer un chroot, il est d’abord nécessaire de le lancer en tant qu’utilisateur root. Il est inutile de créer manuellement des chroots afin de lancer le processus à l’intérieur ; ces environnements sont difficiles à mettre en place, jamais correctement maintenus et contiennent toujours bien plus de bogues que le système de fichiers principal. En cas de compromission, l’attaquant peut exploiter le système de fichiers spécifiquement conçu à cet effet. Malheureusement, de nombreux administrateurs confondent « lancer en tant que root » et « s’exécuter en tant que root », ce qui entraîne le changement d’UID avant le démarrage d’HAProxy, réduisant ainsi les restrictions de sécurité effectives.

HAProxy devra être lancé en tant qu’utilisateur root afin de :

  • ajuster les limites des descripteurs de fichiers
  • se lier à des numéros de port privilégiés
  • se lier à une interface réseau spécifique
  • écouter de manière transparente une adresse étrangère
  • s’isoler à l’intérieur d’une prison chroot
  • passer à un autre UID non privilégié

HAProxy peut nécessiter d’être exécuté en tant qu’utilisateur root afin de :

  • lier à une interface pour les connexions sortantes
  • lier à des ports sources privilégiés pour les connexions sortantes
  • lier transparentement à une adresse étrangère pour les connexions sortantes

La plupart des utilisateurs n’auront jamais besoin du cas « exécuter en tant que root ». Toutefois, le cas « démarrer en tant que root » couvre la majorité des utilisations.

Une configuration sécurisée comportera :

  • un énoncé chroot pointant vers un emplacement vide sans aucun droit d’accès. Cela peut être préparé de cette manière sur la ligne de commande UNIX :
# mkdir /var/empty && chmod 0 /var/empty || echo "Failed"

et référencé ainsi dans la section global de la configuration HAProxy :

chroot /var/empty
  • à la fois des instructions uid/utilisateur et gid/groupe dans la section globale :
user haproxy
group haproxy
  • un socket de statistiques dont le mode, le propriétaire (uid) et le groupe (gid) sont configurés pour correspondre à l’utilisateur et/ou au groupe autorisés à accéder à l’interface CLI, afin qu’aucun utilisateur ne puisse y accéder :
stats socket /var/run/haproxy.stat uid hatop gid hatop mode 600

13.1. Prise en charge des capacités Linux

Depuis la version v2.9, HAProxy prend en charge les capacités Linux. Si le binaire est compilé avec USE_LINUX_CAP=1, il est capable de conserver les capacités attribuées par le mot-clé ‘setcap’ lors du passage de l’utilisateur root à un utilisateur non root.

Depuis la version v3.1, HAProxy vérifie également si les capacités spécifiées dans le mot-clé ‘setcap’ ont été définies dans son fichier binaire en tant qu’ensemble Autorisé par l’administrateur (appel système capget). Si tel est le cas, il effectue la transition de ces capacités dans l’ensemble Effectif de son processus (appel système capset), tout en s’exécutant en tant qu’utilisateur non privilégié.

Cela a été fait afin d’éviter tous les cas d’utilisation potentiels lorsque HAProxy démarre et s’exécute en tant qu’utilisateur root : mode de proxy transparent, liaison à des ports privilégiés.

Le mot-clé ‘setcap’ prend en charge les capacités réseau suivantes :

  • cap_net_admin : proxy transparent, liaison du socket à une interface réseau spécifique, utilisation de l’action set-mark ;
  • cap_net_raw (sous-ensemble de cap_net_admin) : proxy transparent ;
  • cap_net_bind_service : liaison du socket à une interface réseau spécifique ;
  • cap_sys_admin : création du socket dans un espace de noms réseau spécifique.

HAProxy ne réalise jamais la transition de ces capacités de son ensemble « Permitted » vers l’ensemble « Effective », si elles ne sont pas listées en tant qu’argument de « setcap ». Pour en savoir plus sur le mot-clé « setcap » et les capacités prises en charge, reportez-vous à la section 3.1 Gestion des processus et sécurité du guide de configuration.

L’administrateur peut ajouter les capacités nécessaires au fichier binaire haproxy dans l’ensemble autorisé à l’aide de la commande suivante :

Exemple :

# setcap cap_net_admin,cap_net_bind_service=p /usr/local/sbin/haproxy

Les capacités ajoutées seront visibles dans l’ensemble Autorisé du processus après son démarrage. Si les mêmes capacités sont spécifiées en tant qu’arguments de l’option ‘setcap’, elles pourront également être observées dans l’ensemble Effectif du processus. Cette situation peut être vérifiée à l’aide de la commande suivante :

Exemple :

# grep Cap /proc/<haproxy PID>/status
CapInh: 0000000000000000
CapPrm: 0000000000001400
CapEff: 0000000000001400
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

Consultez les détails supplémentaires sur setcap et les jeux de capacités dans les pages de manuel Linux (capabilities(7)).

Dans certains cas d’utilisation, comme le proxy transparent ou la création de socket dans un espace réseau spécifique, le parseur de fichier de configuration détecte que les capacités cap_net_raw ou cap_sys_admin ou d’autres capacités prises en charge sont nécessaires. Ensuite, durant l’étape d’initialisation, le processus HAProxy vérifie si ces capacités peuvent être ajoutées à son jeu Effectif. Si cela n’est pas possible en raison d’une erreur de syscall capget ou capset (restrictions imposées sur les appels systèmes par certains modules de sécurité comme SELinux, Seccomp, etc.), le processus émet des avertissements diagnostiques (commençant par -dD).

En raison du support de nombreuses plates-formes différentes, chacune avec ses propres paramètres système, il est impossible au parseur de déduire à partir du fichier de configuration si une liaison à des ports privilégiés est prévue. En cas de privilèges insuffisants (exécution en tant qu’utilisateur non root), le processus ne se terminera que par un message d’alerte similaire au suivant. Il incombe à l’utilisateur de vérifier à nouveau sa configuration et les capacités du binaire HAProxy.

Exemple :

$ haproxy -dD -f haproxy.cfg
...
[ALERT]    (96797): Binding [haproxy.cfg:36] for frontend fe: cannot bind socket (Permission denied) for [0.0.0.0:80]
[ALERT]    (96797): [haproxy.main()] Some protocols failed to start their listeners! Exiting.