* released 1.1.24

* if a client sent a full request then shut its write connection down, then
  the request was aborted. This case was detected only when using haproxy
  both as health-check client and as a server.
* if 'option httpchk' is used in a 'health' mode server, then responses will
  change from 'OK' to 'HTTP/1.0 200 OK'.
* fixed a Linux-only bug in case of HTTP server health-checks, where a single
  server response followed by a close could be ignored, and the server seen
  as failed.
* renamed 'haproxy.txt' to 'haproxy-fr.txt'
* large documentation and examples cleanups
This commit is contained in:
willy tarreau 2005-12-17 14:10:59 +01:00
parent eedaa9f220
commit 197e8ec2c3
6 changed files with 393 additions and 307 deletions

View File

@ -1,6 +1,16 @@
ChangeLog : ChangeLog :
=========== ===========
2003/09/21 : 1.1.24
- if a client sent a full request then shut its write connection down, then
the request was aborted. This case was detected only when using haproxy
both as health-check client and as a server.
- if 'option httpchk' is used in a 'health' mode server, then responses will
change from 'OK' to 'HTTP/1.0 200 OK'.
- fixed a Linux-only bug in case of HTTP server health-checks, where a single
server response followed by a close could be ignored, and the server seen
as failed.
2003/09/19 : 1.1.23 2003/09/19 : 1.1.23
- fixed a stupid bug introduced in 1.1.22 which caused second and subsequent - fixed a stupid bug introduced in 1.1.22 which caused second and subsequent
'default' sections to keep previous parameters, and not initialize logs 'default' sections to keep previous parameters, and not initialize logs

View File

@ -1,9 +1,9 @@
H A - P r o x y H A - P r o x y
--------------- ---------------
version 1.1.23 version 1.1.24
willy tarreau willy tarreau
2003/09/20 2003/09/21
============ ============
| Abstract | | Abstract |
@ -332,14 +332,22 @@ Health-checking mode
This mode provides a way for external components to check the proxy's health. This mode provides a way for external components to check the proxy's health.
It is meant to be used with intelligent load-balancers which can use send/expect It is meant to be used with intelligent load-balancers which can use send/expect
scripts to check for all of their servers' availability. This one simply accepts scripts to check for all of their servers' availability. This one simply accepts
the connection, returns the word 'OK' and closes it. To enable it, simply the connection, returns the word 'OK' and closes it. If the 'option httpchk' is
set, then the reply will be 'HTTP/1.0 200 OK' with no data, so that it can be
tested from a tool which supports HTTP health-checks. To enable it, simply
specify 'health' as the working mode : specify 'health' as the working mode :
Example : Example :
--------- ---------
# simple response : 'OK'
listen health_check 0.0.0.0:60000 listen health_check 0.0.0.0:60000
mode health mode health
# HTTP response : 'HTTP/1.0 200 OK'
listen http_health_check 0.0.0.0:60001
mode health
option httpchk
2.3) Limiting the number of simultaneous connections 2.3) Limiting the number of simultaneous connections
---------------------------------------------------- ----------------------------------------------------
@ -640,8 +648,8 @@ Examples :
server srv2 192.168.1.2:+1000 server srv2 192.168.1.2:+1000
3.1) Servers monitoring 3.1) Server monitoring
----------------------- ----------------------
It is possible to check the servers status by trying to establish TCP It is possible to check the servers status by trying to establish TCP
connections or even sending HTTP requests to them. A server which fails to connections or even sending HTTP requests to them. A server which fails to
@ -850,45 +858,39 @@ Example :
4.2) Event logging 4.2) Event logging
------------------ ------------------
TCP and HTTP connections can be logged with informations such as date, time,
source IP address, destination address, connection duration, response times,
HTTP request, the HTTP return code, number of bytes transmitted, the conditions
in which the session ended, and even exchanged cookies values, to track a
particular user's problems for example. All messages are sent to up to two
syslog servers. Consult section 1.1 for more info about log facilities. The
syntax follows :
- 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - log <address_1> <facility_1> [max_level_1]
log <address_2> <facility_2> [max_level_2]
or
Les connexions TCP et HTTP peuvent donner lieu à une journalisation sommaire ou
détaillée indiquant, pour chaque connexion, la date, l'heure, l'adresse IP
source, le serveur destination, la durée de la connexion, les temps de réponse,
la requête HTTP, le code de retour, la quantité de données transmises, et même
dans certains cas, la valeur d'un cookie permettant de suivre les sessions.
Tous les messages sont envoyés en syslog vers un ou deux serveurs. Se référer à
la section 1.1 pour plus d'information sur les catégories de logs. La syntaxe
est la suivante :
log <adresse_ip_1> <catégorie_1> [niveau_max_1]
log <adresse_ip_2> <catégorie_2> [niveau_max_2]
ou
log global log global
Remarque : Note :
---------- ------
La syntaxe spécifique 'log global' indique que l'on souhaite utiliser les The particular syntax 'log global' means that the same log configuration as the
paramètres de journalisation définis dans la section 'global'. 'global' section will be used.
Exemple : Example :
--------- ---------
listen http_proxy 0.0.0.0:80 listen http_proxy 0.0.0.0:80
mode http mode http
log 192.168.2.200 local3 log 192.168.2.200 local3
log 192.168.2.201 local4 log 192.168.2.201 local4
Par défaut, les informations contenues dans les logs se situent au niveau TCP By default, only TCP information is logged. It is necessary to set the 'httplog'
uniquement. Il faut préciser l'option 'httplog' pour obtenir les détails du option to obtain more detailed information about HTTP contents. In the event
protocole HTTP. Dans les cas où un mécanisme de surveillance effectuant des where an external component would establish frequent connections to check the
connexions et déconnexions fréquentes, polluerait les logs, il suffit d'ajouter service, logs may be full of useless lines. So it is possible not to log any
l'option 'dontlognull', pour ne plus obtenir une ligne de log pour les sessions session which didn't transfer any data, by the setting of the 'dontlognull'
n'ayant pas donné lieu à un échange de données (requête ou réponse). option. This only has effect on sessions which are established then closed.
Exemple : Example :
--------- ---------
listen http_proxy 0.0.0.0:80 listen http_proxy 0.0.0.0:80
mode http mode http
@ -896,88 +898,81 @@ Exemple :
option dontlognull option dontlognull
log 192.168.2.200 local3 log 192.168.2.200 local3
Depuis la version 1.1.18, un indicateur de complétude de la session a été ajouté Since version 1.1.18, a session completion indicator has been added to HTTP
dans les logs HTTP. C'est un champ de 4 caractères précédant la requête HTTP, logs. It's a 4-characters field preceeding the HTTP request, and indicating :
indiquant : - On the first character, a code reporting the first event which caused the
- sur le premier caractère, un code précisant le premier événement qui a causé session to terminate :
la terminaison de la session :
C : fermeture de la session TCP de la part du client C : the TCP session was aborted by the client.
S : fermeture de la session TCP de la part du serveur, ou refus de connexion S : the TCP session was aborted by the server, or the server refused it.
P : terminaison prématurée des sessions par le proxy, pour cas d'erreur P : the session was abordted prematurely by the proxy, either because of
interne ou de configuration (ex: filtre d'URL) an internal error, or because a DENY filter was matched.
c : expiration du délai d'attente côté client : clitimeout c : the client time-out expired first.
s : expiration du délai d'attente côté serveur: srvtimeout et contimeout s : the server time-out expired first.
- : terminaison normale. - : normal session completion.
- sur le second caractère, l'état d'avancement de la session HTTP lors de la - on the second character, the HTTP session state when it was closed :
fermeture :
R : terminaison en attendant la réception totale de la requête du client R : waiting for complete REQUEST from the client
C : terminaison en attendant la connexion vers le serveur C : waiting for CONNECTION to establish on the server
H : terminaison en attendant la réception totale des entêtes du serveur H : waiting for complete HEADERS from the server
D : terminaison durant le transfert des données du serveur vers le client D : the session was in the DATA phase
L : terminaison durant le transfert des dernières données du proxy vers L : the proxy was still transmitting LAST data to the client while the
le client, alors que le serveur a déjà fini. server had already finished.
- : terminaison normale, après fin de transfert des données - : normal session completion after end of data transfer.
- le troisième caractère indique l'éventuelle identification d'un cookie de - the third character tells whether the persistence cookie was provided by
persistence : the client :
N : aucun cookie de persistence n'a été présenté. N : the client provided NO cookie.
I : le client a présenté un cookie ne correspondant à aucun serveur I : the client provided an INVALID cookie matching no known server.
connu. D : the client provided a cookie designating a server which was DOWN,
D : le client a présenté un cookie correspondant à un serveur hors so either the 'persist' option was used and the client was sent to
d'usage. Suivant l'option 'persist', il a été renvoyé vers un this server, or it was not set and the client was redispatched to
autre serveur ou a tout de même tenté de se connecter sur celui another server.
correspondant au cookie. V : the client provided a valid cookie, and was sent to the associated
V : le client a présenté un cookie valide et a pu se connecter au server.
serveur correspondant. - : does not apply (no cookie set in configuration).
- : non appliquable
- le dernier caractère indique l'éventuel traitement effectué sur un cookie de - the last character reports what operations were performed on the persistence
persistence retrourné par le serveur : cookie returned by the server :
N : aucun cookie de persistence n'a été fourni par le serveur. N : NO cookie was provided by the server.
P : un cookie cookie de persistence n'a été fourni par le serveur. P : a cookie was PROVIDED by the server and transmitted as-is.
I : aucun cookie n'a été fourni par le serveur, il a été inséré par le I : no cookie was provided by the server, and one was INSERTED by the
proxy. proxy.
D : le cookie présenté par le serveur a été supprimé par le proxy pour D : the cookie provided by the server was DELETED by the proxy.
ne pas être retourné au client. R : the cookie provided by the server was REWRITTEN by the proxy.
R : le cookie retourné par le serveur a été modifié par le proxy. - : does not apply (no cookie set in configuration).
- : non appliquable
Le mot clé "capture" permet d'ajouter dans des logs HTTP des informations The 'capture' keyword allows to capture and log informations exchanged between
capturées dans les échanges. La version 1.1.17 supporte uniquement une capture clients and servers. As of version 1.1.23, only cookies can be captured, which
de cookies client et serveur, ce qui permet dans bien des cas, de reconstituer makes it easy to track a complete user session. The syntax is :
la session d'un utilisateur. La syntaxe est la suivante :
capture cookie <préfixe_cookie> len <longueur_capture> capture cookie <cookie_prefix> len <capture_length>
Le premier cookie dont le nom commencera par <préfixe_cookie> sera capturé, et The FIRST cookie whose name starts with <cookie_prefix> will be captured, and
transmis sous la forme "NOM=valeur", sans toutefois, excéder <longueur_capture> logged as 'NAME=value', without exceeding <capture_length> characters (64 max).
caractères (64 au maximum). Lorsque le nom du cookie est fixe et connu, on peut When the cookie name is fixed and known, it's preferable to suffix '=' to it to
le suffixer du signe "=" pour s'assurer qu'aucun autre cookie ne prendra sa ensure that no other cookie will be logged.
place dans les logs.
Exemples : Examples :
---------- ----------
# capture du premier cookie dont le nom commence par "ASPSESSION" # capture the first cookie whose name starts with "ASPSESSION"
capture cookie ASPSESSION len 32 capture cookie ASPSESSION len 32
# capture du premier cookie dont le nom est exactement "vgnvisitor" # capture the first cookie whose name is exactly "vgnvisitor"
capture cookie vgnvisitor= len 32 capture cookie vgnvisitor= len 32
Dans les logs, le champ précédant l'indicateur de complétude contient le cookie In the logs, the field preceeding the completion indicator contains the cookie
positionné par le serveur, précédé du cookie positionné par le client. Chacun de value as sent by the server, preceeded by the cookie value as sent by the
ces champs est remplacé par le signe "-" lorsqu'aucun cookie n'est fourni par le client. Each of these field is replaced with '-' when no cookie was seen.
client ou le serveur.
Enfin, l'option 'forwardfor' ajoute l'adresse IP du client dans un champ Last, the 'forwardfor' option creates an HTTP 'X-Forwarded-For' header which
'X-Forwarded-For' de la requête, ce qui permet à un serveur web final de contains the client's IP address. This is useful to let the final web server
connaître l'adresse IP du client initial. know what the client address was (eg for statistics on domains).
Exemple : Example :
--------- ---------
listen http_proxy 0.0.0.0:80 listen http_proxy 0.0.0.0:80
mode http mode http
@ -988,99 +983,134 @@ Exemple :
capture cookie userid= len 20 capture cookie userid= len 20
4.3) Modification des entêtes HTTP 4.3) HTTP header manipulation
---------------------------------- -----------------------------
En mode HTTP uniquement, il est possible de remplacer certains en-têtes dans la In HTTP mode, it is possible to rewrite, add or delete some of the request and
requête et/ou la réponse à partir d'expressions régulières. Il est également response headers based on regular expressions. It is also possible to block a
possible de bloquer certaines requêtes en fonction du contenu des en-têtes ou de request or a response if a particular header matches a regular expression,
la requête. Une limitation cependant : les en-têtes fournis au milieu de which is enough to stops most elementary protocol attacks, and to protect
connexions persistentes (keep-alive) ne sont pas vus car ils sont considérés against information leak from the internal network. But there is a limitation
comme faisant partie des échanges de données consécutifs à la première requête. to this : since haproxy's HTTP engine knows nothing about keep-alive, only
Les données ne sont pas affectées, ceci ne s'applique qu'aux en-têtes. headers passed during the first request of a TCP session will be seen. All
subsequent headers will be considered data only and not analyzed. Furthermore,
haproxy doesn't touch data contents, it stops at the end of headers.
La syntaxe est : The syntax is :
reqadd <string> pour ajouter un en-tête dans la requête reqadd <string> to add a header to the request
reqrep <search> <replace> pour modifier la requête reqrep <search> <replace> to modify the request
reqirep <search> <replace> idem sans distinction majuscules/minuscules reqirep <search> <replace> same, but ignoring the case
reqdel <search> pour supprimer un en-tête dans la requête reqdel <search> to delete a header in the request
reqidel <search> idem sans distinction majuscules/minuscules reqidel <search> same, but ignoring the case
reqallow <search> autoriser la requête si un entête valide <search> reqallow <search> definitely allow a request if a header matches <search>
reqiallow <search> idem sans distinction majuscules/minuscules reqiallow <search> same, but ignoring the case
reqdeny <search> interdire la requête si un entête valide <search> reqdeny <search> denies a request if a header matches <search>
reqideny <search> idem sans distinction majuscules/minuscules reqideny <search> same, but ignoring the case
reqpass <search> inhibe ces actions sur les entêtes validant <search> reqpass <search> ignore a header matching <search>
reqipass <search> idem sans distinction majuscules/minuscules reqipass <search> same, but ignoring the case
rspadd <string> pour ajouter un en-tête dans la réponse rspadd <string> to add a header to the response
rsprep <search> <replace> pour modifier la réponse rsprep <search> <replace> to modify the response
rspirep <search> <replace> idem sans distinction majuscules/minuscules rspirep <search> <replace> same, but ignoring the case
rspdel <search> pour supprimer un en-tête dans la réponse rspdel <search> to delete the response
rspidel <search> idem sans distinction majuscules/minuscules rspidel <search> same, but ignoring the case
<search> est une expression régulière compatible POSIX regexp supportant le <search> is a POSIX regular expression (regex) which supports grouping through
groupage par parenthèses (sans les '\'). Les espaces et autres séparateurs parenthesis (without the backslash). Spaces and other delimiters must be
doivent êtres précédés d'un '\' pour ne pas être confondus avec la fin de la prefixed with a backslash ('\') to avoid confusion with a field delimiter.
chaîne. De plus, certains caractères spéciaux peuvent être précédés d'un Other characters may be prefixed with a backslash to change their meaning :
backslach ('\') :
\t pour une tabulation \t for a tab
\r pour un retour charriot \r for a carriage return (CR)
\n pour un saut de ligne \n for a new line (LF)
\ pour différencier un espace d'un séparateur \ to mark a space and differentiate it from a delimiter
\# pour différencier un dièse d'un commentaire \# to mark a sharp and differentiate it from a comment
\\ pour utiliser un backslash dans la regex \\ to use a backslash in a regex
\\\\ pour utiliser un backslash dans le texte \\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)
\xXX pour un caractère spécifique XX (comme en C) \xXX to write the ASCII hex code XX as in the C language
<replace> contient la chaîne remplaçant la portion vérifiée par l'expression. <replace> containst the string to be used to replace the largest portion of text
Elle peut inclure les caractères spéciaux ci-dessus, faire référence à un matching the regex. It can make use of the special characters above, and can
groupe délimité par des parenthèses dans l'expression régulière, par sa reference a substring delimited by parenthesis in the regex, by the group
position numérale. Les positions vont de 1 à 9, et sont codées par un '\' numerical order from 1 to 9. In this case, you would write a backslah ('\')
suivi du chiffre désiré. Il est également possible d'insérer un caractère non immediately followed by one digit indicating the group position.
imprimable (utile pour le saut de ligne) inscrivant '\x' suivi du code
hexadécimal de ce caractère (comme en C).
<string> représente une chaîne qui sera ajoutée systématiquement après la <string> represents the string which will systematically be added after the last
dernière ligne d'en-tête. header line. It can also use special characters above.
Remarques : Notes :
--------- -------
- la première ligne de la requête et celle de la réponse sont traitées comme - the first line is considered as a header, which makes it possible to rewrite
des en-têtes, ce qui permet de réécrire des URL et des codes d'erreur. or filter HTTP requests URIs or response codes.
- 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de - 'reqrep' is the equivalent of 'cliexp' in version 1.0, and 'rsprep' is the
'srvexp'. Ces noms sont toujours supportés mais déconseillés. equivalent of 'srvexp' in 1.0. Those names are still supported but
- pour des raisons de performances, le nombre total de caractères ajoutés sur deprecated.
une requête ou une réponse est limité à 4096 depuis la version 1.1.5 (cette - for performances reasons, the number of characters added to a request or to
limite était à 256 auparavant). Cette valeur est modifiable dans le code. a response is limited to 4096 since version 1.1.5 (it was 256 before). This
Pour un usage temporaire, on peut gagner de la place en supprimant quelques value is easy to modify in the code if needed (#define). If it is too short
entêtes inutiles avant les ajouts. on occasional uses, it is possible to gain some space by removing some
useless headers before adding new ones.
Exemples : Examples :
-------- ----------
reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3 ###### a few examples ######
reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
# 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 reqirep ^Proxy-Connection:.* Proxy-Connection:\ close
rspirep ^Server:.* Server:\ Tux-2.0 # rewrite locations
rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3 rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
rspidel ^Connection:
rspadd Connection:\ close ###### 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\?)
# 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
reqidel ^Connection:
rspidel ^Connection:
reqadd Connection:\ close
rspadd Connection:\ close
# change the server name
rspidel ^Server:\
rspadd Server:\ Formilux/0.1.8
4.4) Répartition avec persistence - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - -
---------------------------------
La combinaison de l'insertion de cookie avec la répartition de charge interne 4.4) Load balancing with persistence
permet d'assurer une persistence dans les sessions HTTP d'une manière ------------------------------------
pratiquement transparente pour les applications. Le principe est simple :
- attribuer une valeur d'un cookie à chaque serveur
- effectuer une répartition interne
- insé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 à l'application lors des requêtes ultérieures.
Exemple : Combining cookie insertion with internal load balancing allows to transparently
bring persistence to applications. The principle is quite simple :
- assign a cookie value to each server
- enable the load balancing between servers
- insert a cookie into responses resulting from the balancing algorithm
(indirect accesses), end ensure that no upstream proxy will cache it.
- remove the cookie in the request headers so that the application never sees
it.
Example :
--------- ---------
listen application 0.0.0.0:80 listen application 0.0.0.0:80
mode http mode http
@ -1089,31 +1119,32 @@ Exemple :
server 192.168.1.1:80 cookie server01 check server 192.168.1.1:80 cookie server01 check
server 192.168.1.2:80 cookie server02 check server 192.168.1.2:80 cookie server02 check
4.5) Personalisation des erreurs 4.5) Customizing errors
-------------------------------- -----------------------
Certaines situations conduisent à retourner une erreur HTTP au client : Some situations can make haproxy return an HTTP error code to the client :
- requête invalide ou trop longue => code HTTP 400 - invalid or too long request => HTTP 400
- requête mettant trop de temps à venir => code HTTP 408 - request not completely sent in time => HTTP 408
- requête interdite (bloquée par un reqideny) => code HTTP 403 - forbidden request (matches a deny filter) => HTTP 403
- erreur interne du proxy => code HTTP 500 - internal error in haproxy => HTTP 500
- le serveur a retourné une réponse incomplète ou invalide => code HTTP 502 - the server returned an invalid or incomplete response => HTTP 502
- aucun serveur disponible pour cette requête => code HTTP 503 - no server was available to handle the request => HTTP 503
- le serveur n'a pas répondu dans le temps imparti => code HTTP 504 - the server failed to reply in time => HTTP 504
Un message d'erreur succint tiré de la RFC accompagne ces codes de retour. A succint error message taken from the RFC accompanies these return codes.
Cependant, en fonction du type de clientèle, on peut préférer retourner des But depending on the clients knowledge, it may be better to return custom, user
pages personnalisées. Ceci est possible par le biais de la commande "errorloc" : friendly, error pages. This is made possible through the use of the 'errorloc'
command :
errorloc <code_HTTP> <location> errorloc <HTTP_code> <location>
Au lieu de générer une erreur HTTP <code_HTTP> parmi les codes cités ci-dessus, Instead of generating an HTTP error <HTTP_code> among those above, the proxy
le proxy génèrera un code de redirection temporaire (HTTP 302) vers l'adresse will return a temporary redirection code (HTTP 302) towards the address
d'une page précisée dans <location>. Cette adresse peut être relative au site, specified in <location>. This address may be either relative to the site or
ou absolue. Comme cette réponse est traîtée par le navigateur du client absolute. Since this request will be handled by the client's browser, it's
lui-même, il est indispensable que l'adresse fournie lui soit accessible. mandatory that the returned address be reachable from the outside.
Exemple : Example :
--------- ---------
listen application 0.0.0.0:80 listen application 0.0.0.0:80
errorloc 400 /badrequest.html errorloc 400 /badrequest.html
@ -1124,30 +1155,28 @@ Exemple :
errorloc 503 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 errorloc 504 http://192.168.114.58/error50x.html
4.6) Changement des valeurs par défaut 4.6) Modifying default values
-------------------------------------- -----------------------------
Dans la version 1.1.22 est apparue la notion de valeurs par défaut, ce qui évite Version 1.1.22 introduced the notion of default values, which eliminates the
de répéter des paramètres communs à toutes les instances, tels que les timeouts, pain of often repeating common parameters between many instances, such as
adresses de log, modes de fonctionnement, etc. logs, timeouts, modes, etc...
Les valeurs par défaut sont positionnées dans la dernière section 'defaults' Default values are set in a 'defaults' section. Each of these section clears
précédent l'instance qui les utilisera. On peut donc mettre autant de sections all previously set default parameters, so there may be as many default
'defaults' que l'on veut. Il faut juste se rappeler que la présence d'une telle parameters as needed. Only the last one before a 'listen' section will be
section implique une annulation de tous les paramètres par défaut positionnés used for this section. The 'defaults' section uses the same syntax as the
précédemment, dans le but de les remplacer. 'listen' section, for the supported parameters. The 'defaults' keyword ignores
everything on its command line, so that fake instance names can be specified
there for better clarity.
La section 'defaults' utilise la même syntaxe que la section 'listen', aux In version 1.1.23, only those parameters can be preset in the 'default'
paramètres près qui ne sont pas supportés. Le mot clé 'defaults' peut accepter section :
un commentaire en guise paramètre. - log (the first and second one)
Dans la version 1.1.22, seuls les paramètres suivants peuvent être positionnés
dans une section 'defaults' :
- log (le premier et le second)
- mode { tcp, http, health } - mode { tcp, http, health }
- balance { roundrobin } - balance { roundrobin }
- disabled (pour désactiver toutes les instances qui suivent) - disabled (to disable every further instances)
- enabled (pour faire l'opération inverse, mais c'est le cas par défaut) - enabled (to enable every further instances, this is the default)
- contimeout, clitimeout, srvtimeout, grace, retries, maxconn - contimeout, clitimeout, srvtimeout, grace, retries, maxconn
- option { redispatch, transparent, keepalive, forwardfor, httplog, - option { redispatch, transparent, keepalive, forwardfor, httplog,
dontlognull, persist, httpchk } dontlognull, persist, httpchk }
@ -1155,18 +1184,16 @@ dans une section 'defaults' :
- cookie, capture - cookie, capture
- errorloc - errorloc
Ne sont pas supportés dans cette version, les adresses de dispatch et les As of 1.1.24, it is not possible to put certain parameters in a 'defaults'
configurations de serveurs, ainsi que tous les filtres basés sur les section, mainly regular expressions and server configurations :
expressions régulières :
- dispatch, server, - dispatch, server,
- req*, rsp*, - req*, rsp*
Enfin, il n'y a pas le moyen, pour le moment, d'invalider un paramètre booléen Last, there's no way yet to change a boolean option from its assigned default
positionné par défaut. Donc si une option est spécifiée dans les paramètres par value. So if an 'option' statement is set in a 'defaults' section, the only
défaut, le seul moyen de la désactiver pour une instance, c'est de changer les way to flush it is to redefine a new 'defaults' section without this 'option'.
paramètres par défaut avant la déclaration de l'instance.
Exemples : Examples :
---------- ----------
defaults applications TCP defaults applications TCP
log global log global
@ -1205,14 +1232,14 @@ Exemples :
server srv1 192.168.1.2:+8000 cookie srv2 check port 8080 inter 1000 server srv1 192.168.1.2:+8000 cookie srv2 check port 8080 inter 1000
defaults defaults
# section vide qui annule tous les paramètes par défaut. # this empty section voids all default parameters
======================= =========================
| Paramétrage système | | System-specific setup |
======================= =========================
Sous Linux 2.4 Linux 2.4
============== =========
-- cut here -- -- cut here --
#!/bin/sh #!/bin/sh
@ -1254,4 +1281,17 @@ echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
-- cut here -- -- cut here --
-- fin --
FreeBSD
=======
A FreeBSD port of HA-Proxy is now available and maintained, thanks to
Clement Laforet <sheepkiller@cultdeadsheep.org>.
For more information :
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
-- end --

View File

@ -1,9 +1,9 @@
H A - P r o x y H A - P r o x y
--------------- ---------------
version 1.1.23 version 1.1.24
willy tarreau willy tarreau
2003/09/20 2003/09/21
================ ================
| Introduction | | Introduction |
@ -347,14 +347,22 @@ Mode supervision
Il s'agit d'un mode offrant à un composant externe une visibilité de l'état de Il s'agit d'un mode offrant à un composant externe une visibilité de l'état de
santé du service. Il se contente de retourner "OK" à tout client se connectant santé du service. Il se contente de retourner "OK" à tout client se connectant
sur son port. Il peut être utilisé avec des répartiteurs de charge évolués pour sur son port. Il peut être utilisé avec des répartiteurs de charge évolués pour
déterminer quels sont les services utilisables. Pour activer ce mode, préciser déterminer quels sont les services utilisables. Si l'option 'httpchk' est
activé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éciser
le mode HEALTH sous la déclaration du relais. le mode HEALTH sous la déclaration du relais.
Exemple : Exemple :
--------- ---------
# réponse simple : 'OK'
listen health_check 0.0.0.0:60000 listen health_check 0.0.0.0:60000
mode health mode health
# réponse HTTP : 'HTTP/1.0 200 OK'
listen http_health_check 0.0.0.0:60001
mode health
option httpchk
2.3) Limitation du nombre de connexions simultanées 2.3) Limitation du nombre de connexions simultanées
--------------------------------------------------- ---------------------------------------------------
@ -951,7 +959,8 @@ indiquant :
persistence retrourné par le serveur : persistence retrourné par le serveur :
N : aucun cookie de persistence n'a été fourni par le serveur. N : aucun cookie de persistence n'a été fourni par le serveur.
P : un cookie cookie de persistence n'a été fourni par le serveur. P : un cookie de persistence a été fourni par le serveur et transmis
tel quel.
I : aucun cookie n'a été fourni par le serveur, il a été inséré par le I : aucun cookie n'a été fourni par le serveur, il a été inséré par le
proxy. proxy.
D : le cookie présenté par le serveur a été supprimé par le proxy pour D : le cookie présenté par le serveur a été supprimé par le proxy pour
@ -1058,7 +1067,7 @@ hexad
dernière ligne d'en-tête. dernière ligne d'en-tête.
Remarques : Remarques :
--------- -----------
- la première ligne de la requête et celle de la réponse sont traitées comme - la première ligne de la requête et celle de la réponse sont traitées comme
des en-têtes, ce qui permet de réécrire des URL et des codes d'erreur. des en-têtes, ce qui permet de réécrire des URL et des codes d'erreur.
- 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de - 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
@ -1070,14 +1079,47 @@ Remarques :
entêtes inutiles avant les ajouts. entêtes inutiles avant les ajouts.
Exemples : Exemples :
-------- ----------
reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3 ###### a few examples ######
reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
# 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 reqirep ^Proxy-Connection:.* Proxy-Connection:\ close
rspirep ^Server:.* Server:\ Tux-2.0 # rewrite locations
rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3 rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
rspidel ^Connection:
rspadd Connection:\ close ###### 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\?)
# 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
reqidel ^Connection:
rspidel ^Connection:
reqadd Connection:\ close
rspadd Connection:\ close
# change the server name
rspidel ^Server:\
rspadd Server:\ Formilux/0.1.8
4.4) Répartition avec persistence 4.4) Répartition avec persistence
@ -1153,7 +1195,7 @@ La section 'defaults' utilise la m
paramètres près qui ne sont pas supportés. Le mot clé 'defaults' peut accepter paramètres près qui ne sont pas supportés. Le mot clé 'defaults' peut accepter
un commentaire en guise paramètre. un commentaire en guise paramètre.
Dans la version 1.1.22, seuls les paramètres suivants peuvent être positionnés Dans la version 1.1.23, seuls les paramètres suivants peuvent être positionnés
dans une section 'defaults' : dans une section 'defaults' :
- log (le premier et le second) - log (le premier et le second)
- mode { tcp, http, health } - mode { tcp, http, health }
@ -1171,7 +1213,7 @@ Ne sont pas support
configurations de serveurs, ainsi que tous les filtres basés sur les configurations de serveurs, ainsi que tous les filtres basés sur les
expressions régulières : expressions régulières :
- dispatch, server, - dispatch, server,
- req*, rsp*, - req*, rsp*
Enfin, il n'y a pas le moyen, pour le moment, d'invalider un paramètre booléen Enfin, il n'y a pas le moyen, pour le moment, d'invalider un paramètre booléen
positionné par défaut. Donc si une option est spécifiée dans les paramètres par positionné par défaut. Donc si une option est spécifiée dans les paramètres par
@ -1266,4 +1308,16 @@ echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
-- cut here -- -- cut here --
Sous FreeBSD
============
Un port de HA-Proxy sous FreeBSD est désormais disponible, grâce à
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
-- fin -- -- fin --

View File

@ -145,6 +145,7 @@ listen health 0.0.0.0:3130
listen health 0.0.0.0:31300 listen health 0.0.0.0:31300
mode health mode health
option httpchk
clitimeout 1500 clitimeout 1500
srvtimeout 1500 srvtimeout 1500
maxconn 6000 maxconn 6000

View File

@ -1,3 +1,5 @@
# this config needs haproxy-1.1.23
global global
log 127.0.0.1 local0 log 127.0.0.1 local0
log 127.0.0.1 local1 notice log 127.0.0.1 local1 notice
@ -10,41 +12,33 @@ global
#debug #debug
#quiet #quiet
listen appli1-rewrite 0.0.0.0:10001 defaults
log global log global
mode http mode http
option httplog option httplog
option dontlognull option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli1-rewrite 0.0.0.0:10001
cookie SERVERID rewrite cookie SERVERID rewrite
balance roundrobin balance roundrobin
server app1_1 192.168.34.23:8080 cookie app1inst1 check inter 2000 rise 2 fall 5 server app1_1 192.168.34.23:8080 cookie app1inst1 check inter 2000 rise 2 fall 5
server app1_2 192.168.34.32:8080 cookie app1inst2 check inter 2000 rise 2 fall 5 server app1_2 192.168.34.32:8080 cookie app1inst2 check inter 2000 rise 2 fall 5
server app1_3 192.168.34.27:8080 cookie app1inst3 check inter 2000 rise 2 fall 5 server app1_3 192.168.34.27:8080 cookie app1inst3 check inter 2000 rise 2 fall 5
server app1_4 192.168.34.42:8080 cookie app1inst4 check inter 2000 rise 2 fall 5 server app1_4 192.168.34.42:8080 cookie app1inst4 check inter 2000 rise 2 fall 5
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli2-insert 0.0.0.0:10002 listen appli2-insert 0.0.0.0:10002
log global
mode http
option httplog
option dontlognull
option httpchk option httpchk
balance roundrobin balance roundrobin
cookie SERVERID insert indirect nocache cookie SERVERID insert indirect nocache
server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3 server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3
server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3 server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3
capture cookie vgnvisitor= len 32 capture cookie vgnvisitor= len 32
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
reqidel ^Connection: # disable keep-alive reqidel ^Connection: # disable keep-alive
reqadd Connection:\ close reqadd Connection:\ close
@ -53,40 +47,16 @@ listen appli2-insert 0.0.0.0:10002
rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address
listen appli3-relais 0.0.0.0:10003 listen appli3-relais 0.0.0.0:10003
log global
mode http
option httplog
option dontlognull
dispatch 192.168.135.17:80 dispatch 192.168.135.17:80
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli4-backup 0.0.0.0:10004 listen appli4-backup 0.0.0.0:10004
log global
mode http
option httplog
option dontlognull
option httpchk /index.html option httpchk /index.html
option persist option persist
balance roundrobin balance roundrobin
server inst1 192.168.114.56:80 check inter 2000 fall 3 server inst1 192.168.114.56:80 check inter 2000 fall 3
server inst2 192.168.114.56:81 check inter 2000 fall 3 backup server inst2 192.168.114.56:81 check inter 2000 fall 3 backup
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli5-backup 0.0.0.0:10005 listen appli5-backup 0.0.0.0:10005
log global
mode http
option httplog
option dontlognull
option httpchk * option httpchk *
balance roundrobin balance roundrobin
cookie SERVERID insert indirect nocache cookie SERVERID insert indirect nocache
@ -94,12 +64,7 @@ listen appli5-backup 0.0.0.0:10005
server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3 server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3
server inst3 192.168.114.57:80 backup check inter 2000 fall 3 server inst3 192.168.114.57:80 backup check inter 2000 fall 3
capture cookie ASPSESSION len 32 capture cookie ASPSESSION len 32
retries 3 srvtimeout 20000
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
reqidel ^Connection: # disable keep-alive reqidel ^Connection: # disable keep-alive
reqadd Connection:\ close reqadd Connection:\ close

View File

@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4.h>
#endif #endif
#define HAPROXY_VERSION "1.1.23" #define HAPROXY_VERSION "1.1.24"
#define HAPROXY_DATE "2003/09/20" #define HAPROXY_DATE "2003/09/21"
/* this is for libc5 for example */ /* this is for libc5 for example */
#ifndef TCP_NODELAY #ifndef TCP_NODELAY
@ -2167,7 +2167,10 @@ int event_accept(int fd) {
fdtab[cfd].state = FD_STREADY; fdtab[cfd].state = FD_STREADY;
if (p->mode == PR_MODE_HEALTH) { /* health check mode, no client reading */ if (p->mode == PR_MODE_HEALTH) { /* health check mode, no client reading */
client_retnclose(s, 3, "OK\n"); /* forge an "OK" response */ if (p->options & PR_O_HTTP_CHK) /* "option httpchk" will make it speak HTTP */
client_retnclose(s, 19, "HTTP/1.0 200 OK\r\n\r\n"); /* forge a 200 response */
else
client_retnclose(s, 3, "OK\n"); /* forge an "OK" response */
} }
else { else {
FD_SET(cfd, StaticReadEvent); FD_SET(cfd, StaticReadEvent);
@ -2215,6 +2218,7 @@ int event_srv_chk_w(int fd) {
int skerr, lskerr; int skerr, lskerr;
lskerr = sizeof(skerr); lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr); getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
/* in case of TCP only, this tells us if the connection succeeded */
if (skerr) if (skerr)
s->result = -1; s->result = -1;
else { else {
@ -2260,19 +2264,23 @@ int event_srv_chk_r(int fd) {
int skerr, lskerr; int skerr, lskerr;
lskerr = sizeof(skerr); lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
s->result = -1; s->result = len = -1;
if (!skerr) {
#ifndef MSG_NOSIGNAL #ifndef MSG_NOSIGNAL
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
if (!skerr)
len = recv(fd, reply, sizeof(reply), 0); len = recv(fd, reply, sizeof(reply), 0);
#else #else
len = recv(fd, reply, sizeof(reply), MSG_NOSIGNAL); /* Warning! Linux returns EAGAIN on SO_ERROR if data are still available
* but the connection was closed on the remote end. Fortunately, recv still
* works correctly and we don't need to do the getsockopt() on linux.
*/
len = recv(fd, reply, sizeof(reply), MSG_NOSIGNAL);
#endif #endif
if ((len >= sizeof("HTTP/1.0 000")) && if ((len >= sizeof("HTTP/1.0 000")) &&
!memcmp(reply, "HTTP/1.", 7) && !memcmp(reply, "HTTP/1.", 7) &&
(reply[9] == '2' || reply[9] == '3')) /* 2xx or 3xx */ (reply[9] == '2' || reply[9] == '3')) /* 2xx or 3xx */
s->result = 1; s->result = 1;
}
FD_CLR(fd, StaticReadEvent); FD_CLR(fd, StaticReadEvent);
task_wakeup(&rq, t); task_wakeup(&rq, t);
@ -2455,7 +2463,14 @@ int process_cli(struct session *t) {
* better to release the maximum of system buffers instead ? */ * better to release the maximum of system buffers instead ? */
//FD_CLR(t->cli_fd, StaticReadEvent); //FD_CLR(t->cli_fd, StaticReadEvent);
//tv_eternity(&t->crexpire); //tv_eternity(&t->crexpire);
break;
/* FIXME: if we break here (as up to 1.1.23), having the client
* shutdown its connection can lead to an abort further.
* it's better to either return 1 or even jump directly to the
* data state which will save one schedule.
*/
//break;
goto process_data;
} }
/* to get a complete header line, we need the ending \r\n, \n\r, \r or \n too */ /* to get a complete header line, we need the ending \r\n, \n\r, \r or \n too */
@ -2777,6 +2792,7 @@ int process_cli(struct session *t) {
return t->cli_state != CL_STHEADERS; return t->cli_state != CL_STHEADERS;
} }
else if (c == CL_STDATA) { else if (c == CL_STDATA) {
process_data:
/* read or write error */ /* read or write error */
if (t->res_cw == RES_ERROR || t->res_cr == RES_ERROR) { if (t->res_cw == RES_ERROR || t->res_cr == RES_ERROR) {
tv_eternity(&t->crexpire); tv_eternity(&t->crexpire);
@ -3985,11 +4001,11 @@ void select_loop() {
// //
// } // }
status=select(maxfd, status = select(maxfd,
readnotnull ? ReadEvent : NULL, readnotnull ? ReadEvent : NULL,
writenotnull ? WriteEvent : NULL, writenotnull ? WriteEvent : NULL,
NULL, NULL,
(next_time >= 0) ? &delta : NULL); (next_time >= 0) ? &delta : NULL);
/* this is an experiment on the separation of the select work */ /* this is an experiment on the separation of the select work */
// status = (readnotnull ? select(maxfd, ReadEvent, NULL, NULL, (next_time >= 0) ? &delta : NULL) : 0); // status = (readnotnull ? select(maxfd, ReadEvent, NULL, NULL, (next_time >= 0) ? &delta : NULL) : 0);