blob: 201e71c18800ae0c2214882d515cd716ba602dc5 [file] [log] [blame]
willy tarreau0f7af912005-12-17 12:21:26 +01001
2 H A - P r o x y
3 ---------------
willy tarreauefae1842005-12-17 12:51:03 +01004 version 1.1.1
willy tarreau0f7af912005-12-17 12:21:26 +01005 willy tarreau
willy tarreauefae1842005-12-17 12:51:03 +01006 2002/03/13
willy tarreau0f7af912005-12-17 12:21:26 +01007
willy tarreaub719f002005-12-17 12:55:07 +01008================
9| Introduction |
10================
willy tarreau0f7af912005-12-17 12:21:26 +010011
12HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
13environnement hautement disponible. En effet, il est capable de :
14 - assurer un aiguillage statique défini par des cookies ;
willy tarreau5cbea6f2005-12-17 12:48:26 +010015 - assurer une répartition de charge avec création de cookies pour
16 assurer la persistence de session ;
willy tarreau0f7af912005-12-17 12:21:26 +010017 - fournir une visibilité externe de son état de santé ;
18 - s'arrêter en douceur sans perte brutale de service.
willy tarreau5cbea6f2005-12-17 12:48:26 +010019 - modifier/ajouter/supprimer des entêtes dans la requête et la réponse.
willy tarreau0f7af912005-12-17 12:21:26 +010020
21Il requiert peu de ressources, et son architecture événementielle
22mono-processus lui permet facilement de gérer plusieurs milliers de
23connexions simultanées sur plusieurs relais sans effondrer le système.
24
25===========================
26| Paramètres de lancement |
27===========================
28
29Les options de lancement sont peu nombreuses :
30
31 -f <fichier de configuration>
32 -n <nombre maximal total de connexions simultanées>
33 -N <nombre maximal de connexions simultanées par proxy>
34 -d active le mode debug
35 -D passe en daemon
36 -s affiche les statistiques (si option compilée)
37 -l ajoute des informations aux statistiques
38
39Le nombre maximal de connexion simultanées par proxy est le paramètre
40par défaut pour les proxies pour lesquels ce paramètre n'est pas
41précisé dans le fichier de configuration.
42
43Le nombre maximal total de connexions simultanées limite le nombre de
44connexions TCP utilisables à un instant par le processus, tous proxies
45confondus.
46
47============================
48| Fichier de configuration |
49============================
50
51
52Commentaires
53============
54
55L'analyseur du fichier de configuration ignore des lignes vides, les
56espaces, les tabulations, et tout ce qui est compris entre le symbole
willy tarreau5cbea6f2005-12-17 12:48:26 +010057'#' (s'il n'est pas précédé d'un '\'), et la fin de la ligne.
willy tarreau0f7af912005-12-17 12:21:26 +010058
59
60Serveur
61=======
62
63Le fichier de configuration contient des sections repérées par le mot
64clé "listen" :
65
66 listen <nom_instance> <adresse_IP>:<port>
67
68<nom_instance> est le nom de l'instance décrite. Ce nom sera envoyé
69dans les logs, donc il est souhaitable d'utiliser un nom relatif au
70service relayé. Aucun test n'est effectué concernant l'unicité de ce
71nom, qui n'est pas obligatoire, mais fortement recommandée.
72
73<adresse_IP> est l'adresse IP sur laquelle le relais attend ses
74connexions. L'adresse 0.0.0.0 signifie que les connexions pourront
75s'effectuer sur toutes les adresses de la machine.
76
77<port> est le numéro de port TCP sur lequel le relais attend ses
78connexions. Le couple <adresse_IP>:<port> doit être unique pour toutes
79les instances d'une même machine. L'attachement à un port inférieur à
801024 nécessite un niveau de privilège particulier.
81
82Exemple :
83---------
84 listen http_proxy 127.0.0.1:80
85
86
87Inhibition
88==========
89
90Un serveur peut être désactivé pour des besoins de maintenance, sans
91avoir à commenter toute une partie du fichier. Il suffit de
92positionner le mot clé "disabled" dans sa section :
93
94 listen smtp_proxy 0.0.0.0:25
95 disabled
96
97Mode
98====
99
100Un serveur peut fonctionner dans trois modes différents :
101 - TCP
102 - HTTP
103 - supervision
104
105Mode TCP
106--------
107Dans ce mode, le service relaye, dès leur établissement, les
willy tarreau5cbea6f2005-12-17 12:48:26 +0100108connexions TCP vers un ou plusieurs serveurs. Aucun traitement n'est
willy tarreau0f7af912005-12-17 12:21:26 +0100109effectué sur le flux. Il s'agit simplement d'une association
110<adresse_source:port_source> <adresse_destination:port_destination>.
111Pour l'utiliser, préciser le mode TCP sous la déclaration du relais :
112
113 listen smtp_proxy 0.0.0.0:25
114 mode tcp
115
116Mode HTTP
117---------
118Dans ce mode, le service relaye les connexions TCP vers un ou
119plusieurs serveurs, une fois qu'il dispose d'assez d'informations pour
120en prendre la décision. Les entêtes HTTP sont analysés pour y trouver
121un éventuel cookie, et certains d'entre-eux peuvent être modifiés par
122le biais d'expressions régulières. Pour activer ce mode, préciser le
123mode HTTP sous la déclaration du relais :
124
125 listen http_proxy 0.0.0.0:80
126 mode http
127
128Mode supervision
129----------------
130Il s'agit d'un mode offrant à un composant externe une visibilité de
131l'état de santé du service. Il se contente de retourner "OK" à tout
132client se connectant sur son port. Il peut être utilisé avec des
133répartiteurs de charge évolués pour déterminer quels sont les services
134utilisables. Pour activer ce mode, préciser le mode HEALTH sous la
135déclaration du relais :
136
137 listen health_check 0.0.0.0:60000
138 mode health
139
140
141Limitation du nombre de connexions simultanées
142==============================================
143
144Le paramètre "maxconn" permet de fixer la limite acceptable en nombre
145de connexions simultanées par proxy. Chaque proxy qui atteint cette
146valeur cesse d'écouter jusqu'à libération d'une connexion. Voir plus
147loin concernant les limitations liées au système. Exemple:
148
149 maxconn 16000
150
151
152Arrêt en douceur
153================
154
155Il est possible d'arrêter les services en douceur en envoyant un
156signal SIG_USR1 au processus relais. Tous les services seront alors
157mis en phase d'arrêt, mais pourront continuer d'accepter des connexions
158pendant un temps défini par le paramètre "grace" (en millisecondes).
159Cela permet par exemple, de faire savoir rapidement à un répartiteur
160de charge qu'il ne doit plus utiliser un relais, tout en continuant
161d'assurer le service le temps qu'il s'en rende compte. Remarque : les
162connexions actives ne sont jamais cassées. Dans le pire des cas, il
163faudra attendre en plus leur expiration avant l'arrêt total du
164processus. La valeur par défaut est 0 (pas de grâce).
165
166Exemple :
167---------
168
169 # le service tournera encore 10 secondes après la demande d'arrêt
170 listen http_proxy 0.0.0.0:80
171 mode http
172 grace 10000
173
174 listen health_check 0.0.0.0:60000
175 mode health
176 grace 0
177
178
179Temps d'expiration des connexions
180=================================
181
182Il est possible de paramétrer certaines durées d'expiration au niveau
183des connexions TCP. Trois temps indépendants sont configurables et
184acceptent des valeurs en millisecondes. Si l'une de ces trois
185temporisations est dépassée, la session est terminée à chaque
186extrémité.
187
188 - temps d'attente d'une donnée de la part du client, ou de la
189 possibilité de lui envoyer des données : "clitimeout" :
190
191 # time-out client à 2mn30.
192 clitimeout 150000
193
194 - temps d'attente d'une donnée de la part du serveur, ou de la
195 possibilité de lui envoyer des données : "srvtimeout" :
196
197 # time-out client à 30s.
198 srvtimeout 30000
199
200 - temps d'attente de l'établissement d'une connexion vers un serveur
201 "contimeout" :
202
203 # on abandonne si la connexion n'est pas établie après 3 secondes
204 contimeout 3000
205
206Remarque: "contimeout" et "srvtimeout" n'ont pas d'utilité dans le cas
207du serveur de type "health".
208
209Tentatives de reconnexion
210=========================
211
212Lors d'un échec de connexion vers un serveur, il est possible de
213retenter (potentiellement vers un autre serveur, en cas de répartition
214de charge). Le nombre de nouvelles tentatives infructueuses avant
215abandon est fourni par le paramètre "retries" :
216
217 # on essaie encore trois fois maxi
218 retries 3
219
220Adresse du serveur
221==================
222
223Le serveur vers lequel sont redirigées les connexions est défini par
224le paramètre "dispatch" sous la forme <adresse_ip>:<port> :
225
226 # on envoie toutes les nouvelles connexions ici
227 dispatch 192.168.1.2:80
228
229Remarque: ce paramètre n'a pas d'utilité pour un serveur en mode "health".
230
231Définition du nom du cookie
232===========================
233
234En mode HTTP, il est possible de rechercher la valeur d'un cookie pour
235savoir vers quel serveur aiguiller la requête utilisateur. Le nom du
236cookie est donné par le paramètre "cookie" :
237
238 listen http_proxy 0.0.0.0:80
239 mode http
240 cookie SERVERID
241
willy tarreau5cbea6f2005-12-17 12:48:26 +0100242On peut modifier l'utilisation du cookie pour la rendre plus
243intelligente vis-à-vis des applications relayées. Il est possible,notamment
244de supprimer ou réécrire un cookie retourné par un serveur accédé en direct,
245et d'insérer un cookie dans une réponse HTTP orientée vers un serveur
246sélectionné en répartition de charge.
247
248Pour ne conserver le cookie qu'en accès indirect, donc à travers le
249dispatcheur, et le supprimer lors des accès directs :
250
251 cookie SERVERID indirect
252
253Pour réécrire le nom du serveur dans un cookie lors d'un accès direct :
254
255 cookie SERVERID rewrite
256
257Pour créer un cookie comportant le nom du serveur lors d'un accès en
258répartition de charge interne. Dans ce cas, il est indispensable que tous les
259serveurs aient un cookie renseigné.
260
261 cookie SERVERID insert
262
263Remarque: Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite'
264pour s'adapter à des applications générant déjà le cookie, avec un contenu
265invalide. Il suffit pour cela de les spécifier sur la même ligne.
willy tarreau0f7af912005-12-17 12:21:26 +0100266
267Assignation d'un serveur à une valeur de cookie
268===============================================
269
270En mode HTTP, il est possible d'associer des serveurs à des valeurs de
271cookie par le paramètre "server". La syntaxe est :
272
willy tarreau5cbea6f2005-12-17 12:48:26 +0100273 server <identifiant> <adresse_ip>:<port> cookie <valeur>
willy tarreau0f7af912005-12-17 12:21:26 +0100274
willy tarreau5cbea6f2005-12-17 12:48:26 +0100275<identifiant> est un nom quelconque de serveur utilisé pour
276l'identifier dans la configuration (erreurs...).
willy tarreau0f7af912005-12-17 12:21:26 +0100277<adresse_ip>:<port> le couple adresse-port sur lequel le serveur écoute.
willy tarreau5cbea6f2005-12-17 12:48:26 +0100278<valeur> est la valeur trouvée dans le cookie,
willy tarreau0f7af912005-12-17 12:21:26 +0100279
280Exemple : le cookie SERVERID peut contenir server01 ou server02
281-------
282 listen http_proxy 0.0.0.0:80
283 mode http
284 cookie SERVERID
285 dispatch 192.168.1.100:80
willy tarreau5cbea6f2005-12-17 12:48:26 +0100286 server web1 192.168.1.1:80 cookie server01
287 server web2 192.168.1.2:80 cookie server02
288
289Attention : la syntaxe a changé depuis la version 1.0.
290---------
291
292Répartiteur de charge interne
293=============================
294
295Le relais peut effectuer lui-même la répartition de charge entre les
296différents serveurs décrits pour un service donné, en mode TCP comme
297en mode HTTP. Pour cela, on précise le mot clé 'balance' dans la
298définition du service, éventuellement suivi du nom d'un algorithme de
299répartition. En version 1.1.0, seul 'roundrobin' est géré, et c'est
300aussi la valeur implicite par défaut. Il est évident qu'en cas
301d'utilisation du répartiteur interne, il ne faudra pas spécifier
302d'adresse de dispatch, et qu'il faudra au moins un serveur.
303
304Exemple : même que précédemment en répartition interne
305-------
306
307 listen http_proxy 0.0.0.0:80
308 mode http
309 cookie SERVERID
310 balance roundrobin
311 server web1 192.168.1.1:80 cookie server01
312 server web2 192.168.1.2:80 cookie server02
313
willy tarreau0f7af912005-12-17 12:21:26 +0100314
willy tarreau5cbea6f2005-12-17 12:48:26 +0100315Surveillance des serveurs
316=========================
willy tarreau0f7af912005-12-17 12:21:26 +0100317
willy tarreau5cbea6f2005-12-17 12:48:26 +0100318A cette date, l'état des serveurs n'est testé que par établissement
319de connexion TCP toutes les 2 secondes, avec 3 essais pour déclarer
320un serveur en panne, 2 pour le déclarer utilisable. Un serveur hors
321d'usage ne sera pas utilisé dans le processus de répartition de charge
322interne. Pour activer la surveillance, ajouter le mot clé 'check' à la
323fin de la déclaration du serveur.
324
325Exemple : même que précédemment avec surveillance
326-------
327
328 listen http_proxy 0.0.0.0:80
329 mode http
330 cookie SERVERID
331 balance roundrobin
332 server web1 192.168.1.1:80 cookie server01 check
333 server web2 192.168.1.2:80 cookie server02 check
334
335
336Reconnexion vers un répartiteur en cas d'échec direct
337=====================================================
willy tarreau0f7af912005-12-17 12:21:26 +0100338
339En mode HTTP, si un serveur défini par un cookie ne répond plus, les
340clients seront définitivement aiguillés dessus à cause de leur cookie,
341et de ce fait, définitivement privés de service. La spécification du
willy tarreau5cbea6f2005-12-17 12:48:26 +0100342paramètre "redispatch" autorise dans ce cas à renvoyer les connexions
343échouées vers le répartiteur (externe ou interne) afin d'assigner un
willy tarreau0f7af912005-12-17 12:21:26 +0100344nouveau serveur à ces clients.
345
346Exemple :
347-------
348 listen http_proxy 0.0.0.0:80
349 mode http
350 cookie SERVERID
351 dispatch 192.168.1.100:80
willy tarreau5cbea6f2005-12-17 12:48:26 +0100352 server web1 192.168.1.1:80 cookie server01
353 server web2 192.168.1.2:80 cookie server02
354 redispatch # renvoyer vers dispatch si serveur HS.
355
356Fonctionnement en mode transparent
357==================================
358
359En mode HTTP, le mot clé "transparent" permet d'intercepter des
360sessions routées à travers la machine hébergeant le proxy. Dans
361ce mode, on ne précise pas l'adresse de répartition "dispatch",
362car celle-ci est tirée de l'adresse destination de la session
363détournée. Le système doit permettre de rediriger les paquets
364vers un processus local.
365
366Exemple :
367-------
368 listen http_proxy 0.0.0.0:65000
369 mode http
370 transparent
371 cookie SERVERID
willy tarreau0f7af912005-12-17 12:21:26 +0100372 server server01 192.168.1.1:80
373 server server02 192.168.1.2:80
willy tarreau5cbea6f2005-12-17 12:48:26 +0100374
375 # iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
376 --dport 80 -j REDIRECT --to-ports 65000
willy tarreau0f7af912005-12-17 12:21:26 +0100377
378Journalisation des connexions
379=============================
380
381Les connexions TCP et HTTP peuvent donner lieu à une journalisation
382sommaire indiquant, pour chaque connexion, la date, l'heure, les adresses
383IP source et destination, et les ports source et destination qui la
384caractérisent. Ultérieurement, les URLs seront loguées en mode HTTP,
385tout comme les arrêts de service. Tous les messages sont envoyés en
386syslog vers un ou deux serveurs. La syntaxe est la suivante :
387
388 log <adresse_ip> <facility>
389
390Exemple :
391---------
392 listen http_proxy 0.0.0.0:80
393 mode http
394 log 192.168.2.200 local3
395 log 192.168.2.201 local4
396
397Les connexions sont envoyées en niveau "info". Les démarrages de
398service seront envoyés en "notice", les signaux d'arrêts en "warning"
399et les arrêts définitifs en "alert".
400
401Les catégories possibles sont :
402 kern, user, mail, daemon, auth, syslog, lpr, news,
403 uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
404 local0, local1, local2, local3, local4, local5, local6, local7
405
406
willy tarreau5cbea6f2005-12-17 12:48:26 +0100407Modification des entêtes HTTP
408=============================
willy tarreau0f7af912005-12-17 12:21:26 +0100409
410En mode HTTP uniquement, il est possible de remplacer certains entêtes
willy tarreau5cbea6f2005-12-17 12:48:26 +0100411dans la requête et/ou la réponse à partir d'expressions régulières. Une
412limitation cependant : les entêtes fournis au milieu de connexions
413persistentes (keep-alive) ne sont pas vus. Les données ne sont pas
414affectées, ceci ne s'applique qu'aux entêtes.
willy tarreau0f7af912005-12-17 12:21:26 +0100415
416La syntaxe est :
willy tarreau5cbea6f2005-12-17 12:48:26 +0100417 reqadd <string> pour ajouter un entête dans la requête
418 reqrep <search> <replace> pour modifier la requête
419 reqrep <search> pour supprimer un entête dans la requête
420
421 rspadd <string> pour ajouter un entête dans la réponse
422 rsprep <search> <replace> pour modifier la réponse
423 rsprep <search> pour supprimer un entête dans la réponse
424
willy tarreau0f7af912005-12-17 12:21:26 +0100425
426<search> est une expression régulière compatible GNU regexp supportant
427le groupage par parenthèses (sans les '\'). Les espaces et autres
428séparateurs doivent êtres précédés d'un '\' pour ne pas être confondus
willy tarreau5cbea6f2005-12-17 12:48:26 +0100429avec la fin de la chaîne. De plus, certains caractères spéciaux peuvent
430être précédés d'un backslach ('\') :
431
432 \t pour une tabulation
433 \r pour un retour charriot
434 \n pour un saut de ligne
435 \ pour différencier un espace d'un séparateur
436 \# pour différencier un dièse d'un commentaire
437 \\ pour un backslash
438 \xXX pour un caractère spécifique XX (comme en C)
willy tarreau0f7af912005-12-17 12:21:26 +0100439
willy tarreau0f7af912005-12-17 12:21:26 +0100440
willy tarreau5cbea6f2005-12-17 12:48:26 +0100441<replace> contient la chaîne remplaçant la portion vérifiée par l'expression.
442Elle peut inclure les caractères spéciaux ci-dessus, faire référence à un
443groupe délimité par des parenthèses dans l'expression régulière, par sa
444position numérale. Les positions vont de 1 à 9, et sont codées par un '\'
445suivi du chiffre désiré. Il est également possible d'insérer un caractère non
446imprimable (utile pour le saut de ligne) inscrivant '\x' suivi du code
447hexadécimal de ce caractère (comme en C).
448
449<string> représente une chaîne qui sera ajoutée systématiquement après la
450dernière ligne d'entête.
451
452Remarques :
453---------
454 - la première ligne de la requête et celle de la réponse sont traitées comme
455 des entêtes, ce qui permet de réécrire des URL et des codes d'erreur.
456 - 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
457 'srvexp'. Ces noms sont toujours supportés mais déconseillés.
458 - pour des raisons de performances, le nombre total de caractères ajoutés sur
459 une requête ou une réponse est limité à 256. Cette valeur est modifiable dans
460 le code. Pour un usage temporaire, on peut gagner de la place en supprimant
461 quelques entêtes inutiles avant les ajouts.
willy tarreau0f7af912005-12-17 12:21:26 +0100462
463Exemples :
willy tarreau5cbea6f2005-12-17 12:48:26 +0100464--------
465 reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3
466 reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
467 reqrep ^Proxy-Connection:.* Proxy-Connection:\ close
468 rsprep ^Server:.* Server:\ Tux-2.0
469 rsprep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
470 rspdel ^Connection:.*
471 rspadd Connection:\ close
willy tarreau0f7af912005-12-17 12:21:26 +0100472
473
willy tarreau5cbea6f2005-12-17 12:48:26 +0100474Répartition avec persistence
475============================
476
477La combinaison de l'insertion de cookie avec la répartition de charge interne
478permet d'assurer une persistence dans les sessions HTTP d'une manière
479pratiquement transparente pour les applications. Le principe est simple :
480 - assigner un cookie à chaque serveur
481 - effectuer une répartition interne
482 - insérer un cookie dans les réponses issues d'une répartition
483
484Exemple :
485-------
486 listen application 0.0.0.0:80
487 mode http
488 cookie SERVERID insert indirect
489 balance roundrobin
490 server 192.168.1.1:80 cookie server01 check
491 server 192.168.1.2:80 cookie server02 check
492
willy tarreaub719f002005-12-17 12:55:07 +0100493=======================
494| Paramétrage système |
495=======================
willy tarreau0f7af912005-12-17 12:21:26 +0100496
497Sous Linux 2.4
498==============
499
willy tarreaub719f002005-12-17 12:55:07 +0100500-- cut here --
501#!/bin/sh
502# set this to about 256/4M (16384 for 256M machine)
503MAXFILES=16384
504echo $MAXFILES > /proc/sys/fs/file-max
505ulimit -n $MAXFILES
506
507if [ -e /proc/sys/net/ipv4/ip_conntrack_max ]; then
508 echo 65536 > /proc/sys/net/ipv4/ip_conntrack_max
509fi
510
511if [ -e /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait ]; then
512 # 30 seconds for fin, 15 for time wait
513 echo 3000 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait
514 echo 1500 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_time_wait
515 echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_invalid_scale
516 echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_out_of_window
517fi
518
willy tarreau0f7af912005-12-17 12:21:26 +0100519echo 1024 60999 > /proc/sys/net/ipv4/ip_local_port_range
willy tarreau5cbea6f2005-12-17 12:48:26 +0100520echo 32768 > /proc/sys/net/ipv4/ip_queue_maxlen
willy tarreaub719f002005-12-17 12:55:07 +0100521echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
522echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
willy tarreau0f7af912005-12-17 12:21:26 +0100523echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets
willy tarreaub719f002005-12-17 12:55:07 +0100524echo 262144 > /proc/sys/net/ipv4/tcp_max_orphans
525echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
willy tarreau0f7af912005-12-17 12:21:26 +0100526echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
527echo 0 > /proc/sys/net/ipv4/tcp_timestamps
willy tarreau5cbea6f2005-12-17 12:48:26 +0100528echo 0 > /proc/sys/net/ipv4/tcp_ecn
willy tarreaub719f002005-12-17 12:55:07 +0100529echo 0 > /proc/sys/net/ipv4/tcp_sack
530echo 0 > /proc/sys/net/ipv4/tcp_dsack
531
532# auto-tuned on 2.4
533#echo 262143 > /proc/sys/net/core/rmem_max
534#echo 262143 > /proc/sys/net/core/rmem_default
535
536echo 16384 65536 524288 > /proc/sys/net/ipv4/tcp_rmem
537echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
538
539-- cut here --
willy tarreau0f7af912005-12-17 12:21:26 +0100540
541-- fin --