mirror of
https://github.com/haproxy/haproxy.git
synced 2026-06-11 09:52:56 -04:00
* if a cookie is used in insert+indirect mode, it's desirable that the the servers don't see it. It was not possible to remove it correctly with regexps, so now it's removed automatically.
796 lines
30 KiB
Text
796 lines
30 KiB
Text
|
|
H A - P r o x y
|
|
---------------
|
|
version 1.1.10
|
|
willy tarreau
|
|
2002/05/10
|
|
|
|
================
|
|
| Introduction |
|
|
================
|
|
|
|
HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
|
|
environnement hautement disponible. En effet, il est capable de :
|
|
- effectuer un aiguillage statique défini par des cookies ;
|
|
- effectuer une répartition de charge avec création de cookies pour assurer la
|
|
persistence de session ;
|
|
- fournir une visibilité externe de son état de santé ;
|
|
- s'arrêter en douceur sans perte brutale de service.
|
|
- modifier/ajouter/supprimer des entêtes dans la requête et la réponse.
|
|
- interdire des requêtes qui vérifient certaines conditions.
|
|
|
|
Il requiert peu de ressources, et son architecture événementielle mono-processus
|
|
lui permet facilement de gérer plusieurs milliers de connexions simultanées sur
|
|
plusieurs relais sans effondrer le système.
|
|
|
|
|
|
===========================
|
|
| Paramètres de lancement |
|
|
===========================
|
|
|
|
Les options de lancement sont peu nombreuses :
|
|
|
|
-f <fichier de configuration>
|
|
-n <nombre maximal total de connexions simultanées>
|
|
-N <nombre maximal de connexions simultanées par proxy>
|
|
-d active le mode debug
|
|
-D passe en daemon
|
|
-s affiche les statistiques (si option compilée)
|
|
-l ajoute des informations aux statistiques
|
|
|
|
Le nombre maximal de connexion simultanées par proxy est le paramètre par défaut
|
|
pour les proxies pour lesquels ce paramètre n'est pas précisé dans le fichier de
|
|
configuration. Il s'agit du paramètre 'maxconn' dans les sections 'listen'.
|
|
|
|
Le nombre maximal total de connexions simultanées limite le nombre de connexions
|
|
TCP utilisables à un instant donné par le processus, tous proxies confondus. Ce
|
|
paramètre remplace le paramètre 'maxconn' de la section 'global'.
|
|
|
|
Le mode debug correspond à l'option 'debug' de la section 'global'. Dans ce
|
|
mode, toutes les connexions, déconnexions, et tous les échanges d'entêtes HTTP
|
|
sont affichés.
|
|
|
|
Les statistiques ne sont disponibles que si le programme a été compilé avec
|
|
l'option "STATTIME". Il s'agit principalement de données brutes n'ayant
|
|
d'utilité que lors de benchmarks par exemple.
|
|
|
|
|
|
============================
|
|
| Fichier de configuration |
|
|
============================
|
|
|
|
Structure
|
|
=========
|
|
|
|
L'analyseur du fichier de configuration ignore des lignes vides, les espaces,
|
|
les tabulations, et tout ce qui est compris entre le symbole '#' (s'il n'est pas
|
|
précédé d'un '\'), et la fin de la ligne, ce qui constitue un commentaire.
|
|
|
|
Le fichier de configuration est découpé en sections répérées par des mots clés
|
|
tels que :
|
|
|
|
- 'global'
|
|
- 'listen'
|
|
|
|
Tous les paramètres font référence à la section définie par le dernier mot clé
|
|
reconnu.
|
|
|
|
|
|
1) Paramètres globaux
|
|
=====================
|
|
|
|
Il s'agit des paramètres agissant sur le processus, ou bien sur l'ensemble des
|
|
proxies. Ils sont tous spécifiés dans la section 'global'. Les paramètres
|
|
supportés sont :
|
|
|
|
- log <adresse> <catégorie>
|
|
- maxconn <nombre>
|
|
- uid <identifiant>
|
|
- gid <identifiant>
|
|
- chroot <répertoire>
|
|
- nbproc <nombre>
|
|
- daemon
|
|
- debug
|
|
- quiet
|
|
|
|
1.1) Journalisation des événements
|
|
----------------------------------
|
|
La plupart des événements sont journalisés : démarrages, arrêts, disparition et
|
|
apparition de serveurs, connexions, erreurs. Tous les messages sont envoyés en
|
|
syslog vers un ou deux serveurs. La syntaxe est la suivante :
|
|
|
|
log <adresse_ip> <facility>
|
|
|
|
Les connexions sont envoyées en niveau "info". Les démarrages de service et de
|
|
serveurs seront envoyés en "notice", les signaux d'arrêts en "warning" et les
|
|
arrêts définitifs de services et de serveurs en "alert". Ceci est valable aussi
|
|
bien pour les proxies que pour les serveurs testés par les proxies.
|
|
|
|
Les catégories possibles sont :
|
|
kern, user, mail, daemon, auth, syslog, lpr, news,
|
|
uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
|
|
local0, local1, local2, local3, local4, local5, local6, local7
|
|
|
|
Exemple :
|
|
---------
|
|
global
|
|
log 192.168.2.200 local3
|
|
log 192.168.2.201 local4
|
|
|
|
1.2) limitation du nombre de connexions
|
|
---------------------------------------
|
|
Il est possible et conseillé de limiter le nombre global de connexions par
|
|
processus. Les connexions sont comprises au sens 'acceptation de connexion',
|
|
donc il faut s'attendre en règle général à avoir un peu plus du double de
|
|
sessions TCP que le maximum de connexions fixé. C'est important pour fixer le
|
|
paramètre 'ulimit -n' avant de lancer le proxy. Pour comptabiliser le nombre
|
|
de sockets nécessaires, il faut prendre en compte ces paramètres :
|
|
- 1 socket par connexion entrante
|
|
- 1 socket par connexion sortante
|
|
- 1 socket par proxy
|
|
- 1 socket pour chaque serveur en cours de health-check
|
|
- 1 socket pour les logs (tous serveurs confondus)
|
|
|
|
Positionner la limite du nombre de descripteurs de fichiers (ulimit -n) à
|
|
2 * maxconn + nbproxy + nbserveurs + 1. Dans une future version, haproxy sera
|
|
capable de positionner lui-même cette limite.
|
|
|
|
1.3) Diminution des privilèges
|
|
------------------------------
|
|
Afin de réduire les risques d'attaques dans le cas où une faille non identifiée
|
|
serait exploitée, il est possible de diminuer les privilèges du processus, et
|
|
de le cloisonner.
|
|
|
|
Dans la section 'global', le paramètre 'uid' permet de spécifier un identifiant
|
|
numérique d'utilisateur. La valeur 0, correspondant normalement au super-
|
|
utilisateur, possède ici une signification particulière car elle indique que
|
|
l'on ne souhaite pas changer cet identifiant et conserver la valeur courante.
|
|
C'est la valeur par défaut. De la même manière, le paramètre 'gid' correspond à
|
|
un identifiant de groupe, et utilise par défaut la valeur 0 pour ne rien
|
|
changer. Il est particulièrement déconseillé d'utiliser des comptes génériques
|
|
tels que 'nobody' car cette pratique revient à utiliser 'root' si d'autres
|
|
processus utilisent les mêmes identifiants.
|
|
|
|
Le paramètre 'chroot' autorise à changer la racine du processus une fois le
|
|
programme lancé, de sorte que ni le processus, ni l'un de ses descendants ne
|
|
puisse remonter de nouveau à la racine. Ce type de cloisonnement (chroot) est
|
|
parfois contournable sur certains OS (Linux 2.2, Solaris), mais visiblement
|
|
fiable sur d'autres (Linux 2.4). Aussi, il est important d'utiliser un
|
|
répertoire spécifique au service pour cet usage, et de ne pas mutualiser un même
|
|
répertoire pour plusieurs services de nature différente.
|
|
|
|
Remarque: dans le cas où une telle faille serait mise en évidence, il est fort
|
|
probable que les premières tentatives de son exploitation provoquent un arrêt du
|
|
programme, à cause d'un signal de type 'Segmentation Fault', 'Bus Error' ou
|
|
encore 'Illegal Instruction'. Même s'il est vrai que faire tourner le serveur en
|
|
environnement limité réduit les risques d'intrusion, il est parfois bien utile
|
|
dans ces circonstances de connaître les conditions d'apparition du problème, via
|
|
l'obtention d'un fichier 'core'. La plupart des systèmes, pour des raisons de
|
|
sécurité, désactivent la génération du fichier 'core' après un changement
|
|
d'identifiant pour le processus. Il faudra donc soit lancer le processus à
|
|
partir d'un compte utilisateur aux droits réduits (mais ne pouvant pas effectuer
|
|
le chroot), ou bien le faire en root sans réduction des droits (uid 0). Dans ce
|
|
cas, le fichier se trouvera soit dans le répertoire de lancement, soit dans le
|
|
répertoire spécifié après l'option 'chroot'. Ne pas oublier la commande suivante
|
|
pour autoriser la génération du fichier avant de lancer le programme :
|
|
|
|
# ulimit -c unlimited
|
|
|
|
Exemple :
|
|
---------
|
|
|
|
global
|
|
uid 30000
|
|
gid 30000
|
|
chroot /var/chroot/haproxy
|
|
|
|
1.4) modes de fonctionnement
|
|
----------------------------
|
|
Le service peut fonctionner dans plusieurs modes :
|
|
- avant- / arrière-plan
|
|
- silencieux / normal / debug
|
|
|
|
Le mode par défaut est normal, avant-plan, c'est à dire que le programme ne rend
|
|
pas la main une fois lancé. Il ne faut surtout pas le lancer comme ceci dans un
|
|
script de démarrage du système, sinon le système ne finirait pas son
|
|
initialisation. Il faut le mettre en arrière-plan, de sorte qu'il rende la main
|
|
au processus appelant. C'est ce que fait l'option 'daemon' de la section
|
|
'global', et qui est l'équivalent du paramètre '-D' de la ligne de commande.
|
|
|
|
Par ailleurs, certains messages d'alerte sont toujours envoyés sur la sortie
|
|
standard, même en mode 'daemon'. Pour ne plus les voir ailleurs que dans les
|
|
logs, il suffit de passer en mode silencieux par l'ajout de l'option 'quiet'.
|
|
Cette option n'a pas d'équivalent en ligne de commande.
|
|
|
|
Enfin, le mode 'debug' permet de diagnostiquer les origines de certains
|
|
problèmes en affichant les connexions, déconnexions et échanges d'en-têtes HTTP
|
|
entre les clients et les serveurs. Ce mode est incompatible avec les options
|
|
'daemon' et 'quiet' pour des raisons de bon sens.
|
|
|
|
1.5) accroissement de la capacité de traitement
|
|
-----------------------------------------------
|
|
Sur des machines multi-processeurs, il peut sembler gâché de n'utiliser qu'un
|
|
processeur pour effectuer les tâches de relayage, même si les charges
|
|
nécessaires à saturer un processeur actuel sont bien au-delà des ordres de
|
|
grandeur couramment rencontrés. Cependant, pour des besoins particuliers, le
|
|
programme sait démarrer plusieurs processus se répartissant la charge de
|
|
travail. Ce nombre de processus est spécifié par le paramètre 'nbproc' de la
|
|
section 'global'. Sa valeur par défaut est naturellement 1. Ceci ne fonctionne
|
|
qu'en mode 'daemon'.
|
|
|
|
Exemple :
|
|
---------
|
|
|
|
global
|
|
daemon
|
|
quiet
|
|
nbproc 2
|
|
|
|
|
|
2) Définition d'un service en écoute
|
|
====================================
|
|
|
|
Les sections de service débutent par le mot clé "listen" :
|
|
|
|
listen <nom_instance> <adresse_IP>:<port>
|
|
|
|
- <nom_instance> est le nom de l'instance décrite. Ce nom sera envoyé dans les
|
|
logs, donc il est souhaitable d'utiliser un nom relatif au service relayé. Aucun
|
|
test n'est effectué concernant l'unicité de ce nom, qui n'est pas obligatoire,
|
|
mais fortement recommandée.
|
|
|
|
- <adresse_IP> est l'adresse IP sur laquelle le relais attend ses
|
|
connexions. L'adresse 0.0.0.0 signifie que les connexions pourront s'effectuer
|
|
sur toutes les adresses de la machine.
|
|
|
|
- <port> est le numéro de port TCP sur lequel le relais attend ses
|
|
connexions. Le couple <adresse_IP>:<port> doit être unique pour toutes les
|
|
instances d'une même machine. L'attachement à un port inférieur à 1024
|
|
nécessite un niveau de privilège particulier lors du lancement du programme
|
|
(indépendamment du paramètre 'uid' de la section 'global').
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 127.0.0.1:80
|
|
|
|
|
|
2.1) Inhibition d'un service
|
|
----------------------------
|
|
Un serveur peut être désactivé pour des besoins de maintenance, sans avoir à
|
|
commenter toute une partie du fichier. Il suffit de positionner le mot clé
|
|
"disabled" dans sa section :
|
|
|
|
listen smtp_proxy 0.0.0.0:25
|
|
disabled
|
|
|
|
2.2) Mode de fonctionnement
|
|
---------------------------
|
|
Un serveur peut fonctionner dans trois modes différents :
|
|
- TCP
|
|
- HTTP
|
|
- supervision
|
|
|
|
Mode TCP
|
|
--------
|
|
Dans ce mode, le service relaye, dès leur établissement, les connexions TCP vers
|
|
un ou plusieurs serveurs. Aucun traitement n'est effectué sur le flux. Il s'agit
|
|
simplement d'une association source<adresse:port> -> destination<adresse:port>.
|
|
Pour l'utiliser, préciser le mode TCP sous la déclaration du relais.
|
|
|
|
Exemple :
|
|
---------
|
|
listen smtp_proxy 0.0.0.0:25
|
|
mode tcp
|
|
|
|
Mode HTTP
|
|
---------
|
|
Dans ce mode, le service relaye les connexions TCP vers un ou plusieurs
|
|
serveurs, une fois qu'il dispose d'assez d'informations pour en prendre la
|
|
décision. Les entêtes HTTP sont analysés pour y trouver un éventuel cookie, et
|
|
certains d'entre-eux peuvent être modifiés par le biais d'expressions
|
|
régulières. Pour activer ce mode, préciser le mode HTTP sous la déclaration du
|
|
relais.
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
|
|
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
|
|
le mode HEALTH sous la déclaration du relais.
|
|
|
|
Exemple :
|
|
---------
|
|
listen health_check 0.0.0.0:60000
|
|
mode health
|
|
|
|
|
|
2.3) Limitation du nombre de connexions simultanées
|
|
---------------------------------------------------
|
|
Le paramètre "maxconn" permet de fixer la limite acceptable en nombre de
|
|
connexions simultanées par proxy. Chaque proxy qui atteint cette valeur cesse
|
|
d'écouter jusqu'à libération d'une connexion. Voir plus loin concernant les
|
|
limitations liées au système.
|
|
|
|
Exemple :
|
|
---------
|
|
listen tiny_server 0.0.0.0:80
|
|
maxconn 10
|
|
|
|
|
|
2.4) Arrêt en douceur
|
|
---------------------
|
|
Il est possible d'arrêter les services en douceur en envoyant un signal SIG_USR1
|
|
au processus relais. Tous les services seront alors mis en phase d'arrêt, mais
|
|
pourront continuer d'accepter des connexions pendant un temps défini par le
|
|
paramètre 'grace' (en millisecondes). Cela permet par exemple, de faire savoir
|
|
rapidement à un répartiteur de charge qu'il ne doit plus utiliser un relais,
|
|
tout en continuant d'assurer le service le temps qu'il s'en rende compte.
|
|
Remarque : les connexions actives ne sont jamais cassées. Dans le pire des cas,
|
|
il faudra attendre en plus leur expiration avant l'arrêt total du processus. La
|
|
valeur par défaut est 0 (pas de grâce, arrêt immédiat de l'écoute).
|
|
|
|
Exemple :
|
|
---------
|
|
# arrêter en douceur par 'killall -USR1 haproxy'
|
|
# le service tournera encore 10 secondes après la demande d'arrêt
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
grace 10000
|
|
|
|
# ce port n'est testé que par un répartiteur de charge.
|
|
listen health_check 0.0.0.0:60000
|
|
mode health
|
|
grace 0
|
|
|
|
|
|
2.5) Temps d'expiration des connexions
|
|
--------------------------------------
|
|
Il est possible de paramétrer certaines durées d'expiration au niveau des
|
|
connexions TCP. Trois temps indépendants sont configurables et acceptent des
|
|
valeurs en millisecondes. Si l'une de ces trois temporisations est dépassée, la
|
|
session est terminée à chaque extrémité.
|
|
|
|
- temps d'attente d'une donnée de la part du client, ou de la
|
|
possibilité de lui envoyer des données : "clitimeout" :
|
|
|
|
# time-out client à 2mn30.
|
|
clitimeout 150000
|
|
|
|
- temps d'attente d'une donnée de la part du serveur, ou de la
|
|
possibilité de lui envoyer des données : "srvtimeout" :
|
|
|
|
# time-out serveur à 30s.
|
|
srvtimeout 30000
|
|
|
|
- temps d'attente de l'établissement d'une connexion vers un serveur
|
|
"contimeout" :
|
|
|
|
# on abandonne si la connexion n'est pas établie après 4 secondes
|
|
contimeout 4000
|
|
|
|
Remarques :
|
|
-----------
|
|
- "contimeout" et "srvtimeout" n'ont pas d'utilité dans le cas du serveur de
|
|
type "health".
|
|
- sous de fortes charges, ou sur un réseau saturé ou défectueux, il est
|
|
possible de perdre des paquets. Du fait que la première retransmission TCP
|
|
n'ait lieu qu'au bout de 3 secoudes, fixer un timeout de connexion inférieur
|
|
à 3 secondes ne permet pas de se rattraper sur la perte de paquets car la
|
|
session aura été abandonnée avant la première retransmission. Une valeur de
|
|
4 secondes réduira considérablement le nombre d'échecs de connexion.
|
|
|
|
2.6) Tentatives de reconnexion
|
|
------------------------------
|
|
Lors d'un échec de connexion vers un serveur, il est possible de
|
|
retenter (potentiellement vers un autre serveur, en cas de répartition
|
|
de charge). Le nombre de nouvelles tentatives infructueuses avant
|
|
abandon est fourni par le paramètre "retries".
|
|
|
|
Exemple :
|
|
---------
|
|
# on essaie encore trois fois maxi
|
|
retries 3
|
|
|
|
|
|
2.7) Adresse du serveur
|
|
-----------------------
|
|
Le serveur vers lequel sont redirigées les nouvelles connexions est défini par
|
|
le paramètre "dispatch" sous la forme <adresse_ip>:<port>. Il correspond à un
|
|
serveur d'assignation de cookie dans le cas où le service consiste à assurer
|
|
uniquement une persistence HTTP, ou bien simplement au serveur destination dans
|
|
le cas de relayage TCP simple.
|
|
|
|
Exemple :
|
|
---------
|
|
# on envoie toutes les nouvelles connexions ici
|
|
dispatch 192.168.1.2:80
|
|
|
|
Remarque :
|
|
----------
|
|
Ce paramètre n'a pas d'utilité pour un serveur en mode 'health', ni en mode
|
|
'balance'.
|
|
|
|
|
|
2.8) Définition du nom du cookie
|
|
--------------------------------
|
|
En mode HTTP, il est possible de rechercher la valeur d'un cookie pour savoir
|
|
vers quel serveur aiguiller la requête utilisateur. Le nom du cookie est donné
|
|
par le paramètre "cookie".
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID
|
|
|
|
On peut modifier l'utilisation du cookie pour la rendre plus intelligente
|
|
vis-à-vis des applications relayées. Il est possible, notamment de supprimer ou
|
|
réécrire un cookie retourné par un serveur accédé en direct, et d'insérer un
|
|
cookie dans une réponse HTTP adressée à un serveur sélectionné en répartition
|
|
de charge.
|
|
|
|
Exemples :
|
|
----------
|
|
|
|
Pour ne conserver le cookie qu'en accès indirect, donc à travers le
|
|
dispatcheur, et supprimer toutes ses éventuelles occurences lors des accès
|
|
directs :
|
|
|
|
cookie SERVERID indirect
|
|
|
|
Pour remplacer la valeur d'un cookie existant par celle attribuée à un serveur,
|
|
lors d'un accès direct :
|
|
|
|
cookie SERVERID rewrite
|
|
|
|
Pour créer un cookie comportant la valeur attribuée à un serveur lors d'un accès
|
|
en répartition de charge interne. Dans ce cas, il est indispensable que tous les
|
|
serveurs aient un cookie renseigné :
|
|
|
|
cookie SERVERID insert
|
|
|
|
Remarques :
|
|
-----------
|
|
- Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite' pour s'adapter
|
|
à des applications générant déjà le cookie, avec un contenu invalide. Il suffit
|
|
pour cela de les spécifier sur la même ligne.
|
|
- dans le cas où 'insert' et 'indirect' sont spécifiés, le cookie n'est jamais
|
|
transmis au serveur vu qu'il n'en a pas connaissance et ne pourrait pas le
|
|
comprendre.
|
|
|
|
2.9) Assignation d'un serveur à une valeur de cookie
|
|
----------------------------------------------------
|
|
En mode HTTP, il est possible d'associer des serveurs à des valeurs de
|
|
cookie par le paramètre 'server'. La syntaxe est :
|
|
|
|
server <identifiant> <adresse_ip>:<port> cookie <valeur>
|
|
|
|
- <identifiant> est un nom quelconque de serveur utilisé pour l'identifier dans la
|
|
configuration et les logs.
|
|
- <adresse_ip>:<port> est le couple adresse-port sur lequel le serveur écoute.
|
|
- <valeur> est la valeur à reconnaître ou positionner dans le cookie.
|
|
|
|
Exemple : le cookie SERVERID peut contenir server01 ou server02
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID
|
|
dispatch 192.168.1.100:80
|
|
server web1 192.168.1.1:80 cookie server01
|
|
server web2 192.168.1.2:80 cookie server02
|
|
|
|
Attention : la syntaxe a changé depuis la version 1.0.
|
|
-----------
|
|
|
|
3) Répartiteur de charge interne
|
|
=================================
|
|
|
|
Le relais peut effectuer lui-même la répartition de charge entre les différents
|
|
serveurs définis pour un service donné, en mode TCP comme en mode HTTP. Pour
|
|
cela, on précise le mot clé 'balance' dans la définition du service,
|
|
éventuellement suivi du nom d'un algorithme de répartition. En version 1.1.9,
|
|
seul 'roundrobin' est géré, et c'est aussi la valeur implicite par défaut. Il
|
|
est évident qu'en cas d'utilisation du répartiteur interne, il ne faudra pas
|
|
spécifier d'adresse de dispatch, et qu'il faudra au moins un serveur.
|
|
|
|
Exemple : même que précédemment en répartition interne
|
|
---------
|
|
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID
|
|
balance roundrobin
|
|
server web1 192.168.1.1:80 cookie server01
|
|
server web2 192.168.1.2:80 cookie server02
|
|
|
|
|
|
3.1) Surveillance des serveurs
|
|
------------------------------
|
|
A cette date, l'état des serveurs n'est testé que par établissement de connexion
|
|
TCP toutes les 2 secondes, avec 3 essais pour déclarer un serveur en panne, 2
|
|
pour le déclarer utilisable. Un serveur hors d'usage ne sera pas utilisé dans le
|
|
processus de répartition de charge interne. Pour activer la surveillance,
|
|
ajouter le mot clé 'check' à la fin de la déclaration du serveur. Il est
|
|
possible de spécifier l'intervalle (en millisecondes) séparant deux tests du
|
|
serveur par le paramètre "inter", le nombre d'échecs acceptés par le paramètre
|
|
"fall", et le nombre de succès avant reprise par le paramètre "rise". Les
|
|
paramètres non précisés prennent les valeurs suivantes par défaut :
|
|
- inter : 2000
|
|
- rise : 2
|
|
- fall : 3
|
|
|
|
Exemples :
|
|
----------
|
|
# même que précédemment avec surveillance
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID
|
|
balance roundrobin
|
|
server web1 192.168.1.1:80 cookie server01 check
|
|
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
|
|
|
|
# Insertion automatique de cookie dans la réponse du serveur, et suppression
|
|
# automatique dans la requête.
|
|
listen web_appl 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID insert indirect
|
|
balance roundrobin
|
|
server web1 192.168.1.1:80 cookie server01 check
|
|
server web2 192.168.1.2:80 cookie server02 check
|
|
|
|
|
|
3.2) Reconnexion vers un répartiteur en cas d'échec direct
|
|
----------------------------------------------------------
|
|
En mode HTTP, si un serveur défini par un cookie ne répond plus, les clients
|
|
seront définitivement aiguillés dessus à cause de leur cookie, et de ce fait,
|
|
définitivement privés de service. La spécification du paramètre 'redispatch'
|
|
autorise dans ce cas à renvoyer les connexions échouées vers le répartiteur
|
|
(externe ou interne) afin d'assigner un nouveau serveur à ces clients.
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID
|
|
dispatch 192.168.1.100:80
|
|
server web1 192.168.1.1:80 cookie server01
|
|
server web2 192.168.1.2:80 cookie server02
|
|
redispatch # renvoyer vers dispatch si serveur HS.
|
|
|
|
|
|
4) Fonctionnalités additionnelles
|
|
=================================
|
|
|
|
D'autres fonctionnalités d'usage moins courant sont disponibles. Il s'agit
|
|
principalement du mode transparent, de la journalisation des connexions, et de
|
|
la réécriture des entêtes.
|
|
|
|
4.1) Fonctionnement en mode transparent
|
|
---------------------------------------
|
|
En mode HTTP, le mot clé 'transparent' permet d'intercepter des sessions routées
|
|
à travers la machine hébergeant le proxy. Dans ce mode, on ne précise pas
|
|
l'adresse de répartition 'dispatch', car celle-ci est tirée de l'adresse
|
|
destination de la session détournée. Le système doit permettre de rediriger les
|
|
paquets vers un processus local.
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:65000
|
|
mode http
|
|
transparent
|
|
cookie SERVERID
|
|
server server01 192.168.1.1:80
|
|
server server02 192.168.1.2:80
|
|
|
|
# iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
|
|
--dport 80 -j REDIRECT --to-ports 65000
|
|
|
|
|
|
4.2) Journalisation des connexions
|
|
----------------------------------
|
|
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 transmise.
|
|
Tous les messages sont envoyés en syslog vers un ou deux serveurs. La syntaxe
|
|
est la suivante :
|
|
|
|
log <adresse_ip> <facility>
|
|
log <adresse_ip> <facility>
|
|
ou
|
|
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'.
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
log 192.168.2.200 local3
|
|
log 192.168.2.201 local4
|
|
|
|
Les connexions sont envoyées en niveau "info". Les démarrages de service seront
|
|
envoyés en "notice", les signaux d'arrêts en "warning" et les arrêts définitifs
|
|
en "alert". Ceci est valable aussi bien pour les proxies que pour les serveurs
|
|
testés au sein des proxies. Les catégories possibles sont :
|
|
|
|
kern, user, mail, daemon, auth, syslog, lpr, news,
|
|
uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
|
|
local0, local1, local2, local3, local4, local5, local6, local7
|
|
|
|
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).
|
|
|
|
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.
|
|
|
|
Exemple :
|
|
---------
|
|
listen http_proxy 0.0.0.0:80
|
|
mode http
|
|
log global
|
|
option httplog
|
|
option dontlognull
|
|
option forwardfor
|
|
|
|
|
|
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.
|
|
|
|
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 une requête qui valide <search>
|
|
reqiallow <search> idem sans distinction majuscules/minuscules
|
|
reqdeny <search> interdire une requête qui valide <search>
|
|
reqdeny <search> idem sans distinction majuscules/minuscules
|
|
|
|
rspadd <string> pour ajouter un en-tête dans la réponse
|
|
rsprep <search> <replace> pour modifier la réponse
|
|
rspirep <search> <replace> idem sans distinction majuscules/minuscules
|
|
rspdel <search> pour supprimer un en-tête dans la réponse
|
|
rspidel <search> idem sans distinction majuscules/minuscules
|
|
|
|
|
|
<search> est une expression régulière compatible GNU 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 ('\') :
|
|
|
|
\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 un backslash
|
|
\xXX pour un caractère spécifique XX (comme en C)
|
|
|
|
|
|
<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).
|
|
|
|
<string> représente une chaîne qui sera ajoutée systématiquement après la
|
|
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
|
|
'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.
|
|
|
|
Exemples :
|
|
--------
|
|
reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3
|
|
reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
|
|
reqirep ^Proxy-Connection:.* Proxy-Connection:\ close
|
|
rspirep ^Server:.* Server:\ Tux-2.0
|
|
rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
|
|
rspidel ^Connection:
|
|
rspadd Connection:\ close
|
|
|
|
|
|
4.4) Répartition avec persistence
|
|
---------------------------------
|
|
|
|
La combinaison de l'insertion de cookie avec la répartition de charge interne
|
|
permet d'assurer une persistence dans les sessions HTTP d'une maniè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
|
|
- cacher ce cookie à l'application
|
|
|
|
Exemple :
|
|
-------
|
|
listen application 0.0.0.0:80
|
|
mode http
|
|
cookie SERVERID insert indirect
|
|
balance roundrobin
|
|
server 192.168.1.1:80 cookie server01 check
|
|
server 192.168.1.2:80 cookie server02 check
|
|
|
|
=======================
|
|
| Paramétrage système |
|
|
=======================
|
|
|
|
Sous Linux 2.4
|
|
==============
|
|
|
|
-- cut here --
|
|
#!/bin/sh
|
|
# set this to about 256/4M (16384 for 256M machine)
|
|
MAXFILES=16384
|
|
echo $MAXFILES > /proc/sys/fs/file-max
|
|
ulimit -n $MAXFILES
|
|
|
|
if [ -e /proc/sys/net/ipv4/ip_conntrack_max ]; then
|
|
echo 65536 > /proc/sys/net/ipv4/ip_conntrack_max
|
|
fi
|
|
|
|
if [ -e /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait ]; then
|
|
# 30 seconds for fin, 15 for time wait
|
|
echo 3000 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_fin_wait
|
|
echo 1500 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_timeout_time_wait
|
|
echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_invalid_scale
|
|
echo 0 > /proc/sys/net/ipv4/netfilter/ip_ct_tcp_log_out_of_window
|
|
fi
|
|
|
|
echo 1024 60999 > /proc/sys/net/ipv4/ip_local_port_range
|
|
echo 32768 > /proc/sys/net/ipv4/ip_queue_maxlen
|
|
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
|
|
echo 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
|
|
echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets
|
|
echo 262144 > /proc/sys/net/ipv4/tcp_max_orphans
|
|
echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
|
|
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
|
|
echo 0 > /proc/sys/net/ipv4/tcp_timestamps
|
|
echo 0 > /proc/sys/net/ipv4/tcp_ecn
|
|
echo 0 > /proc/sys/net/ipv4/tcp_sack
|
|
echo 0 > /proc/sys/net/ipv4/tcp_dsack
|
|
|
|
# auto-tuned on 2.4
|
|
#echo 262143 > /proc/sys/net/core/rmem_max
|
|
#echo 262143 > /proc/sys/net/core/rmem_default
|
|
|
|
echo 16384 65536 524288 > /proc/sys/net/ipv4/tcp_rmem
|
|
echo 16384 349520 699040 > /proc/sys/net/ipv4/tcp_wmem
|
|
|
|
-- cut here --
|
|
|
|
-- fin --
|