HAProxy : Redirection HTTP en utilisant les maps

How to achieve redirection using (regex) maps in HAProxy?

Une map est globalement un fichier contenant une structure de keys / values. Si vous avez une liste importante de redirection à faire (un domaine vers un autre, vers URI, etc) il est intéressant de se servir des maps afin de gagner en lisibilité sur la configuration finale de HAProxy. C'est quand même plus sympa d'avoir une ligne de configuration pour 10 domaines que 10 lignes d'acls, non ? :)

Création d'un fichier map

Il faut commencer par créer son premier fichier de map. Personnellement, je les place dans un dossier maps.

mkdir /etc/haproxy/maps

Par convention, j'utilise l'extension .map.

touch /etc/haproxy/maps/domain.map

Maintenant qu'on a notre fichier, il ne reste plus qu'à le remplir…

Les exemples qui vont suivre n'existent pas mais n'hésitez pas à consulter les sites en question ;-)

Redirection d'un domaine vers un second

Prenons le cas le plus classique : redirection de domain.tld vers www.domain.tld

vim /etc/haproxy/maps/domain.map

Admettons que l'on veuille rediriger :

On reprend notre fichier de map crée précédemment et on fait une liste key/value

/etc/haproxy/maps/domain.map

toucher.rectal.digital    www.toucher.rectal.digital
chiffrer.info             www.chiffrer.info

Puis on termine par créer la règle dans la configuration de HAProxy : /etc/haproxy/haproxy.cfg

frontend http
  [...]
  http-request redirect code 301 location https://%[hdr(host),map(/etc/haproxy/maps/domain.map)]%HU if { hdr(host),map(/etc/haproxy/maps/domain.map) -m found }

On dit simplement à HAProxy : si tu trouves le domaine appelé (key) alors redirection (301) vers le domaine que je souhaite (value) en gardant l'URI d'origine (%HU).

Avec cette configuration ça ne marchera que pour un domaine (%hdr(host)). Et si l'on veut rediriger une URI vers un domaine en particulier (#SEO) ?

Redirection d'une URI vers un domaine spécifique

Si l'on souhaite cette fois redirigier :

  • www.chiffrer.info/faq vers faq.chiffrer.info
  • toucher.rectal.digital/crypter vers chiffrer.info/onditpascrypter

En application : /etc/haproxy/maps/path.map

www.chiffrer.info/faq              https://faq.chiffrer.info
toucher.rectal.digital/crypter     https://chiffrer.info/onditpascrypter

/etc/haproxy/haproxy.cfg

frontend http
  [...]
  http-request redirect location %[base,map(/etc/haproxy/maps/path.map)] code 301 if { base,map(/etc/haproxy/maps/path.map) -m found }

Même explication que précédemment. Si l'on test la première redirection mise en place :

$ curl -I www.chiffrer.info/faq
HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: https://faq.chiffrer.info

Redirection à base de regex

Avec les regex on va pouvoir travailler sur des redirections plus complexes.

Si l'on reprend en exemple les deux domaines précédents et que l'on veuille rediriger A vers B en récupérant un ID aléatoire dans l'URI ?

Prenons un cas classique :

www.chiffrer.info/faq?id=1337 vers faq.chiffre.info/1337

La map doit ressembler à ça

^www.chiffrer.info/faq?id=[0-9]+$      faq.chiffre.info/\1

Globalement la regex va matcher le numéro d'id et l'ajouter à la back reference (\1).

Pour ce cas précis, il faut disposer de haproxy 1.7 minimum qui introduit la map map_regm.

Toujours dans le frontend :

http-request redirect location %[base,map_regm(/etc/haproxy/maps/reg.map)] code 301 if { base,map_regm(/etc/haproxy/maps/reg.map) -m found }

Cet exemple n'est pas testé mais ça devrait marcher ;-)

Ressources


Commentaires