mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
* released 1.1.9 : SECURITY FIX
* don't use snprintf()'s return value as an end of message since it may be larger. This caused bus errors and segfaults in internal libc's getenv() during localtime() in send_log(). * removed dead insecure send_syslog() function and all references to it. * fixed warnings on Solaris due to buggy implementation of isXXXX().
This commit is contained in:
parent
a159808bf2
commit
c29948c439
2
Makefile
2
Makefile
@ -45,5 +45,5 @@ haproxy: haproxy.o
|
|||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -vf *.[oas] *~ core haproxy test nohup.out gmon.out
|
rm -f *.[oas] *~ core haproxy test nohup.out gmon.out
|
||||||
|
|
||||||
|
590
doc/haproxy.txt
590
doc/haproxy.txt
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
H A - P r o x y
|
H A - P r o x y
|
||||||
---------------
|
---------------
|
||||||
version 1.1.8
|
version 1.1.9
|
||||||
willy tarreau
|
willy tarreau
|
||||||
2002/04/16
|
2002/05/02
|
||||||
|
|
||||||
================
|
================
|
||||||
| Introduction |
|
| Introduction |
|
||||||
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
|
HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
|
||||||
environnement hautement disponible. En effet, il est capable de :
|
environnement hautement disponible. En effet, il est capable de :
|
||||||
- assurer un aiguillage statique défini par des cookies ;
|
- effectuer un aiguillage statique défini par des cookies ;
|
||||||
- assurer une répartition de charge avec création de cookies pour assurer la
|
- effectuer une répartition de charge avec création de cookies pour assurer la
|
||||||
persistence de session ;
|
persistence de session ;
|
||||||
- fournir une visibilité externe de son état de santé ;
|
- fournir une visibilité externe de son état de santé ;
|
||||||
- s'arrêter en douceur sans perte brutale de service.
|
- s'arrêter en douceur sans perte brutale de service.
|
||||||
@ -43,20 +43,28 @@ pour les proxies pour lesquels ce param
|
|||||||
configuration. Il s'agit du paramètre 'maxconn' dans les sections 'listen'.
|
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
|
Le nombre maximal total de connexions simultanées limite le nombre de connexions
|
||||||
TCP utilisables à un instant par le processus, tous proxies confondus. Ce
|
TCP utilisables à un instant donné par le processus, tous proxies confondus. Ce
|
||||||
paramètre remplace le paramètre 'maxconn' de la section 'global'.
|
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 |
|
| Fichier de configuration |
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Commentaires
|
Structure
|
||||||
============
|
=========
|
||||||
|
|
||||||
L'analyseur du fichier de configuration ignore des lignes vides, les espaces,
|
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
|
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.
|
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
|
Le fichier de configuration est découpé en sections répérées par des mots clés
|
||||||
tels que :
|
tels que :
|
||||||
@ -68,8 +76,8 @@ Tous les param
|
|||||||
reconnu.
|
reconnu.
|
||||||
|
|
||||||
|
|
||||||
1) Paramètres généraux
|
1) Paramètres globaux
|
||||||
======================
|
=====================
|
||||||
|
|
||||||
Il s'agit des paramètres agissant sur le processus, ou bien sur l'ensemble des
|
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
|
proxies. Ils sont tous spécifiés dans la section 'global'. Les paramètres
|
||||||
@ -96,7 +104,7 @@ syslog vers un ou deux serveurs. La syntaxe est la suivante :
|
|||||||
Les connexions sont envoyées en niveau "info". Les démarrages de service et de
|
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
|
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
|
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 au sein des proxies.
|
bien pour les proxies que pour les serveurs testés par les proxies.
|
||||||
|
|
||||||
Les catégories possibles sont :
|
Les catégories possibles sont :
|
||||||
kern, user, mail, daemon, auth, syslog, lpr, news,
|
kern, user, mail, daemon, auth, syslog, lpr, news,
|
||||||
@ -121,56 +129,142 @@ de sockets n
|
|||||||
- 1 socket par connexion sortante
|
- 1 socket par connexion sortante
|
||||||
- 1 socket par proxy
|
- 1 socket par proxy
|
||||||
- 1 socket pour chaque serveur en cours de health-check
|
- 1 socket pour chaque serveur en cours de health-check
|
||||||
- 1 socket pour les logs
|
- 1 socket pour les logs (tous serveurs confondus)
|
||||||
|
|
||||||
Positionner la limite du nombre de descripteurs de fichiers (ulimit -n) à
|
Positionner la limite du nombre de descripteurs de fichiers (ulimit -n) à
|
||||||
2 * maxconn + nbproxy + nbserveurs + 1.
|
2 * maxconn + nbproxy + nbserveurs + 1. Dans une future version, haproxy sera
|
||||||
|
capable de positionner lui-même cette limite.
|
||||||
|
|
||||||
1.3) Changement d'uid et de gid
|
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
|
||||||
|
====================================
|
||||||
|
|
||||||
Serveur
|
Les sections de service débutent par le mot clé "listen" :
|
||||||
=======
|
|
||||||
|
|
||||||
Le fichier de configuration contient des sections repérées par le mot
|
|
||||||
clé "listen" :
|
|
||||||
|
|
||||||
listen <nom_instance> <adresse_IP>:<port>
|
listen <nom_instance> <adresse_IP>:<port>
|
||||||
|
|
||||||
<nom_instance> est le nom de l'instance décrite. Ce nom sera envoyé
|
- <nom_instance> est le nom de l'instance décrite. Ce nom sera envoyé dans les
|
||||||
dans les logs, donc il est souhaitable d'utiliser un nom relatif au
|
logs, donc il est souhaitable d'utiliser un nom relatif au service relayé. Aucun
|
||||||
service relayé. Aucun test n'est effectué concernant l'unicité de ce
|
test n'est effectué concernant l'unicité de ce nom, qui n'est pas obligatoire,
|
||||||
nom, qui n'est pas obligatoire, mais fortement recommandée.
|
mais fortement recommandée.
|
||||||
|
|
||||||
<adresse_IP> est l'adresse IP sur laquelle le relais attend ses
|
- <adresse_IP> est l'adresse IP sur laquelle le relais attend ses
|
||||||
connexions. L'adresse 0.0.0.0 signifie que les connexions pourront
|
connexions. L'adresse 0.0.0.0 signifie que les connexions pourront s'effectuer
|
||||||
s'effectuer sur toutes les adresses de la machine.
|
sur toutes les adresses de la machine.
|
||||||
|
|
||||||
<port> est le numéro de port TCP sur lequel le relais attend ses
|
- <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
|
connexions. Le couple <adresse_IP>:<port> doit être unique pour toutes les
|
||||||
les instances d'une même machine. L'attachement à un port inférieur à
|
instances d'une même machine. L'attachement à un port inférieur à 1024
|
||||||
1024 nécessite un niveau de privilège particulier.
|
nécessite un niveau de privilège particulier lors du lancement du programme
|
||||||
|
(indépendamment du paramètre 'uid' de la section 'global').
|
||||||
|
|
||||||
Exemple :
|
Exemple :
|
||||||
---------
|
---------
|
||||||
listen http_proxy 127.0.0.1:80
|
listen http_proxy 127.0.0.1:80
|
||||||
|
|
||||||
|
|
||||||
Inhibition
|
2.1) Inhibition d'un service
|
||||||
==========
|
----------------------------
|
||||||
|
Un serveur peut être désactivé pour des besoins de maintenance, sans avoir à
|
||||||
Un serveur peut être désactivé pour des besoins de maintenance, sans
|
commenter toute une partie du fichier. Il suffit de positionner le mot clé
|
||||||
avoir à commenter toute une partie du fichier. Il suffit de
|
"disabled" dans sa section :
|
||||||
positionner le mot clé "disabled" dans sa section :
|
|
||||||
|
|
||||||
listen smtp_proxy 0.0.0.0:25
|
listen smtp_proxy 0.0.0.0:25
|
||||||
disabled
|
disabled
|
||||||
|
|
||||||
Mode
|
2.2) Mode de fonctionnement
|
||||||
====
|
---------------------------
|
||||||
|
|
||||||
Un serveur peut fonctionner dans trois modes différents :
|
Un serveur peut fonctionner dans trois modes différents :
|
||||||
- TCP
|
- TCP
|
||||||
- HTTP
|
- HTTP
|
||||||
@ -178,86 +272,89 @@ Un serveur peut fonctionner dans trois modes diff
|
|||||||
|
|
||||||
Mode TCP
|
Mode TCP
|
||||||
--------
|
--------
|
||||||
Dans ce mode, le service relaye, dès leur établissement, les
|
Dans ce mode, le service relaye, dès leur établissement, les connexions TCP vers
|
||||||
connexions TCP vers un ou plusieurs serveurs. Aucun traitement n'est
|
un ou plusieurs serveurs. Aucun traitement n'est effectué sur le flux. Il s'agit
|
||||||
effectué sur le flux. Il s'agit simplement d'une association
|
simplement d'une association source<adresse:port> -> destination<adresse:port>.
|
||||||
<adresse_source:port_source> <adresse_destination:port_destination>.
|
Pour l'utiliser, préciser le mode TCP sous la déclaration du relais.
|
||||||
Pour l'utiliser, préciser le mode TCP sous la déclaration du relais :
|
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
---------
|
||||||
listen smtp_proxy 0.0.0.0:25
|
listen smtp_proxy 0.0.0.0:25
|
||||||
mode tcp
|
mode tcp
|
||||||
|
|
||||||
Mode HTTP
|
Mode HTTP
|
||||||
---------
|
---------
|
||||||
Dans ce mode, le service relaye les connexions TCP vers un ou
|
Dans ce mode, le service relaye les connexions TCP vers un ou plusieurs
|
||||||
plusieurs serveurs, une fois qu'il dispose d'assez d'informations pour
|
serveurs, une fois qu'il dispose d'assez d'informations pour en prendre la
|
||||||
en prendre la décision. Les entêtes HTTP sont analysés pour y trouver
|
décision. Les entêtes HTTP sont analysés pour y trouver un éventuel cookie, et
|
||||||
un éventuel cookie, et certains d'entre-eux peuvent être modifiés par
|
certains d'entre-eux peuvent être modifiés par le biais d'expressions
|
||||||
le biais d'expressions régulières. Pour activer ce mode, préciser le
|
régulières. Pour activer ce mode, préciser le mode HTTP sous la déclaration du
|
||||||
mode HTTP sous la déclaration du relais :
|
relais.
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
---------
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
|
|
||||||
Mode supervision
|
Mode supervision
|
||||||
----------------
|
----------------
|
||||||
Il s'agit d'un mode offrant à un composant externe une visibilité de
|
Il s'agit d'un mode offrant à un composant externe une visibilité de l'état de
|
||||||
l'état de santé du service. Il se contente de retourner "OK" à tout
|
santé du service. Il se contente de retourner "OK" à tout client se connectant
|
||||||
client se connectant sur son port. Il peut être utilisé avec des
|
sur son port. Il peut être utilisé avec des répartiteurs de charge évolués pour
|
||||||
répartiteurs de charge évolués pour déterminer quels sont les services
|
déterminer quels sont les services utilisables. Pour activer ce mode, préciser
|
||||||
utilisables. Pour activer ce mode, préciser le mode HEALTH sous la
|
le mode HEALTH sous la déclaration du relais.
|
||||||
déclaration du relais :
|
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
---------
|
||||||
listen health_check 0.0.0.0:60000
|
listen health_check 0.0.0.0:60000
|
||||||
mode health
|
mode health
|
||||||
|
|
||||||
|
|
||||||
Limitation du nombre de connexions simultanées
|
2.3) Limitation du nombre de connexions simultanées
|
||||||
==============================================
|
---------------------------------------------------
|
||||||
|
Le paramètre "maxconn" permet de fixer la limite acceptable en nombre de
|
||||||
Le paramètre "maxconn" permet de fixer la limite acceptable en nombre
|
connexions simultanées par proxy. Chaque proxy qui atteint cette valeur cesse
|
||||||
de connexions simultanées par proxy. Chaque proxy qui atteint cette
|
d'écouter jusqu'à libération d'une connexion. Voir plus loin concernant les
|
||||||
valeur cesse d'écouter jusqu'à libération d'une connexion. Voir plus
|
limitations liées au système.
|
||||||
loin concernant les limitations liées au système. Exemple:
|
|
||||||
|
|
||||||
maxconn 16000
|
|
||||||
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
Exemple :
|
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
|
# le service tournera encore 10 secondes après la demande d'arrêt
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
grace 10000
|
grace 10000
|
||||||
|
|
||||||
|
# ce port n'est testé que par un répartiteur de charge.
|
||||||
listen health_check 0.0.0.0:60000
|
listen health_check 0.0.0.0:60000
|
||||||
mode health
|
mode health
|
||||||
grace 0
|
grace 0
|
||||||
|
|
||||||
|
|
||||||
Temps d'expiration des connexions
|
2.5) Temps d'expiration des connexions
|
||||||
=================================
|
--------------------------------------
|
||||||
|
Il est possible de paramétrer certaines durées d'expiration au niveau des
|
||||||
Il est possible de paramétrer certaines durées d'expiration au niveau
|
connexions TCP. Trois temps indépendants sont configurables et acceptent des
|
||||||
des connexions TCP. Trois temps indépendants sont configurables et
|
valeurs en millisecondes. Si l'une de ces trois temporisations est dépassée, la
|
||||||
acceptent des valeurs en millisecondes. Si l'une de ces trois
|
session est terminée à chaque extrémité.
|
||||||
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
|
- temps d'attente d'une donnée de la part du client, ou de la
|
||||||
possibilité de lui envoyer des données : "clitimeout" :
|
possibilité de lui envoyer des données : "clitimeout" :
|
||||||
@ -268,91 +365,117 @@ extr
|
|||||||
- temps d'attente d'une donnée de la part du serveur, ou de la
|
- temps d'attente d'une donnée de la part du serveur, ou de la
|
||||||
possibilité de lui envoyer des données : "srvtimeout" :
|
possibilité de lui envoyer des données : "srvtimeout" :
|
||||||
|
|
||||||
# time-out client à 30s.
|
# time-out serveur à 30s.
|
||||||
srvtimeout 30000
|
srvtimeout 30000
|
||||||
|
|
||||||
- temps d'attente de l'établissement d'une connexion vers un serveur
|
- temps d'attente de l'établissement d'une connexion vers un serveur
|
||||||
"contimeout" :
|
"contimeout" :
|
||||||
|
|
||||||
# on abandonne si la connexion n'est pas établie après 3 secondes
|
# on abandonne si la connexion n'est pas établie après 4 secondes
|
||||||
contimeout 3000
|
contimeout 4000
|
||||||
|
|
||||||
Remarque: "contimeout" et "srvtimeout" n'ont pas d'utilité dans le cas
|
Remarques :
|
||||||
du serveur de type "health".
|
-----------
|
||||||
|
- "contimeout" et "srvtimeout" n'ont pas d'utilité dans le cas du serveur de
|
||||||
Tentatives de reconnexion
|
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
|
Lors d'un échec de connexion vers un serveur, il est possible de
|
||||||
retenter (potentiellement vers un autre serveur, en cas de répartition
|
retenter (potentiellement vers un autre serveur, en cas de répartition
|
||||||
de charge). Le nombre de nouvelles tentatives infructueuses avant
|
de charge). Le nombre de nouvelles tentatives infructueuses avant
|
||||||
abandon est fourni par le paramètre "retries" :
|
abandon est fourni par le paramètre "retries".
|
||||||
|
|
||||||
|
Exemple :
|
||||||
|
---------
|
||||||
# on essaie encore trois fois maxi
|
# on essaie encore trois fois maxi
|
||||||
retries 3
|
retries 3
|
||||||
|
|
||||||
Adresse du serveur
|
|
||||||
==================
|
|
||||||
|
|
||||||
Le serveur vers lequel sont redirigées les connexions est défini par
|
2.7) Adresse du serveur
|
||||||
le paramètre "dispatch" sous la forme <adresse_ip>:<port> :
|
-----------------------
|
||||||
|
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
|
# on envoie toutes les nouvelles connexions ici
|
||||||
dispatch 192.168.1.2:80
|
dispatch 192.168.1.2:80
|
||||||
|
|
||||||
Remarque: ce paramètre n'a pas d'utilité pour un serveur en mode "health".
|
Remarque :
|
||||||
|
----------
|
||||||
|
Ce paramètre n'a pas d'utilité pour un serveur en mode 'health', ni en mode
|
||||||
|
'balance'.
|
||||||
|
|
||||||
Définition du nom du cookie
|
|
||||||
===========================
|
|
||||||
|
|
||||||
En mode HTTP, il est possible de rechercher la valeur d'un cookie pour
|
2.8) Définition du nom du cookie
|
||||||
savoir vers quel serveur aiguiller la requête utilisateur. Le nom du
|
--------------------------------
|
||||||
cookie est donné par le paramètre "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
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
cookie SERVERID
|
cookie SERVERID
|
||||||
|
|
||||||
On peut modifier l'utilisation du cookie pour la rendre plus
|
On peut modifier l'utilisation du cookie pour la rendre plus intelligente
|
||||||
intelligente vis-à-vis des applications relayées. Il est possible,notamment
|
vis-à-vis des applications relayées. Il est possible, notamment de supprimer ou
|
||||||
de supprimer ou réécrire un cookie retourné par un serveur accédé en direct,
|
réécrire un cookie retourné par un serveur accédé en direct, et d'insérer un
|
||||||
et d'insérer un cookie dans une réponse HTTP orientée vers un serveur
|
cookie dans une réponse HTTP adressée à un serveur sélectionné en répartition
|
||||||
sélectionné en répartition de charge.
|
de charge.
|
||||||
|
|
||||||
|
Exemples :
|
||||||
|
----------
|
||||||
|
|
||||||
Pour ne conserver le cookie qu'en accès indirect, donc à travers le
|
Pour ne conserver le cookie qu'en accès indirect, donc à travers le
|
||||||
dispatcheur, et le supprimer lors des accès directs :
|
dispatcheur, et supprimer toutes ses éventuelles occurences lors des accès
|
||||||
|
directs :
|
||||||
|
|
||||||
cookie SERVERID indirect
|
cookie SERVERID indirect
|
||||||
|
|
||||||
Pour réécrire le nom du serveur dans un cookie lors d'un accès direct :
|
Pour remplacer la valeur d'un cookie existant par celle attribuée à un serveur,
|
||||||
|
lors d'un accès direct :
|
||||||
|
|
||||||
cookie SERVERID rewrite
|
cookie SERVERID rewrite
|
||||||
|
|
||||||
Pour créer un cookie comportant le nom du serveur lors d'un accès en
|
Pour créer un cookie comportant la valeur attribuée à un serveur lors d'un accès
|
||||||
répartition de charge interne. Dans ce cas, il est indispensable que tous les
|
en répartition de charge interne. Dans ce cas, il est indispensable que tous les
|
||||||
serveurs aient un cookie renseigné.
|
serveurs aient un cookie renseigné :
|
||||||
|
|
||||||
cookie SERVERID insert
|
cookie SERVERID insert
|
||||||
|
|
||||||
Remarque: Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite'
|
Remarque :
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Assignation d'un serveur à une valeur de cookie
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
|
2.9) Assignation d'un serveur à une valeur de cookie
|
||||||
|
----------------------------------------------------
|
||||||
En mode HTTP, il est possible d'associer des serveurs à des valeurs de
|
En mode HTTP, il est possible d'associer des serveurs à des valeurs de
|
||||||
cookie par le paramètre "server". La syntaxe est :
|
cookie par le paramètre 'server'. La syntaxe est :
|
||||||
|
|
||||||
server <identifiant> <adresse_ip>:<port> cookie <valeur>
|
server <identifiant> <adresse_ip>:<port> cookie <valeur>
|
||||||
|
|
||||||
<identifiant> est un nom quelconque de serveur utilisé pour
|
- <identifiant> est un nom quelconque de serveur utilisé pour l'identifier dans la
|
||||||
l'identifier dans la configuration (erreurs...).
|
configuration et les logs.
|
||||||
<adresse_ip>:<port> le couple adresse-port sur lequel le serveur écoute.
|
- <adresse_ip>:<port> est le couple adresse-port sur lequel le serveur écoute.
|
||||||
<valeur> est la valeur trouvée dans le cookie,
|
- <valeur> est la valeur à reconnaître ou positionner dans le cookie.
|
||||||
|
|
||||||
Exemple : le cookie SERVERID peut contenir server01 ou server02
|
Exemple : le cookie SERVERID peut contenir server01 ou server02
|
||||||
-------
|
---------
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
cookie SERVERID
|
cookie SERVERID
|
||||||
@ -361,22 +484,21 @@ Exemple : le cookie SERVERID peut contenir server01 ou server02
|
|||||||
server web2 192.168.1.2:80 cookie server02
|
server web2 192.168.1.2:80 cookie server02
|
||||||
|
|
||||||
Attention : la syntaxe a changé depuis la version 1.0.
|
Attention : la syntaxe a changé depuis la version 1.0.
|
||||||
---------
|
-----------
|
||||||
|
|
||||||
Répartiteur de charge interne
|
3) Répartiteur de charge interne
|
||||||
=============================
|
=================================
|
||||||
|
|
||||||
Le relais peut effectuer lui-même la répartition de charge entre les
|
Le relais peut effectuer lui-même la répartition de charge entre les différents
|
||||||
différents serveurs décrits pour un service donné, en mode TCP comme
|
serveurs définis pour un service donné, en mode TCP comme en mode HTTP. Pour
|
||||||
en mode HTTP. Pour cela, on précise le mot clé 'balance' dans la
|
cela, on précise le mot clé 'balance' dans la définition du service,
|
||||||
définition du service, éventuellement suivi du nom d'un algorithme de
|
éventuellement suivi du nom d'un algorithme de répartition. En version 1.1.9,
|
||||||
répartition. En version 1.1.0, seul 'roundrobin' est géré, et c'est
|
seul 'roundrobin' est géré, et c'est aussi la valeur implicite par défaut. Il
|
||||||
aussi la valeur implicite par défaut. Il est évident qu'en cas
|
est évident qu'en cas d'utilisation du répartiteur interne, il ne faudra pas
|
||||||
d'utilisation du répartiteur interne, il ne faudra pas spécifier
|
spécifier d'adresse de dispatch, et qu'il faudra au moins un serveur.
|
||||||
d'adresse de dispatch, et qu'il faudra au moins un serveur.
|
|
||||||
|
|
||||||
Exemple : même que précédemment en répartition interne
|
Exemple : même que précédemment en répartition interne
|
||||||
-------
|
---------
|
||||||
|
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
@ -386,46 +508,50 @@ Exemple : m
|
|||||||
server web2 192.168.1.2:80 cookie server02
|
server web2 192.168.1.2:80 cookie server02
|
||||||
|
|
||||||
|
|
||||||
Surveillance des serveurs
|
3.1) Surveillance des serveurs
|
||||||
=========================
|
------------------------------
|
||||||
|
A cette date, l'état des serveurs n'est testé que par établissement de connexion
|
||||||
A cette date, l'état des serveurs n'est testé que par établissement
|
TCP toutes les 2 secondes, avec 3 essais pour déclarer un serveur en panne, 2
|
||||||
de connexion TCP toutes les 2 secondes, avec 3 essais pour déclarer
|
pour le déclarer utilisable. Un serveur hors d'usage ne sera pas utilisé dans le
|
||||||
un serveur en panne, 2 pour le déclarer utilisable. Un serveur hors
|
processus de répartition de charge interne. Pour activer la surveillance,
|
||||||
d'usage ne sera pas utilisé dans le processus de répartition de charge
|
ajouter le mot clé 'check' à la fin de la déclaration du serveur. Il est
|
||||||
interne. Pour activer la surveillance, ajouter le mot clé 'check' à la
|
possible de spécifier l'intervalle (en millisecondes) séparant deux tests du
|
||||||
fin de la déclaration du serveur. Il est possible de spécifier
|
serveur par le paramètre "inter", le nombre d'échecs acceptés par le paramètre
|
||||||
l'intervalle (en millisecondes) séparant deux tests du serveur par le
|
"fall", et le nombre de succès avant reprise par le paramètre "rise". Les
|
||||||
paramètre "inter", le nombre d'échecs acceptés par le paramètre "fall",
|
paramètres non précisés prennent les valeurs suivantes par défaut :
|
||||||
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
|
- inter : 2000
|
||||||
- rise : 2
|
- rise : 2
|
||||||
- fall : 3
|
- fall : 3
|
||||||
|
|
||||||
Exemple : même que précédemment avec surveillance
|
Exemples :
|
||||||
-------
|
----------
|
||||||
|
# même que précédemment avec surveillance
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
cookie SERVERID
|
cookie SERVERID
|
||||||
balance roundrobin
|
balance roundrobin
|
||||||
server web1 192.168.1.1:80 cookie server01 check
|
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
|
||||||
|
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
|
server web2 192.168.1.2:80 cookie server02 check
|
||||||
|
|
||||||
|
|
||||||
Reconnexion vers un répartiteur en cas d'échec direct
|
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
|
||||||
En mode HTTP, si un serveur défini par un cookie ne répond plus, les
|
seront définitivement aiguillés dessus à cause de leur cookie, et de ce fait,
|
||||||
clients seront définitivement aiguillés dessus à cause de leur cookie,
|
définitivement privés de service. La spécification du paramètre 'redispatch'
|
||||||
et de ce fait, définitivement privés de service. La spécification du
|
autorise dans ce cas à renvoyer les connexions échouées vers le répartiteur
|
||||||
paramètre "redispatch" autorise dans ce cas à renvoyer les connexions
|
(externe ou interne) afin d'assigner un nouveau serveur à ces clients.
|
||||||
échouées vers le répartiteur (externe ou interne) afin d'assigner un
|
|
||||||
nouveau serveur à ces clients.
|
|
||||||
|
|
||||||
Exemple :
|
Exemple :
|
||||||
-------
|
---------
|
||||||
listen http_proxy 0.0.0.0:80
|
listen http_proxy 0.0.0.0:80
|
||||||
mode http
|
mode http
|
||||||
cookie SERVERID
|
cookie SERVERID
|
||||||
@ -434,18 +560,24 @@ Exemple :
|
|||||||
server web2 192.168.1.2:80 cookie server02
|
server web2 192.168.1.2:80 cookie server02
|
||||||
redispatch # renvoyer vers dispatch si serveur HS.
|
redispatch # renvoyer vers dispatch si serveur HS.
|
||||||
|
|
||||||
Fonctionnement en mode transparent
|
|
||||||
==================================
|
|
||||||
|
|
||||||
En mode HTTP, le mot clé "transparent" permet d'intercepter des
|
4) Fonctionnalités additionnelles
|
||||||
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'autres fonctionnalités d'usage moins courant sont disponibles. Il s'agit
|
||||||
détournée. Le système doit permettre de rediriger les paquets
|
principalement du mode transparent, de la journalisation des connexions, et de
|
||||||
vers un processus local.
|
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 :
|
Exemple :
|
||||||
-------
|
---------
|
||||||
listen http_proxy 0.0.0.0:65000
|
listen http_proxy 0.0.0.0:65000
|
||||||
mode http
|
mode http
|
||||||
transparent
|
transparent
|
||||||
@ -456,17 +588,25 @@ Exemple :
|
|||||||
# iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
|
# iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
|
||||||
--dport 80 -j REDIRECT --to-ports 65000
|
--dport 80 -j REDIRECT --to-ports 65000
|
||||||
|
|
||||||
Journalisation des connexions
|
|
||||||
=============================
|
|
||||||
|
|
||||||
Les connexions TCP et HTTP peuvent donner lieu à une journalisation
|
4.2) Journalisation des connexions
|
||||||
sommaire indiquant, pour chaque connexion, la date, l'heure, les adresses
|
----------------------------------
|
||||||
IP source et destination, et les ports source et destination qui la
|
Les connexions TCP et HTTP peuvent donner lieu à une journalisation sommaire ou
|
||||||
caractérisent. Ultérieurement, les URLs seront loguées en mode HTTP,
|
détaillée indiquant, pour chaque connexion, la date, l'heure, l'adresse IP
|
||||||
tout comme les arrêts de service. Tous les messages sont envoyés en
|
source, le serveur destination, la durée de la connexion, les temps de réponse,
|
||||||
syslog vers un ou deux serveurs. La syntaxe est la suivante :
|
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>
|
||||||
|
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 :
|
Exemple :
|
||||||
---------
|
---------
|
||||||
@ -475,34 +615,62 @@ Exemple :
|
|||||||
log 192.168.2.200 local3
|
log 192.168.2.200 local3
|
||||||
log 192.168.2.201 local4
|
log 192.168.2.201 local4
|
||||||
|
|
||||||
Les connexions sont envoyées en niveau "info". Les démarrages de
|
Les connexions sont envoyées en niveau "info". Les démarrages de service seront
|
||||||
service seront envoyés en "notice", les signaux d'arrêts en "warning"
|
envoyés en "notice", les signaux d'arrêts en "warning" et les arrêts définitifs
|
||||||
et les arrêts définitifs en "alert". Ceci est valable aussi bien
|
en "alert". Ceci est valable aussi bien pour les proxies que pour les serveurs
|
||||||
pour les proxies que pour les serveurs testés au sein des proxies.
|
testés au sein des proxies. Les catégories possibles sont :
|
||||||
|
|
||||||
Les catégories possibles sont :
|
|
||||||
kern, user, mail, daemon, auth, syslog, lpr, news,
|
kern, user, mail, daemon, auth, syslog, lpr, news,
|
||||||
uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
|
uucp, cron, auth2, ftp, ntp, audit, alert, cron2,
|
||||||
local0, local1, local2, local3, local4, local5, local6, local7
|
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).
|
||||||
|
|
||||||
Modification des entêtes HTTP
|
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.
|
||||||
|
|
||||||
En mode HTTP uniquement, il est possible de remplacer certains entêtes
|
Exemple :
|
||||||
dans la requête et/ou la réponse à partir d'expressions régulières. Une
|
---------
|
||||||
limitation cependant : les entêtes fournis au milieu de connexions
|
listen http_proxy 0.0.0.0:80
|
||||||
persistentes (keep-alive) ne sont pas vus. Les données ne sont pas
|
mode http
|
||||||
affectées, ceci ne s'applique qu'aux entêtes.
|
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 :
|
La syntaxe est :
|
||||||
reqadd <string> pour ajouter un entête dans la requête
|
reqadd <string> pour ajouter un en-tête dans la requête
|
||||||
reqrep <search> <replace> pour modifier la requête
|
reqrep <search> <replace> pour modifier la requête
|
||||||
reqrep <search> pour supprimer un entête dans 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 entête dans la réponse
|
rspadd <string> pour ajouter un en-tête dans la réponse
|
||||||
rsprep <search> <replace> pour modifier la réponse
|
rsprep <search> <replace> pour modifier la réponse
|
||||||
rsprep <search> pour supprimer un entête dans 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
|
<search> est une expression régulière compatible GNU regexp supportant
|
||||||
@ -529,12 +697,12 @@ imprimable (utile pour le saut de ligne) inscrivant '\x' suivi du code
|
|||||||
hexadécimal de ce caractère (comme en C).
|
hexadécimal de ce caractère (comme en C).
|
||||||
|
|
||||||
<string> représente une chaîne qui sera ajoutée systématiquement après la
|
<string> représente une chaîne qui sera ajoutée systématiquement après la
|
||||||
dernière ligne d'entête.
|
dernière ligne d'en-tête.
|
||||||
|
|
||||||
Remarques :
|
Remarques :
|
||||||
---------
|
---------
|
||||||
- la première ligne de la requête et celle de la réponse sont traitées comme
|
- la première ligne de la requête et celle de la réponse sont traitées comme
|
||||||
des entêtes, ce qui permet de réécrire des URL et des codes d'erreur.
|
des en-têtes, ce qui permet de réécrire des URL et des codes d'erreur.
|
||||||
- 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
|
- 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
|
||||||
'srvexp'. Ces noms sont toujours supportés mais déconseillés.
|
'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
|
- pour des raisons de performances, le nombre total de caractères ajoutés sur
|
||||||
@ -547,15 +715,15 @@ Exemples :
|
|||||||
--------
|
--------
|
||||||
reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3
|
reqrep ^(GET.*)(.free.fr)(.*) \1.online.fr\3
|
||||||
reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
|
reqrep ^(POST.*)(.free.fr)(.*) \1.online.fr\3
|
||||||
reqrep ^Proxy-Connection:.* Proxy-Connection:\ close
|
reqirep ^Proxy-Connection:.* Proxy-Connection:\ close
|
||||||
rsprep ^Server:.* Server:\ Tux-2.0
|
rspirep ^Server:.* Server:\ Tux-2.0
|
||||||
rsprep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
|
rspirep ^(Location:\ )([^:]*://[^/]*)(.*) \1\3
|
||||||
rspdel ^Connection:.*
|
rspidel ^Connection:
|
||||||
rspadd Connection:\ close
|
rspadd Connection:\ close
|
||||||
|
|
||||||
|
|
||||||
Répartition avec persistence
|
4.4) Répartition avec persistence
|
||||||
============================
|
---------------------------------
|
||||||
|
|
||||||
La combinaison de l'insertion de cookie avec la répartition de charge interne
|
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
|
permet d'assurer une persistence dans les sessions HTTP d'une manière
|
||||||
@ -563,6 +731,7 @@ pratiquement transparente pour les applications. Le principe est simple :
|
|||||||
- assigner un cookie à chaque serveur
|
- assigner un cookie à chaque serveur
|
||||||
- effectuer une répartition interne
|
- effectuer une répartition interne
|
||||||
- insérer un cookie dans les réponses issues d'une répartition
|
- insérer un cookie dans les réponses issues d'une répartition
|
||||||
|
- cacher ce cookie à l'application
|
||||||
|
|
||||||
Exemple :
|
Exemple :
|
||||||
-------
|
-------
|
||||||
@ -572,6 +741,7 @@ Exemple :
|
|||||||
balance roundrobin
|
balance roundrobin
|
||||||
server 192.168.1.1:80 cookie server01 check
|
server 192.168.1.1:80 cookie server01 check
|
||||||
server 192.168.1.2:80 cookie server02 check
|
server 192.168.1.2:80 cookie server02 check
|
||||||
|
reqidel ^Cookie:\ SERVERID=
|
||||||
|
|
||||||
=======================
|
=======================
|
||||||
| Paramétrage système |
|
| Paramétrage système |
|
||||||
|
176
haproxy.c
176
haproxy.c
@ -10,12 +10,19 @@
|
|||||||
* Pending bugs :
|
* Pending bugs :
|
||||||
* - solaris only : sometimes, an HTTP proxy with only a dispatch address causes
|
* - solaris only : sometimes, an HTTP proxy with only a dispatch address causes
|
||||||
* the proxy to terminate (no core) if the client breaks the connection during
|
* the proxy to terminate (no core) if the client breaks the connection during
|
||||||
* the response. Seen on 1.1.8pre4, but never reproduced.
|
* the response. Seen on 1.1.8pre4, but never reproduced. May not be related to
|
||||||
|
* the snprintf() bug since requests we simple (GET / HTTP/1.0).
|
||||||
* - cookie in insert+indirect mode sometimes segfaults !
|
* - cookie in insert+indirect mode sometimes segfaults !
|
||||||
* - a proxy with an invalid config will prevent the startup even if disabled.
|
* - a proxy with an invalid config will prevent the startup even if disabled.
|
||||||
*
|
*
|
||||||
* ChangeLog :
|
* ChangeLog :
|
||||||
*
|
*
|
||||||
|
* 2002/04/19 : 1.1.9
|
||||||
|
* - don't use snprintf()'s return value as an end of message since it may
|
||||||
|
* be larger. This caused bus errors and segfaults in internal libc's
|
||||||
|
* getenv() during localtime() in send_log().
|
||||||
|
* - removed dead insecure send_syslog() function and all references to it.
|
||||||
|
* - fixed warnings on Solaris due to buggy implementation of isXXXX().
|
||||||
* 2002/04/18 : 1.1.8
|
* 2002/04/18 : 1.1.8
|
||||||
* - option "dontlognull"
|
* - option "dontlognull"
|
||||||
* - fixed "double space" bug in config parser
|
* - fixed "double space" bug in config parser
|
||||||
@ -134,8 +141,8 @@
|
|||||||
#include <linux/netfilter_ipv4.h>
|
#include <linux/netfilter_ipv4.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HAPROXY_VERSION "1.1.8"
|
#define HAPROXY_VERSION "1.1.9"
|
||||||
#define HAPROXY_DATE "2002/04/18"
|
#define HAPROXY_DATE "2002/04/19"
|
||||||
|
|
||||||
/* this is for libc5 for example */
|
/* this is for libc5 for example */
|
||||||
#ifndef TCP_NODELAY
|
#ifndef TCP_NODELAY
|
||||||
@ -748,78 +755,12 @@ struct sockaddr_in *str2sa(char *str) {
|
|||||||
return &sa;
|
return &sa;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function tries to send a syslog message to the syslog server at
|
|
||||||
* address <sa>. It doesn't care about errors nor does it report them.
|
|
||||||
* WARNING! no check is made on the prog+hostname+date length, so the
|
|
||||||
* local hostname + the prog name must be shorter than MAX_SYSLOG_LEN-19.
|
|
||||||
* the message will be truncated to fit the maximum length.
|
|
||||||
*/
|
|
||||||
void send_syslog(struct sockaddr_in *sa,
|
|
||||||
int facility, int level, char *message)
|
|
||||||
{
|
|
||||||
|
|
||||||
static int logfd = -1; /* syslog UDP socket */
|
|
||||||
struct timeval tv;
|
|
||||||
struct tm *tm;
|
|
||||||
static char logmsg[MAX_SYSLOG_LEN];
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if (logfd < 0) {
|
|
||||||
if ((logfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (facility < 0 || level < 0
|
|
||||||
|| sa == NULL || progname == NULL || message == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
tm = localtime(&tv.tv_sec);
|
|
||||||
|
|
||||||
p = logmsg;
|
|
||||||
//p += sprintf(p, "<%d>%s %2d %02d:%02d:%02d %s %s[%d]: ",
|
|
||||||
// facility * 8 + level,
|
|
||||||
// monthname[tm->tm_mon],
|
|
||||||
// tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
|
||||||
// hostname, progname, pid);
|
|
||||||
/* 20011216/WT : other progs don't set the hostname, and syslogd
|
|
||||||
* systematically repeats it which is contrary to RFC3164.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* warning: buffer overflow possible on progname.
|
|
||||||
*/
|
|
||||||
p += sprintf(p, "<%d>%s %2d %02d:%02d:%02d %s[%d]: ",
|
|
||||||
facility * 8 + level,
|
|
||||||
monthname[tm->tm_mon],
|
|
||||||
tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
|
||||||
progname, pid);
|
|
||||||
|
|
||||||
if (((char *)&logmsg - p + MAX_SYSLOG_LEN) > 0) {
|
|
||||||
int len = strlen(message);
|
|
||||||
if (len > ((char *)&logmsg + MAX_SYSLOG_LEN - p))
|
|
||||||
len = ((char *)&logmsg + MAX_SYSLOG_LEN - p);
|
|
||||||
memcpy(p, message, len);
|
|
||||||
p += len;
|
|
||||||
}
|
|
||||||
#ifndef MSG_NOSIGNAL
|
|
||||||
sendto(logfd, logmsg, p - logmsg, MSG_DONTWAIT,
|
|
||||||
(struct sockaddr *)sa, sizeof(*sa));
|
|
||||||
#else
|
|
||||||
sendto(logfd, logmsg, p - logmsg, MSG_DONTWAIT | MSG_NOSIGNAL,
|
|
||||||
(struct sockaddr *)sa, sizeof(*sa));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sends a syslog message to both log servers of a proxy,
|
* This function sends a syslog message to both log servers of a proxy,
|
||||||
* or to global log servers if the proxy is NULL.
|
* or to global log servers if the proxy is NULL.
|
||||||
* It also tries not to waste too much time computing the message header.
|
* It also tries not to waste too much time computing the message header.
|
||||||
* It doesn't care about errors nor does it report them.
|
* It doesn't care about errors nor does it report them.
|
||||||
* WARNING! no check is made on the prog+hostname+date length, so the
|
|
||||||
* local hostname + the prog name must be shorter than MAX_SYSLOG_LEN-19.
|
|
||||||
* the message will be truncated to fit the maximum length.
|
|
||||||
*/
|
*/
|
||||||
void send_log(struct proxy *p, int level, char *message, ...) {
|
void send_log(struct proxy *p, int level, char *message, ...) {
|
||||||
static int logfd = -1; /* syslog UDP socket */
|
static int logfd = -1; /* syslog UDP socket */
|
||||||
@ -844,25 +785,32 @@ void send_log(struct proxy *p, int level, char *message, ...) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
if (tv.tv_sec != tvsec) {
|
if (tv.tv_sec != tvsec || dataptr == NULL) {
|
||||||
/* this string is rebuild only once a second */
|
/* this string is rebuild only once a second */
|
||||||
struct tm *tm = localtime(&tv.tv_sec);
|
struct tm *tm = localtime(&tv.tv_sec);
|
||||||
tvsec = tv.tv_sec;
|
tvsec = tv.tv_sec;
|
||||||
|
|
||||||
/*
|
hdr_len = snprintf(logmsg, sizeof(logmsg),
|
||||||
* warning: buffer overflow possible on progname.
|
"<<<<>%s %2d %02d:%02d:%02d %s[%d]: ",
|
||||||
|
monthname[tm->tm_mon],
|
||||||
|
tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||||
|
progname, pid);
|
||||||
|
/* WARNING: depending upon implementations, snprintf may return
|
||||||
|
* either -1 or the number of bytes that would be needed to store
|
||||||
|
* the total message. In both cases, we must adjust it.
|
||||||
*/
|
*/
|
||||||
dataptr = logmsg + snprintf(logmsg, sizeof(logmsg),
|
if (hdr_len < 0 || hdr_len > sizeof(logmsg))
|
||||||
"<<<<>%s %2d %02d:%02d:%02d %s[%d]: ",
|
hdr_len = sizeof(logmsg);
|
||||||
monthname[tm->tm_mon],
|
|
||||||
tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
|
dataptr = logmsg + hdr_len;
|
||||||
progname, pid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(argp, message);
|
va_start(argp, message);
|
||||||
data_len = vsnprintf(dataptr, logmsg + sizeof(logmsg) - dataptr, message, argp);
|
data_len = vsnprintf(dataptr, logmsg + sizeof(logmsg) - dataptr, message, argp);
|
||||||
dataptr[data_len - 1] = '\n'; /* force a break on ultra-long lines */
|
if (data_len < 0 || data_len > (logmsg + sizeof(logmsg) - dataptr))
|
||||||
|
data_len = logmsg + sizeof(logmsg) - dataptr;
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
dataptr[data_len - 1] = '\n'; /* force a break on ultra-long lines */
|
||||||
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
if (global.logfac1 >= 0) {
|
if (global.logfac1 >= 0) {
|
||||||
@ -889,7 +837,13 @@ void send_log(struct proxy *p, int level, char *message, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (nbloggers-- > 0) {
|
while (nbloggers-- > 0) {
|
||||||
/* do this for each log target */
|
/* For each target, we may have a different facility.
|
||||||
|
* We can also have a different log level for each message.
|
||||||
|
* This induces variations in the message header length.
|
||||||
|
* Since we don't want to recompute it each time, nor copy it every
|
||||||
|
* time, we only change the facility in the pre-computed header,
|
||||||
|
* and we change the pointer to the header accordingly.
|
||||||
|
*/
|
||||||
fac_level = (facilities[nbloggers] << 3) + level;
|
fac_level = (facilities[nbloggers] << 3) + level;
|
||||||
log_ptr = logmsg + 3; /* last digit of the log level */
|
log_ptr = logmsg + 3; /* last digit of the log level */
|
||||||
do {
|
do {
|
||||||
@ -898,15 +852,14 @@ void send_log(struct proxy *p, int level, char *message, ...) {
|
|||||||
log_ptr--;
|
log_ptr--;
|
||||||
} while (fac_level && log_ptr > logmsg);
|
} while (fac_level && log_ptr > logmsg);
|
||||||
*log_ptr = '<';
|
*log_ptr = '<';
|
||||||
hdr_len = dataptr - log_ptr;
|
|
||||||
|
|
||||||
/* the total syslog message now starts at p, for hdr_len+data_len */
|
/* the total syslog message now starts at logptr, for dataptr+data_len-logptr */
|
||||||
|
|
||||||
#ifndef MSG_NOSIGNAL
|
#ifndef MSG_NOSIGNAL
|
||||||
sendto(logfd, log_ptr, hdr_len + data_len, MSG_DONTWAIT,
|
sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT,
|
||||||
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
||||||
#else
|
#else
|
||||||
sendto(logfd, log_ptr, hdr_len + data_len, MSG_DONTWAIT | MSG_NOSIGNAL,
|
sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT | MSG_NOSIGNAL,
|
||||||
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2096,7 +2049,7 @@ int exp_replace(char *dst, char *src, char *str, regmatch_t *matches) {
|
|||||||
while (*str) {
|
while (*str) {
|
||||||
if (*str == '\\') {
|
if (*str == '\\') {
|
||||||
str++;
|
str++;
|
||||||
if (isdigit(*str)) {
|
if (isdigit((int)*str)) {
|
||||||
int len, num;
|
int len, num;
|
||||||
|
|
||||||
num = *str - '0';
|
num = *str - '0';
|
||||||
@ -2298,7 +2251,7 @@ int process_cli(struct session *t) {
|
|||||||
p1 = req->h + 8; /* first char after 'Cookie: ' */
|
p1 = req->h + 8; /* first char after 'Cookie: ' */
|
||||||
|
|
||||||
while (p1 < ptr) {
|
while (p1 < ptr) {
|
||||||
while (p1 < ptr && (isspace(*p1) || *p1 == ';'))
|
while (p1 < ptr && (isspace((int)*p1) || *p1 == ';'))
|
||||||
p1++;
|
p1++;
|
||||||
|
|
||||||
if (p1 == ptr)
|
if (p1 == ptr)
|
||||||
@ -2326,7 +2279,7 @@ int process_cli(struct session *t) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
p4=p3;
|
p4=p3;
|
||||||
while (p4 < ptr && !isspace(*p4) && *p4 != ';')
|
while (p4 < ptr && !isspace((int)*p4) && *p4 != ';')
|
||||||
p4++;
|
p4++;
|
||||||
|
|
||||||
/* here, we have the cookie name between p1 and p2,
|
/* here, we have the cookie name between p1 and p2,
|
||||||
@ -2776,7 +2729,7 @@ int process_srv(struct session *t) {
|
|||||||
p1 = rep->h + 12; /* first char after 'Set-Cookie: ' */
|
p1 = rep->h + 12; /* first char after 'Set-Cookie: ' */
|
||||||
|
|
||||||
while (p1 < ptr) { /* in fact, we'll break after the first cookie */
|
while (p1 < ptr) { /* in fact, we'll break after the first cookie */
|
||||||
while (p1 < ptr && (isspace(*p1)))
|
while (p1 < ptr && (isspace((int)*p1)))
|
||||||
p1++;
|
p1++;
|
||||||
|
|
||||||
if (p1 == ptr || *p1 == ';') /* end of cookie */
|
if (p1 == ptr || *p1 == ';') /* end of cookie */
|
||||||
@ -2796,7 +2749,7 @@ int process_srv(struct session *t) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
p4 = p3;
|
p4 = p3;
|
||||||
while (p4 < ptr && !isspace(*p4) && *p4 != ';')
|
while (p4 < ptr && !isspace((int)*p4) && *p4 != ';')
|
||||||
p4++;
|
p4++;
|
||||||
|
|
||||||
/* here, we have the cookie name between p1 and p2,
|
/* here, we have the cookie name between p1 and p2,
|
||||||
@ -3167,13 +3120,6 @@ int process_chk(struct task *t) {
|
|||||||
if (!(global.mode & MODE_QUIET))
|
if (!(global.mode & MODE_QUIET))
|
||||||
Warning("server %s DOWN.\n", s->id);
|
Warning("server %s DOWN.\n", s->id);
|
||||||
|
|
||||||
// sprintf(trash, "Server %s/%s is DOWN.\n",
|
|
||||||
// s->proxy->id, s->id);
|
|
||||||
//
|
|
||||||
// if (s->proxy->logfac1 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv1, s->proxy->logfac1, LOG_ALERT, trash);
|
|
||||||
// if (s->proxy->logfac2 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv2, s->proxy->logfac2, LOG_ALERT, trash);
|
|
||||||
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
|
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3195,12 +3141,6 @@ int process_chk(struct task *t) {
|
|||||||
if (s->health == s->rise) {
|
if (s->health == s->rise) {
|
||||||
if (!(global.mode & MODE_QUIET))
|
if (!(global.mode & MODE_QUIET))
|
||||||
Warning("server %s UP.\n", s->id);
|
Warning("server %s UP.\n", s->id);
|
||||||
// sprintf(trash, "Server %s/%s is UP.\n", s->proxy->id, s->id);
|
|
||||||
|
|
||||||
// if (s->proxy->logfac1 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv1, s->proxy->logfac1, LOG_NOTICE, trash);
|
|
||||||
// if (s->proxy->logfac2 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv2, s->proxy->logfac2, LOG_NOTICE, trash);
|
|
||||||
send_log(s->proxy, LOG_NOTICE, "Server %s/%s is UP.\n", s->proxy->id, s->id);
|
send_log(s->proxy, LOG_NOTICE, "Server %s/%s is UP.\n", s->proxy->id, s->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3221,13 +3161,6 @@ int process_chk(struct task *t) {
|
|||||||
if (s->health == s->rise) {
|
if (s->health == s->rise) {
|
||||||
if (!(global.mode & MODE_QUIET))
|
if (!(global.mode & MODE_QUIET))
|
||||||
Warning("server %s DOWN.\n", s->id);
|
Warning("server %s DOWN.\n", s->id);
|
||||||
// sprintf(trash, "Server %s/%s is DOWN.\n",
|
|
||||||
// s->proxy->id, s->id);
|
|
||||||
//
|
|
||||||
// if (s->proxy->logfac1 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv1, s->proxy->logfac1, LOG_ALERT, trash);
|
|
||||||
// if (s->proxy->logfac2 >= 0)
|
|
||||||
// send_syslog(&s->proxy->logsrv2, s->proxy->logfac2, LOG_ALERT, trash);
|
|
||||||
|
|
||||||
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
|
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
|
||||||
}
|
}
|
||||||
@ -3488,12 +3421,6 @@ static int maintain_proxies(void) {
|
|||||||
t = tv_remain(&now, &p->stop_time);
|
t = tv_remain(&now, &p->stop_time);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
Warning("Proxy %s stopped.\n", p->id);
|
Warning("Proxy %s stopped.\n", p->id);
|
||||||
// sprintf(trash, "Proxy %s stopped.\n", p->id);
|
|
||||||
|
|
||||||
// if (p->logfac1 >= 0)
|
|
||||||
// send_syslog(&p->logsrv1, p->logfac1, LOG_WARNING, trash);
|
|
||||||
// if (p->logfac2 >= 0)
|
|
||||||
// send_syslog(&p->logsrv2, p->logfac2, LOG_WARNING, trash);
|
|
||||||
send_log(p, LOG_WARNING, "Proxy %s stopped.\n", p->id);
|
send_log(p, LOG_WARNING, "Proxy %s stopped.\n", p->id);
|
||||||
|
|
||||||
fd_delete(p->listen_fd);
|
fd_delete(p->listen_fd);
|
||||||
@ -3523,13 +3450,6 @@ static void soft_stop(void) {
|
|||||||
while (p) {
|
while (p) {
|
||||||
if (p->state != PR_STDISABLED) {
|
if (p->state != PR_STDISABLED) {
|
||||||
Warning("Stopping proxy %s in %d ms.\n", p->id, p->grace);
|
Warning("Stopping proxy %s in %d ms.\n", p->id, p->grace);
|
||||||
// sprintf(trash, "Stopping proxy %s in %d ms.\n", p->id, p->grace);
|
|
||||||
|
|
||||||
// if (p->logfac1 >= 0)
|
|
||||||
// send_syslog(&p->logsrv1, p->logfac1, LOG_WARNING, trash);
|
|
||||||
// if (p->logfac2 >= 0)
|
|
||||||
// send_syslog(&p->logsrv2, p->logfac2, LOG_WARNING, trash);
|
|
||||||
|
|
||||||
send_log(p, LOG_WARNING, "Stopping proxy %s in %d ms.\n", p->id, p->grace);
|
send_log(p, LOG_WARNING, "Stopping proxy %s in %d ms.\n", p->id, p->grace);
|
||||||
tv_delayfrom(&p->stop_time, &now, p->grace);
|
tv_delayfrom(&p->stop_time, &now, p->grace);
|
||||||
}
|
}
|
||||||
@ -4298,7 +4218,7 @@ int readcfgfile(char *file) {
|
|||||||
end = line + strlen(line);
|
end = line + strlen(line);
|
||||||
|
|
||||||
/* skip leading spaces */
|
/* skip leading spaces */
|
||||||
while (isspace(*line))
|
while (isspace((int)*line))
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
arg = 0;
|
arg = 0;
|
||||||
@ -4345,10 +4265,10 @@ int readcfgfile(char *file) {
|
|||||||
*line = 0;
|
*line = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (isspace(*line)) {
|
else if (isspace((int)*line)) {
|
||||||
/* a non-escaped space is an argument separator */
|
/* a non-escaped space is an argument separator */
|
||||||
*line++ = 0;
|
*line++ = 0;
|
||||||
while (isspace(*line))
|
while (isspace((int)*line))
|
||||||
line++;
|
line++;
|
||||||
args[++arg] = line;
|
args[++arg] = line;
|
||||||
}
|
}
|
||||||
@ -4658,14 +4578,6 @@ int start_proxies() {
|
|||||||
FD_SET(fd, StaticReadEvent);
|
FD_SET(fd, StaticReadEvent);
|
||||||
fd_insert(fd);
|
fd_insert(fd);
|
||||||
listeners++;
|
listeners++;
|
||||||
// fprintf(stderr,"Proxy %s : socket bound.\n", curproxy->id);
|
|
||||||
|
|
||||||
// sprintf(trash, "Proxy %s started.\n", curproxy->id);
|
|
||||||
//
|
|
||||||
// if (curproxy->logfac1 >= 0)
|
|
||||||
// send_syslog(&curproxy->logsrv1, curproxy->logfac1, LOG_INFO, trash);
|
|
||||||
// if (curproxy->logfac2 >= 0)
|
|
||||||
// send_syslog(&curproxy->logsrv2, curproxy->logfac2, LOG_INFO, trash);
|
|
||||||
|
|
||||||
send_log(curproxy, LOG_NOTICE, "Proxy %s started.\n", curproxy->id);
|
send_log(curproxy, LOG_NOTICE, "Proxy %s started.\n", curproxy->id);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user