Introduction

Haproxy est un outil utilisé pour faire du service discovery. Ses caractéristiques sont :

  • il sert de proxy et est stateful
  • il fait du stickyness en maintenant un client au même serveur de backend.
  • il sert de Loadbalancer et fait du High Availability avec 9 algorithmes de LoadBalancing
    • Round Robin
    • Least
    • First
    • Source
    • URI
    • HDR
  • il facilite ainsi la sécurisation et la mise en place du SSL
  • il permet de faire de la translation d'adresse et de port
  • il est multi-protocole et facilite la configuration en terme de timeout
  • il permet de faire du forwarding
  • il comprend un système de monitoring
  • il permet de faire du service reload
  • il permet de faire du spof avec l’outil keepAlive
  • il permet de faire du slow start
  • il permet de faire du stickyness
  • il permet de faire de la réécriture d'url
  • il est utilisé pour faire du service discovery
Installation

L’installation sur un système Linux, on a :

apt-get install haproxy

La configuration se fait dans le fichier /etc/haproxy/haproxy.cfg

La commande de test suivant nous permettra de voir la version installé :

haproxy -v

Le fichier haproxy.cfg permet de faire la configuration de haproxy, et il servira à faire à peu près 95% de la config. Il est sectionné en plusieurs parties :

  • global
  • default
  • frontend
  • backend
  • listen (qui a pour vocation a remplacé frontend et backend)

Vous aurez plus d’information sur la note dédiée un peu plus en avant.

Les configurations à savoir sont :

  • configuration du daemon : il se fait dans le fichier /etc/sysconfig
  • configuration du logrotate : il se fait en configurant le fichier /etc/haproxy/haproxy.cfg
  • Le repertoire de stockage des données est /var/lib/haproxy
  • Les templates d’erreurs de haproxy sont dans /usr/share/haproxy. Ces templates pourront nous aider à définir des formats de réponse automatique comme une réponse 404. On pourra dans un contexte de sécurisation camoufler une erreur 404 avec une page légitime.
Configuration

Haproxy fonctionne en frontend et redirige les requêtes vers un ensemble de ressources en backend. Pour configurer ce service, il faudra tout d’abord lui demander d’écouter sur :

  • une IP
  • un Port
  • une URL

Cette configuration est celle du frontend. Par la suite, il faudra configurer le backend où on précisera des ressources telles que les serveurs… On pourra préciser plusieurs services et définir le type de LoadBalancing qui sera appliqué. C’est également possible d’appliquer des règles spécifiques, de rajouter des headers sur les requêtes qui seront redirigées vers les services de backend. Le plus important à retenir jusqu’ici est le principe de frontend et de backend. Vous pouvez consulter plus de documentation sur le site officiel.

Exemple : Soit un client qui fait une requête sur le listener du Haproxy c’est-à-dire que la requête arrive sur le frontend. Cette requête sera redirigé vers un backend si elle vérifie certaines condition du frontend spécifique. Ensuite, on aura un chemin. Les étapes :

  • frontend : IP/URL/Port d’écout tel que défini dans la configuration du haproxy. C’est possible d’avoir plusieurs frontend. Ici, la requête est arrivée sur une URL ou un IP précis et sur un port précis (443, 80…)

  • application des règles : des règles sont appliquées pour déterminer le frontend correspondant à la requête cliente. Par la suite une décision sera faite :

    • la requête peut être bloquée
    • la requête peut être modifiée c’est-à-dire que des entêtes peuvent être ajoutées ou enlevées ou modifiée…
  • une règle de redirection du frontend vers le backend

  • Dans le backend, une décision de LoadBalancing peut être appliquée. Des règles en place permettront de choisir le serveur vers qui redirigé la requête

  • un chemin retour

  • journalisation des échanges

    Dans le fichier de configuration de Haproxy, on note 2 partie :

  • section Global

  • section Default

Global

Cette section correspond aux paramètres du service haproxy. Un exemple est définie comme suit :

global
    log /dev/log local5 debug
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

Une pétite explication de ces paramètres :

  • log : c’est la façon donc haproxy va s’occuper de la journalisation
  • chroot : la sécurité de haproxy
  • stats : pour permettre d’interargir avec haproxy avec des outils tiers notamment hatop pour configurer haproxy en GUI. Il permet aussi de définir le timeout qui est le temps de durer d’une connexion
  • user : l’utilisateur du service haproxy
  • group : groupe correspondant
  • daemon : ce mode permet à haproxy de s’exécuter en tant que service.
  • eventuellement le ssl

Default

Cette section s’applique si aucune configuration n’est précisée (définition d’un frontend et d’un backend pour une requête précise). Il est comme suit :

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    errorfile 400 /etc/haproxy/errors/400.http

On a donc :

  • log global : journalisation vers syslog ou suivant la définition de la section global
  • mode http : protocole de LoadBalancing. Il est possible de définir autre chose notamment tcp, smtp…
  • option : permet de préciser la nécessité de journalisation de certaines options
    • option httplog
    • option dontlognull : spécifie qu’il ne faut pas journaliser lorsque les requêtes sont nulles
  • timeout connect : spécifie le durée d’essaie de connexion avec le backend. Ce temps est en ms. Après ce temps, si le serveur ne répond pas, on considère le serveur indisponible.
  • timeout client/server
  • errorfile : permet de spécifier le fichier d’erreur qui devra être affichée en cas d’erreur

Lorsqu’on a rédiger un fichier de configuration haproxy, il est possible de tester la configuration avec la commande :

haproxy -c -f [myconfig_file.conf]

Exemple :

haproxy -c -f /etc/haproxy/haproxy.conf

C’est important de faire ce test pour un nouveau fichier de configuration haproxy avant de remplacer le fichier par défaut.

Exemple

Frontend

Avec Haproxy, on peut définir plusieurs frontend et cette capacité nous permet de mutualisé ce service. Un exemple de frontend minimaliste est :

frontend myapp_front
    bind *:80
    default_backend myapp_back

Le mot clé frontend permet de définir un nouveau frontend. L’indentation est très important dans la rédaction d’un fichier Haproxy. Dans frontend, on pourra définir des paramètres dont les plus importants sont :

  • bind : ici la valeur *:80 a été donné. * spécifie qu’on souhaite écouter sur tous les ip de la machine sur lequel tourne le service haproxy. C’est également possible de définir un ip précis. On aura par exemple : bind 10.0.0.1:80
  • default_backend : est une variable imposée, il spécifie le backend correspondant. La valeur donnée est le nom d’un backend qui a été défini

Backend

La définition d’un backend est comme suit :

backend myapp_back
    server server1 10.0.0.1:80

Le mot clé backend permet de définir un backend. Comme paramètre, on peut spécifier les serveurs qu’on aimerait lié avec le mot clé server. Dans le cas où on a plusieurs serveurs dans le backend, il est possible de spécifier un algorithme de loadbalancing avec le mot clé balance. Dans cet exemple, nous allons utiliser un algorithme de Round Robin On retrouve alors la configuration suivante :

backend myapp_back
    balance roundrobin
    server server1 10.0.0.1:80
    server server2 10.0.0.2:5000

L’algorithme de Round Robin est l’algorithme par défaut utiliser lorsque ce paramètre n’est pas précisé.

Au final, nous obtenons le fichier suivant :

global
    log /dev/log local5 debug
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    errorfile 400 /etc/haproxy/errors/400.http

frontend myapp_front
    bind *:80
    default_backend myapp_back

backend myapp_back
    balance roundrobin
    server server1 10.0.0.1:80
    server server2 10.0.0.2:5000
Options

Haproxy a beaucoup d’options que nous pouvons utilise, il s’agit notamment de :

  • ACL qui permet de mieux gérer les requêtes entrantes et les regiriger vers certains server de backend
  • Forwrad for qui permet de transporter l’IP du client responsable de la requête entre le serveur Haproxy et le serveur de backend. Dans ce cas, Haproxy ne remplamcera plus l’ip du client par son ip.

Dans cette partie, nous allons juste voir comment implémenter des ACL, je vous recommande de vous rendre sur la documentation Haproxy pour plus d’informations sur ses fonctionnalités. Une ACL permet un meilleur filtrage et redirection des requêtes reçues au niveau du frontend. On peut notamment les filtrer suivant l’URL, ce que nous allons faire dans cet exemple… Pour un filtrage en fonction de 2 url à savoir : mct.aubinaso.fr et www.aubinaso.fr, on aura la configuration du frontend suivant :

frontend myapp_front
    bind *:80
    mode http

    acl myapp_front1 hdr_dom(host) -i mct.aubinaso.fr
    use_backend mybackend1 if myapp_front1

    acl myapp_front2 hdr_dom(host) -i www.aubinaso.fr
    use_backend mybackend2 if myapp_front2

La ligne mode http informe qu’il s’agit d’une acl appliquée à la couche 7. Nous avons rajouté 2 entrées pour loadbalancer sur 2 ACL. Les urls sont mct.aubinaso.fr et www.aubinaso.fr. nous créons donc 2 règles acl avec pour nom myapp_front1 et myapp_front2. Le mot clé hdr_dom(host) recupère les URL de la requête et en fonction de l’url, le client sera redirigé sur mybackend1 ou mybackend2.

Variable
NOM="John"
echo $NOM
echo "$NOM"
echo "${NOM}
Condition
if [[ -z "$chaine" ]]; then
  echo "La chaine est vide"
elif [[ -n "$chaine" ]]; then
  echo "La chaine est vide"
fi