* 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 :
===========
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
- fixed a stupid bug introduced in 1.1.22 which caused second and subsequent
'default' sections to keep previous parameters, and not initialize logs

View File

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

View File

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

View File

@ -1,3 +1,5 @@
# this config needs haproxy-1.1.23
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
@ -10,41 +12,33 @@ global
#debug
#quiet
listen appli1-rewrite 0.0.0.0:10001
defaults
log global
mode http
option httplog
option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli1-rewrite 0.0.0.0:10001
cookie SERVERID rewrite
balance roundrobin
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_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
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli2-insert 0.0.0.0:10002
log global
mode http
option httplog
option dontlognull
option httpchk
balance roundrobin
cookie SERVERID insert indirect nocache
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
capture cookie vgnvisitor= len 32
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
reqidel ^Connection: # disable keep-alive
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
listen appli3-relais 0.0.0.0:10003
log global
mode http
option httplog
option dontlognull
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
log global
mode http
option httplog
option dontlognull
option httpchk /index.html
option persist
balance roundrobin
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
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appli5-backup 0.0.0.0:10005
log global
mode http
option httplog
option dontlognull
option httpchk *
balance roundrobin
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 inst3 192.168.114.57:80 backup check inter 2000 fall 3
capture cookie ASPSESSION len 32
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
srvtimeout 20000
reqidel ^Connection: # disable keep-alive
reqadd Connection:\ close

View File

@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h>
#endif
#define HAPROXY_VERSION "1.1.23"
#define HAPROXY_DATE "2003/09/20"
#define HAPROXY_VERSION "1.1.24"
#define HAPROXY_DATE "2003/09/21"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@ -2167,7 +2167,10 @@ int event_accept(int fd) {
fdtab[cfd].state = FD_STREADY;
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 {
FD_SET(cfd, StaticReadEvent);
@ -2215,6 +2218,7 @@ int event_srv_chk_w(int fd) {
int skerr, lskerr;
lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
/* in case of TCP only, this tells us if the connection succeeded */
if (skerr)
s->result = -1;
else {
@ -2260,19 +2264,23 @@ int event_srv_chk_r(int fd) {
int skerr, lskerr;
lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
s->result = -1;
if (!skerr) {
s->result = len = -1;
#ifndef MSG_NOSIGNAL
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
if (!skerr)
len = recv(fd, reply, sizeof(reply), 0);
#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
if ((len >= sizeof("HTTP/1.0 000")) &&
!memcmp(reply, "HTTP/1.", 7) &&
(reply[9] == '2' || reply[9] == '3')) /* 2xx or 3xx */
s->result = 1;
}
if ((len >= sizeof("HTTP/1.0 000")) &&
!memcmp(reply, "HTTP/1.", 7) &&
(reply[9] == '2' || reply[9] == '3')) /* 2xx or 3xx */
s->result = 1;
FD_CLR(fd, StaticReadEvent);
task_wakeup(&rq, t);
@ -2455,7 +2463,14 @@ int process_cli(struct session *t) {
* better to release the maximum of system buffers instead ? */
//FD_CLR(t->cli_fd, StaticReadEvent);
//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 */
@ -2777,6 +2792,7 @@ int process_cli(struct session *t) {
return t->cli_state != CL_STHEADERS;
}
else if (c == CL_STDATA) {
process_data:
/* read or write error */
if (t->res_cw == RES_ERROR || t->res_cr == RES_ERROR) {
tv_eternity(&t->crexpire);
@ -3985,11 +4001,11 @@ void select_loop() {
//
// }
status=select(maxfd,
readnotnull ? ReadEvent : NULL,
writenotnull ? WriteEvent : NULL,
NULL,
(next_time >= 0) ? &delta : NULL);
status = select(maxfd,
readnotnull ? ReadEvent : NULL,
writenotnull ? WriteEvent : NULL,
NULL,
(next_time >= 0) ? &delta : NULL);
/* this is an experiment on the separation of the select work */
// status = (readnotnull ? select(maxfd, ReadEvent, NULL, NULL, (next_time >= 0) ? &delta : NULL) : 0);