haproxy/doc/haproxy-fr.txt

2892 lines
129 KiB
Plaintext
Raw Normal View History

-------------------
HAProxy
Manuel de r<>f<EFBFBD>rence
-------------------
version 1.3.2
willy tarreau
2006/09/03
2005-12-17 11:21:26 +00:00
!!!! NOTE: CE DOCUMENT EST PERIME !!!!
Veuillez utiliser le fichier "configuration.txt" situ<74> dans le m<>me
r<>pertoire, ou t<>l<EFBFBD>charger une version <20> jour <20> l'emplacement ci-dessous :
http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
================
| Introduction |
================
2005-12-17 11:21:26 +00:00
HAProxy est un relais TCP/HTTP offrant des facilit<69>s d'int<6E>gration en
2005-12-17 11:21:26 +00:00
environnement hautement disponible. En effet, il est capable de :
- effectuer un aiguillage statique d<>fini par des cookies ;
- effectuer une r<>partition de charge avec cr<63>ation de cookies pour assurer
la persistence de session ;
2005-12-17 11:21:26 +00:00
- fournir une visibilit<69> externe de son <20>tat de sant<6E> ;
- s'arr<72>ter en douceur sans perte brutale de service ;
- modifier/ajouter/supprimer des en-t<>tes dans la requ<71>te et la r<>ponse ;
- interdire des requ<71>tes qui v<>rifient certaines conditions ;
- utiliser des serveurs de secours lorsque les serveurs principaux sont hors
d'usage.
- maintenir des clients sur le bon serveur serveur d'application en fonction
de cookies applicatifs.
2006-05-21 21:05:54 +00:00
- fournir des rapports d'<27>tat en HTML <20> des utilisateurs authentifi<66>s, <20>
travers des URI de l'application intercept<70>es.
Il requiert peu de ressources, et son architecture <20>v<EFBFBD>nementielle mono-
processus lui permet facilement de g<>rer plusieurs milliers de connexions
simultan<EFBFBD>es sur plusieurs relais sans effondrer le syst<73>me.
2005-12-17 11:21:26 +00:00
===========================
| Param<61>tres de lancement |
===========================
Les options de lancement sont peu nombreuses :
-f <fichier de configuration>
-n <nombre maximal total de connexions simultan<61>es>
= 'maxconn' dans la section 'global'
-N <nombre maximal de connexions simultan<61>es par instance>
= 'maxconn' dans les sections 'listen' ou 'default'
2005-12-17 11:21:26 +00:00
-d active le mode debug
-D passe en daemon
-q d<>sactive l'affichage de messages sur la sortie standard.
-V affiche les messages sur la sortie standard, m<>me si -q ou 'quiet' sont
sp<73>cifi<66>s.
-c v<>rifie le fichier de configuration puis quitte avec un code de retour 0
si aucune erreur n'a <20>t<EFBFBD> trouv<75>e, ou 1 si une erreur de syntaxe a <20>t<EFBFBD>
d<>tect<63>e.
-p <fichier> indique au processus p<>re qu'il doit <20>crire les PIDs de ses
fils dans ce fichier en mode d<>mon.
-sf specifie une liste de PIDs auxquels envoyer un signal FINISH
-st specifie une liste de PIDs auxquels envoyer un signal TERMINATE
2005-12-17 11:21:26 +00:00
-s affiche les statistiques (si option compil<69>e)
-l ajoute des informations aux statistiques
-dk d<>sactive l'utilisation de kqueue()
-ds d<>sactive l'utilisation de epoll() speculatif
-de d<>sactive l'utilisation de epoll()
-dp d<>sactive l'utilisation de poll()
-db d<>sactive la mise en arri<72>re-plan (utile pour d<>bugger)
-m <megs> applique une limitation de <megs> Mo d'utilisation m<>moire
2005-12-17 11:21:26 +00:00
Le nombre maximal de connexion simultan<61>es par proxy est le param<61>tre par
d<EFBFBD>faut pour les proxies pour lesquels ce param<61>tre n'est pas pr<70>cis<69> dans le
fichier de configuration. Il s'agit du param<61>tre 'maxconn' dans les sections
'listen'.
Le nombre maximal total de connexions simultan<61>es limite le nombre de
connexions TCP utilisables <20> un instant donn<6E> par le processus, tous proxies
confondus. Ce param<61>tre remplace le param<61>tre 'maxconn' de la section 'global'.
2005-12-17 11:21:26 +00:00
Le mode debug correspond <20> l'option 'debug' de la section 'global'. Dans ce
mode, toutes les connexions, d<>connexions, et tous les <20>changes d'en-t<>tes HTTP
sont affich<63>s.
Pour debugger, l'option '-db' est tr<74>s pratique car elle d<>sactive
temporairement le mode daemon et le mode multi-processus. Le service peut alors
<EFBFBD>tre arr<72>t<EFBFBD> par un simple appui sur Ctrl-C, sans avoir <20> modifier la
configuration ni <20> activer le mode debug complet.
Les statistiques ne sont disponibles que si le programme a <20>t<EFBFBD> compil<69> avec
l'option "STATTIME". Il s'agit principalement de donn<6E>es brutes n'ayant
2006-05-21 21:05:54 +00:00
d'utilit<69> que lors de benchmarks par exemple, et sont amen<65>es <20> disparaitre.
Les param<61>tres '-st' et '-sf' sont utilis<69>s pour la reconfiguration <20> chaud.
Voir la section <20> ce sujet.
2005-12-17 11:21:26 +00:00
============================
| Fichier de configuration |
============================
Structure
=========
2005-12-17 11:21:26 +00:00
L'analyseur du fichier de configuration ignore des lignes vides, les espaces,
les tabulations, et tout ce qui est compris entre le symbole '#' (s'il n'est
pas pr<70>c<EFBFBD>d<EFBFBD> d'un '\'), et la fin de la ligne, ce qui constitue un commentaire.
Le fichier de configuration est d<>coup<75> en sections r<>p<EFBFBD>r<EFBFBD>es par des mots cl<63>s
tels que :
- 'global'
- 'listen'
- 'defaults'
Tous les param<61>tres font r<>f<EFBFBD>rence <20> la section d<>finie par le dernier mot cl<63>
reconnu.
1) Param<61>tres globaux
=====================
Il s'agit des param<61>tres agissant sur le processus, ou bien sur l'ensemble des
proxies. Ils sont tous sp<73>cifi<66>s dans la section 'global'. Les param<61>tres
support<EFBFBD>s sont :
- log <adresse> <cat<61>gorie> [niveau_max]
- maxconn <nombre>
- uid <identifiant>
- gid <identifiant>
- user <nom d'utilisateur>
- group <nom de groupe>
- chroot <r<>pertoire>
- nbproc <nombre>
- daemon
- debug
- nokqueue
- nosepoll
- noepoll
- nopoll
- quiet
- pidfile <fichier>
- ulimit-n <nombre>
- tune.maxpollevents <nombre>
1.1) Journalisation des <20>v<EFBFBD>nements
----------------------------------
La plupart des <20>v<EFBFBD>nements sont journalis<69>s : d<>marrages, arr<72>ts, disparition et
apparition de serveurs, connexions, erreurs. Tous les messages sont envoy<6F>s en
syslog vers un ou deux serveurs. La syntaxe est la suivante :
log <adresse_ip> <cat<61>gorie> [niveau_max]
Les connexions sont envoy<6F>es en niveau "info". Les d<>marrages de service et de
serveurs seront envoy<6F>s en "notice", les signaux d'arr<72>ts en "warning" et les
arr<EFBFBD>ts d<>finitifs de services et de serveurs en "alert". Ceci est valable aussi
bien pour les proxies que pour les serveurs test<73>s par les proxies. Le
param<EFBFBD>tre optionnel <niveau_max> d<>finit le niveau maximal de traces <20>mises
parmi les 8 valeurs suivantes :
emerg, alert, crit, err, warning, notice, info, debug
Par compatibilit<69> avec les versions 1.1.16 et ant<6E>rieures, la valeur par d<>faut
est "debug" si l'option n'est pas pr<70>cis<69>e.
Les cat<61>gories possibles sont :
kern, user, mail, daemon, auth, syslog, lpr, news,
uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
local0, local1, local2, local3, local4, local5, local6, local7
Conform<EFBFBD>ment <20> la RFC3164, les messages <20>mis sont limit<69>s <20> 1024 caract<63>res.
Exemple :
---------
global
log 192.168.2.200 local3
log 127.0.0.1 local4 notice
1.2) limitation du nombre de connexions
---------------------------------------
Il est possible et conseill<6C> de limiter le nombre global de connexions par
processus <20> l'aide du mot cl<63> global 'maxconn'. Les connexions sont comprises
au sens 'acceptation de connexion', donc il faut s'attendre en r<>gle g<>n<EFBFBD>ral <20>
avoir un peu plus du double de sessions TCP que le maximum de connexions fix<69>.
C'est important pour fixer le param<61>tre 'ulimit -n' avant de lancer le proxy.
Pour comptabiliser le nombre de sockets n<>cessaires, il faut prendre en compte
ces param<61>tres :
- 1 socket par connexion entrante
- 1 socket par connexion sortante
- 1 socket par couple adresse/port d'<27>coute par proxy
- 1 socket pour chaque serveur en cours de health-check
- 1 socket pour les logs (tous serveurs confondus)
Dans le cas o<> chaque proxy n'<27>coute que sur un couple adresse/port,
positionner la limite du nombre de descripteurs de fichiers (ulimit -n) <20>
(2 * maxconn + nbproxy + nbserveurs + 1). A partir des versions 1.1.32/1.2.6,
il est possible de sp<73>cifier cette limite dans la configuration <20> l'aide du
mot-cl<63> global 'ulimit-n', <20> condition bien entendu que le proxy ait <20>t<EFBFBD>
d<EFBFBD>marr<EFBFBD> sous le compte root (ou avec des droits suffisants pour <20>lever le
nombre de descripteurs de fichiers). Cette solution met un terme au probl<62>me
r<EFBFBD>current d'incertitude de l'ad<61>quation entre les limites syst<73>mes lors de la
derni<EFBFBD>re relance du proxessus et les limites en nombre de connexions. Noter que
cette limite s'applique par processus.
Exemple :
---------
global
maxconn 32000
ulimit-n 65536
1.3) Diminution des privil<69>ges
------------------------------
Afin de r<>duire les risques d'attaques dans le cas o<> une faille non identifi<66>e
serait exploit<69>e, il est possible de diminuer les privil<69>ges du processus, et
de l'isoler dans un r<>pertoire sans risque.
Dans la section 'global', le param<61>tre 'uid' permet de sp<73>cifier un identifiant
num<EFBFBD>rique d'utilisateur. La valeur 0, correspondant normalement au super-
utilisateur, poss<73>de ici une signification particuli<6C>re car elle indique que
l'on ne souhaite pas changer cet identifiant et conserver la valeur courante.
C'est la valeur par d<>faut. De la m<>me mani<6E>re, le param<61>tre 'gid' correspond <20>
un identifiant de groupe, et utilise par d<>faut la valeur 0 pour ne rien
changer. Dans le cas o<> il ne serait pas possible de sp<73>cifier un identifiant
num<EFBFBD>rique pour l'uid, il est possible de sp<73>cifier un nom d'utilisateur apr<70>s
le mot-cl<63> 'user'. De la m<>me mani<6E>re, il est possible de pr<70>ciser un nom de
groupe apr<70>s le mot-cl<63> 'group'.
Il est particuli<6C>rement d<>conseill<6C> d'utiliser des comptes g<>n<EFBFBD>riques tels que
'nobody' car cette pratique revient <20> utiliser 'root' si d'autres processus
utilisent les m<>mes identifiants.
Le param<61>tre 'chroot' autorise <20> changer la racine du processus une fois le
programme lanc<6E>, de sorte que ni le processus, ni l'un de ses descendants ne
puissent remonter de nouveau <20> la racine. Ce type de cloisonnement (chroot) est
g<EFBFBD>n<EFBFBD>ralement contournable sur certains OS (Linux, Solaris) pour peu que
l'attaquant poss<73>de des droits 'root' et soit en mesure d'utiliser ou de cr<63>er
un r<>pertoire. Aussi, il est important d'utiliser un r<>pertoire sp<73>cifique au
service pour cet usage, et de ne pas mutualiser un m<>me r<>pertoire pour
plusieurs services de nature diff<66>rente. Pour rendre l'isolement plus robuste,
il est conseill<6C> d'utiliser un r<>pertoire vide, sans aucun droit, et de changer
l'uid du processus de sorte qu'il ne puisse rien faire dans ledit r<>pertoire.
Remarque importante :
---------------------
Dans le cas o<> une telle faille serait mise en <20>vidence, il est fort probable
que les premi<6D>res tentatives de son exploitation provoquent un arr<72>t du
programme, <20> cause d'un signal de type 'Segmentation Fault', 'Bus Error' ou
encore 'Illegal Instruction'. M<>me s'il est vrai que faire tourner le serveur
en environnement limit<69> r<>duit les risques d'intrusion, il est parfois bien
utile dans ces circonstances de conna<6E>tre les conditions d'apparition du
probl<EFBFBD>me, via l'obtention d'un fichier 'core'. La plupart des syst<73>mes, pour
des raisons de s<>curit<69>, d<>sactivent la g<>n<EFBFBD>ration du fichier 'core' apr<70>s un
changement d'identifiant pour le processus. Il faudra donc soit lancer le
processus <20> partir d'un compte utilisateur aux droits r<>duits (mais ne pouvant
pas effectuer le chroot), ou bien le faire en root sans r<>duction des droits
(uid 0). Dans ce cas, le fichier se trouvera soit dans le r<>pertoire de
lancement, soit dans le r<>pertoire sp<73>cifi<66> apr<70>s l'option 'chroot'. Ne pas
oublier la commande suivante pour autoriser la g<>n<EFBFBD>ration du fichier avant de
lancer le programme :
# ulimit -c unlimited
Exemple :
---------
# with uid/gid
global
uid 30000
gid 30000
chroot /var/chroot/haproxy
# with user/group
global
user haproxy
group public
chroot /var/chroot/haproxy
1.4) Modes de fonctionnement
----------------------------
Le service peut fonctionner dans plusieurs modes :
- avant- / arri<72>re-plan
- silencieux / normal / debug
Le mode par d<>faut est normal, avant-plan, c'est <20> dire que le programme ne
rend pas la main une fois lanc<6E>. Il ne faut surtout pas le lancer comme ceci
dans un script de d<>marrage du syst<73>me, sinon le syst<73>me ne finirait pas son
initialisation. Il faut le mettre en arri<72>re-plan, de sorte qu'il rende la main
au processus appelant. C'est ce que fait l'option 'daemon' de la section
'global', et qui est l'<27>quivalent du param<61>tre '-D' de la ligne de commande.
Le param<61>tre de ligne de commande '-db' inhibe les options globales 'daemon'
et 'nbproc' pour faire fonctionner le processus en mode normal, avant-plan.
Par ailleurs, certains messages d'alerte sont toujours envoy<6F>s sur la sortie
standard, m<>me en mode 'daemon'. Pour ne plus les voir ailleurs que dans les
logs, il suffit de passer en mode silencieux par l'ajout de l'option 'quiet'.
Cette option n'a pas d'<27>quivalent en ligne de commande.
Enfin, le mode 'debug' permet de diagnostiquer les origines de certains
probl<EFBFBD>mes en affichant les connexions, d<>connexions et <20>changes d'en-t<>tes HTTP
entre les clients et les serveurs. Ce mode est incompatible avec les options
'daemon' et 'quiet' pour des raisons de bon sens.
1.5) Accroissement de la capacit<69> de traitement
-----------------------------------------------
Sur des machines multi-processeurs, il peut sembler g<>ch<63> de n'utiliser qu'un
processeur pour effectuer les t<>ches de relayage, m<>me si les charges
n<EFBFBD>cessaires <20> saturer un processeur actuel sont bien au-del<65> des ordres de
grandeur couramment rencontr<74>s. Cependant, pour des besoins particuliers, le
programme sait d<>marrer plusieurs processus se r<>partissant la charge de
travail. Ce nombre de processus est sp<73>cifi<66> par le param<61>tre 'nbproc' de la
section 'global'. Sa valeur par d<>faut est naturellement 1. Ceci ne fonctionne
qu'en mode 'daemon'. Un usage d<>j<EFBFBD> rencontr<74> pour ce param<61>tre fut de d<>passer
la limite de nombre de descripteurs de fichiers allou<6F>e par processus sous
Solaris.
Exemple :
---------
global
daemon
quiet
nbproc 2
2005-12-17 11:21:26 +00:00
1.6) Simplification de la gestion des processus
-----------------------------------------------
Haproxy supporte dor<6F>navant la notion de fichiers de pid (-> pidfiles). Si le
param<EFBFBD>tre '-p' de ligne de commande, ou l'option globale 'pidfile' sont suivis
d'un nom de fichier, alors ce fichier sera supprim<69> puis recr<63><72> et contiendra
le num<75>ro de PID des processus fils, <20> raison d'un par ligne (valable
uniquement en mode d<>mon). Ce fichier n'est PAS relatif au cloisonnement chroot
afin de rester compatible avec un r<>pertoire prot<6F>g<EFBFBD> en lecture seule. Il
appartiendra <20> l'utilisateur ayant lanc<6E> le processus, et disposera des droits
0644.
Exemple :
---------
global
daemon
quiet
nbproc 2
pidfile /var/run/haproxy-private.pid
# pour stopper seulement ces processus parmi d'autres :
# kill $(</var/run/haproxy-private.pid)
# pour recharger une configuration avec un impact minimal sur le service,
# et sans casser les sessions existantes :
# haproxy -f haproxy.cfg -p /var/run/haproxy-private.pid -sf $(</var/run/haproxy-private.pid)
2005-12-17 11:21:26 +00:00
1.7) M<>canismes de traitements des <20>v<EFBFBD>nements
---------------------------------------------
A partir de la version 1.2.5, haproxy supporte les m<>canismes poll() et
epoll(). Sur les systems o<> select() est limit<69> par FD_SETSIZE (comme Solaris),
poll() peut <20>tre une alternative int<6E>ressante. Des tests de performance
montrent que les performances de poll() ne d<>croissent pas aussi vite que le
nombre de sockets augmente, ce qui en fait une solution s<>re pour les fortes
charges. Cela dit, Soalris utilise d<>j<EFBFBD> poll() pour <20>muler select(), donc tant
que le nombre de sockets ne d<>passe pas FD_SETSIZE, poll() ne devrait pas
apporter de performances suppl<70>mentaires. Sur les syst<73>mes <20> base Linux
incluant le patch epoll() (ou tous les Linux 2.6), haproxy utilisera epoll()
qui est extr<74>mement rapide ind<6E>pendamment du nombre de sockets. Les tests sur
haproxy ont montr<74> une performance constante de 1 <20> 40000 sessions simultan<61>es.
La version 1.3.9 a introduit le support de kqueue() pour FreeBSD/OpenBSD, ainsi
qu'une variante appel<65>e "speculative epoll()" consistant <20> tenter d'effectuer
les op<6F>rations d'entr<74>es/sorties avant de cha<68>ner les <20>v<EFBFBD>nements par les appels
syst<EFBFBD>me.
Afin d'optimiser la latence, il est d<>sormais possible de limiter le nombre
d'<27>v<EFBFBD>nements remont<6E>s <20> chaque appel. La limite par d<>faut est fix<69>e <20> 200. Si
une latence plus petite est recherch<63>e, il peut <20>tre justifi<66> d'abaisser cette
limite par l'utilisation du param<61>tre 'tune.maxpollevents' dans la section
'global'. L'augmenter permettra d'<27>conomiser un peu le processeur en pr<70>sence
de tr<74>s grands nombres de connexions simultan<61>es.
Haproxy utilisera kqueue() ou speculative epoll() lorsque ce sera disponible,
puis epoll(), et se repliera sur poll(), puis en dernier lieu sur select().
Cependant, si pour une raison quelconque il s'av<61>rait n<>cessaire de d<>sactiver
epoll() ou poll() (p.ex: <20> cause d'un bug ou juste pour comparer les
performances), de nouvelles options globales ont <20>t<EFBFBD> ajout<75>es dans ce but :
'nosepoll', 'nokqueue', 'noepoll' et 'nopoll'.
Exemple :
---------
global
# utiliser seulement select()
noepoll
nopoll
tune.maxpollevents 100
Remarque :
----------
Dans le but d'assurer une portabilit<69> maximale des configurations, ces options
sont accept<70>es et ignor<6F>es si les m<>canismes poll() ou epoll() n'ont pas <20>t<EFBFBD>
activ<EFBFBD>s lors de la compilation.
Afin de simplifier la r<>solution de probl<62>mes, le param<61>tre '-de' en ligne de
commande d<>sactive epoll(), le param<61>tre '-dp' d<>sactive poll(), '-dk' kqueue()
et '-ds' d<>sactive speculative epoll(). Ils sont respectivement <20>quivalents <20>
'noepoll', 'nopoll', 'nokqueue' et 'nosepoll'.
2) D<>finition d'un service en <20>coute
====================================
2005-12-17 11:21:26 +00:00
Les sections de service d<>butent par le mot cl<63> "listen" :
2005-12-17 11:21:26 +00:00
listen <nom_instance> [ <adresse_IP>:<plage_ports>[,...] ]
2005-12-17 11:21:26 +00:00
- <nom_instance> est le nom de l'instance d<>crite. Ce nom sera envoy<6F> dans les
logs, donc il est souhaitable d'utiliser un nom relatif au service relay<61>.
Aucun test n'est effectu<74> concernant l'unicit<69> de ce nom, qui n'est pas
obligatoire, mais fortement recommand<6E>e.
- <adresse_IP> est l'adresse IP sur laquelle le relais attend ses connexions.
L'absence d'adresse ainsi que l'adresse 0.0.0.0 signifient que les connexions
pourront s'effectuer sur toutes les adresses de la machine.
- <plage_ports> correspond soit <20> un port, soit <20> une plage de ports sur
lesquels le relais acceptera des connexions pour l'adresse IP sp<73>cifi<66>e.
Cette plage peut <20>tre :
- soit un port num<75>rique (ex: '80')
- soit une plage constitu<74>e de deux valeurs s<>par<61>es par un tiret
(ex: '2000-2100') repr<70>sentant les extr<74>mit<69>s incluses dans la
plage.
Il faut faire attention <20> l'usage des plages, car chaque combinaison
<adresse_IP>:<port> consomme une socket, donc un descripteur de fichier.
Le couple <adresse_IP>:<port> doit <20>tre unique pour toutes les instances
d'une m<>me machine. L'attachement <20> un port inf<6E>rieur <20> 1024 n<>cessite un
niveau de privil<69>ge particulier lors du lancement du programme
(ind<6E>pendamment du param<61>tre 'uid' de la section 'global').
- le couple <adresse_IP>:<plage_ports> peut <20>tre r<>p<EFBFBD>t<EFBFBD> ind<6E>finiment pour
demander au relais d'<27>couter <20>galement sur d'autres adresses et/ou d'autres
plages de ports. Pour cela, il suffit de s<>parer les couples par une virgule.
2005-12-17 11:21:26 +00:00
Exemples :
---------
listen http_proxy :80
listen x11_proxy 127.0.0.1:6000-6009
listen smtp_proxy 127.0.0.1:25,127.0.0.1:587
listen ldap_proxy :389,:663
2005-12-17 11:21:26 +00:00
Si toutes les adresses ne tiennent pas sur une ligne, il est possible d'en
rajouter <20> l'aide du mot cl<63> 'bind'. Dans ce cas, il n'est m<>me pas n<>cessaire
de sp<73>cifier la premi<6D>re adresse sur la ligne listen, ce qui facilite parfois
l'<27>criture de configurations :
2005-12-17 11:21:26 +00:00
bind [ <adresse_IP>:<plage_ports>[,...] ]
2005-12-17 11:21:26 +00:00
Exemples :
----------
listen http_proxy
bind :80,:443
bind 10.0.0.1:10080,10.0.0.1:10443
2005-12-17 11:21:26 +00:00
2.1) Inhibition d'un service
----------------------------
Un service peut <20>tre d<>sactiv<69> pour des besoins de maintenance, sans avoir <20>
commenter toute une partie du fichier. Il suffit de positionner le mot cl<63>
"disabled" dans sa section :
2005-12-17 11:21:26 +00:00
listen smtp_proxy 0.0.0.0:25
disabled
2005-12-17 11:21:26 +00:00
Remarque: le mot cl<63> 'enabled' permet de r<>activer un service pr<70>alablement
d<>sactiv<69> par le mot cl<63> 'disabled', par exemple <20> cause d'une
configuration par d<>faut.
2.2) Mode de fonctionnement
---------------------------
Un service peut fonctionner dans trois modes diff<66>rents :
2005-12-17 11:21:26 +00:00
- TCP
- HTTP
- <20>tat de sant<6E>
2005-12-17 11:21:26 +00:00
Mode TCP
--------
Dans ce mode, le service relaye, d<>s leur <20>tablissement, les connexions TCP
vers un ou plusieurs serveurs. Aucun traitement n'est effectu<74> sur le flux. Il
s'agit simplement d'une association
source<adresse:port> -> destination<adresse:port>.
Pour l'utiliser, pr<70>ciser le mode TCP sous la d<>claration du relais.
2005-12-17 11:21:26 +00:00
Exemple :
---------
2005-12-17 11:21:26 +00:00
listen smtp_proxy 0.0.0.0:25
mode tcp
2005-12-17 11:21:26 +00:00
Mode HTTP
---------
Dans ce mode, le service relaye les connexions TCP vers un ou plusieurs
serveurs, une fois qu'il dispose d'assez d'informations pour en prendre la
d<EFBFBD>cision. Les en-t<>tes HTTP sont analys<79>s pour y trouver un <20>ventuel cookie, et
certains d'entre-eux peuvent <20>tre modifi<66>s par le biais d'expressions
r<EFBFBD>guli<EFBFBD>res. Pour activer ce mode, pr<70>ciser le mode HTTP sous la d<>claration du
relais.
2005-12-17 11:21:26 +00:00
Exemple :
---------
2005-12-17 11:21:26 +00:00
listen http_proxy 0.0.0.0:80
mode http
2005-12-17 11:21:26 +00:00
Mode supervision
----------------
Il s'agit d'un mode offrant <20> un composant externe une visibilit<69> de l'<27>tat de
sant<EFBFBD> du service. Il se contente de retourner "OK" <20> tout client se connectant
sur son port. Il peut <20>tre utilis<69> avec des r<>partiteurs de charge <20>volu<6C>s pour
d<EFBFBD>terminer quels sont les services utilisables. Si l'option 'httpchk' est
activ<EFBFBD>e, alors la r<>ponse changera en 'HTTP/1.0 200 OK' pour satisfaire les
attentes de composants sachant tester en HTTP. Pour activer ce mode, pr<70>ciser
le mode HEALTH sous la d<>claration du relais.
2005-12-17 11:21:26 +00:00
Exemple :
---------
# r<>ponse simple : 'OK'
2005-12-17 11:21:26 +00:00
listen health_check 0.0.0.0:60000
mode health
2005-12-17 11:21:26 +00:00
# r<>ponse HTTP : 'HTTP/1.0 200 OK'
listen http_health_check 0.0.0.0:60001
mode health
option httpchk
2.2.1 Supervision
-----------------
Les versions 1.1.32 et 1.2.6 apportent une nouvelle solution pour valider le
bon fonctionnement du proxy sans perturber le service. Le mot-cl<63> 'monitor-net'
a <20>t<EFBFBD> cr<63><72> dans le butd de sp<73>cifier un r<>seau d'<27>quipements qui ne PEUVENT PAS
utiliser le service pour autre chose que des tests de fonctionnement. C'est
particuli<EFBFBD>rement adapt<70> aux proxies TCP, car cela emp<6D>che le proxy de relayer
des <20>tablissements de connexion <20>mis par un outil de surveillance.
Lorsque c'est utilis<69> sur un proxy TCP, la connexion est accept<70>e puis referm<72>e
et rien n'est logu<67>. C'est suffisant pour qu'un r<>partiteur de charge en amont
d<EFBFBD>tecte que le service est disponible.
Lorsque c'est utilis<69> sur un proxy HTTP, la connexion est accept<70>e, rien n'est
logu<EFBFBD>, puis la r<>ponse suivante est envoy<6F>e et la session referm<72>e :
"HTTP/1.0 200 OK". C'est normalement suffisant pour qu'un r<>partiteur de charge
HTTP en amont d<>tecte le service comme op<6F>rationnel, aussi bien <20> travers des
tests TCP que HTTP.
Les proxies utilisant le mot-cl<63> 'monitor-net' peuvent accessoirement se passer
de l'option 'dontlognull', ce qui permettra de loguer les connexions vides
<EFBFBD>mises depuis d'autres adresses que celles du r<>seau de tests.
Exemple :
---------
listen tse-proxy
bind :3389,:1494,:5900 # TSE, ICA and VNC at once.
mode tcp
balance roundrobin
server tse-farm 192.168.1.10
monitor-net 192.168.1.252/31 # L4 load-balancers on .252 and .253
2005-12-17 11:21:26 +00:00
Lorsque le syst<73>me effectuant les tests est situ<74> derri<72>re un proxy, le mot-cl<63>
'monitor-net' n'est pas utilisable du fait que haproxy verra toujours la m<>me
adresse pour le proxy. Pour pallier <20> cette limitation, la version 1.2.15 a
apport<EFBFBD> le mot-cl<63> 'monitor-uri'. Il d<>finit une URI qui ne sera ni retransmise
ni log<6F>e, mais pour laquelle haproxy retournera imm<6D>diatement une r<>ponse
"HTTP/1.0 200 OK". Cela rend possibles les tests de validit<69> d'une cha<68>ne
reverse-proxy->haproxy en une requ<71>te HTTP. Cela peut <20>tre utilis<69> pour valider
une combinaision de stunnel+haproxy <20> l'aide de tests HTTPS par exemple. Bien
entendu, ce mot-cl<63> n'est valide qu'en mode HTTP, sinon il n'y a pas de notion
d'URI. Noter que la m<>thode et la version HTTP sont simplement ignor<6F>es.
Exemple :
---------
listen stunnel_backend :8080
mode http
balance roundrobin
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
monitor-uri /haproxy_test
2.3) Limitation du nombre de connexions simultan<61>es
---------------------------------------------------
Le param<61>tre "maxconn" permet de fixer la limite acceptable en nombre de
connexions simultan<61>es par proxy. Chaque proxy qui atteint cette valeur cesse
d'<27>couter jusqu'<27> lib<69>ration d'une connexion. Voir plus loin concernant les
limitations li<6C>es au syst<73>me.
2005-12-17 11:21:26 +00:00
Exemple :
---------
listen tiny_server 0.0.0.0:80
maxconn 10
2.4) Arr<72>t en douceur
---------------------
Il est possible d'arr<72>ter les services en douceur en envoyant un signal
SIGUSR1 au processus relais. Tous les services seront alors mis en phase
d'arr<72>t, mais pourront continuer d'accepter des connexions pendant un temps
d<EFBFBD>fini par le param<61>tre 'grace' (en millisecondes). Cela permet par exemple,
de faire savoir rapidement <20> un r<>partiteur de charge qu'il ne doit plus
utiliser un relais, tout en continuant d'assurer le service le temps qu'il
s'en rende compte.
Remarque :
----------
Les connexions actives ne sont jamais cass<73>es. Dans le pire des cas, il faudra
attendre en plus leur expiration avant l'arr<72>t total du processus, ou bien tuer
manuellement le processus par l'envoi d'un signal SIGTERM. La valeur par d<>faut
du param<61>tre 'grace' est 0 (pas de gr<67>ce, arr<72>t imm<6D>diat de l'<27>coute).
2005-12-17 11:21:26 +00:00
Exemple :
---------
# arr<72>ter en douceur par 'killall -USR1 haproxy'
2005-12-17 11:21:26 +00:00
# le service tournera encore 10 secondes apr<70>s la demande d'arr<72>t
listen http_proxy 0.0.0.0:80
mode http
grace 10000
2005-12-17 11:21:26 +00:00
# ce port n'est test<73> que par un r<>partiteur de charge.
2005-12-17 11:21:26 +00:00
listen health_check 0.0.0.0:60000
mode health
grace 0
2005-12-17 11:21:26 +00:00
A partir de la version 1.2.8, un nouveau m<>canisme de reconfiguration <20> chaud
a <20>t<EFBFBD> introduit. Il est d<>sormais possible de mettre les proxies en "pause" en
envoyant un signal SIGTTOU aux processus. Cela d<>sactivera les sockets d'<27>coute
sans casser les sessions existantes. Suite <20> cela, l'envoi d'un signal SIGTTIN
r<EFBFBD>activera les sockets d'<27>coute. Ceci est tr<74>s pratique pour tenter de charger
une nouvelle configuration ou m<>me une nouvelle version de haproxy sans casser
les connexions existantes. Si le rechargement s'effectue correctement, il ne
reste plus qu'<27> envoyer un signal SIGUSR1 aux anciens processus, ce qui
provoquera leur arr<72>t imm<6D>diat d<>s que leurs connexions seront termin<69>es ; en
revanche, si le rechargement <20>choue, il suffit d'envoyer un signal SIGTTIN pour
remettre les ports en <20>coute et r<>tablir le service imm<6D>diatement. Veuillez
noter que le param<61>tre 'grace' est ignor<6F> pour le signal SIGTTOU ainsi que le
signal SIGUSR1 une fois le processus en pause. Aussi, il peut s'av<61>rer tr<74>s
utile de sauver le fichier de pid avant de d<>marrer une nouvelle instance.
Ce m<>canisme est pleinement exploit<69> <20> partir de la version 1.2.11 avec les
options '-st' et '-sf' (voir ci-dessous).
2.4) Reconfiguration <20> chaud
----------------------------
Les param<61>tres '-st' et '-sf' sont utilis<69>s pour informer des processus
existants que la configuration va <20>tre recharg<72>e. Ils recevront le signal
SIGTTOU, leur demandant de lib<69>rer les ports en <20>coute afin que le nouveau
processus puisse les prendre. Si quoi que ce soit se passe mal, le nouveau
processus leur enverra un signal SIGTTIN pour leur indiquer qu'ils peuvent
se remettre en <20>coute et continuer leur travail. En revanche, si la
configuration se charge correctement, alors ils recevront un signal de demande
de fin de travail en douceur (-sf), ou de terminaison imm<6D>diate (-st) qui
coupera les sessions en cours. Un usage typique tel que celui-ci permet de
recharger une configuration sans interruption de service :
# haproxy -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
2005-12-17 11:21:26 +00:00
2.5) Temps d'expiration des connexions
--------------------------------------
Il est possible de param<61>trer certaines dur<75>es d'expiration au niveau des
connexions TCP. Trois temps ind<6E>pendants sont configurables et acceptent des
valeurs en millisecondes. Si l'une de ces trois temporisations est d<>pass<73>e, la
session est termin<69>e <20> chaque extr<74>mit<69>.
2005-12-17 11:21:26 +00:00
- temps d'attente d'une donn<6E>e de la part du client, ou de la
possibilit<69> de lui envoyer des donn<6E>es : "clitimeout" :
# time-out client <20> 2mn30.
clitimeout 150000
2005-12-17 11:21:26 +00:00
- temps d'attente d'une donn<6E>e de la part du serveur, ou de la
possibilit<69> de lui envoyer des donn<6E>es : "srvtimeout" :
# time-out serveur <20> 30s.
srvtimeout 30000
2005-12-17 11:21:26 +00:00
- temps d'attente de l'<27>tablissement d'une connexion vers un serveur
"contimeout" :
# on abandonne si la connexion n'est pas <20>tablie apr<70>s 4 secondes
contimeout 4000
2005-12-17 11:21:26 +00:00
Remarques :
-----------
- "contimeout" et "srvtimeout" n'ont pas d'utilit<69> dans le cas du serveur de
type "health".
- sous de fortes charges, ou sur un r<>seau satur<75> ou d<>fectueux, il est
possible de perdre des paquets. Du fait que la premi<6D>re retransmission
TCP n'ait lieu qu'au bout de 3 secoudes, fixer un timeout de connexion
inf<6E>rieur <20> 3 secondes ne permet pas de se rattraper sur la perte
de paquets car la session aura <20>t<EFBFBD> abandonn<6E>e avant la premi<6D>re
retransmission. Une valeur de 4 secondes r<>duira consid<69>rablement
le nombre d'<27>checs de connexion.
- A compter de la version 1.3.14, il est possible de sp<73>cifier les dur<75>es
d'expiration dans des unit<69>s de temps arbitraires <20> choisir parmi
{ us, ms, s, m, h, d }. Pour cela, la valeur enti<74>re doit <20>tre suffix<69>e
de l'unit<69>.
2.6) Tentatives de reconnexion
------------------------------
2005-12-17 11:21:26 +00:00
Lors d'un <20>chec de connexion vers un serveur, il est possible de
retenter (potentiellement vers un autre serveur, en cas de r<>partition
de charge). Le nombre de nouvelles tentatives infructueuses avant
abandon est fourni par le param<61>tre "retries".
2005-12-17 11:21:26 +00:00
Exemple :
---------
# on essaie encore trois fois maxi
retries 3
2005-12-17 11:21:26 +00:00
Il est <20> noter que la tentative de reconnexion peut amener <20> utiliser un autre
serveur si le premier a disparu entre deux tentatives de connexion.
2005-12-17 11:21:26 +00:00
2.7) Adresse du serveur
-----------------------
Le serveur vers lequel sont redirig<69>es les nouvelles connexions est d<>fini par
le param<61>tre "dispatch" sous la forme <adresse_ip>:<port>. Il correspond <20> un
serveur d'assignation de cookie dans le cas o<> le service consiste <20> assurer
uniquement une persistence HTTP, ou bien simplement au serveur destination dans
le cas de relayage TCP simple. Cet ancien mode ne permet pas de tester l'<27>tat
du serveur distant, et il est maintenant recommand<6E> d'utiliser de pr<70>f<EFBFBD>rence
le mode 'balance'.
2005-12-17 11:21:26 +00:00
Exemple :
---------
# on envoie toutes les nouvelles connexions ici
dispatch 192.168.1.2:80
2005-12-17 11:21:26 +00:00
Remarque :
----------
Ce param<61>tre n'a pas d'utilit<69> pour un serveur en mode 'health', ni en mode
'balance'.
2005-12-17 11:21:26 +00:00
2.8) Adresse de sortie
----------------------
Il est possible de forcer l'adresse utilis<69>e pour <20>tablir les connexions vers
les serveurs <20> l'aide du param<61>tre "source". Il est m<>me possible de forcer le
port, bien que cette fonctionnalit<69> se limite <20> des usages tr<74>s sp<73>cifiques.
C'est particuli<6C>rement utile en cas d'adressage multiple, et plus g<>n<EFBFBD>ralement
pour permettre aux serveurs de trouver le chemin de retour dans des contextes
de routage difficiles. Si l'adresse est '0.0.0.0' ou '*' ou vide, elle sera
choisie librement par le systeme. Si le port est '0' ou vide, il sera choisi
librement par le syst<73>me. Il est <20> noter que depuis la version 1.1.18, les
tests de bon fonctionnement des serveurs seront aussi effectu<74>s <20> partir de la
source sp<73>cifi<66>e par ce param<61>tre.
Exemples :
----------
listen http_proxy *:80
# toutes les connexions prennent l'adresse 192.168.1.200
source 192.168.1.200:0
listen rlogin_proxy *:513
# utiliser l'adresse 192.168.1.200 et le port r<>serv<72> 900
source 192.168.1.200:900
2.9) D<>finition du nom du cookie
--------------------------------
En mode HTTP, il est possible de rechercher la valeur d'un cookie pour savoir
vers quel serveur aiguiller la requ<71>te utilisateur. Le nom du cookie est donn<6E>
par le param<61>tre "cookie".
2005-12-17 11:21:26 +00:00
Exemple :
---------
listen http_proxy :80
mode http
cookie SERVERID
2005-12-17 11:21:26 +00:00
On peut modifier l'utilisation du cookie pour la rendre plus intelligente
vis-<2D>-vis des applications relay<61>es. Il est possible, notamment de supprimer ou
r<EFBFBD><EFBFBD>crire un cookie retourn<72> par un serveur acc<63>d<EFBFBD> en direct, et d'ins<6E>rer un
cookie dans une r<>ponse HTTP adress<73>e <20> un serveur s<>lectionn<6E> en r<>partition
de charge, et m<>me de signaler aux proxies amont de ne pas cacher le cookie
ins<EFBFBD>r<EFBFBD>.
Exemples :
----------
Pour ne conserver le cookie qu'en acc<63>s indirect, donc <20> travers le
dispatcheur, et supprimer toutes ses <20>ventuelles occurences lors des acc<63>s
directs :
cookie SERVERID indirect
Pour remplacer la valeur d'un cookie existant par celle attribu<62>e <20> un serveur,
lors d'un acc<63>s direct :
cookie SERVERID rewrite
Pour cr<63>er un cookie comportant la valeur attribu<62>e <20> un serveur lors d'un
acc<EFBFBD>s en r<>partition de charge interne. Dans ce cas, il est souhaitable que
tous les serveurs aient un cookie renseign<67>. Un serveur non assign<67> d'un cookie
retournera un cookie vide (cookie de suppression) :
cookie SERVERID insert
Pour r<>utiliser un cookie applicatif et lui pr<70>fixer l'identifiant du serveur,
puis le supprimer dans les requ<71>tes suivantes, utiliser l'option 'prefix'. Elle
permet d'ins<6E>rer une instance de haproxy devant une application sans risquer
d'incompatibilit<69>s d<>es <20> des clients qui ne supporteraient pas d'apprendre
plus d'un cookie :
cookie JSESSIONID prefix
Pour ins<6E>rer un cookie, en s'assurant qu'un cache en amont ne le stockera pas,
ajouter le mot cl<63> 'nocache' apr<70>s 'insert' :
cookie SERVERID insert nocache
Pour ins<6E>rer un cookie seulement suite aux requ<71>tes de type POST, ajouter le
mot cl<63> 'postonly' apr<70>s 'insert' :
cookie SERVERID insert postonly
Remarques :
-----------
- Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite' pour
s'adapter <20> des applications g<>n<EFBFBD>rant d<>j<EFBFBD> le cookie, avec un contenu
invalide. Il suffit pour cela de les sp<73>cifier sur la m<>me ligne.
- dans le cas o<> 'insert' et 'indirect' sont sp<73>cifi<66>s, le cookie n'est jamais
transmis au serveur vu qu'il n'en a pas connaissance et ne pourrait pas le
comprendre.
- il est particuli<6C>rement recommand<6E> d'utiliser 'nocache' en mode insertion si
des caches peuvent se trouver entre les clients et l'instance du proxy. Dans
le cas contraire, un cache HTTP 1.0 pourrait cacher la r<>ponse, incluant le
cookie de persistence ins<6E>r<EFBFBD>, donc provoquer des changements de serveurs pour
des clients partageant le m<>me cache.
- le mode 'prefix' ne n<>cessite pas d'utiliser 'indirect', 'nocache', ni
'postonly', car tout comme le mode 'rewrite', il s'appuie sur un cookie
pr<70>sent<6E> par l'application qui est cens<6E>e savoir <20> quel moment il peut
<20>tre <20>mis sans risque. Toutefois, comme il n<>cessite de rectifier le cookie
pr<70>sent<6E> par le client dans chaque requ<71>te ult<6C>rieure, il est indispensable
de s'assurer que le client et le serveur communiqueront sans "keep-alive
HTTP". Dans le doute, il est recommand<6E> d'utiliser l'option "httpclose".
- lorsque l'application est bien connue, et que les parties n<>cessitant de la
persistence sont syst<73>matiquement acc<63>d<EFBFBD>es par un formulaire en mode POST,
il est plus efficace encore de combiner le mot cl<63> "postonly" avec "insert"
et "indirect", car la page d'accueil reste cachable, et c'est l'application
qui g<>re le 'cache-control'.
2005-12-17 11:21:26 +00:00
2.10) Assignation d'un serveur <20> une valeur de cookie
----------------------------------------------------
En mode HTTP, il est possible d'associer des valeurs de cookie <20> des serveurs
par le param<61>tre 'server'. La syntaxe est :
2005-12-17 11:21:26 +00:00
server <identifiant> <adresse_ip>:<port> cookie <valeur>
2005-12-17 11:21:26 +00:00
- <identifiant> est un nom quelconque de serveur utilis<69> pour l'identifier dans la
configuration et les logs.
- <adresse_ip>:<port> est le couple adresse-port sur lequel le serveur <20>coute.
- <valeur> est la valeur <20> reconna<6E>tre ou positionner dans le cookie.
2005-12-17 11:21:26 +00:00
Exemple : le cookie SERVERID peut contenir server01 ou server02
---------
listen http_proxy :80
mode http
cookie SERVERID
dispatch 192.168.1.100:80
server web1 192.168.1.1:80 cookie server01
server web2 192.168.1.2:80 cookie server02
Attention : la syntaxe a chang<6E> depuis la version 1.0.
-----------
3) R<>partiteur de charge autonome
=================================
Le relais peut effectuer lui-m<>me la r<>partition de charge entre les diff<66>rents
serveurs d<>finis pour un service donn<6E>, en mode TCP comme en mode HTTP. Pour
cela, on pr<70>cise le mot cl<63> 'balance' dans la d<>finition du service,
<EFBFBD>ventuellement suivi du nom d'un algorithme de r<>partition. Jusqu'<27> la version
1.2.11, seul 'roundrobin' <20>tait g<>r<EFBFBD>, et c'est aussi la valeur implicite par
d<EFBFBD>faut. Avec la version 1.2.12, le nouveau mot cl<63> 'source' est apparu. La
version 1.3.10 a <20>galement apport<72> le mot cl<63> 'uri'. Il est <20>vident qu'en cas
d'utilisation du r<>partiteur interne, il ne faudra pas sp<73>cifier d'adresse de
dispatch, et qu'il faudra au moins un serveur.
Exemple : m<>me que pr<70>c<EFBFBD>demment en r<>partition interne
---------
listen http_proxy :80
mode http
cookie SERVERID
balance roundrobin
server web1 192.168.1.1:80 cookie server01
server web2 192.168.1.2:80 cookie server02
Depuis la version 1.1.22, il est possible de d<>terminer automatiquement le port
du serveur vers lequel sera envoy<6F>e la connexion, en fonction du port d'<27>coute
sur lequel le client s'est connect<63>. En effet, il y a 4 possibilit<69>s pour le
champ <port> de l'adresse serveur :
- non sp<73>cifi<66> ou nul :
la connexion sera envoy<6F>e au serveur sur le m<>me port que celui sur
lequel le relais a re<72>u la connexion.
- valeur num<75>rique (seul cas support<72> pour les versions ant<6E>rieures) :
le serveur recevra la connexion sur le port d<>sign<67>.
- valeur num<75>rique pr<70>c<EFBFBD>d<EFBFBD>e d'un signe '+' :
la connexion sera envoy<6F>e au serveur sur le m<>me port que celui sur
lequel le relais a re<72>u la connexion, auquel on ajoute la valeur d<>sign<67>e.
- valeur num<75>rique pr<70>c<EFBFBD>d<EFBFBD>e d'un signe '-' :
la connexion sera envoy<6F>e au serveur sur le m<>me port que celui sur
lequel le relais a re<72>u la connexion, duquel on soustrait la valeur
d<>sign<67>e.
Exemples :
----------
# m<>me que pr<70>c<EFBFBD>demment
listen http_proxy :80
mode http
cookie SERVERID
balance roundrobin
server web1 192.168.1.1 cookie server01
server web2 192.168.1.2 cookie server02
# relayage simultan<61> des ports 80 et 81 et 8080-8089
listen http_proxy :80,:81,:8080-8089
mode http
cookie SERVERID
balance roundrobin
server web1 192.168.1.1 cookie server01
server web2 192.168.1.2 cookie server02
# relayage TCP des ports 25, 389 et 663 vers les ports 1025, 1389 et 1663
listen http_proxy :25,:389,:663
mode tcp
balance roundrobin
server srv1 192.168.1.1:+1000
server srv2 192.168.1.2:+1000
Comme indiqu<71> pr<70>c<EFBFBD>demment, la version 1.2.12 apporta le nouveau mot cl<63>
'source'. Lorsque celui-ci est utilis<69>, l'adresse IP du client est hach<63>e et
distribu<EFBFBD>e de mani<6E>re homog<6F>ne parmi les serveurs disponibles, de sorte qu'une
m<EFBFBD>me adresse IP aille toujours sur le m<>me serveur tant qu'il n'y a aucun
changement dans le nombre de serveurs disponibles. Ceci peut <20>tre utilis<69> par
exemple pour attacher le HTTP et le HTTPS sur un m<>me serveur pour un m<>me
client. Cela peut <20>galement <20>tre utilis<69> pour am<61>liorer la persistance
lorsqu'une partie de la population des clients n'accepte pas les cookies. Dans
ce cas, seuls ces derniers seront perturb<72>s par la perte d'un serveur.
NOTE: il est important de prendre en compte le fait que beaucoup d'internautes
naviguent <20> travers des fermes de proxies qui assignent des adresses IP
diff<66>rentes <20> chaque requ<71>te. D'autres internautes utilisent des liens <20>
la demande et obtiennent une adresse IP diff<66>rente <20> chaque connexion. De
ce fait, le param<61>tre 'source' doit <20>tre utilis<69> avec une extr<74>me
pr<70>caution.
Exemples :
----------
# assurer qu'une m<>me adresse IP ira sur le m<>me serveur pour tout service
listen http_proxy
bind :80,:443
mode http
balance source
server web1 192.168.1.1
server web2 192.168.1.2
# am<61>liorer la persistance par l'utilisation de la source en plus du cookie :
listen http_proxy :80
mode http
cookie SERVERID
balance source
server web1 192.168.1.1 cookie server01
server web2 192.168.1.2 cookie server02
De plus, tel qu'indiqu<71> ci-dessus, la version 1.3.10 a introduit le mot cl<63>
'uri'. Il est tr<74>s pratique dans le cas de r<>partition de charge entre des
reverse-proxy-caches, parce qu'il utilisera le r<>sultat d'un hachage de l'URI
pour choisir un serveur, ce qui aura pour effet d'optimiser le taux de cache
du fait que la m<>me URI sera toujours envoy<6F>e au m<>me cache. Ce mot-cl<63> n'est
autoris<EFBFBD> qu'en mode HTTP.
Example :
---------
# Envoie toujours une URI donn<6E>e au m<>me serveur
listen http_proxy
bind :3128
mode http
balance uri
server squid1 192.168.1.1
server squid2 192.168.1.2
La version 1.3.14 a apport<72> une nouvelle m<>thode 'balance url_param'. Elle
consiste <20> se baser sur un param<61>tre pass<73> dans l'URL pour effectuer un hachage
utilis<EFBFBD> pour d<>terminer le serveur <20> utiliser. Ceci est principalement utile
pour des applications n'ayant pas une exigence stricte de persistance, mais
pour lesquelles elle procure un gain de performance notable dans des
environnements o<> il n'est pas toujours possible d'utiliser des cookies. En cas
d'absence du param<61>tre dans l'URL, alors une r<>partition de type 'round robin'
est effectu<74>e.
Example :
---------
# hache le param<61>tre "basket_id" dans l'URL pour d<>terminer le serveur
listen http_proxy
bind :3128
mode http
balance url_param basket_id
server ebiz1 192.168.1.1
server ebiz2 192.168.1.2
3.1) Surveillance des serveurs
------------------------------
Il est possible de tester l'<27>tat des serveurs par <20>tablissement de connexion
TCP ou par envoi d'une requ<71>te HTTP. Un serveur hors d'usage ne sera pas
utilis<EFBFBD> dans le processus de r<>partition de charge interne. Pour activer la
surveillance, ajouter le mot cl<63> 'check' <20> la fin de la d<>claration du serveur.
Il est possible de sp<73>cifier l'intervalle (en millisecondes) s<>parant deux
tests du serveur par le param<61>tre "inter", le nombre d'<27>checs accept<70>s par le
param<EFBFBD>tre "fall", et le nombre de succ<63>s avant reprise par le param<61>tre "rise".
Les param<61>tres non pr<70>cis<69>s prennent les valeurs suivantes par d<>faut :
- inter : 2000
- rise : 2
- fall : 3
- port : port de connexion du serveur
- addr : adresse de connexion du serveur (par defaut: adresse du serveur)
Le mode par d<>faut consiste <20> <20>tablir des connexions TCP uniquement. Dans
certains cas de pannes, des serveurs peuvent continuer <20> accepter les
connexions sans les traiter. Depuis la version 1.1.16, haproxy est en mesure
d'envoyer des requ<71>tes HTTP courtes et tr<74>s peu co<63>teuses. Les versions 1.1.16
et 1.1.17 utilisent "OPTIONS / HTTP/1.0". Dans les versions 1.1.18 <20> 1.1.20,
les requ<71>tes ont <20>t<EFBFBD> chang<6E>es en "OPTIONS * HTTP/1.0" pour des raisons de
contr<EFBFBD>le d'acc<63>s aux ressources. Cependant, cette requ<71>te document<6E>e dans la
RFC2068 n'est pas comprise par tous les serveurs. Donc <20> partir de la version
1.1.21, la requ<71>te par d<>faut est revenue <20> "OPTIONS / HTTP/1.0", mais il est
possible de param<61>trer la partie URI. Les requ<71>tes OPTIONS pr<70>sentent
l'avantage d'<27>tre facilement extractibles des logs, et de ne pas induire
d'acc<63>s aux fichiers c<>t<EFBFBD> serveur. Seules les r<>ponses 2xx et 3xx sont
consid<EFBFBD>r<EFBFBD>es valides, les autres (y compris non-r<>ponses) aboutissent <20> un
<EFBFBD>chec. Le temps maximal imparti pour une r<>ponse est <20>gal <20> l'intervalle entre
deux tests (param<61>tre "inter"). Pour activer ce mode, sp<73>cifier l'option
"httpchk", <20>ventuellement suivie d'une m<>thode et d'une URI. L'option "httpchk"
accepte donc 4 formes :
- option httpchk -> OPTIONS / HTTP/1.0
- option httpchk URI -> OPTIONS <URI> HTTP/1.0
- option httpchk METH URI -> <METH> <URI> HTTP/1.0
- option httpchk METH URI VER -> <METH> <URI> <VER>
HAProxy est souvent utilis<69> pour relayer divers protocoles reposant sur TCP,
tels que HTTPS, SMTP ou LDAP, le plus commun <20>tant HTTPS. Un probl<62>me assez
couramment rencontr<74> dans les data centers est le besoin de relayer du trafic
vers des serveurs lointains tout en maintenant la possibilit<69> de basculer sur
un serveur de secours. Les tests purement TCP ne suffisent pas toujours dans
ces situations car l'on trouve souvent, dans la cha<68>ne, des proxies, firewalls
ou r<>partiteurs de charge qui peuvent acquitter la connexion avant qu'elle
n'atteigne le serveur. La seule solution <20> ce probl<62>me est d'envoyer des tests
applicatifs. Comme la demande pour les tests HTTPS est <20>lev<65>e, ce test a <20>t<EFBFBD>
impl<EFBFBD>ment<EFBFBD> en version 1.2.15 sur la base de messages SSLv3 CLIENT HELLO. Pour
l'activer, utiliser "option ssl-hello-chk". Ceci enverra des messages SSLv3
CLIENT HELLO aux serveurs, en annon<6F>ant un support pour la majorit<69> des
algorithmes de chiffrement. Si en retour, le serveur envoie ce qui ressemble <20>
une r<>ponse SSLv3 SERVER HELLO ou ALERT (refus des algorithmes), alors la
r<EFBFBD>ponse sera consid<69>r<EFBFBD>e comme valide. Noter qu'Apache ne produit pas de log
lorsqu'il re<72>oit des messages HELLO, ce qui en fait un type de message
parfaitement adapt<70> <20> ce besoin.
La version 1.3.10 est accompagn<67>e d'un nouveau test d'<27>tat pour le SMTP. Par
d<EFBFBD>faut, il consiste <20> envoyer "HELO localhost" aux serveurs, et <20> attendre le
message "250" en retour. Notez qu'il peut aussi envoyer une requ<71>te plus
sp<EFBFBD>cifique :
- option smtpchk -> envoie "HELO localhost"
- option smtpchk EHLO mail.mydomain.com -> envoie ce message ESMTP
Voir les exemples ci-apr<70>s.
Depuis la version 1.1.17, il est possible de d<>finir des serveurs de secours,
utilis<EFBFBD>s uniquement lorsqu'aucun des autres serveurs ne fonctionne. Pour cela,
ajouter le mot cl<63> "backup" sur la ligne de d<>finition du serveur. Un serveur
de secours n'est appel<65> que lorsque tous les serveurs normaux, ainsi que tous
les serveurs de secours qui le pr<70>c<EFBFBD>dent sont hors d'usage. Il n'y a donc pas
de r<>partition de charge entre des serveurs de secours par d<>faut. A partir
de la version 1.2.9, il est possible de les utiliser simultan<61>ment gr<67>ce <20>
l'option 'allbackups'. Ce type de serveurs peut servir <20> retourner des pages
d'indisponibilit<69> de service. Dans ce cas, il est pr<70>f<EFBFBD>rable de ne pas affecter
de cookie, afin que les clients qui le rencontrent n'y soient pas affect<63>s
d<EFBFBD>finitivement. Le fait de ne pas mettre de cookie envoie un cookie vide, ce
qui a pour effet de supprimer un <20>ventuel cookie affect<63> pr<70>c<EFBFBD>demment.
Depuis la version 1.1.22, il est possible d'envoyer les tests de fonctionnement
vers un port diff<66>rent de celui de service. C'est n<>cessaire principalement
pour les configurations o<> le serveur n'a pas de port pr<70>d<EFBFBD>fini, par exemple
lorsqu'il est d<>duit du port d'acceptation de la connexion. Pour cela, utiliser
le param<61>tre 'port' suivi du num<75>ro de port devant r<>pondre aux requ<71>tes. Il
est possible d'envoyer les tests de fonctionnement vers une adresse diff<66>rente
de celle de service. Cela permet d'utiliser, sur la machine faisant fonctionner
HAproxy, un d<>mon permettant des tests specifiques ( REGEX sur un r<>sultat et
basculement de plusieurs fermes en cas d'erreur sur l'une d'elles).
Enfin, depuis la version 1.1.17, il est possible de visualiser rapidement
l'<27>tat courant de tous les serveurs. Pour cela, il suffit d'envoyer un signal
SIGHUP au processus proxy. L'<27>tat de tous les serveurs de tous les proxies est
envoy<EFBFBD> dans les logs en niveau "notice", ainsi que sur la sortie d'erreurs si
elle est active. C'est une bonne raison pour avoir au moins un serveur de logs
local en niveau notice.
Depuis la version 1.1.18 (et 1.2.1), un message d'urgence est envoy<6F> dans les
logs en niveau 'emerg' si tous les serveurs d'une m<>me instance sont tomb<6D>s,
afin de notifier l'administrateur qu'il faut prendre une action imm<6D>diate.
Depuis les versions 1.1.30 et 1.2.3, plusieurs serveurs peuvent partager la
m<EFBFBD>me valeur de cookie. C'est particuli<6C>rement utile en mode backup, pour
s<EFBFBD>lectionner des chemins alternatifs pour un serveur donn<6E>, pour mettre en
oeuvre l'arr<72>t en douceur d'un serveur, ou pour diriger les clients
temporairement vers une page d'erreur en attendant le red<65>marrage d'une
application. Le principe est que lorsqu'un serveur est d<>tect<63> comme inop<6F>rant,
le proxy cherchera le prochain serveur poss<73>dant la m<>me valeur de cookie pour
chaque client qui le demandera. S'il ne trouve pas de serveur normal, alors il
le cherchera parmi les serveurs de backup. Consulter le guide d'architecture
pour plus d'informations.
Exemples :
----------
# conf du paragraphe 3) avec surveillance TCP
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# m<>me que pr<70>c<EFBFBD>demment avec surveillance HTTP par 'OPTIONS / HTTP/1.0'
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# m<>me que pr<70>c<EFBFBD>demment avec surveillance HTTP par 'OPTIONS /index.html HTTP/1.0'
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# idem avec surveillance HTTP par 'HEAD /index.jsp? HTTP/1.1\r\nHost: www'
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# r<>partition avec persistence bas<61>e sur le pr<70>fixe de cookie, et arr<72>t en
# douceur utilisant un second port (81) juste pour les health-checks.
listen http_proxy 0.0.0.0:80
mode http
cookie JSESSIONID prefix
balance roundrobin
option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www
server web1-norm 192.168.1.1:80 cookie s1 check port 81
server web2-norm 192.168.1.2:80 cookie s2 check port 81
server web1-stop 192.168.1.1:80 cookie s1 check port 80 backup
server web2-stop 192.168.1.2:80 cookie s2 check port 80 backup
# Insertion automatique de cookie dans la r<>ponse du serveur, et suppression
# automatique dans la requ<71>te, tout en indiquant aux caches de ne pas garder
# ce cookie.
listen web_appl 0.0.0.0:80
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check
# idem avec serveur applicatif de secours sur autre site, et serveur de pages d'erreurs
listen web_appl 0.0.0.0:80
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check
server web-backup 192.168.2.1:80 cookie server03 check backup
server web-excuse 192.168.3.1:80 check backup
# relayage SMTP+TLS avec test du serveur et serveur de backup
listen http_proxy :25,:587
mode tcp
balance roundrobin
server srv1 192.168.1.1 check port 25 inter 30000 rise 1 fall 2
server srv2 192.168.1.2 backup
# relayage HTTPS avec test du serveur et serveur de backup
listen http_proxy :443
mode tcp
option ssl-hello-chk
balance roundrobin
server srv1 192.168.1.1 check inter 30000 rise 1 fall 2
server srv2 192.168.1.2 backup
# Utilisation d'un groupe de serveurs pour le backup (n<>cessite haproxy 1.2.9)
listen http_proxy 0.0.0.0:80
mode http
balance roundrobin
option httpchk
server inst1 192.168.1.1:80 cookie s1 check
server inst2 192.168.1.2:80 cookie s2 check
server inst3 192.168.1.3:80 cookie s3 check
server back1 192.168.1.10:80 check backup
server back2 192.168.1.11:80 check backup
option allbackups # all backups will be used
2005-12-17 11:21:26 +00:00
3.2) Reconnexion vers un r<>partiteur en cas d'<27>chec direct
----------------------------------------------------------
En mode HTTP, si un serveur d<>fini par un cookie ne r<>pond plus, les clients
seront d<>finitivement aiguill<6C>s dessus <20> cause de leur cookie, et de ce fait,
d<EFBFBD>finitivement priv<69>s de service. La sp<73>cification du param<61>tre 'redispatch'
autorise dans ce cas <20> renvoyer les connexions <20>chou<6F>es vers le r<>partiteur
(externe ou interne) afin d'assigner un nouveau serveur <20> ces clients.
2005-12-17 11:21:26 +00:00
Exemple :
---------
2005-12-17 11:21:26 +00:00
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
dispatch 192.168.1.100:80
server web1 192.168.1.1:80 cookie server01
server web2 192.168.1.2:80 cookie server02
redispatch # renvoyer vers dispatch si refus de connexion.
Par d<>faut (et dans les versions 1.1.16 et ant<6E>rieures), le param<61>tre
redispatch ne s'applique qu'aux <20>checs de connexion au serveur. Depuis la
version 1.1.17, il s'applique aussi aux connexions destin<69>es <20> des serveurs
identifi<EFBFBD>s comme hors d'usage par la surveillance. Si l'on souhaite malgr<67>
tout qu'un client disposant d'un cookie correspondant <20> un serveur d<>fectueux
tente de s'y connecter, il faut pr<70>ciser l'option "persist" :
listen http_proxy 0.0.0.0:80
mode http
option persist
cookie SERVERID
dispatch 192.168.1.100:80
server web1 192.168.1.1:80 cookie server01
server web2 192.168.1.2:80 cookie server02
redispatch # renvoyer vers dispatch si serveur HS.
3.3) Assignation de poids diff<66>rents <20> des serveurs
---------------------------------------------------
Parfois il arrive d'ajouter de nouveaux serveurs pour accro<72>tre la capacit<69>
d'une ferme de serveur, mais le nouveau serveur est soit beaucoup plus petit
que les autres (dans le cas d'un ajout d'urgence de mat<61>riel de r<>cup<75>ration),
soit plus puissant (lors d'un investissement dans du mat<61>riel neuf). Pour cette
raison, il semble parfois judicieux de pouvoir envoyer plus de clients vers les
plus gros serveurs. Jusqu'<27> la version 1.2.11, il <20>tait n<>cessaire de r<>pliquer
plusieurs fois les d<>finitions des serveurs pour augmenter leur poids. Depuis
la version 1.2.12, l'option 'weight' est disponible. HAProxy construit alors
une vue des serveurs disponibles la plus homog<6F>ne possible en se basant sur
leur poids de sorte que la charge se distribue de la mani<6E>re la plus lisse
possible. Le poids compris entre 1 et 256 doit refl<66>ter la capacit<69> d'un
serveur par rapport aux autres. Le poids de 1 donne la fr<66>quence d'apparition
la plus faible, et 256 la fr<66>quence la plus <20>lev<65>e. De cette mani<6E>re, si un
serveur disparait, les capacit<69>s restantes sont toujours respect<63>es.
Exemple :
---------
# distribution <20>quitable sur 2 opteron and un ancien pentium3
listen web_appl 0.0.0.0:80
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server pentium3-800 192.168.1.1:80 cookie server01 weight 8 check
server opteron-2.0G 192.168.1.2:80 cookie server02 weight 20 check
server opteron-2.4G 192.168.1.3:80 cookie server03 weight 24 check
server web-backup1 192.168.2.1:80 cookie server04 check backup
server web-excuse 192.168.3.1:80 check backup
Notes :
-------
- lorsque le poids n'est pas sp<73>cifi<66>, la valeur par d<>faut est <20> 1
- le poids n'impacte pas les tests de fonctionnement (health checks), donc il
est plus propre d'utiliser les poids que de r<>pliquer le m<>me serveur
plusieurs fois.
- les poids s'appliquent <20>galement aux serveurs de backup si l'option
'allbackups' est positionn<6E>e.
- le poids s'applique aussi <20> la r<>partition selon la source
('balance source').
- quels que soient les poids, le premier serveur sera toujours assign<67> en
premier. Cette r<>gle facilite les diagnostics.
- pour les puristes, l'algorithme de calculation de la vue des serveurs donne
une priorit<69> aux premiers serveurs, donc la vue est la plus uniforme si les
serveurs sont d<>clar<61>s dans l'ordre croissant de leurs poids.
La distribution du trafic suivra exactement le s<>quencement suivant :
Request| 1 1 1 1
number | 1 2 3 4 5 6 7 8 9 0 1 2 3
--------+---------------------------
p3-800 | X . . . . . . X . . . . .
opt-20 | . X . X . X . . . X . X .
opt-24 | . . X . X . X . X . X . X
3.4) Limitation du nombre de sessions concurrentes par serveur
--------------------------------------------------------------
Certains serveurs web multi-processus tels qu'Apache souffrent d<>s qu'il y a
trop de sessions concurrentes, parce qu'il est tr<74>s co<63>teux de faire
fonctionner des centaines ou des milliers de processus sur un syst<73>me. Une
solution consiste <20> augmenter le nombre de serveurs et de r<>partir la charge
entre eux, mais cela pose un probl<62>me lorsque le but est uniquement de r<>sister
<EFBFBD> des pics de charge occasionnels.
Pour r<>soudre ce probl<62>me, une nouvelle fonctionnalit<69> a <20>t<EFBFBD> impl<70>ment<6E>e dans
HAProxy 1.2.13. Il s'agit d'une limite "maxconn" par serveur, associ<63>e <20> une
file d'attente par serveur et par proxy. Ceci transforme HAProxy en un tampon
entre des milliers de clients et quelques serveurs. Dans bien des cas, le fait
de diminuer la valeur maxconn am<61>liorera notablement les performances des
serveurs et diminuera les temps de r<>ponse simplement parce que les serveurs
seront moins congestionn<6E>s.
Quand une requ<71>te cherche <20> joindre n'importe quel serveur, le premier serveur
non satur<75> est utilis<69>, en respectant l'algorithme de r<>partition de charge. Si
tous les serveurs sont satur<75>s, alors la requ<71>te sera mise dans la file
d'attente globale de l'instance. Elle sortira de cette file d'attente lorsque
toutes les requ<71>tes pr<70>c<EFBFBD>dentes auront <20>t<EFBFBD> lib<69>r<EFBFBD>es et qu'un serveur aura <20>t<EFBFBD>
lib<EFBFBD>r<EFBFBD> d'une connexion pour la traiter.
Si une requ<71>te fait r<>f<EFBFBD>rence <20> un serveur en particulier (p.ex: hachage d'IP
source, ou persistance par cookie), et que ce server est satur<75>, alors la
requ<EFBFBD>te sera mise dans la file d'attente d<>di<64>e <20> ce serveur. Cette file
d'attente est prioritaire sur la file d'attente globale, de sorte qu'il soit
plus facile d'atteindre le site pour les utilisateurs qui s'y trouvent d<>j<EFBFBD>
que pour les nouveaux utilisateurs.
Pour cela, les logs ont d<> <20>tre enrichis pour indiquer le nombre de sessions
par serveur, la position de la requ<71>te dans les files d'attentes, et le temps
pass<EFBFBD> en file d'attente. Ceci aide consid<69>rablement <20> faire de la pr<70>vision de
capacit<EFBFBD>. Voir la section 'logs' plus bas pour plus d'informations.
Exemple :
---------
# Prendre soin du P3 qui n'a que 256 Mo de RAM.
listen web_appl 0.0.0.0:80
maxconn 10000
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server pentium3-800 192.168.1.1:80 cookie s1 weight 8 maxconn 100 check
server opteron-2.0G 192.168.1.2:80 cookie s2 weight 20 maxconn 300 check
server opteron-2.4G 192.168.1.3:80 cookie s3 weight 24 maxconn 300 check
server web-backup1 192.168.2.1:80 cookie s4 check maxconn 200 backup
server web-excuse 192.168.3.1:80 check backup
2006-05-21 21:05:54 +00:00
Cette option se montra si efficace pour r<>duire les temps de r<>ponse des
serveurs que certains utilisateurs voulaient utiliser des valeurs trop basses
pour am<61>liorer les performances de leurs serveurs. Seulement, ils n'<27>taient
alors plus en mesure de supporter de tr<74>s fortes charges parce qu'il n'<27>tait
plus possible de les saturer. Pour cette raison, la version 1.2.14 a apport<72> la
limitation dynamique de connexions avec l'addition du param<61>tre "minconn".
Lorsque ce param<61>tre est associ<63> <20> "maxconn", il active la limitation dynamique
bas<EFBFBD>e sur la charge de l'instance. Le nombre maximal de sessions concurrentes
sur un serveur devient alors proportionnel au nombre de sessions de l'instance
par rapport <20> son 'maxconn'. Un minimum de <minconn> sessions sera toujours
permis quelle que soit la charge. Ceci assurera que les serveurs travailleront
au meilleur de leurs performances sous des charges normales, et qu'ils seront
tout de m<>me capables de supporter de fortes pointes lorsque n<>cessaire. La
limite dynamique est calcul<75>e comme ceci :
srv.dyn_limit = max(srv.minconn, srv.maxconn * inst.sess / inst.maxconn)
Exemple :
---------
# Prendre soin du P3 qui n'a que 256 Mo de RAM.
listen web_appl 0.0.0.0:80
maxconn 10000
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server pentium3-800 192.168.1.1:80 cookie s1 weight 8 minconn 10 maxconn 100 check
server opteron-2.0G 192.168.1.2:80 cookie s2 weight 20 minconn 30 maxconn 300 check
server opteron-2.4G 192.168.1.3:80 cookie s3 weight 24 minconn 30 maxconn 300 check
server web-backup1 192.168.2.1:80 cookie s4 check maxconn 200 backup
server web-excuse 192.168.3.1:80 check backup
Dans l'exemple ci-dessus, le serveur "pentium3-800' recevra au plus 100
connexions simultan<61>es lorsque l'instance du proxy en atteindra 10000, et
recevra seulement 10 connexions simultan<61>es tant que le proxy sera sous les 1000
sessions.
Il est possible de limiter la taille de la file d'attente dans le but de
redistribuer les connexions destin<69>es <20> un serveur en particulier qui sont trop
loin pour avoir une chance d'<27>tre servies en un temps raisonnable. Ceci n'est
acceptable que dans le cas o<> l'affinit<69> entre le client et le serveur n'est
pas obligatoire, mais motiv<69>e uniquement par des raisons de performances, par
exemple, par l'utilisation d'un cache local au serveur. L'option 'maxqueue'
permet de pr<70>ciser la limite par serveur, tel que dans l'exemple ci-dessous :
... (m<>me exemple que pr<70>c<EFBFBD>demment)
server pentium3-800 192.168.1.1:80 cookie s1 weight 8 minconn 10 maxconn 100 check maxqueue 50
server opteron-2.0G 192.168.1.2:80 cookie s2 weight 20 minconn 30 maxconn 300 check maxqueue 200
server opteron-2.4G 192.168.1.3:80 cookie s3 weight 24 minconn 30 maxconn 300 check
En l'absence du param<61>tre 'maxqueue', la file d'un serveur n'a pas de limite
d<EFBFBD>finie. Dans le cas contraire, lorsque la file atteint la limite fix<69>e par
'maxqueue', les clients sont d<>plac<61>s vers la file globale.
Notes :
-------
- la requ<71>te ne restera pas ind<6E>finiment en file d'attente, elle est
assuj<75>tie au param<61>tre 'contimeout', et si une requ<71>te ne peut pas
sortir de la file avant ce time-out, soit parce que le serveur est
satur<75>, soit parce qu'il y a trop de requ<71>tes en file d'attente,
alors elle expirera avec une erreur 503.
2006-05-21 21:05:54 +00:00
- si seul <minconn> est sp<73>cifi<66>, il a le m<>me effet que <maxconn>
- positionner des valeurs trop basses pour 'maxconn' peut am<61>liorer les
performances mais aussi permettre <20> des utilisateurs trop lents de bloquer
un serveur pour les autres utilisateurs.
2006-05-21 21:05:54 +00:00
3.5) Abandon des requ<71>tes abort<72>es
----------------------------------
En pr<70>sence de tr<74>s fortes charges, les serveurs mettront un certain temps <20>
r<EFBFBD>pondre. La file d'attente du proxy se remplira, et les temps de r<>ponse
suivront une croissance proportionnelle <20> la taille de file d'attente fois
le temps moyen de r<>ponse par session. Lorsque les clients attendront plus de
quelques secondes, ils cliqueront souvent sur le bouton 'STOP' de leur
navigateur, laissant des requ<71>tes inutiles en file d'attente et ralentissant
donc les autres utilisateurs.
Comme il n'y a aucun moyen de distinguer un vrai clic sur STOP d'une simple
fermeture du canal de sortie sur le client (shutdown(SHUT_WR)), les agents HTTP
doivent <20>tre conservateurs et consid<69>rer que le client n'a probablement ferm<72>
que le canal de sortie en attendant la r<>ponse. Toutefois, ceci introduit des
risques de congestion lorsque beaucoup d'utilisateurs font de m<>me, et s'av<61>re
aujourd'hui compl<70>tement inutile car probablement aucun client ne referme la
session en attendant la r<>ponse. Certains agents HTTP supportent ceci (Squid,
Apache, HAProxy), et d'autres ne le supportent pas (TUX, et la plupart des
r<EFBFBD>partiteurs de charge mat<61>riels). Donc la probabilit<69> pour qu'une notification
de fermeture d'un canal d'entr<74>e c<>t<EFBFBD> client repr<70>sente un utilisateur cliquant
sur 'STOP' est proche de 100%, et il est vraiment tentant d'abandonner la
requ<EFBFBD>te pr<70>matur<75>ment sans polluer les serveurs.
Pour cette raison, une nouvelle option "abortonclose" a <20>t<EFBFBD> introduite en
version 1.2.14. Par d<>faut (sans l'option), le comportement reste conforme <20>
HTTP. Mais lorsque l'option est sp<73>cifi<66>e, une session dont le canal entrant
est ferm<72> sera abort<72>e si cela est possible, c'est <20> dire que la requ<71>te est
soit en file d'attente, soit en tentative de connexion. Ceci r<>duit
consid<EFBFBD>rablement la longueur des files d'attentes et la charge sur les serveurs
satur<EFBFBD>s lorsque les utilisateurs sont tent<6E>s de cliquer sur 'STOP', ce qui <20>
son tour, r<>duit les temps de r<>ponse pour les autres utilisateurs.
Exemple :
---------
listen web_appl 0.0.0.0:80
maxconn 10000
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server web1 192.168.1.1:80 cookie s1 weight 10 maxconn 100 check
server web2 192.168.1.2:80 cookie s2 weight 10 maxconn 100 check
server web3 192.168.1.3:80 cookie s3 weight 10 maxconn 100 check
server bck1 192.168.2.1:80 cookie s4 check maxconn 200 backup
option abortonclose
4) Fonctionnalit<69>s additionnelles
=================================
D'autres fonctionnalit<69>s d'usage moins courant sont disponibles. Il s'agit
2006-05-21 21:05:54 +00:00
principalement du mode transparent, de la journalisation des connexions, de la
r<EFBFBD><EFBFBD>criture des en-t<>tes, et du statut sous forme de page HTML.
4.1) Fonctionnalit<69>s r<>seau
---------------------------
4.1.1) Fonctionnement en mode transparent
---------------------------------------
En mode HTTP, le mot cl<63> 'transparent' permet d'intercepter des sessions
rout<EFBFBD>es <20> travers la machine h<>bergeant le proxy. Dans ce mode, on ne pr<70>cise
pas l'adresse de r<>partition 'dispatch', car celle-ci est tir<69>e de l'adresse
destination de la session d<>tourn<72>e. Le syst<73>me doit permettre de rediriger les
paquets vers un processus local.
Exemple :
---------
listen http_proxy 0.0.0.0:65000
mode http
transparent
cookie SERVERID
server server01 192.168.1.1:80
server server02 192.168.1.2:80
# iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
--dport 80 -j REDIRECT --to-ports 65000
2005-12-17 11:21:26 +00:00
Remarque :
----------
Si le port n'est pas sp<73>cifi<66> sur le serveur, c'est le port auquel s'est
adress<EFBFBD> le client qui sera utilis<69>. Cela permet de relayer tous les ports TCP
d'une m<>me adresse avec une m<>me instance et sans utiliser directement le mode
transparent.
Exemple :
---------
listen http_proxy 0.0.0.0:65000
mode tcp
server server01 192.168.1.1 check port 60000
server server02 192.168.1.2 check port 60000
# iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
-j REDIRECT --to-ports 65000
2005-12-17 11:21:26 +00:00
4.1.2) Choix d'une adresse source par serveur
---------------------------------------------------
Avec les versions 1.1.30 et 1.2.3, il devient possible de sp<73>cifier une adresse
IP source pour joindre chaque serveur. C'est utile pour joindre des serveurs de
backup <20> partir d'un LAN diff<66>rent, ou pour utiliser des chemins alternatifs
pour joindre le m<>me serveur. C'est <20>galement utilisable pour faciliter une
r<EFBFBD>partition de charge selon l'adresse IP source pour des connexions sortantes.
Bien entendu, la m<>me adresse est utilis<69>e pour les health-checks.
Exemple :
---------
# utiliser une adresse particuli<6C>re pour joindre les 2 serveur
listen http_proxy 0.0.0.0:65000
mode http
balance roundrobin
server server01 192.168.1.1:80 source 192.168.2.13
server server02 192.168.1.2:80 source 192.168.2.13
Exemple :
---------
# utiliser une adresse particuli<6C>re pour joindre chaque serveur
listen http_proxy 0.0.0.0:65000
mode http
balance roundrobin
server server01 192.168.1.1:80 source 192.168.1.1
server server02 192.168.2.1:80 source 192.168.2.1
Exemple :
---------
# faire une r<>partition d'adresse sources pour joindre le m<>me proxy <20>
# travers deux liens WAN
listen http_proxy 0.0.0.0:65000
mode http
balance roundrobin
server remote-proxy-way1 192.168.1.1:3128 source 192.168.2.1
server remote-proxy-way2 192.168.1.1:3128 source 192.168.3.1
Exemple :
---------
# forcer une connexion TCP <20> s'attacher <20> un port particulier
listen http_proxy 0.0.0.0:2000
mode tcp
balance roundrobin
server srv1 192.168.1.1:80 source 192.168.2.1:20
server srv2 192.168.1.2:80 source 192.168.2.1:20
4.1.3) Maintien de session TCP (keep-alive)
-------------------------------------------
Avec la version 1.2.7, il devient possible d'activer le maintien de session
TCP (TCP keep-alive) <20> la fois c<>t<EFBFBD> client et c<>t<EFBFBD> serveur. Cela permet
d'emp<6D>cher des sessions longues d'expirer sur des <20>quipements de niveau 4
externes tels que des firewalls ou des r<>partiteurs de charge. Cela permet
aussi au syst<73>me de d<>tecter et terminer des sessions fig<69>es lorsqu'aucun
time-out n'a <20>t<EFBFBD> positionn<6E> (fortement d<>conseill<6C>). Le proxy ne peut pas
positionner l'intervalle entre les annonces ni le nombre maximal, veuillez
vous r<>f<EFBFBD>rer au manuel du syst<73>me d'exploitation pour cela. Il existe 3 options
pour activer le maintien de session TCP :
option tcpka # active le keep-alive c<>t<EFBFBD> client et c<>t<EFBFBD> serveur
option clitcpka # active le keep-alive c<>t<EFBFBD> client
option srvtcpka # active le keep-alive c<>t<EFBFBD> serveur
4.1.4) R<>manence des donn<6E>es TCP (lingering)
--------------------------------------------
Il est possible de d<>sactiver la conservation de donn<6E>es non acquitt<74>es par un
client <20> la fin d'une session. Cela peut parfois s'av<61>rer n<>cessaire lorsque
haproxy est utilis<69> en face d'un grand nombre de clients non fiables et qu'un
nombre <20>lev<65> de sockets en <20>tat FIN_WAIT est observ<72> sur la machine. L'option
peut <20>tre utilis<69>e dans un frontend pour ajuster les connexions vers les
clients, et dans un backend pour ajuster les connexions vers les serveurs :
option nolinger # d<>sactive la conservation de donn<6E>es
4.2) Journalisation des connexions
----------------------------------
L'un des points forts de HAProxy est ind<6E>niablement la pr<70>cision de ses logs.
Il fournit probablement le plus fin niveau d'information disponible pour un
tel outil, ce qui est tr<74>s important pour les diagnostics en environnements
complexes. En standard, les informations journalis<69>es incluent le port client,
les chronom<6F>trages des <20>tats TCP/HTTP, des <20>tats de session pr<70>cis au moment de
la terminaison et sa cause, des informations sur les d<>cisions d'aiguillage du
trafic vers un serveur, et bien s<>r la possibilit<69> de capturer des en-t<>tes
arbitraires.
Dans le but d'am<61>liorer la r<>activit<69> des administrateurs, il offre une grande
transparence sur les probl<62>mes rencontr<74>s, <20> la fois internes et externes, et
il est possible d'envoyer les logs vers des serveurs diff<66>rents en m<>me temps
avec des niveaux de filtrage diff<66>rents :
- logs globaux au niveau processus (erreurs syst<73>me, arr<72>ts/d<>marrages, ...)
- erreurs syst<73>me et internes par instance (manque de ressources, bugs, ...)
- probl<62>mes externes par instance (arr<72>ts/relance serveurs, limites, ...)
- activit<69> par instance (connexions clients), aussi bien lors de leur
<20>tablissement qu'<27> leur terminaison.
La possibilit<69> de distribuer diff<66>rents niveaux de logs <20> diff<66>rents serveurs
permet <20> plusieurs <20>quipes de production d'int<6E>ragir et de corriger leurs
probl<EFBFBD>mes le plus t<>t possible. Par exemple, l'<27>quipe syst<73>me peut surveiller
occasionnellement les erreurs syst<73>me, pendant que l'<27>quipe application
surveille les alertes d'arr<72>ts/d<>marrages de ses serveurs en temps r<>el, et
que l'<27>quipe s<>curit<69> analyse l'activit<69> en diff<66>r<EFBFBD> d'une heure.
4.2.1) Niveaux de log
---------------------
Les connexions TCP et HTTP peuvent donner lieu <20> une journalisation sommaire ou
d<EFBFBD>taill<EFBFBD>e indiquant, pour chaque connexion, la date, l'heure, l'adresse IP
source, le serveur destination, la dur<75>e de la connexion, les temps de r<>ponse,
la requ<71>te HTTP, le code de retour, la quantit<69> de donn<6E>es transmises, et m<>me
dans certains cas, la valeur d'un cookie permettant de suivre les sessions.
Tous les messages sont envoy<6F>s en syslog vers un ou deux serveurs. Se r<>f<EFBFBD>rer <20>
la section 1.1 pour plus d'information sur les cat<61>gories de logs. La syntaxe
est la suivante :
2005-12-17 11:21:26 +00:00
log <adresse_ip_1> <cat<61>gorie_1> [niveau_max_1]
log <adresse_ip_2> <cat<61>gorie_2> [niveau_max_2]
ou
log global
Remarque :
----------
La syntaxe sp<73>cifique 'log global' indique que l'on souhaite utiliser les
param<EFBFBD>tres de journalisation d<>finis dans la section 'global'.
2005-12-17 11:21:26 +00:00
Exemple :
---------
listen http_proxy 0.0.0.0:80
mode http
log 192.168.2.200 local3
log 192.168.2.201 local4
2005-12-17 11:21:26 +00:00
4.2.2) Format des logs
----------------------
Par d<>faut, les connexions sont journalis<69>es au niveau TCP d<>s l'<27>tablissement
de la session entre le client et le relais. En pr<70>cisant l'option 'tcplog',
la connexion ne sera journalis<69>e qu'en fin de session, ajoutant des pr<70>cisions
sur son <20>tat lors de la d<>connexion, ainsi que le temps de connexion et la
dur<EFBFBD>e totale de la session. Le nombre de sessions restantes apr<70>s la
d<EFBFBD>connexion est <20>galement indiqu<71> (pour le serveur, l'instance et le process).
Exemple de journalisation TCP :
-------------------------------
listen relais-tcp 0.0.0.0:8000
mode tcp
option tcplog
log 192.168.2.200 local3
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/0/5007 0 -- 1/1/1 0/0
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 nom_instance relais-tcp
5 nom_serveur Srv1
6 temps_file '/' temps_connect '/' temps_total 0/0/5007
7 octets lus 0
8 etat_terminaison --
9 conn_srv '/' conns_inst '/' conns_processus 1/1/1
10 position en file d'attente srv '/' globale 0/0
Une autre option, 'httplog', fournit plus de d<>tails sur le protocole HTTP,
notamment la requ<71>te et l'<27>tat des cookies. Dans les cas o<> un m<>canisme de
surveillance effectuant des connexions et d<>connexions fr<66>quentes, polluerait
les logs, il suffit d'ajouter l'option 'dontlognull', pour ne plus obtenir une
ligne de log pour les sessions n'ayant pas donn<6E> lieu <20> un <20>change de donn<6E>es
(requ<71>te ou r<>ponse).
2005-12-17 11:21:26 +00:00
Exemple de journalisation HTTP :
--------------------------------
listen http_proxy 0.0.0.0:80
mode http
option httplog
option dontlognull
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/0/7/147/723 200 243 - - ---- 2/3/3 0/0 "HEAD / HTTP/1.0"
Exemple plus complet :
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 137/202/205 0/0 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 nom_instance relais-http
5 nom_serveur Srv1
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt 3183/-1/-1/-1/11215
7 Code_retour_HTTP 503
8 octets lus 0
9 cookies_requ<71>te_captur<75>s -
10 cookies_reponse_captur<75>s -
11 etat_terminaison SC--
12 conns_srv '/' conns_inst '/' conns_processus 137/202/205
13 position file serveur '/' globale 0/0
14 '{' entetes_requ<71>te_captur<75>s '}' {w.ods.org|Mozilla}
15 '{' entetes_reponse_captur<75>s '}' {}
16 '"' requ<71>te_HTTP '"' "HEAD / HTTP/1.0"
Note pour les analyseurs de logs : l'URI est TOUJOURS le dernier champ de la ligne, et
commence par un guillemet '"'.
Le probl<62>me de loguer uniquement en fin de session, c'est qu'il est impossible
de savoir ce qui se passe durant de gros transferts ou des sessions longues.
Pour pallier <20> ce probl<62>me, une nouvelle option 'logasap' a <20>t<EFBFBD> introduite dans
la version 1.1.28 (1.2.1). Lorsqu'elle est activ<69>e, le proxy loguera le plus
t<EFBFBD>t possible, c'est <20> dire juste avant que ne d<>butent les transferts de
donn<EFBFBD>es. Cela signifie, dans le cas du TCP, qu'il loguera toujours le r<>sultat
de la connexion vers le serveur, et dans le cas HTTP, qu'il loguera en fin de
traitement des en-t<>tes de la r<>ponse du serveur, auquel cas le nombre d'octets
repr<EFBFBD>sentera la taille des en-t<>tes retourn<72>s au client.
Afin d'<27>viter toute confusion avec les logs normaux, le temps total de
transfert et le nombre d'octets transf<73>r<EFBFBD>s sont pr<70>fix<69>s d'un signe '+'
rappelant que les valeurs r<>elles sont certainement plus <20>lev<65>es.
Exemple :
---------
listen http_proxy 0.0.0.0:80
mode http
option httplog
option dontlognull
option logasap
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
4.2.3) Chronom<6F>trage des <20>v<EFBFBD>nements
-----------------------------------
Pour d<>celer des probl<62>mes r<>seau, les mesures du temps <20>coul<75> entre certains
<EFBFBD>v<EFBFBD>nements sont d'une tr<74>s grande utilit<69>. Tous les temps sont mesur<75>s en
millisecondes (ms). En mode HTTP, quatre points de mesure sont rapport<72>s sous
la forme Tq/Tw/Tc/Tr/Tt :
- Tq: temps total de r<>ception de la requ<71>te HTTP de la part du client.
C'est le temps qui s'est <20>coul<75> entre le moment o<> le client a <20>tabli
sa connexion vers le relais, et le moment o<> ce dernier a re<72>u le dernier
en-t<>te HTTP validant la fin de la requ<71>te. Une valeur '-1' ici indique
que la requ<71>te compl<70>te n'a jamais <20>t<EFBFBD> re<72>ue.
- Tw: temps total pass<73> dans les files d'attente avant d'obtenir une place
vers un serveur. Ceci tient compte <20> la fois de la file d'attente globale
et de celle du serveur, et d<>pend du nombre de requ<71>tes dans la file et du
temps n<>cessaire au serveur pour compl<70>ter les sessions pr<70>c<EFBFBD>dentes. La
valeur '-1' indique que la requ<71>te a <20>t<EFBFBD> d<>truite avant d'atteindre une
file.
- Tc: temps d'<27>tablissement de la connexion TCP du relais vers le serveur.
C'est le temps <20>coul<75> entre le moment ou le relais a initi<74> la demande de
connexion vers le serveur, et le moment o<> ce dernier l'a acquitt<74>e, c'est
<20> dire le temps entre l'envoi du paquet TCP SYN la r<>ception du SYN/ACK.
Une valeur '-1' ici indique que la connexion n'a jamais pu <20>tre <20>tablie
vers le serveur.
- Tr: temps de r<>ponse du serveur. C'est le temps que le serveur a mis pour
renvoyer la totalit<69> des en-t<>tes HTTP <20> partir du moment o<> il a acquitt<74>
la connexion. Ca repr<70>sente exactement le temps de traitement de la
transaction sans le transfert des donn<6E>es associ<63>es. Une valeur '-1'
indique que le serveur n'a pas envoy<6F> la totalit<69> de l'en-t<>te HTTP.
- Tt: dur<75>e de vie totale de la session, entre le moment o<> la demande de
connexion du client a <20>t<EFBFBD> acquitt<74>e et le moment o<> la connexion a <20>t<EFBFBD>
referm<72>e aux deux extr<74>mit<69>s (client et serveur). La signification change
un peu si l'option 'logasap' est pr<70>sente. Dans ce cas, le temps correspond
uniquement <20> (Tq + Tw + Tc + Tr), et se trouve pr<70>fix<69> d'un signe '+'. On
peut donc d<>duire Td, le temps de transfert des donn<6E>es, en excluant les
autres temps :
Td = Tt - (Tq + Tw + Tc + Tr)
Les temps rapport<72>s <20> '-1' sont simplement <20> <20>liminer de cette <20>quation.
En mode TCP ('option tcplog'), seuls les deux indicateurs Tw, Tc et Tt sont
rapport<EFBFBD>s.
Ces temps fournissent de pr<70>cieux renseignement sur des causes probables de
probl<EFBFBD>mes. Du fait que le protocole TCP d<>finisse des temps de retransmission
de 3 secondes, puis 6, 12, etc..., l'observation de temps proches de multiples
de 3 secondes indique pratiquement toujours des pertes de paquets li<6C>s <20> un
probl<EFBFBD>me r<>seau (c<>ble ou n<>gociation). De plus, si <Tt> est proche d'une
valeur de time-out dans la configuration, c'est souvent qu'une session a <20>t<EFBFBD>
abandonn<EFBFBD>e sur expiration d'un time-out.
Cas les plus fr<66>quents :
- Si Tq est proche de 3000, un paquet a tr<74>s certainement <20>t<EFBFBD> perdu entre
le client et le relais.
- Si Tc est proche de 3000, un paquet a tr<74>s certainement <20>t<EFBFBD> perdu entre
le relais et le serveur durant la phase de connexion. Cet indicateur
devrait normalement toujours <20>tre tr<74>s bas (moins de quelques dizaines).
- Si Tr est presque toujours inf<6E>rieur <20> 3000, et que certaines valeurs
semblent proches de la valeur moyenne major<6F>e de 3000, il y a peut-<2D>tre
de pertes entre le relais et le serveur.
- Si Tt est l<>g<EFBFBD>rement sup<75>rieur au time-out, c'est souvent parce que le
client et le serveur utilisent du keep-alive HTTP entre eux et que la
session est maintenue apr<70>s la fin des <20>changes. Voir plus loin pour
savoir comment d<>sactiver le keep-alive HTTP.
Autres cas ('xx' repr<70>sentant une valeur quelconque <20> ignorer) :
-1/xx/xx/xx/Tt: le client n'a pas envoy<6F> sa requ<71>te dans le temps imparti ou
a referm<72> sa connexion sans compl<70>ter la requ<71>te.
Tq/-1/xx/xx/Tt: Il n'<27>tait pas possible de traiter la request, probablement
parce que tous les serveurs <20>taient hors d'usage.
Tq/Tw/-1/xx/Tt: la connexion n'a pas pu s'<27>tablir vers le serveur (refus ou
time-out au bout de Tt-(Tq+Tw) ms).
Tq/Tw/Tc/-1/Tt: le serveur a accept<70> la connexion mais n'a pas r<>pondu dans
les temps ou bien a referm<72> sa connexion trop t<>t, au bout
de Tt-(Tq+Tw+Tc) ms.
4.2.4) Conditions de d<>connexion
--------------------------------
Les logs TCP et HTTP fournissent un indicateur de compl<70>tude de la session dans
le champ 'etat_terminaison', juste avant le nombre de connexions actives. C'est
un champ long de 2 caract<63>res en TCP et de 4 caract<63>res en HTTP, chacun ayant
une signification pr<70>cise :
- sur le premier caract<63>re, un code pr<70>cisant le premier <20>v<EFBFBD>nement qui a caus<75>
la terminaison de la session :
C : fermeture inattendue de la session TCP de la part du client.
S : fermeture inattendue de la session TCP de la part du serveur, ou
refus explicite de connexion de la part de ce dernier.
P : terminaison pr<70>matur<75>e des sessions par le proxy, pour cause
d'imposition d'une limite sur le nombre de connexions, pour cause
de configuration (ex: filtre d'URL), ou parce qu'un contr<74>le de
s<>curit<69> a d<>tect<63> et bloqu<71> une anomalie dans la r<>ponse du
serveur qui aurait pu causer une fuite d'informations (par exemple,
un cookie cachable).
R : une ressource sur le proxy a <20>t<EFBFBD> <20>puis<69>e (m<>moire, sockets, ports
source, ...). G<>n<EFBFBD>ralement, cela arrive au cours de l'<27>tablissement
d'une connexion, et les logs syst<73>me doivent contenir une copie de
l'<27>rreur pr<70>cise.
I : une erreur interne a <20>t<EFBFBD> identifi<66>e par le proxy <20> la suite d'un
auto-contr<74>le. Ceci ne doit JAMAIS arriver, et vous <20>tes encourag<61>s
<20> remonter n'importe quel log contenant ceci car il s'agira un bug.
c : le d<>lai maximal d'attente du client a expir<69> (clitimeout).
s : le d<>lai maximal d'attente du serveur a expir<69> (srvtimeout et contimeout)
- : terminaison normale de session.
- sur le second caract<63>re, l'<27>tat d'avancement de la session TCP/HTTP lors de
la fermeture :
R : attente d'une REQUETE HTTP compl<70>te de la part du client. Rien n'a
<20>t<EFBFBD> transmis au serveur.
Q : attente en file d'attente (QUEUE) d'une place pour avoir une
connexion vers un serveur. Ne peut appara<72>tre que sur un serveur
poss<73>dant un param<61>tre 'maxconn'. Aucune connexion n'a <20>t<EFBFBD> envoy<6F>e
au serveur.
C : attente de l'<27>tablissement d'une CONNEXION vers le serveur. Le
serveur peut au plus avoir vu la tentative de connexion, mais
aucune donn<6E>e n'a <20>t<EFBFBD> <20>chang<6E>e.
H : attente, r<>ception ou traitement des en-t<>tes HTTP ("HEADERS").
D : transfert des DONNEES du serveur vers le client.
L : transfert des derni<6E>res ("LAST") donn<6E>es du proxy vers le client,
alors que le serveur a d<>j<EFBFBD> fini.
T : requ<71>te bloqu<71>e en mode "tarpit" par le proxy. Elle a <20>t<EFBFBD> maintenue
ouverte vers le client pendant toute la dur<75>e du contimeout ou
jusqu'<27> l'abandon de la part du client.
- : terminaison normale, apr<70>s fin de transfert des donn<6E>es.
- le troisi<73>me caract<63>re indique l'<27>ventuelle identification d'un cookie de
persistence (uniquement en mode HTTP) :
N : aucun cookie de persistence n'a <20>t<EFBFBD> pr<70>sent<6E>. C'est g<>n<EFBFBD>ralement le
cas sur les NOUVELLES connexions clients.
I : le client a pr<70>sent<6E> un cookie INVALIDE ne correspondant <20> aucun
serveur connu. Ceci peut <20>tre d<> <20> un changement de configuration
r<>cent, <20> des m<>langes de noms de cookies entre sites HTTP/HTTPS,
ou <20> une attaque.
D : le client a pr<70>sent<6E> un cookie correspondant <20> un serveur hors
d'usage ("DOWN"). Suivant l'option 'persist', il a <20>t<EFBFBD> renvoy<6F> vers
un autre serveur ou a tout de m<>me tent<6E> de se connecter sur celui
correspondant au cookie.
V : le client a pr<70>sent<6E> un cookie VALIDE et a pu se connecter au
serveur correspondant.
- : non appliquable (pas de cookie positionn<6E> dans la configuration).
- le dernier caract<63>re indique l'<27>ventuel traitement effectu<74> sur un cookie de
persistence retrourn<72> par le serveur (uniquement en mode HTTP) :
N : aucun cookie de persistance n'a <20>t<EFBFBD> fourni par le serveur, et aucun
n'a <20>t<EFBFBD> ins<6E>r<EFBFBD>.
I : aucun cookie de persistance n'a <20>t<EFBFBD> fourni par le serveur, et le
proxy en a INSERE un.
P : un cookie de persistence a <20>t<EFBFBD> fourni par le serveur et transmis
tel quel ("PASSIF").
R : le cookie retourn<72> par le serveur a <20>t<EFBFBD> REECRIT par le proxy.
D : le cookie pr<70>sent<6E> par le serveur a <20>t<EFBFBD> DETRUIT par le proxy pour
ne pas <20>tre retourn<72> au client.
- : non appliquable
La combinaison des deux premiers indicateurs fournit une grande quantiti<74>
d'informations sur ce qui se passait lorsque la session s'est termin<69>e. Cela
peut notamment aider <20> d<>tecter une saturation de serveur, des troubles r<>seau,
des <20>puisements de ressources syst<73>me locales, des attaques, etc...
Les combinaisons d'indicateurs les plus fr<66>quentes sont <20>num<75>r<EFBFBD>es ici.
Indic Raison
CR Le client a abandonn<6E> avant d'<27>mettre une requ<71>te compl<70>te. Il est
tr<74>s probable que la requ<71>te ait <20>t<EFBFBD> tap<61>e <20> la main dans un client
telnet et abort<72>e trop t<>t.
cR Le temps imparti au client a expir<69> avant r<>ception d'une requ<71>te
compl<70>te. Ceci est parfois caus<75> par un param<61>tre TCP MSS trop <20>lev<65>
sur le client pour des r<>seaux PPPoE sur ADSL qui ne peuvent pas
transporter des paquets entiers, ou par des clients qui <20>nvoient des
requ<71>tes <20> la main et ne tapent pas assez vite.
SC Le serveur a explicitement refus<75> la connexion (le proxy a re<72>u un
RST TCP ou un message ICMP en retour). Dans certains cas, cela peut
<20>tre la couche r<>seau qui indique au proxy que le serveur n'est pas
joignable (p.ex: pas de route, pas de r<>ponse ARP en local, etc...)
sC La connexion au serveur n'a pas pu s'<27>tablir dans le temps imparti.
PC Le proxy a refus<75> d'<27>tablir une connexion au serveur parce que le
nombre de connexions a atteint la limite 'maxconn' (global ou de
l'instance). Le param<61>tre 'maxconn' de l'instance pourrait <20>tre
augment<6E>, tout comme le param<61>tre 'maxconn' global.
RC Une ressource locale a <20>t<EFBFBD> <20>puis<69>e (m<>moire, sockets, ports source),
emp<6D>chant la connexion au serveur de s'<27>tablir. Les logs d'erreurs
diront pr<70>cis<69>ment ce qui manquait. Dans tous les cas, le seul rem<65>de
consiste <20> affiner le param<61>trage syst<73>me.
cH Le temps imparti au client a expir<69> au cours d'une requ<71>te POST. Ceci
est parfois caus<75> par un param<61>tre TCP MSS trop <20>lev<65> sur le client
pour des r<>seaux PPPoE sur ADSL qui ne peuvent pas transporter des
paquets entiers.
CH Le client a abandonn<6E> alors qu'il attendait un d<>but de r<>ponse de la
part du serveur. Cela peut <20>tre caus<75> par le serveur qui mettait trop
de temps <20> r<>pondre, ou par un client cliquant pr<70>cipitamment sur le
bouton 'Stop'.
CQ Le client a abandonn<6E> alors que sa session <20>tait mise en file
d'attente pour obtenir un serveur avec suffisamment de connexions
libres pour l'accepter. Cela signifie soit que l'ensemble des
serveurs <20>taient satur<75>s, soit que le serveur assign<67> a mis trop de
temps <20> r<>pondre.
CT Le client a abandonn<6E> alors que sa session <20>tait bloqu<71>e en mode
tarpit.
sQ La session a attendu trop longtemps en file d'attente et a <20>t<EFBFBD>
expir<69>e.
SH Le serveur a abort<72> brutalement alors qu'il devait envoyer ses
en-t<>tes. En g<>n<EFBFBD>ral, cela indique qu'il a crash<73>.
sH Le serveur n'a pas pu r<>pondre durant le temps imparti, ce qui montre
des transactions trop longues, probablement caus<75>es par un back-end
satur<75>. Les seules solutions sont de corriger le probl<62>me sur
l'application, d'accro<72>tre le param<61>tre 'srvtimeout' pour supporter
des attentes plus longues au risque que les clients abandonnent <20>
leur tour, ou bien d'ajouter des serveurs.
PR Le proxy a bloqu<71> une requ<71>te du client, soit <20> cause d'une syntaxe
HTTP invalide, auquel cas il a renvoy<6F> une erreur HTTP 400 au client,
soit <20> cause d'une requ<71>te validant un filtre d'interdiction, auquel
cas le proxy a renvoy<6F> une erreur HTTP 403.
PH Le proxy a bloqu<71> la r<>ponse du serveur parce qu'elle <20>tait invalide,
incompl<70>te, dangereuse ('cache control'), ou parce qu'elle validait
un filtre de s<>curit<69>. Dans tous les cas, une erreur HTTP 502 est
renvoy<6F>e au client.
PT Le proxy a bloqu<71> une requ<71>te du client et a maintenu sa connection
ouverte avant de lui retourner une erreur "500 server error". Rien
n'a <20>t<EFBFBD> envoy<6F> au serveur.
cD Le client n'a pas lu de donn<6E>es pendant le temps qui lui <20>tait
imparti. Ceci est souvent caus<75> par des probl<62>mes r<>seau c<>t<EFBFBD> client.
CD Le client a abort<72> sa connection de mani<6E>re inattendue pendant le
transfert des donn<6E>es. Ceci est provoqu<71> soit par le crash d'un
navigateur, ou par une session en HTTP keep-alive entre le serveur
et le client termin<69>e en premier par le client.
sD Le serveur n'a rien fait durant le temps imparti par le param<61>tre
'srvtimeout'. Ceci est souvent caus<75> par des timeouts trop courts
sur des <20>quipements de niveau 4 (firewalls, r<>partiteurs de charge)
situ<74>s entre le proxy et le serveur.
4.2.5) Caract<63>res non-imprimables
---------------------------------
Depuis la version 1.1.29, les caract<63>res non-imprimables ne sont plus envoy<6F>s
tels quels dans les lignes de logs, mais inscrits sous la forme de deux chiffres
hexad<EFBFBD>cimaux, pr<70>fix<69>s du caract<63>re d'<27>chappement '#'. Les seuls caract<63>res
dor<EFBFBD>navant logu<67>s tels quels sont compris entre 32 et 126. Bien <20>videmment, le
caract<EFBFBD>re d'<27>chappement '#' est lui-m<>me encod<6F> afin de lever l'ambiguit<69>. Il en
est de m<>me pour le caract<63>re '"', ainsi que les caract<63>res '{', '|' et '}' pour
les en-t<>tes.
4.2.6) Capture d'en-t<>tes HTTP et de cookies
--------------------------------------------
La version 1.1.23 a apport<72> la capture des cookies, et la version 1.1.29 la
capture d'en-t<>tes. Tout ceci est effectu<74> en utilisant le mot-cl<63> 'capture'.
Les captures de cookies facilitent le suivi et la reconstitution d'une session
utilisateur. La syntaxe est la suivante :
capture cookie <pr<70>fixe_cookie> len <longueur_capture>
Ceci activera la capture de cookies <20> la fois dans les requ<71>tes et dans les
r<EFBFBD>ponses. De cette mani<6E>re, il devient facile de d<>tecter lorsqu'un utilisateur
bascule sur une nouvelle session par exemple, car le serveur lui r<>assignera un
nouveau cookie.
Le premier cookie dont le nom commencera par <pr<70>fixe_cookie> sera captur<75>, et
transmis sous la forme "NOM=valeur", sans toutefois, exc<78>der <longueur_capture>
caract<EFBFBD>res (64 au maximum). Lorsque le nom du cookie est fixe et connu, on peut
le suffixer du signe "=" pour s'assurer qu'aucun autre cookie ne prendra sa
place dans les logs.
Exemples :
----------
# capture du premier cookie dont le nom commence par "ASPSESSION"
capture cookie ASPSESSION len 32
# capture du premier cookie dont le nom est exactement "vgnvisitor"
capture cookie vgnvisitor= len 32
Dans les logs, le champ pr<70>c<EFBFBD>dant l'indicateur de compl<70>tude contient le cookie
positionn<EFBFBD> par le serveur, pr<70>c<EFBFBD>d<EFBFBD> du cookie positionn<6E> par le client. Chacun
de ces champs est remplac<61> par le signe "-" lorsqu'aucun cookie n'est fourni
par le client ou le serveur, ou lorsque l'option est d<>sactiv<69>e..
Les captures d'en-t<>tes ont un r<>le compl<70>tement diff<66>rent. Elles sont utiles
pour suivre un identifiant de requ<71>te globalement unique positionn<6E> par un
autre proxy en amont, pour journaliser les noms de serveurs virtuels, les types
de clients web, la longueur des POST, les 'referrers', etc. Dans la r<>ponse, on
peut chercher des informations relatives <20> la longueur annonc<6E>e de la r<>ponse,
le fonctionnement attendu du cache, ou encore la localisation d'un objet en cas
de redirection. Tout comme pour les captures de cookies, il est possible
d'inclure les en-t<>tes de requ<71>tes et de r<>ponse simultan<61>ment. La syntaxe est
la suivante :
capture request header <nom> len <longueur max>
capture response header <nom> len <longueur max>
Note: Les noms d'en-t<>tes ne sont pas sensibles <20> la casse.
Exemples:
---------
# conserver le nom du serveur virtuel acc<63>d<EFBFBD> par le client
capture request header Host len 20
# noter la longueur des donn<6E>es envoy<6F>es dans un POST
capture request header Content-Length len 10
# noter le fonctionnement attendu du cache par le serveur
capture response header Cache-Control len 8
# noter l'URL de redirection
capture response header Location len 20
Les en-t<>tes non trouv<75>s sont logu<67>s <20> vide, et si un en-t<>te apparait plusieurs
fois, seule la derni<6E>re occurence sera conserv<72>e. Les en-t<>tes de requ<71>te sont
regroup<EFBFBD>s entre deux accolades '{' et '}' dans l'ordre de leur d<>claration, et
chacun s<>par<61>s par une barre verticale '|', sans aucun espace. Les en-t<>tes de
r<EFBFBD>ponse sont pr<70>sent<6E>s de la m<>me mani<6E>re, mais apr<70>s un espace suivant le bloc
d'en-t<>te de requ<71>te. Le tout pr<70>c<EFBFBD>de la requ<71>te HTTP. Exemple :
Config:
capture request header Host len 20
capture request header Content-Length len 10
capture request header Referer len 20
capture response header Server len 20
capture response header Content-Length len 10
capture response header Cache-Control len 8
capture response header Via len 20
capture response header Location len 20
Log :
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/0/162/+162 200 +350 - - ---- 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] relais-http netcache 0/0/0/182/+182 200 +279 - - ---- 0/0/0 0/0 {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/0/2/126/+128 200 +223 - - ---- 0/0/0 0/0 {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.2.7) Exemples de logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/0/7/147/6723 200 243 - - ---- 1/3/5 0/0"HEAD / HTTP/1.0"
=> requ<71>te longue (6.5s) saisie <20> la main avec un client telnet. Le serveur a
r<>pondu en 147 ms et la session s'est termin<69>e normalement ('----')
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/1230/7/147/6870 200 243 - - ---- 99/239/324 0/9 "HEAD / HTTP/1.0"
=> Idem, mais la requ<71>te a <20>t<EFBFBD> mise en attente dans la file globale derri<72>re
9 autres requ<71>tes d<>j<EFBFBD> pr<70>sentes, et y a attendu 1230 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/+30 200 +243 - - ---- 1/3/3 0/0 "GET /image.iso HTTP/1.0"
=> requ<71>te pour un long transfert. L'option 'logasap' <20>tait sp<73>cifi<66>e donc le
log a <20>t<EFBFBD> g<>n<EFBFBD>r<EFBFBD> juste avant le transfert de donn<6E>es. Le serveur a r<>pondu
en 14 ms, 243 octets d'en-t<>tes ont <20>t<EFBFBD> transf<73>r<EFBFBD>s au client, et le temps
total entre l'accept() et le premier octet de donn<6E>e est de 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/0/7/14/30 502 243 - - PH-- 0/2/3 0/0 "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> le proxy a bloqu<71> une r<>ponse du serveur soit <20> cause d'un filtre 'rspdeny'
ou 'rspideny', soit parce qu'il a d<>tect<63> un risque de fuite sensible
d'informations risquant d'<27>tre cach<63>es. Dans ce cas, la r<>ponse est
remplac<61>e par '502 bad gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 0/2/2 0/0 ""
=> Le client n'a pas envoy<6F> sa requ<71>te et a referm<72> la connexion lui-m<>me
('C---') au bout de 8.5s, alors que le relais attendait l'en-t<>te ('-R--').
Aucune connexion n'a <20>t<EFBFBD> envoy<6F>e vers le serveur.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 0/2/2 0/0 ""
=> Le client n'a pas envoy<6F> sa requ<71>te et son time-out a expir<69> ('c---') au
bout de 50s, alors que le relais attendait l'en-t<>te ('-R--'). Aucune
connexion n'a <20>t<EFBFBD> envoy<6F>e vers le serveur, mais le relais a tout de m<>me
pu renvoyer un message 408 au client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
=> log en mode 'tcplog'. Expiration du time-out c<>t<EFBFBD> client ('cD') au bout de
5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 115/202/205 0/0 "HEAD / HTTP/1.0"
=> La requ<71>te client met 3s <20> entrer (peut-<2D>tre un probl<62>me r<>seau), et la
connexion ('SC--') vers le serveur <20>choue au bout de 4 tentatives de 2
secondes (retries 3 dans la conf), puis un code 503 est retourn<72> au
client. Il y avait 115 connexions sur ce serveur, 202 connexions sur cette
instance, et 205 sur l'ensemble des instances pour ce processus. Il est
possible que le serveur ait refus<75> la connexion parce qu'il y en avait
d<>j<EFBFBD> trop d'<27>tablies.
4.3) Modification des en-t<>tes HTTP
----------------------------------
En mode HTTP uniquement, il est possible de remplacer certains en-t<>tes dans la
requ<EFBFBD>te et/ou la r<>ponse <20> partir d'expressions r<>guli<6C>res. Il est <20>galement
possible de bloquer certaines requ<71>tes en fonction du contenu des en-t<>tes ou
de la requ<71>te. Une limitation cependant : les en-t<>tes fournis au milieu de
connexions persistentes (keep-alive) ne sont pas vus car ils sont consid<69>r<EFBFBD>s
comme faisant partie des <20>changes de donn<6E>es cons<6E>cutifs <20> la premi<6D>re requ<71>te.
Les donn<6E>es ne sont pas affect<63>es, ceci ne s'applique qu'aux en-t<>tes.
La syntaxe est :
reqadd <string> pour ajouter un en-t<>te dans la requ<71>te
reqrep <search> <replace> pour modifier la requ<71>te
reqirep <search> <replace> idem sans distinction majuscules/minuscules
reqdel <search> pour supprimer un en-t<>te dans la requ<71>te
reqidel <search> idem sans distinction majuscules/minuscules
reqallow <search> autoriser la requ<71>te si un en-t<>te valide <search>
reqiallow <search> idem sans distinction majuscules/minuscules
reqdeny <search> interdire la requ<71>te si un en-t<>te valide <search>
reqideny <search> idem sans distinction majuscules/minuscules
reqpass <search> inhibe ces actions sur les en-t<>tes validant <search>
reqipass <search> idem sans distinction majuscules/minuscules
reqtarpit <search> bloquer et maintenir une request validant <search>
reqitarpit <search> idem sans distinction majuscules/minuscules
rspadd <string> pour ajouter un en-t<>te dans la r<>ponse
rsprep <search> <replace> pour modifier la r<>ponse
rspirep <search> <replace> idem sans distinction majuscules/minuscules
rspdel <search> pour supprimer un en-t<>te dans la r<>ponse
rspidel <search> idem sans distinction majuscules/minuscules
rspdeny <search> remplace la r<>ponse par un HTTP 502 si un
en-t<>te valide <search>
rspideny <search> idem sans distinction majuscules/minuscules
2005-12-17 11:21:26 +00:00
<search> est une expression r<>guli<6C>re compatible POSIX regexp supportant le
groupage par parenth<74>ses (sans les '\'). Les espaces et autres s<>parateurs
doivent <20>tres pr<70>c<EFBFBD>d<EFBFBD>s d'un '\' pour ne pas <20>tre confondus avec la fin de la
cha<EFBFBD>ne. De plus, certains caract<63>res sp<73>ciaux peuvent <20>tre pr<70>c<EFBFBD>d<EFBFBD>s d'un
backslach ('\') :
\t pour une tabulation
\r pour un retour charriot
\n pour un saut de ligne
\ pour diff<66>rencier un espace d'un s<>parateur
\# pour diff<66>rencier un di<64>se d'un commentaire
\\ pour utiliser un backslash dans la regex
\\\\ pour utiliser un backslash dans le texte
\xXX pour un caract<63>re sp<73>cifique XX (comme en C)
<replace> contient la cha<68>ne rempla<6C>ant la portion v<>rifi<66>e par l'expression.
Elle peut inclure les caract<63>res sp<73>ciaux ci-dessus, faire r<>f<EFBFBD>rence <20> un
groupe d<>limit<69> par des parenth<74>ses dans l'expression r<>guli<6C>re, par sa
position num<75>rale. Les positions vont de 0 <20> 9, et sont cod<6F>es par un '\'
suivi du chiffre d<>sir<69> (0 d<>signant la ligne compl<70>te). Il est <20>galement
possible d'ins<6E>rer un caract<63>re non imprimable (utile pour le saut de ligne)
inscrivant '\x' suivi du code hexad<61>cimal de ce caract<63>re (comme en C).
<string> repr<70>sente une cha<68>ne qui sera ajout<75>e syst<73>matiquement apr<70>s la
derni<EFBFBD>re ligne d'en-t<>te.
Remarques :
-----------
- la premi<6D>re ligne de la requ<71>te et celle de la r<>ponse sont trait<69>es comme
des en-t<>tes, ce qui permet de r<><72>crire des URL et des codes d'erreur.
- 'reqrep' est l'<27>quivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
'srvexp'. Ces noms sont toujours support<72>s mais d<>conseill<6C>s.
- pour des raisons de performances, le nombre total de caract<63>res ajout<75>s sur
une requ<71>te ou une r<>ponse est limit<69> <20> 4096 depuis la version 1.1.5 (cette
limite <20>tait <20> 256 auparavant). Cette valeur est modifiable dans le code.
Pour un usage temporaire, on peut gagner de la place en supprimant quelques
en-t<>tes inutiles avant les ajouts.
- une requ<71>te bloqu<71>e produira une r<>ponse "HTTP 403 forbidden" tandis qu'une
r<>ponse bloqu<71>e produira une r<>ponse "HTTP 502 Bad gateway".
- une requ<71>te bloqu<71>e par 'reqtarpit' sera maintenue pendant une dur<75>e <20>gale
au param<61>tre 'contimeout', ou jusqu'<27> l'abandon du client. Rien ne sera
envoy<6F> au serveur. Lorsque le temps allou<6F> expire, le proxy r<>pondra avec
une r<>ponse "500 server error" de sorte que l'attaquant ne suspecte pas
qu'il ait <20>t<EFBFBD> bloqu<71>. Les logs rapporteront aussi ce code 500, mais les
flags de terminaison indiqueront "PT".
2005-12-17 11:21:26 +00:00
Exemples :
----------
###### a few examples ######
# rewrite 'online.fr' instead of 'free.fr' for GET and POST requests
reqrep ^(GET\ .*)(.free.fr)(.*) \1.online.fr\3
reqrep ^(POST\ .*)(.free.fr)(.*) \1.online.fr\3
# force proxy connections to close
reqirep ^Proxy-Connection:.* Proxy-Connection:\ close
# rewrite locations
rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
###### A full configuration being used on production ######
# Every header should end with a colon followed by one space.
reqideny ^[^:\ ]*[\ ]*$
# block Apache chunk exploit
reqideny ^Transfer-Encoding:[\ ]*chunked
reqideny ^Host:\ apache-
# block annoying worms that fill the logs...
reqideny ^[^:\ ]*\ .*(\.|%2e)(\.|%2e)(%2f|%5c|/|\\\\)
reqideny ^[^:\ ]*\ ([^\ ]*\ [^\ ]*\ |.*%00)
reqideny ^[^:\ ]*\ .*<script
reqideny ^[^:\ ]*\ .*/(root\.exe\?|cmd\.exe\?|default\.ida\?)
# tarpit attacks on the login page.
reqtarpit ^[^:\ ]*\ .*\.php?login=[^0-9]
# allow other syntactically valid requests, and block any other method
reqipass ^(GET|POST|HEAD|OPTIONS)\ /.*\ HTTP/1\.[01]$
reqipass ^OPTIONS\ \\*\ HTTP/1\.[01]$
reqideny ^[^:\ ]*\
# force connection:close, thus disabling HTTP keep-alive
option httpclos
# change the server name
rspidel ^Server:\
rspadd Server:\ Formilux/0.1.8
2005-12-17 11:21:26 +00:00
De plus, l'option 'forwardfor' ajoute l'adresse IP du client dans un champ
'X-Forwarded-For' de la requ<71>te, ce qui permet <20> un serveur web final de
conna<EFBFBD>tre l'adresse IP du client initial. Depuis la version 1.3.8, il est
possible de pr<70>ciser le mot-cl<63> "except" suivi d'une adresse ou un r<>seau
IP source pour lequel l'ent<6E>te ne sera pas ajout<75>. C'est tr<74>s pratique dans le
cas o<> un autre reverse-proxy ajoutant d<>j<EFBFBD> l'ent<6E>te est install<6C> sur la m<>me
machine ou dans une DMZ connue. Le cas le plus fr<66>quent est li<6C> <20> l'utilisation
de stunnel en local.
Enfin, l'option 'httpclose' apparue dans la version 1.1.28/1.2.1 supprime tout
en-t<>te de type 'Connection:' et ajoute 'Connection: close' dans les deux sens.
Ceci simplifie la d<>sactivation du keep-alive HTTP par rapport <20> l'ancienne
m<EFBFBD>thode impliquant 4 r<>gles.
Exemple :
---------
listen http_proxy 0.0.0.0:80
mode http
log global
option httplog
option dontlognull
option forwardfor except 127.0.0.1/8
option httpclose
Notons que certains serveurs HTTP ne referment pas n<>cessairement la session
TCP en fin de traitement lorsqu'ils re<72>oivent un ent<6E>te 'Connection: close',
ce qui se traduit par des grands nombres de sessions <20>tablies et des temps
globaux tr<74>s longs sur les requ<71>tes. Pour contourner ce probl<62>me, la version
1.2.9 apporte une nouvelle option 'forceclose' qui referme la connexion sortant
vers le serveur d<>s qu'il commence <20> r<>pondre et seulement si le tampon de
requ<EFBFBD>te est vide. Attention toutefois <20> ne PAS utiliser cette option si des
m<EFBFBD>thodes CONNECT sont attendues entre le client et le serveur. L'option
'forceclose' implique l'option 'httpclose'.
Exemple :
---------
listen http_proxy 0.0.0.0:80
mode http
log global
option httplog
option dontlognull
option forwardfor
option forceclose
4.4) R<>partition avec persistence
---------------------------------
La combinaison de l'insertion de cookie avec la r<>partition de charge interne
permet d'assurer une persistence dans les sessions HTTP d'une mani<6E>re
pratiquement transparente pour les applications. Le principe est simple :
- attribuer une valeur d'un cookie <20> chaque serveur
- effectuer une r<>partition interne
- ins<6E>rer un cookie dans les r<>ponses issues d'une r<>partition uniquement,
et faire en sorte que des caches ne m<>morisent pas ce cookie.
- cacher ce cookie <20> l'application lors des requ<71>tes ult<6C>rieures.
2005-12-17 11:21:26 +00:00
Exemple :
---------
listen application 0.0.0.0:80
mode http
cookie SERVERID insert nocache indirect
balance roundrobin
server srv1 192.168.1.1:80 cookie server01 check
server srv2 192.168.1.2:80 cookie server02 check
2005-12-17 11:21:26 +00:00
L'autre solution apport<72>e par les versions 1.1.30 et 1.2.3 est de r<>utiliser un
cookie en provenance du serveur et de lui pr<70>fixer l'identifiant du serveur.
Dans ce cas, ne pas oublier de forcer le mode "httpclose" pour emp<6D>cher le
client et le serveur de travailler en mode "keep-alive" afin que le proxy
puisse corriger le nom du cookie dans toutes les futures requ<71>tes.
listen application 0.0.0.0:80
mode http
cookie JSESSIONID prefix
balance roundrobin
server srv1 192.168.1.1:80 cookie srv1 check
server srv2 192.168.1.2:80 cookie srv2 check
option httpclose
4.5) Protection contre les fuites d'informations du serveur
-----------------------------------------------------------
Dans les versions 1.1.28 et 1.2.1, une nouvelle option 'checkcache' a <20>t<EFBFBD>
cr<EFBFBD><EFBFBD>e. Elle sert <20> inspecter minutieusement les en-t<>tes 'Cache-control',
'Pragma', et 'Set-cookie' dans les r<>ponses serveur pour d<>terminer s'il y a
un risque de cacher un cookie sur un proxy c<>t<EFBFBD> client. Quand cette option est
activ<EFBFBD>e, les seules r<>ponses qui peuvent <20>tre retourn<72>es au client sont :
- toutes celles qui n'ont pas d'en-t<>te 'Set-cookie' ;
- toutes celles qui ont un code de retour autre que 200, 203, 206, 300, 301,
410, sauf si le serveur a positionn<6E> un en-t<>te 'Cache-control: public' ;
- celles qui font suite <20> une requ<71>te POST, sauf si le serveur a positionn<6E>
un en-t<>te 'Cache-control: public' ;
- celles qui ont un en-t<>te 'Pragma: no-cache' ;
- celles qui ont un en-t<>te 'Cache-control: private' ;
- celles qui ont un en-t<>te 'Cache-control: no-store' ;
- celles qui ont un en-t<>te 'Cache-control: max-age=0' ;
- celles qui ont un en-t<>te 'Cache-control: s-maxage=0' ;
- celles qui ont un en-t<>te 'Cache-control: no-cache' ;
- celles qui ont un en-t<>te 'Cache-control: no-cache="set-cookie"' ;
- celles qui ont un en-t<>te 'Cache-control: no-cache="set-cookie,'
(autorisant d'autres champs apr<70>s set-cookie).
Si une r<>ponse ne respecte pas ces pr<70>-requis, alors elle sera bloqu<71>e de la
m<EFBFBD>me mani<6E>re que s'il s'agissait d'un filtre 'rspdeny', avec en retour un
message "HTTP 502 bad gateway". L'<27>tat de session montre "PH--" ce qui veut
dire que c'est le proxy qui a bloqu<71> la r<>ponse durant le traitement des
en-t<>tes. De plus, un message d'alerte sera envoy<6F> dans les logs de sorte que
l'administrateur sache qu'il y a une action correctrice <20> entreprendre.
4.6) Personalisation des erreurs
--------------------------------
Certaines situations conduisent <20> retourner une erreur HTTP au client :
- requ<71>te invalide ou trop longue => code HTTP 400
- requ<71>te mettant trop de temps <20> venir => code HTTP 408
- requ<71>te interdite (bloqu<71>e par un reqideny) => code HTTP 403
- erreur interne du proxy => code HTTP 500
- le serveur a retourn<72> une r<>ponse incompl<70>te ou invalide => code HTTP 502
- aucun serveur disponible pour cette requ<71>te => code HTTP 503
- le serveur n'a pas r<>pondu dans le temps imparti => code HTTP 504
Un message d'erreur succint tir<69> de la RFC accompagne ces codes de retour.
Cependant, en fonction du type de client<6E>le, on peut pr<70>f<EFBFBD>rer retourner des
pages personnalis<69>es. Ceci est possible de deux mani<6E>res, l'une reposant sur
une redirection vers un serveur connu, et l'autre consistant <20> retourner un
fichier local.
4.6.1) Redirection
------------------
Une redirection d'erreur est assur<75>e par le biais de la commande "errorloc" :
errorloc <code_HTTP> <location>
Au lieu de g<>n<EFBFBD>rer une erreur HTTP <code_HTTP> parmi les codes cit<69>s ci-dessus,
le proxy g<>n<EFBFBD>rera un code de redirection temporaire (HTTP 302) vers l'adresse
d'une page pr<70>cis<69>e dans <location>. Cette adresse peut <20>tre relative au site,
ou absolue. Comme cette r<>ponse est tra<72>t<EFBFBD>e par le navigateur du client
lui-m<>me, il est indispensable que l'adresse fournie lui soit accessible.
Exemple :
---------
listen application 0.0.0.0:80
errorloc 400 /badrequest.html
errorloc 403 /forbidden.html
errorloc 408 /toolong.html
errorloc 500 http://haproxy.domain.net/bugreport.html
errorloc 502 http://192.168.114.58/error50x.html
errorloc 503 http://192.168.114.58/error50x.html
errorloc 504 http://192.168.114.58/error50x.html
Note: la RFC2616 stipule qu'un client doit r<>utiliser la m<>me m<>thode pour
acc<EFBFBD>der <20> l'URL de redirection que celle qui l'a retourn<72>e, ce qui pose des
probl<EFBFBD>mes avec les requ<71>tes POST. Le code de retour 303 a <20>t<EFBFBD> cr<63><72> expr<70>s pour
r<EFBFBD>gler ce probl<62>me, indiquant au client qu'il doit acc<63>der <20> l'URL retourn<72>e
dans le champ Location avec la m<>thode GET uniquement. Seulement, certains
navigateurs ant<6E>rieurs <20> HTTP/1.1 ne connaissent pas ce code de retour. De
plus, la plupart des navigateurs se comportent d<>j<EFBFBD> avec le code 302 comme ils
devraient le faire avec le 303. Donc, dans le but de laisser le choix <20>
l'utilisateur, les versions 1.1.31 et 1.2.5 apportent deux nouvelles commandes
visant <20> remplacer 'errorloc' : 'errorloc302' et 'errorloc303'.
Leur usage non ambig<69> est recommand<6E> <20> la place de la commande 'errorloc' (qui
utilise toujours 302). Dans le doute, pr<70>f<EFBFBD>rez l'utilisation de 'errorloc303'
d<EFBFBD>s que vous savez que vos clients supportent le code de retour HTTP 303.
4.6.2) Fichiers locaux
----------------------
Parfois il est souhaitable de changer l'erreur retourn<72>e sans recourir <20> des
redirections. La seconde m<>thode consiste <20> charger des fichiers locaux lors
du d<>marrage et <20> les envoyer en guise de pur contenu HTTP en cas d'erreur.
C'est ce que fait le mot cl<63> 'errorfile'.
Attention, il y a des pi<70>ges <20> prendre en compte :
- les fichiers sont charg<72>s durant l'analyse de la configuration, avant de
faire le chroot(). Donc ils sont relatifs au syst<73>me de fichiers r<>el. Pour
cette raison, il est recommand<6E> de toujours passer un chemin absolu vers ces
fichiers.
- le contenu de ces fichiers n'est pas du HTML mais vraiment du protocole HTTP
avec potentiellement un corps HTML. Donc la premi<6D>re ligne et les en-t<>tes
sont obligatoires. Id<49>alement, chaque ligne dans la partie HTTP devrait se
terminer par un CR-LF pour un maximum de compatibilit<69>.
- les r<>ponses sont limit<69>es <20> une taille de buffer (BUFSIZE), g<>n<EFBFBD>ralement 8
ou 16 ko.
- les r<>ponses ne devraient pas inclure de r<>f<EFBFBD>rences aux serveurs locaux,
afin de ne pas risquer de cr<63>er des boucles infinies sur le navigateur dans
le cas d'une panne locale.
Exemple :
---------
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
4.7) Changement des valeurs par d<>faut
--------------------------------------
Dans la version 1.1.22 est apparue la notion de valeurs par d<>faut, ce qui
<EFBFBD>vite de r<>p<EFBFBD>ter des param<61>tres communs <20> toutes les instances, tels que les
timeouts, adresses de log, modes de fonctionnement, etc.
Les valeurs par d<>faut sont positionn<6E>es dans la derni<6E>re section 'defaults'
pr<EFBFBD>c<EFBFBD>dent l'instance qui les utilisera. On peut donc mettre autant de sections
'defaults' que l'on veut. Il faut juste se rappeler que la pr<70>sence d'une telle
section implique une annulation de tous les param<61>tres par d<>faut positionn<6E>s
pr<EFBFBD>c<EFBFBD>demment, dans le but de les remplacer.
La section 'defaults' utilise la m<>me syntaxe que la section 'listen', aux
param<EFBFBD>tres pr<70>s qui ne sont pas support<72>s. Le mot cl<63> 'defaults' peut accepter
un commentaire en guise param<61>tre.
Dans la version 1.1.28/1.2.1, seuls les param<61>tres suivants peuvent <20>tre
positionn<EFBFBD>s dans une section 'defaults' :
- log (le premier et le second)
- mode { tcp, http, health }
- balance { roundrobin }
- disabled (pour d<>sactiver toutes les instances qui suivent)
- enabled (pour faire l'op<6F>ration inverse, mais c'est le cas par d<>faut)
- contimeout, clitimeout, srvtimeout, grace, retries, maxconn
- option { redispatch, transparent, keepalive, forwardfor, logasap, httpclose,
checkcache, httplog, tcplog, dontlognull, persist, httpchk }
- redispatch, redisp, transparent, source { addr:port }
- cookie, capture
- errorloc
Ne sont pas support<72>s dans cette version, les adresses de dispatch et les
configurations de serveurs, ainsi que tous les filtres bas<61>s sur les
expressions r<>guli<6C>res :
- dispatch, server,
- req*, rsp*
Enfin, il n'y a pas le moyen, pour le moment, d'invalider un param<61>tre bool<6F>en
positionn<EFBFBD> par d<>faut. Donc si une option est sp<73>cifi<66>e dans les param<61>tres par
d<EFBFBD>faut, le seul moyen de la d<>sactiver pour une instance, c'est de changer les
param<EFBFBD>tres par d<>faut avant la d<>claration de l'instance.
Exemples :
----------
defaults applications TCP
log global
mode tcp
balance roundrobin
clitimeout 180000
srvtimeout 180000
contimeout 4000
retries 3
redispatch
listen app_tcp1 10.0.0.1:6000-6063
server srv1 192.168.1.1 check port 6000 inter 10000
server srv2 192.168.1.2 backup
listen app_tcp2 10.0.0.2:6000-6063
server srv1 192.168.2.1 check port 6000 inter 10000
server srv2 192.168.2.2 backup
defaults applications HTTP
log global
mode http
option httplog
option forwardfor
option dontlognull
balance roundrobin
clitimeout 20000
srvtimeout 20000
contimeout 4000
retries 3
listen app_http1 10.0.0.1:80-81
cookie SERVERID postonly insert indirect
capture cookie userid= len 10
server srv1 192.168.1.1:+8000 cookie srv1 check port 8080 inter 1000
server srv1 192.168.1.2:+8000 cookie srv2 check port 8080 inter 1000
defaults
# section vide qui annule tous les param<61>tes par d<>faut.
2006-05-21 21:05:54 +00:00
4.8) Rapport d'<27>tat sous forme de page HTML
-------------------------------------------
Avec la version 1.2.14, il devient possible pour haproxy d'interceptre des
requ<EFBFBD>tes pour une URI particuli<6C>re et de retourner un rapport complet d'<27>tat de
l'activit<69> du proxy, et des statistiques sur les serveurs. Ceci est disponible
via le mot cl<63> "stats" associ<63> <20> n'importe laquelle de ces options :
- stats enable
- stats uri <uri prefix>
- stats realm <authentication realm>
- stats auth <user:password>
- stats scope <proxy_id> | '.'
Par d<>faut, le rapport est d<>sactiv<69>. Le fait de sp<73>cifier une des combinaision
ci-dessus active le rapport pour l'instance de proxy qui le r<>f<EFBFBD>rence. La
solution la plus simple est d'utiliser "stats enable" qui activera le rapport
avec les param<61>tres par d<>faut suivant :
- default URI : "/haproxy?stats" (CONFIG_STATS_DEFAULT_URI)
- default auth : non sp<73>cifi<66> (pas d'authentication)
- default realm : "HAProxy Statistics" (CONFIG_STATS_DEFAULT_REALM)
- default scope : non specifi<66> (acc<63>s <20> toutes les instances)
L'option "stats uri <uri_prefix>" permet d'intercepter un autre pr<70>fixe d'URI
que celui par d<>faut. Noter que n'importe quelle URI qui COMMENCE avec cette
cha<EFBFBD>ne sera valid<69>e. Par exemple, une instance pourrait <20>tre d<>di<64>e <20> la page
d'<27>tat seulement et r<>pondre <20> toute URI.
Example :
---------
# intercepte n'importe quelle URI et retourne la page d'<27>tat.
listen stats :8080
mode http
stats uri /
L'option "stats auth <user:password>" active l'authentification "Basic" et
ajoute un couple "user:password" valide <20> la liste des comptes autoris<69>s.
L'utilisateur <user> et le mot de passe <password> doivent <20>tre pr<70>cis<69>s
en clair dans le fichier de configuration, et comme ceci est de
l'authentification HTTP "Basic", il faut <20>tre conscient qu'ils transitent en
clair sur le r<>seau, donc il ne faut pas utiliser de compte sensible. La liste
est illimit<69>e dans le but de pouvoir fournir des acc<63>s facilement <20> des
d<EFBFBD>veloppeurs ou <20> des clients.
L'option "stats realm <realm>" d<>finit le "domaine" ("realm") de validit<69> du
mot de passe qui sera pr<70>sent<6E> dans la bo<62>te de dialogue du navigateur
lorsqu'il demandera un compte utilisateur et un mot de passe. Il est important
de s'assurer que celui-ci soit diff<66>rent de ceux utilis<69>s par l'application,
autrement le navigateur tentera d'en utiliser un cach<63> depuis l'application.
Noter que les espaces dans le nom de "realm" doivent <20>tre prot<6F>g<EFBFBD>s par un
backslash ('\').
L'option "stats scope <proxy_id>" limite la port<72>e du rapport d'<27>tat. Par
d<EFBFBD>faut, toutes les instances proxy sont list<73>es. Mais dans certaines
circonstances, il serait pr<70>f<EFBFBD>rable de ne lister que certains proxies ou
simplement le proxy courant. C'est ce que fait cette option. Le nom sp<73>cial "."
(un simple point) r<>f<EFBFBD>rence le proxy courant. Cette option peut <20>tre r<>p<EFBFBD>t<EFBFBD>e
autant de fois que n<>cessaire pour autoriser d'autres proxies, m<>me pour des
noms r<>f<EFBFBD>renc<6E>s plus loin dans la configuration ou bien des noms qui n'existent
pas encore. Le nom pr<70>cis<69> est celui qui apparait apr<70>s le mot cl<63> "listen".
Exemple :
---------
# simple application embarquant la page d'<27>tat authentifi<66>e
listen app1 192.168.1.100:80
mode http
option httpclose
balance roundrobin
cookie SERVERID postonly insert indirect
server srv1 192.168.1.1:8080 cookie srv1 check inter 1000
server srv1 192.168.1.2:8080 cookie srv2 check inter 1000
stats uri /my_stats
stats realm Statistics\ for\ MyApp1-2
stats auth guest:guest
stats auth admin:AdMiN123
stats scope .
stats scope app2
# simple application embarquant la page d'<27>tat sans authentification
listen app2 192.168.2.100:80
mode http
option httpclose
balance roundrobin
cookie SERVERID postonly insert indirect
server srv1 192.168.2.1:8080 cookie srv1 check inter 1000
server srv1 192.168.2.2:8080 cookie srv2 check inter 1000
stats uri /my_stats
stats realm Statistics\ for\ MyApp2
stats scope .
listen admin_page :8080
mode http
stats uri /my_stats
stats realm Global\ statistics
stats auth admin:AdMiN123
Notes :
-------
- les options "stats" peuvent aussi <20>tre sp<73>cifi<66>es dans une section
"defaults", auquel cas la m<>me configuration exactement sera fournie <20>
toutes les instances suivantes, d'o<> l'utilit<69> du scope ".". Toutefois, si
une instance red<65>finit n'importe quel param<61>tre "stats", alors les d<>fauts
ne lui seront pas appliqu<71>s.
- l'authentification "Basic" est tr<74>s simpliste et non s<>curis<69>e contre la
capture r<>seau. Aucun mot de passe sensible ne doit <20>tre utilis<69>, et il
est bon de savoir qu'il n'existe pas de moyen de le supprimer du navigateur
apr<70>s usage, donc il sera envoy<6F> tel quel <20> l'application au cours des
acc<63>s successifs.
- Il est tr<74>s important de pr<70>ciser l'option "httpclose", sinon le proxy ne
sera pas en mesure de d<>tecter les URI dans les sessions keep-alive
maintenues entre le navigateur et les serveurs, donc les URI de stats
seront transmises telles quelles aux serveurs comme si l'option n'<27>tait
pas pr<70>cis<69>e.
5) Listes d'acc<63>s
=================
Avec la version 1.3.10, un nouveau concept de listes d'acc<63>s (ACL) a vu le
jour. Comme il n'<27>tait pas n<>cessaire de r<>inventer la roue, et du fait que
toutes les r<>flexions pass<73>es aboutissaient <20> des propositions non
satisfaisantes, il a finalement <20>t<EFBFBD> d<>cid<69> que quelque chose de proche de ce
que Squid offre serait un bon compromis entre une richesse fonctionnelle et une
facilit<EFBFBD> d'utilisation
Le principe est tr<74>s simple : les ACLs sont d<>clar<61>es avec un nom, un test et
une liste de valeurs valides <20> tester. Des conditions sont appliqu<71>es sur
diverses actions, et ces conditions effectuent un ET logique entre les ACLs. La
condition n'est donc valid<69>e que si toutes les ACLs sont vraies.
Il est <20>galement possible d'utiliser le mot r<>serv<72> "OR" dans les conditions,
et il est possible pour une ACL d'<27>tre sp<73>cifi<66>e plusieurs fois, m<>me avec des
tests diff<66>rents, auquel cas le premier test r<>ussi validera l'ACL.
Au stade de la version 1.3.12, seuls les tests suivants ont <20>t<EFBFBD> impl<70>ment<6E>s :
Niveaux 3/4 :
src <ipv4_address>[/mask] ... : match IPv4 source address
dst <ipv4_address>[/mask] ... : match IPv4 destination address
src_port <range> ... : match source port range
dst_port <range> ... : match destination port range
dst_conn <range> ... : match #connections on frontend
Niveau 7 :
method <HTTP method> ... : match HTTP method
req_ver <1.0|1.1> ... : match HTTP request version
resp_ver <1.0|1.1> ... : match HTTP response version
status <range> ... : match HTTP response status code in range
url <string> ... : exact string match on URI
url_reg <regex> ... : regex string match on URI
url_beg <string> ... : true if URI begins with <string>
url_end <string> ... : true if URI ends with <string>
url_sub <string> ... : true if URI contains <string>
url_dir <string> ... : true if URI contains <string> between slashes
url_dom <string> ... : true if URI contains <string> between slashes or dots
Une plage ('range') est constitu<74>e d'un ou deux entiers qui peuvent <20>tre
pr<EFBFBD>fix<EFBFBD>s d'un op<6F>rateur. La syntaxe est :
[<op>] <min>[:<max>]
Avec <op> pouvant <20>tre :
'eq' : la valeur doit <20>galer <min> ou <20>tre comprise entre <min> et <max>
'le' : la valeur doit <20>tre inf<6E>rieure ou <20>gale <20> <min>
'lt' : la valeur doit <20>tre strictement inf<6E>rieure <20> <min>
'ge' : la valeur doit <20>tre sup<75>rieure ou <20>gale <20> <min>
'gt' : la valeur doit <20>tre strictement sup<75>rieure <20> <min>
Lorsqu'aucun op<6F>rateur n'est d<>fini, 'eq' est employ<6F>. Noter que lorsqu'un
op<EFBFBD>rateur est sp<73>cifi<66>, il s'applique <20> toutes les plages de valeurs suivantes
jusqu'<27> la fin de la ligne ou bien jusqu'<27> ce qu'un nouvel op<6F>rateur soit
pr<EFBFBD>cis<EFBFBD>. Exemple :
acl status_error status 400:599
acl saturated_frt dst_conn ge 1000
acl invalid_ports src_port lt 512 ge 65535
D'autres tests arrivent (ent<6E>tes, cookies, heure, authentification), c'est
juste une question de temps. Il est aussi pr<70>vu de permettre de lire les
valeurs depuis un fichier, ainsi que d'ignorer la casse pour certains tests.
La seule commande supportant les conditions d'ACL <20> ce jour est la nouvelle
commande "block" qui bloque une requ<71>te et retourne un statut 403 si sa
condition est valid<69>e (cas du "if") ou invalid<69>e (cas du "unless").
Exemple :
---------
acl options_uris url *
acl meth_option method OPTIONS
acl http_1.1 req_ver 1.1
acl allowed_meth method GET HEAD POST OPTIONS CONNECT
acl connect_meth method CONNECT
acl proxy_url url_beg http://
# block if reserved URI "*" used with a method other than "OPTIONS"
block if options_uris !meth_option
# block if the OPTIONS method is used with HTTP 1.0
block if meth_option !http_1.1
# allow non-proxy url with anything but the CONNECT method
block if !connect_meth !proxy_url
# block all unknown methods
block unless allowed_meth
Note: Cette documentation est embryonnaire mais doit permettre de d<>marrer et
surtout d'avancer sur le projet sans <20>tre trop ralenti par la documentation.
=======================
| Param<61>trage syst<73>me |
=======================
2005-12-17 11:21:26 +00:00
Sous Linux 2.4
==============
-- cut here --
#!/bin/sh
# set this to about 256/4M (16384 for 256M machine)
MAXFILES=16384
echo $MAXFILES > /proc/sys/fs/file-max
ulimit -n $MAXFILES
if [ -e /proc/sys/net/ipv4/ip_conntrack_max ]; then
echo 65536 > /proc/sys/net/ipv4/ip_conntrack_max
fi
if [ -e /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait ]; then
# 30 seconds for fin, 15 for time wait
echo 3000 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait
echo 1500 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_time_wait
echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_invalid_scale
echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_out_of_window
fi
2005-12-17 11:21:26 +00:00
echo 1024 60999 > /proc/sys/net/ipv4/ip_local_port_range
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
2005-12-17 11:21:26 +00:00
echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets
echo 262144 > /proc/sys/net/ipv4/tcp_max_orphans
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
2005-12-17 11:21:26 +00:00
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 0 > /proc/sys/net/ipv4/tcp_timestamps
echo 0 > /proc/sys/net/ipv4/tcp_ecn
echo 1 > /proc/sys/net/ipv4/tcp_sack
echo 0 > /proc/sys/net/ipv4/tcp_dsack
# auto-tuned on 2.4
#echo 262143 > /proc/sys/net/core/rmem_max
#echo 262143 > /proc/sys/net/core/rmem_default
echo 16384 65536 524288 > /proc/sys/net/ipv4/tcp_rmem
echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
-- cut here --
2005-12-17 11:21:26 +00:00
Sous FreeBSD
============
Un port de HA-Proxy sous FreeBSD est d<>sormais disponible, gr<67>ce <20>
Clement Laforet <sheepkiller@cultdeadsheep.org>.
Pour plus d'informations :
http://www.freebsd.org/cgi/url.cgi?ports/net/haproxy/pkg-descr
http://www.freebsd.org/cgi/cvsweb.cgi/ports/net/haproxy/
http://www.freshports.org/net/haproxy
2005-12-17 11:21:26 +00:00
-- fin --