Ou : utilisons un logiciel dont c'est le taf de proxyfier :-)

(Oui, j'assume le verbe proxyfier, na)

Il y a quelques temps, j'avais fait un article pour configurer apache en mode reverse proxy.

Je vous invite à le relire rapidement (au moins le chapô ;-) ) pour savoir de quoi l'on parle avec le terme reverse proxy.

Bien que ça fonctionne très bien, il existe des logiciels dédiés à la mise en place d'un reverse proxy, à mettre devant le serveur web.

Le logiciel auquel nous allons nous intéresser aujourd'hui est haproxy et est justement dédié à cet usage.

À noter que nous allons l'utiliser ici en tant que proxy HTTP/HTTPS, mais que haproxy peut servir de proxy pour n'importe quoi, du serveur de messagerie à un serveur mysql, et globalement à tout ce qui utilise TCP.

Pourquoi que donc ?

Avoir un reverse proxy devant son serveur web présente plusieurs avantages.

  •   Ne pas avoir le serveur web publiquement accessible (par exemple pour sa protection)
  •   Faire des pré-traitement sur les requêtes (nombre de sessions, limitation de bande passante, etc)
  •    Balancer les requêtes entre plusieurs serveurs web
  •   Centraliser les accès publics (pour n'utiliser qu'une IP publique avec différents serveurs web derrière)

Une fois n'est pas coutume, attaquons le concret :)

Pré-requis

Pour que cela fonctionne, il vous faut au minimum un serveur web fonctionnel. Il peut être sous apache, nginx, ou même IIS pourquoi pas.

C'est vers lui que nous redirigerons les requêtes.

Il vous faut également un serveur où installer haproxy.

Dans cet exemple, nous prendrons un serveur dédié à cet usage. Cependant, il est aussi possible d'installer haproxy SUR le serveur hébergeant le serveur web (s'il est sous Linux). Ce n'est pas le sujet ici :-)

 

Nous allons donc partir sur un serveur web, et un serveur "passerelle" qui possédera l'adresse publique de votre site, et sur lequel nous installerons haproxy.

Dans notre exemple, ce serveur passerelle sera sous debian 8.

Soit vous avez des serveurs physiques, soit vous les virtualisez.

Si vous vous auto-hébergez, vous ne pourrez pas utiliser votre adresse publique sur votre serveur passerelle. Dans ce cas, mettez en place une redirection de port vers votre serveur passerelle sur votre machinbox (ou routeur). Les ports 80 et 443 suffiront :-)

Terminologie

Haproxy utilise des termes assez classiques dans sa configuration, mais que nous allons tout de même revoir ici afin de bien savoir de quoi l'on parle dans la suite.

  • bind :  attacher en Anglais, permet de dire sur quelle IP et quel port haproxy va écouter. Par exemple, 192.168.1.1 sur le port 80
  • frontend : c'est un bloc de configuration qui permet de définir toutes les règles qui s'appliqueront (domaines écoutés, limitations, etc). Un frontend peut s'appliquer à un ou plusieurs bind.
  • backend : c'est un autre bloc de configuration, que l'on place derrière un frontend. Si le frontend gère ce qui est publique (à "l"avant" du serveur), le backend gère "l'arrière". C'est là que vous définirez les serveurs web vers lesquels envoyer les requêtes.
  • acl : une "access control list" permet de définir des conditions dans un bloc, par exemple "si le domaine contient site1, alors faire cela, si la requête est en https, alors faire ceci"

Aller go : le cambouis c'est pas si salissant

Installation

On commence par installer haproxy. Il est de base dans debian (depuis la version 6)

Si vous voulez faire de l'https, il vous faudra la version au moins 1.5 de haproxy.  (disponible dans les backports debian 7 ou nativement sous debian 8)

Si vous voulez plus de détails sur les versions à installer, rendez vous sur http://haproxy.debian.net/

aptitude update
aptitude install haproxy

Global et default

Les 2 sections global et default permettent de définir des variables qui seront appliquées à tout le reste de la configuration (sauf redéfinition plus précise dans un sous bloc).

Les paramètres définit à l'installation sont corrects, vous pouvez donc laisser ces sections ainsi pour l'instant.

Où configurer

Le fichier de configuration de haproxy est placé dans /etc/haproxy/haproxy.cfg. Néanmoins, pour que cela soit plus pratique à configurer, vous pouvez écrire vos configurations personnalisées dans un fichier /etc/haproxy/haproxy.local, cela évitera d'avoir à modifier le fichier par défaut.

Configuration du frontend

Nous allons voir ici une configuration de frontend basique. Il est possible de faire des choses très compliquées, mais on va rester simple pour l'instant :-)

frontend http-in
    bind IP_PUBLIQUE:80
    mode http
    option httplog
    acl your_acl  hdr(host)   votresiteweb.tld
    use_backend backend1 if your_acl

Attention, l'indentation est importante !

Tous les paramètres du bloc doivent être décalés en dessous pour que haproxy voit que ces paramètres font parti du bloc. En général, une tabulation ou X espaces, selon les préférences.

Vous définissez :

  • frontend http-in : le mot clef frontend indique la présence d'un bloc de configuration frontend. ici, http-in est un nom pour ce frontend, choisi arbitrairement. Vous pouvez nommer le frontend comme vous le souhaitez, une bonne pratique est de prendre un nom clair et pas trop à rallonge :-)
  • IP_PUBLIQUE : l'adresse IP sur laquelle haproxy va écouter. Vous pouvez préciser une IP précise, ou bien 0.0.0.0 pour écouter sur toutes les IP présentes sur le serveur. Vous pouvez aussi mettre plusieurs lignes l'une en dessous de l'autre pour ajouter des IP précises
  • mode http : on définit que ce frontend va traiter uniquement le protocole HTTP (et donc aussi HTTPS). Cela permet déjà à haproxy d'analyser les requêtes, et de rejeter tout ce qui n'est pas formaté correctement vis à vis des RFC
  • option httplog : permet de logguer le détail des requêtes http. Cela permet d'avoir plus d'informations dans les logs haproxy (headers, session http, ...).
  • acl : on définit une ACL, qui sera reconnue si la partie HOST de la requête http correspond exactement à votresiteweb.tld. Il est aussi possible de chercher la fin d'un host (tout ce qui termine par votresiteweb.tld), commence par, contient tel mot, etc. Ici si ça correspond, l'acl se nommera your_acl, nous pourrons la réutiliser dans la suite du bloc.
  • use_backend : on définit ici qu'on va utiliser le backend backend1 SI l'acl your_acl est active. Donc dans notre cas, si la requête traitée contient exactement votresiteweb.tld dans la partie HOST, l'acl est active. Tout se recoupe !

Et voila, en 5 lignes, vous avez configuré un premier frontend pour rediriger votresiteweb.tld vers un backend (qu'il reste à écrire)

On voit déjà que la syntaxe est très simple par rapport à apache (plus de ProxyPass avec des paramètres pas toujours clairs).

On a ici une configuration très simpliste. Je présenterai quelques options montrant la puissance d'haproxy à la fin de cet article.

Configuration du backend

Maintenant que notre frontend est prêt à recevoir les requêtes publiques, il faut créer le backend qui sera à même de savoir envoyer ces requêtes.

backend backend1
    mode http
    option httpchk
    option forwardfor except 127.0.0.1
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    server web-server1  IP_SERVEUR_WEB:80 maxconn 32

De la même manière que pour le frontend, attention à l'indentation pour que les paramètres soient décalés en dessous du mot clef backend

Ici vous définissez :

  • backend backend1 : le mot clef backend permet d'indiquer le début d'un bloc de backend. Le nom backend1 est au choix, comme pour le nom du frontend. Il sera celui à utiliser dans le frontend au moment d'écrire le use_backend
  • mode http : comme pour le frontend, cela indique que ce backend s'occupera d'http, et permet d'utiliser diverses options pratiques (réécriture de header notamment)
  • option httpchk : le httpchk permet de faire en sorte que haproxy vérifie à tout moment l'état des serveurs web derrière lui. Il peut ainsi savoir si le serveur est prêt à recevoir des requêtes, basculer vers un serveur de secours, afficher une page d'erreur en cas de panne, etc. De base, c'est un simple check HTTP sur le / qui est effectué, mais il est possible par exemple de spécifier un script ou un chemin précis
  • forwardfor except 127.0.0.1 : cette option va permettre d'ajouter un en tête xforwardfor dans les requêtes qui passent par le backend, en tête contenant la véritable adresse IP du visiteur. En effet, les requêtes passant par le proxy, c'est son IP qui sera vu niveau réseau par le serveur web ce qui peut être gênant pour faire des statistiques de visites par exemple, car vous auriez l'impression que toutes les visites viennent du serveur proxy... Le except 127.0.0.1 permet d'éviter d'ajouter cet en tête si c'est 127.0.0.1 qui a généré la requête.
  • server web-server1 : cette définition va permettre d'indiquer le serveur vers lequel transmettre les requêtes. IP_SERVEUR_WEB est bien sûr l'adresse IP du serveur web. :80 permet d'indiquer le port ou transmettre. Il est possible d'indiquer plusieurs lignes pour définir plusieurs serveur web et faire de la répartition de charge.
  • maxconn 32 : permet de limiter le nombre maximum de connexions gérées par ce serveur, ici 32. Cela permet d'éviter de surcharger le serveur web au dessus de sa capacité par exemple, et de mitiger directement et à peu de coût une attaque.

A partir de là, c'est tout bon. Vous avez une configuration, certes basique, qui vous permettra de recevoir des requêtes pour votre site, et les transmettre vers votre serveur web :-)

Bien sûr, redémarrez haproxy pour appliquer la configuration.

systemctl restart haproxy

Un peu plus loin : https

frontend

Jusqu'ici, le frontend était uniquement http, pas de certificat.

Mettre en place un frontend https est tout ce qu'il y a de plus simple. On va tout simplement créer un deuxième frontend, cette fois bindé sur le port 443

frontend https-in
    bind IP_PUBLIQUE:443 ssl crt /etc/haproxy/cert/ no-sslv3
    mode http
    option httplog
    acl your_acl  hdr(host)   votresiteweb.tld
    use_backend backend1 if your_acl

On voit quelques différences par rapport à la configuration définie plus haut.

  • https-in : le nom est là encore au choix, mais il faut qu'il soit différent du premier, sinon haproxy renverra une erreur au démarrage.
  • bind : la ligne bind change. On voit qu'on va cette fois se mettre sur le port 443 au lieu de 80, l'HTTPS étant par défaut sur le port 443. Rien ne vous empêche de mettre un autre port selon vos besoins.
  • ssl : ce mot clef (utilisable sur la même ligne que bind) permet d'indiquer à haproxy qu'il va devoir faire du SSL sur ce bind
  • crt /etc/haproxy/cert/ : définit le répertoire dans lequel vous mettre vos certificats. haproxy gère les certificats au format pem, que vous pouvez simplement créer de la façon suivante en mergeant le .crt et le .key :
cat domain.tld.crt domain.tld.key > domain.tld.pem
  • no-sslv3 : cela permet de spécifier à haproxy de refuser d'utiliser le protocole sslv3, considéré désormais comme non sécurisé.

Toutes les autres options sont les même que pour le frontend HTTP (acl, use_backend, ...)

Note sur le dossier des certificats

haproxy gère de manière très efficace les certificats. Vous pouvez les mettre en vrac dans le répertoire, haproxy les parse au démarrage et utilise les certificat de la manière la plus précise possible.

Si par exemple vous possédez un certificat wildcard (*.domain.tld) et un certificat plus précis (sous.domain.tld)

  • Les visites sur sous.domain.tld utiliseront le certificat de sous.domain.tld
  • Les visites sur domain.tld utiliseront le certificat wildcard
  • Les visites sur toto.domain.tld utiliseront le certificat wildcard
  • etc :-)

Backend

Comme c'est le frontend qui gère la partie HTTPS, vous pouvez utiliser exactement les même backend pour le frontend http et le frontend https. Rien à faire à ce niveau là donc, tout est déjà bon dans la configuration.

Redémarrez haproxy, et votre site est prêt à fonctionner en HTTPS !

Encore plus loin : options sympathiques

Cette liste n'est clairement pas exhaustive, haproxy disposant d'une foison incroyable de possibilités. Je ne liste ici que celles qui me semblent les plus utiles de manière générales (en gros, celles que j'utilise moi :-D )

Pour une liste complète, je vous invite à vous référer à la documentation haproxy qui est vraiment très claire et détaillée avec tous les exemples nécessaires à la compréhension.

Plusieurs sites dans un frontend

Comme vous ne pouvez créer qu'un seul frontend écoutant sur le port 80 (ou 443) sur une adresse IP, il va falloir utiliser le même frontend pour gérer plusieurs sites.

Cela se fait très simplement, en utilisant plusieurs acl dans le frontend, par exemple :

acl site1 hdr(host) site1.tld
acl sous-domaine hdr(host) sousdomain.site1.tld
acl toto-site2 hdr(host) toto.site2.tld

Vous pouvez ensuite utiliser un ou plusieurs backend selon les acl :

use_backend backend1 if site1 or sous-domaine or toto-site2

Ou encore :

use_backend backend1 if site1 or sous-domaine
use_backend backend2 if toto-site2

Test de domaine dans un frontend

Dans mes exemples, j'ai à chaque fois utilisé hdr(host) dans mes acl, qui permet de chercher le contenu exact de la variable HOST de la requête HTTP.

Néanmoins, il est possible de faire plus général, comme par exemple créer des acl en se basant sur la fin du HOST, le début, voir chercher si HOST contient telle ou telle chaîne de caractère.

Cela peut permettre de créer une acl qui gérera tout ce qui se termine par site.tdl, tout ce qui contient www., etc

acl test1 hdr_beg(host) www. #On match ce qui commence par www.
acl test2 hdr_end(host) domain.tld #On match tout ce qui termine par domain.tld
acl test3 hdr_reg(host) REGEX #On match tout ce qui correspond à l'expression régulière REGEX

Vous êtes ensuite libre d'utiliser ces acl dans les backend que vous voulez.

Backend par défaut, aussi nommé la poubelle

Une fonctionnalité que je trouve assez intéressante est de prévoir un backend par défaut qui servira de poubelle. Toutes les visites arrivant sur votre serveur et qui ne matchent pas une acl peuvent être considérées comme de la poubelle, voire comme une attaque potentielle, et donc autant ne pas les rediriger vers un site par défaut (comme le fait par exemple de base le vhost apache default)

Pour cela, il suffit d'ajouter dans le frontend le mot clef default_backend qui permet de définir un backend qui sera utilisé pour les requêtes n'ayant matché aucune acl dans le frontend, et de créer un backend qui renverra par exemple une erreur 403 "accès interdit" :

frontend http-in
    [...]
    default_backend poubelle

backend poubelle
    mode http
    http-request deny

Répartition de charge avec un backend

Si vous définissez plusieurs lignes de server dans un backend, alors haproxy va automatiquement répartir (via le protocole round robin) les requêtes entrantes de manière équitables entre les serveurs.

Mais il est également possible de définir des poids pour ces serveurs, si par exemple l'un d'eux est plus puissant, plus à même de recevoir des requêtes

backend backend1
    [...]
    server server1 ip1:80 weight 1
    server server2 ip2:80 weight 2

Ici server2 encaissera 2 fois plus de requêtes que server1

Vous pouvez utiliser le mot clef backup :

backend backend1
    [...]
    server server1 ip1:80
    server server2 ip2:80 backup

Ici, server1 recevra toutes les requêtes, mais si haproxy détecte qu'il n'est plus accessible, alors il enverra automatiquement toutes les requêtes vers server2

Il est possible aussi de combiner ces 2 techniques, faire de la répartition de charge entre plusieurs serveurs tout en ayant d'autres disponibles en backup.

Forcer l'https

Il est possible de dire à haproxy, dans votre frontend sur le port 80, que tel site doit absolument utiliser l'HTTPS. Auquel cas, si haproxy reçoit une requête en HTTP, alors il redirigera immédiatement le visiteur vers exactement la même requête mais en HTTPS :

frontend http-in
    [...]
    # On a plusieurs acl
    acl site1 hdr(host) site1.tld
    acl sous-domaine hdr(host) sousdomaine.site1.tld
    acl toto-site2 hdr(host) toto.site2.tld

    redirect scheme https code 301 if !{ ssl_fc } site1.tld or sous-domaine
    use_backend backend2 if toto-site2

Ici, on va forcer via un code 301 (redirection permanente) la redirection vers l'HTTPS (on détecte que le protocole ssl n'est pas utilisé) pour les accès sur site1.tld et sousdomaine.site1.tld, mais on reste en HTTP et on utilise backend2 si la visite est sur toto.site2.tld

Réécrire des en-têtes dans le backend

On a vu un exemple de réécriture d'en tête dans la partie sur les backend avec le xForwarFor.

Il est possible dans un backend d'écrire tous les en têtes que vous voulez.

Par exemple, si le frontend devant le backend est en https, vous pouvez ajouter un en-tête qui indiquera au serveur web derrière qu'il y a eu traitement https, ce même si le serveur web ne voit jamais le certificat puisque c'est haproxy qui s'en occupe :

backend backend1
    [...]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }

Vous pouvez ainsi écrire (ou réécrire) n'importe quel en-tête.

Par exemple pour réécrire l'en tête serveur :

backend backend1
    [...]
    rspidel ^server #On commence par effacer l'en tête serveur déjà présent
    rspadd  Server:\ Vous\ utilisez\ mon\ super\ serveur\ ! #On rajoute un nouvel en-tete Server (attention à bien protéger les espaces par des \)

 

Voila pour ce tour d'horizon (pas si) rapide sur haproxy !

J'espère que cela vous permettra de vous familiariser avec ce logiciel, qui n'a été ici qu'à peine effleuré :-)

Comme toujours, n'hésitez pas à poser vos questions dans les commentaires !


Victor Avatar Victor est le rédacteur principal du blog.
Comments

Si vous avez des questions, si quelque chose n'est pas clair, n'hésitez pas à commenter !

  • Avatar
    Permalink

    HaproxyTCP

    Posted on

    Bonjour,

    Super article, a quand une version aussi bien pour du TCP ?
    J'ai un Nas synology chez moi et j'aimerais bien que le logiciel "CloudStation" puisse passer a travers "cloud.mondomaine.fr" par exemple.. sauf que ce sont des requêtes TCP et malgré mes nombreux essais je n'arrive pas a faire quelque chose de propre.

    Je pense que ce type de tuto pourrait en intéresse plein d'autre.. (notamment si tu explique comment faire passer de l'openvpn/mysql etc.)

    Merci et bonne journée :)

  • Avatar
    Permalink

    Aurélien

    Posted on

    Bonjour Victor,

    Ce message, juste pour te remercier ! :)
    Un excellent tuto avec des cas concrets.
    Merci à toi.

    Bonne journée

  • Avatar
    Permalink

    Fabrice Scemama

    Posted on

    Super boulot. Bien rédigé, bien structuré, complet et intelligent. Merci!

  • Avatar
    Permalink

    Nicolas

    Posted on

    Le load balancing en se passant des acl, c'est top aussi :)

    tout seul :
    use_backend backend1


    • Avatar
      Permalink

      Victor

      Posted on

      Bonjour Nicolas,

      Effectivement, s'il n'y a qu'un seul site derrière le proxy, le use_backend sans acl est beaucoup plus direct :)

      J'avoue aussi préférer les ACL car cela permet de cibler le site qui est visité : même avec un seul site, une ACL dessus permet de renvoyer les visiteurs qui viennent voir le site vers le bon backend

      Alors que le visiteur qui attaque directement l'adresse IP (ou qui a été mettre un nom de domaine différent dans son fichier etc/hosts) est redirigé vers le default_backend puisqu'il ne matche pas l'acl.
      Cela permet de faire en sorte que ce soit haproxy qui gère ce backend (par exemple, en renvoyant une simple page html "pas de sites ici" plutôt que donner ce rôle au serveur web (qui va alors charger son vhost par défaut, attention à bien l'avoir configuré !)

      C'est ce dont je parle dans la partie "backend par défaut, aussi nommé backend poubelle", mais ça n'a effectivement rien d'obligatoire

  • Avatar
    Permalink

    Ravi

    Posted on

    I'm struck on redirect rule on HAProxy, also post the question on stack exchange but no one answering me as below : https://unix.stackexchange.com/questions/338238/how-to-redirection-on-haproxy-like-apache2

    Here I need to Hide default "app_dev.php" page from URL; Please open above link to get more idea.


    • Avatar
      Permalink

      Victor

      Posted on

      For the redirection part it's simple, you should be able to do that with redirect scheme directive, with something like :

      acl acl_example hdr(host) exemple.com www.example.com http-request redirect scheme https code 301 if !{ ssl_fc } acl_example

      It's how I force https for my websites.

      For the app_dev.php, I honestly do not know. I think that's not the proxy part to do that, as he has no ideas of what is behind him, and it should transmit the information to the webserver, without hiding any information to the webserver nor to the browser.. For me it's a webserver work to rewrite or make URL prettier, but perhaps I have missed something in haproxy regarding this possibility.

      Good luck for this part!

      See you

  • Avatar
    Permalink

    Nicolas

    Posted on

    hier soir, besoin des acls pour la première fois... encore merci pour le tuto, fix en prod dans l'urgence passé comme un charme ;-)

  • Avatar
    Permalink

    Romain

    Posted on

    Salut! Super tuto déjà!

    J'ai vu que tu conseillais d'avoir un serveur dédié pour installer HAProxy dessus, quelle configuration "physique" conseille tu? HAProxy n'a pas l'air gourmand mais je ne sais pas vers quel matériel m'orienter.

    Merci d'avance!


    • Avatar
      Permalink

      Victor

      Posted on

      Hello !

      Merci, content que cet article puisse t'être utile !
      Concernant les performances de haproxy, ça va beaucoup dépendre du nombre de visite bien sûr, mais il reste assez peu gourmand. Auparavant, l'utilisation du SSL utilisait pas mal de ressources (à cause du chiffrement), mais ça s'est bien amélioré depuis les dernières versions.

      A titre indicatif, tous mes sites sont en HTTPS, et la VM qui fait tourner haproxy est un petit deb9 avec 256Mo de RAM et un core virtuel d'un CPU Atom ^^

      Pour des configurations plus costaudes (de l'ordre du dizaine de milliers de visiteurs par jour), c'est principalement le CPU qui va jouer, mais on reste sur du raisonnable, ce n'est pas un serveur web, il ne compile donc pas grand chose. Les plus gros que j'ai vu tournaient sur des Xeon 4 coeurs avec 16Go de RAM, recevaient plus de 10k visites / heures et les ressources restaient à 0 de charge en permenance...

      C'est son principal intérêt, contrairement au serveur web lui-même (apache, nginx, etc), il se contente de faire du routage et de la lecture de header, donc il peut facilement détecter des trucs pourris et traiter pleins de requêtes en se concentrant sur ce qu'il sait faire.

      Si ton objectif est de monter un haproxy d'entreprise, je te conseille de te concentrer sur un CPU avec moins de coeurs, mais plus de fréquence, car même si tu peux faire du multi thread avec Haproxy, c'est la puissance nominale d'un seul core qui permettra d'être le plus efficace ;-)

      Amuse toi bien !

  • Avatar
    Permalink

    Pauline

    Posted on

    Bonjour, Merci beaucoup pour votre tuto. Nous avons un equipement qui reçoit les communication sur le port 9999, et une adresse IP dynamique. Je cherche à mettre en place une passerelle sur internet qui écoute le port 9999 et renvoi tout vers une nouvelle adresse ip:9999

    Vous pensez que c'est possible où simplement destiné au traffic http ou https? Si oui, la methode est celle de ce tuto? Je sais qu'il existe l'overthebox d'ovh, mais j'aimerais bien apprendre à installer une passerelle.

    Merci à vous.


    • Avatar
      Permalink

      Victor

      Posted on

      Bonjour,

      En effet haproxy peut tout à fait fonctionner comme un proxy TCP simple.

      Dans ce cas, on perd le bénéfice des diverses options http (format de log, modification des header, etc), mais il fait très bien le boulot !

      Je vous invite à regarder le mode tcp : http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#mode

      Le concept reste identique à ce tutoriel, si ce n'est qu'il faut éliminer toutes les options liées à http et https.

      Mais le système frontent/backend reste valable :-)

      Bon courage !

  • Avatar
    Permalink

    Pepin

    Posted on

    un grand merci pour ce tuto !

  • Avatar
    Permalink

    Lionel

    Posted on

    Bonjour,

    J'aimerais créer une ACL sur mon shared frontEnd pour dire que le trafic entrant "HTTP"

    www.domain.tld/xxx/* par sur un backend en HTTP et reste en HTTP

    www.domain.tld/* par sur un backend en et passe en HTTPS

    Les certifs sont OK et ça marche en tout HTTP et TOUT HTTP, je veux juste exclure une partie de l'url à cause d'une vieille appli qui ne supporte pas HTTPS.

    Merci pour l'aide !


    • Avatar
      Permalink

      Victor

      Posted on

      Hello Lionel

      Ça me parait jouable, en utilisant une acl avec path_beg qui te permet de définir des critères sur le chemin derrière le domaine

      Il y en a un exemple sur le blog pour gérer let's encrypt si tu veux jeter un oeil : https://blog.victor-hery.com/2015/12/utiliser-letsencrypt-haproxy.html#frontend

      Dans ton cas, tu pourrais probablement faire une acl du genre

      acl stay_http path_beg /xxx/

      Du coup tout ce qui sera en /xxx/ sera géré par cette acl

      Il y a moyen d'être plus précis avec path , notamment vérifier si ça commence par le path, si ça se termine, etc : http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#path

      J'espère que ça suffira à ton bonheur ;-)

    • Avatar
      Permalink

      Lionel

      Posted on

      Ca serait parfait, mais comme c'est un shared je suis obligé de lui coller www.domain.tld/xxx/*, pense tu que c’est jouable ainsi : acl stay_http path_beg www.domain.tld/xxx/ ?

    • Avatar
      Permalink

      Victor

      Posted on

      Mmmh, pour faire ça je jouerai plutôt sur la possibilité de faire des "and" avec use_backend, parce que le path_beg traite vraiment ce qui est "path" dans la requête et pas l'host

      Je ferai 2 acl avec un and de cette manière :

      acl stay_http path_beg /xxx/
      acl domain hdr(host) www.domain.tld
      
      use_backend mon_backend_http if stay_http domain
      

      Sur haproxy, un espace est un "and", pour un "or" il faut spécifier "or", du coup là on dit "utilise le backend mon_backend_http si l'acl stay_http est vraie ET si l'acl domain est vraie"

      A tester, je suis pas sûr à 200% de ma syntaxe (surtout si tu utilises haproxy 2)

      Bon courage !

    • Avatar
      Permalink

      Lionel

      Posted on

      C'est pas gagné ! Pour info je suis sur pfSense.

      Je fais mes deux ACL sur le host et le path que je redirige sur un backend et ca passe bien http.

      Ensuite une action custom pour rediriger ce qui ne concerne pas le path :

      http-request redirect code 308 location https://%[hdr(host)]%[path] if REG unless REG_PATH
      
      REG = www.domain.tld
      REG_PATH = /path/
      

      Et c'est là que ça ne passe pas...

  • Avatar
    Permalink

    Lionel

    Posted on

    Bon, j'ai fini par réussir mon truc !

    rule: code 301 location https://%[hdr(host)]%[path] unless REG_PATH

    Merci pour ton aide, je vais vite faire un petit article avant d'oublier !


    • Avatar
      Permalink

      Lionel

      Posted on


      • Avatar
        Permalink

        Victor

        Posted on

        Ah en effet, la nuance pfsense est importante, je ne l'ai jamais utilisé comme proxy avec haproxy, uniquement comme firewall désolé 😅 (J'ai vaguement souvenir une fois y'a longtemps d'avoir du passer par le shell de BSD pour modifier les fichiers haproxy à la main, mais ça remonte la GUI pfsense était pas encore très au point)

        Top la solution, et l'interface graphique de pfsense pour haproxy me semble vraiment pas mal, c'est cool !

        Content d'avoir pu aider en tout cas, et merci pour avoir pris le temps de venir poster l'article 👍

  • Avatar
    Permalink

    Arnaud

    Posted on

    Bonjour, alors voilà je dois réaliser un loadbalancing de 4 sites web dans la cadre d'un projet en licence pro et je me heurte à un problème, quand je fait une requête à mon haproxy (à l'adresse X.X.X.10) il me dirige bien vers mon serweb1, mais quand je refresh la page, je reste sur serweb1, mais quand je vérifie les stats, il m'indique que serweb1 et serweb2 ont chacun un nombre total de session qui est similaire (2 dans mon cas).

    J'ai suivis votre tutoriel en omettant les acl (je m'en occuperai plus tard.). Concernant la configuration des serveur web apache2, ils sont en configuration de base (j'ai juste modifié l'index afin de pouvoir différentier les 2 à chaque requetes).

    Je vous remercie par avance pour votre aide ^^


    • Avatar
      Permalink

      Victor

      Posted on

      Bonjour Arnaud,

      Effectivement c'est bizarre. Est ce que vous êtes sur de ne pas avoir changé l'algorithme de balancing (par défaut à round robin) ?

      Cela dépend peut être aussi de la version. Il y a un système de sticky cookie dans haproxy qui permet de créer un cookie côté navigateur pour arriver toujours sur le même webserver. C'est principalement utile pour les sites qui utilisent des fonctionnalités qui ne sont pas partagées entre les serveurs web, comme par exemple les paniers sur les sites de vente en ligne.

      Par défaut en 1.8, ce système n'existait pas, mais sur les versions plus récentes peut être que c'est présent par défaut.

      Je te conseille de vérifier dans tes navigateurs si tu n'aurais pas des cookies spécifiques, et faire des tests de panne genre en coupant webserver1 après la première connexion pour voir si ça arrive bien sur webserver2 🤔

      Bon courage !

  • Avatar
    Permalink

    Teddy

    Posted on

    Salut,

    merci pour ce tuto simple et efficace !

    j'ai une question à 2 balles : j'ai tout fait comme indiqué, mais systématiquement, j'ai un "gnagnagna n'autorise pas la connexion"

    j'ai pas encore mis de pare-feu, et du coup j'avoue que je ne comprend pas ce que j'ai pu loupé. Pourrais-tu m'aiguiller ?


    • Avatar
      Permalink

      Victor

      Posted on

      Hello,

      A ma connaissance, il n'y a pas eu de modification fondamentale dans le fonctionnement d'haproxy depuis 2015, donc la configuration devrait fonctionner.

      Vu l'erreur (je suppose que gnagnagna est haproxy ?), j'aurai tendance à penser que l'IP que tu as utilisé pour haproxy n'est peut être pas bonne : bind IP_PUBLIQUE:80

      Est ce que tu as mis une IP précise, ou bien 0.0.0.0 ? Dans le cas d'une IP précise, vérifie que le serveur où est haproxy a bien cette IP, si par exemple ce n'est pas ce serveur qui a l'IP publique (par exemple parce que tu fais du NAT devant), ça pourrait expliquer le souci.

      Si ce n'est pas ça, pourrais tu me préciser où est l'erreur ? Est ce que c'est ce qu'affiche un navigateur web, ou bien tu la vois dans les logs ?

      Bon courage ;-)

  • Avatar
    Permalink

    Schoelcher777

    Posted on

    salut Victor , merci bcp pour ce petit tuto qui a été très très utile !! il me semble c'est le seul tuto fiable pour configurer un RP avec HAProxy sur Ubuntu en français.. peux-tu citer tes sources web ?

    je vous remercie en avance !


    • Avatar
      Permalink

      Victor

      Posted on

      Hello !

      Content que l'article ai pu t'aider, je ne l'avais pas fait pour Ubuntu à la base en plus, encore mieux si ça marche ^^

      Au niveau des sources, c'est entièrement de moi, à partir de mes configurations faites avec mes petites mains :-D

      Le seul lien que j'utilise c'est la documentation officielle de haproxy, que je trouve franchement bien foutue : http://cbonte.github.io/haproxy-dconv/1.8/configuration.html

      Bon courage 💪

  • Avatar
    Permalink

    Bola OUSSOU

    Posted on

    Bonjour Mon cher

    Mes sincères salutations et remerciements pour un tuto claire, limpide qui a penser au lecteur lors de sa rédaction.

    J'ai toutefois besoin d’être qui sur le cas où:

        • si différents serveur web existant après haproxy gèrent déjà eux même leur certificats (renouvellement auto y compris) comment en tenir compte dans la config haproxy ?
        • certains des différents serveur gèrent aussi le forcing vers le https de toute requêtes venu en http. comment en tenir compte dans la config svp

    Encore une foi Merci


    • Avatar
      Permalink

      Victor

      Posted on

      Hello !

      Merci pour ton commentaire ! Désolé j'étais absent tout le week end je n'ai pas pu répondrep lus tôt :-)

      Concernant le fait d'avoir les serveurs finaux qui gèrent les certificats, il y a 2 solutions principales :
      - Utiliser haproxy en mode TCP, il se contente donc de balancer le flux TCP vers les serveurs finaux sans se préoccuper de l'http, et donc il délègue aussi l'établissement de la liaison SSL - Si mettre le certificat également sur haproxy est envisageable, on peut avoir un fonctionnement "full ssl", c'est à dire que le navigateur parle en ssl à haproxy, qui lui même parle en ssl aux serveurs finaux (mot clef "ssl" dans les backend)

      J'ai une préférence pour la seconde option qui permet de profiter du mode http d'haproxy et donc de toutes les options qui vont avec (notamment le travail sur les header http, x-forward-for, etc) mais le balancing TCP marche aussi très bien, il est plus brute de souche on va dire (et hors scope de cet article pour le coup, désolé)

      Concernant le forcing http -> https , dans le cas où haproxy est en TCP, il ne fait rien applicativement donc c'est effectivement aux serveurs finaux de s'en occuper.
      Dans le cas où haproxy est en full ssl, il faut faire attention à ce que haproxy gèrel a redirection, car comme lui parlera aux serveurs finaux en https, ceux-ci auront l'impression d'être tout le temps en https. Donc si haproxy ne fait pas la redirection, tu risques de te retrouver avec des cas trèèès ambigu où le navigateur sera en http, et le serveur final pensera lui être en https, autant dire que c'est crade ^^"

      J'espère que ça pourra te donner des pistes ! Que ça soit pour le TCP ou le mode full ssl, la doc de haproxy reste vraiment bien faite je trouve : http://cbonte.github.io/haproxy-dconv/1.8/configuration.html

  • Avatar
    Permalink

    amazerol

    Posted on

    Merci pour cet excellent article qui introduit de façon efficace et pragmatique HAProxy. J'ai juste eu un peu de mal pour la partie HTTPS car le formatage de la partie a un soucis. Merci encore pour ce partage !


    • Avatar
      Permalink

      Victor

      Posted on

      Hello !

      Merci pour ton commentaire ! Je suis content que cet article serve encore d'introduction potable à haproxy, que j'utilise encore massivement aujourd'hui (d'ailleurs, il faut que je me motive à terminer quelques articles dans mes brouillons..)
      Effectivement il y a un truc qui a foiré avec le formatage de la partie https, considère ça comme réglé, et désolé !

      Amuse toi bien avec 💪

Ajouter un commentaire / Add a Comment

Vous pouvez utiliser la syntaxe Markdown pour formatter votre commentaire.

You can use the Markdown syntax to format your comment.

Flux Atom pour commentaire / Comment Atom Feed

Published

Category

Système

Tags

Restez en contact