From eedaa9f220c6f287438c422b73f668a9d8bf0352 Mon Sep 17 00:00:00 2001 From: willy tarreau <willy@wtap.(none)> Date: Sat, 17 Dec 2005 14:08:03 +0100 Subject: [PATCH] * released 1.1.23 * fixed a stupid bug introduced in 1.1.22 which caused second and subsequent 'default' sections to keep previous parameters, and not initialize logs correctly. * fixed a second stupid bug introduced in 1.1.22 which caused configurations relying on 'dispatch' mode to segfault at the first connection. * 'option httpchk' now supports method, HTTP version and a few headers. * now, 'option httpchk', 'cookie' and 'capture' can be specified in 'defaults' section * a fresh new english documentation * large Makefile cleanup for increased portability * new build script 'build.cfg' for Formilux-0.1.8 * new startup script 'init.haproxy.flx0' for Formilux-0.1.8 --- CHANGELOG | 12 +- Makefile | 49 +- TODO | 13 +- doc/haproxy-en.txt | 1257 +++++++++++++++++++++++ doc/haproxy.txt | 74 +- examples/build.cfg | 25 + examples/config.rc.haproxy | 1 - init.d/haproxy => examples/init.haproxy | 0 examples/init.haproxy.flx0 | 20 + haproxy.c | 136 ++- tests/defaults.cfg | 2 +- 11 files changed, 1512 insertions(+), 77 deletions(-) create mode 100644 doc/haproxy-en.txt create mode 100644 examples/build.cfg rename init.d/haproxy => examples/init.haproxy (100%) create mode 100644 examples/init.haproxy.flx0 diff --git a/CHANGELOG b/CHANGELOG index 658224b2b..cdf4e5aa5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,17 @@ ChangeLog : =========== -2003/09/10 : +2003/09/19 : 1.1.23 + - fixed a stupid bug introduced in 1.1.22 which caused second and subsequent + 'default' sections to keep previous parameters, and not initialize logs + correctly. + - fixed a second stupid bug introduced in 1.1.22 which caused configurations + relying on 'dispatch' mode to segfault at the first connection. + - 'option httpchk' now supports method, HTTP version and a few headers. + - now, 'option httpchk', 'cookie' and 'capture' can be specified in + 'defaults' section + +2003/09/10 : 1.1.22 - 'listen' now supports optionnal address:port-range lists - 'bind' introduced to add new listen addresses - fixed a bug which caused a session to be kept established on a server till diff --git a/Makefile b/Makefile index 45fcad51c..43e4493d4 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,72 @@ +# This makefile supports different OS and CPU setups. +# You should use it this way : +# make TARGET=os CPU=cpu + # Select target OS. TARGET must match a system for which COPTS and LIBS are # correctly defined below. -# You can set it on make's command line. eg: make TARGET=solaris TARGET = linux24 #TARGET = linux22 #TARGET = solaris -#TARGET = solarisv9 #TARGET = openbsd -CC = gcc -LD = gcc +# pass CPU=<cpu_name> to make to optimize for a particular CPU +CPU = generic +#CPU = i586 +#CPU = i686 +#CPU = ultrasparc # By default, we use libc's regex. REGEX=libc #REGEX=pcre +# tools options +CC = gcc +LD = gcc + # This is the directory hosting include/pcre.h and lib/libpcre.* when REGEX=pcre PCREDIR := $(shell pcre-config --prefix 2>/dev/null || :) #PCREDIR=/usr/local # This is for Linux 2.4 with netfilter -COPTS.linux24 = -O2 -DNETFILTER +COPTS.linux24 = -DNETFILTER LIBS.linux24 = # This is for Linux 2.2 -COPTS.linux22 = -O2 -DUSE_GETSOCKNAME +COPTS.linux22 = -DUSE_GETSOCKNAME LIBS.linux22 = # This is for Solaris 8 -COPTS.solaris = -O2 -fomit-frame-pointer -DSOLARIS +COPTS.solaris = -fomit-frame-pointer -DSOLARIS LIBS.solaris = -lnsl -lsocket -# This is for Solaris 8 on UltraSparc2 processor -COPTS.solarisv9 = -O6 -mcpu=v9 -mtune=ultrasparc -fomit-frame-pointer -DSOLARIS -LIBS.solarisv9 = -lnsl -lsocket - # This is for OpenBSD 3.0 -COPTS.openbsd = -O2 +COPTS.openbsd = LIBS.openbsd = -COPTS.libc= -LIBS.libs= +# CPU dependant optimizations +COPTS.generic = -O2 +COPTS.i586 = -O2 -march=i586 +COPTS.i686 = -O2 -march=i686 +COPTS.ultrasparc = -O6 -mcpu=v9 -mtune=ultrasparc +# options for standard regex library +COPTS.libc= +LIBS.libc= + +# options for libpcre COPTS.pcre=-DUSE_PCRE -I$(PCREDIR)/include LIBS.pcre=-L$(PCREDIR)/lib -lpcreposix -lpcre +# you can enable debug arguments with "DEBUG=-g" or disable them with "DEBUG=" #DEBUG = DEBUG = -g -COPTS=$(COPTS.$(TARGET)) $(COPTS.$(REGEX)) +# global options +TARGET_OPTS=$(COPTS.$(TARGET)) +REGEX_OPTS=$(COPTS.$(REGEX)) +CPU_OPTS=$(COPTS.$(CPU)) + +COPTS=$(CPU_OPTS) $(TARGET_OPTS) $(REGEX_OPTS) LIBS=$(LIBS.$(TARGET)) $(LIBS.$(REGEX)) # - use -DSTATTIME=0 to disable statistics, else specify an interval in diff --git a/TODO b/TODO index 72301b2bf..c11c82f3d 100644 --- a/TODO +++ b/TODO @@ -73,11 +73,14 @@ ok> ok- les options ok- le retry ok- les checks + ok- les cookies/captures - les options des serveurs ? - les filtres et regex ? - - les cookies/captures 5) impl�menter "balance source" pour faire un hash sur la source. + permettre de sp�cifier un masque sur lequel s'applique le hachage, + ainsi qu'une option pour hacher en fonction de l'adresse dans le + champ "x-forwarded-for". 6) possibilit� d'un process s�par� par listen : listen XXX @@ -86,6 +89,9 @@ ok> le fait de sp�cifier group_id fera que toutes les instances utilisant le m�me identifiant de groupe seront g�r�es par un m�me processus. + -> plus souple et plus compr�hensible de faire des sections par processus, + ce qui r�soud �galement le cas ci-dessous + 7) g�rer un chroot/uid/gid diff�rents par process : listen XXX chroot /truc @@ -100,3 +106,8 @@ identifiant de groupe seront g - alerte en cas de disparition - le nombre max de sessions � lui envoyer +ok> 9) ajouter des param�tres optionnels � l'option "httpchk" permettant +ok> de forcer la m�thode, la version HTTP et des headers. +ok> ex: option httpchk -> OPTIONS / HTTP/1.0 +ok> option httpchk /test -> OPTIONS /test HTTP/1.0 +ok> option httpchk HEAD / HTTP/1.0\nHost:\ www -> tel quel diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt new file mode 100644 index 000000000..7d678d2e1 --- /dev/null +++ b/doc/haproxy-en.txt @@ -0,0 +1,1257 @@ + + H A - P r o x y + --------------- + version 1.1.23 + willy tarreau + 2003/09/20 + +============ +| Abstract | +============ + +HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited for high +availability environments. Indeed, it can : + - route HTTP requests depending on statically assigned cookies ; + - spread the load among several servers while assuring server persistence + through the use of HTTP cookies ; + - switch to backup servers in the event a main one fails ; + - accept connections to special ports dedicated to service monitoring ; + - stop accepting connections without breaking existing ones ; + - add/modify/delete HTTP headers both ways ; + - block requests matching a particular pattern ; + +It needs very little resource. Its event-driven architecture allows it to easily +handle thousands of simultaneous connections on hundreds of instances without +risking the system's stability. + +==================== +| Start parameters | +==================== + +There are only a few command line options : + + -f <configuration file> + -n <high limit for the total number of simultaneous connections> + -N <high limit for the per-proxy number of simultaneous connections> + -d starts in foregreound with debugging mode enabled + -D starts in daemon mode + -s shows statistics (only if compiled in) + -l shows even more statistics (implies '-s') + + +The maximal number of connections per proxy is used as the default parameter for +each instance for which the 'maxconn' paramter is not set in the 'listen' section. + +The maximal number of total connections limits the number of connections used by +the whole process if the 'maxconn' parameter is not set in the 'global' section. + +The debugging mode has the same effect as the 'debug' option in the 'global' +section. When the proxy runs in this mode, it dumps every connections, +disconnections, timestamps, and HTTP headers to stdout. This should NEVER +be used in an init script since it will prevent the system from starting up. + +Statistics are only available if compiled in with the 'STATTIME' option. It's +only used during code optimization phases. + +====================== +| Configuration file | +====================== + +Structure +========= + +The configuration file parser ignores empty lines, spaces, tabs. Anything +between a sharp ('#') not following a backslash ('\'), and the end of a line +constitutes a comment and is ignored too. + +The configuration file is segmented in sections. A section begins whenever +one of these 3 keywords are encountered : + + - 'global' + - 'listen' + - 'defaults' + +Every parameter refer to the section beginning at the last one of these 3 +keywords. + + +1) Global parameters +==================== + +Global parameters affect the whole process behaviour. They are all set in the +'global' section. There may be several 'global' sections if needed, but their +parameters will only be merged. Allowed parameters in 'global' section include +the following ones : + + - log <address> <facility> [max_level] + - maxconn <number> + - uid <user id> + - gid <group id> + - chroot <directory> + - nbproc <number> + - daemon + - debug + - quiet + +1.1) Event logging +------------------ +Most events are logged : start, stop, servers going up and down, connections and +errors. Each event generates a syslog message which can be sent to up to 2 +servers. The syntax is : + + log <ip_address> <facility> [max_level] + +Connections are logged at level "info". Services initialization and servers +going up are logged at level "notice", termination signals are logged at +"warning", and definitive service termination, as well as loss of servers are +logged at level "alert". The optional parameter <max_level> specifies above +what level messages should be sent. Level can take one of these 8 values : + + emerg, alert, crit, err, warning, notice, info, debug + +For backwards compatibility with versions 1.1.16 and earlier, the default level +value is "debug" if not specified. + +Permitted facilities are : + kern, user, mail, daemon, auth, syslog, lpr, news, + uucp, cron, auth2, ftp, ntp, audit, alert, cron2, + local0, local1, local2, local3, local4, local5, local6, local7 + +According to RFC3164, messages are truncated to 1024 bytes before being emitted. + +Example : +--------- + global + log 192.168.2.200 local3 + log 127.0.0.1 local4 notice + +1.2) limiting the number of connections +--------------------------------------- +It is possible and recommended to limit the global number of per-process +connections. Since one connection includes both a client and a server, it +means that the max number of TCP sessions will be about the double of this +number. It's important to understand this when trying to find best values +for 'ulimit -n' before starting the proxy. To anticipate the number of +sockets needed, all these parameters must be counted : + + - 1 socket per incoming connection + - 1 socket per outgoing connection + - 1 socket per address/port/proxy tuple. + - 1 socket per server being health-checked + - 1 socket for all logs + +In simple configurations where each proxy only listens one one address/port, +set the limit of file descriptors (ulimit -n) to +(2 * maxconn + nbproxies + nbservers + 1). In a future release, haproxy may +be able to set this value itself. + +1.3) Drop of priviledges +------------------------ +In order to reduce the risk and consequences of attacks, in the event where a +yet non-identified vulnerability would be successfully exploited, it's possible +to lower the process priviledges and even isolate it in a riskless directory. + +In the 'global' section, the 'uid' parameter sets a numerical user identifier +which the process will switch to after binding its listening sockets. The value +'0', which normally represents the super-user, here indicates that the UID must +not change during startup. It's the default behaviour. The 'gid' parameter does +the same for the group identifier. It's particularly advised against use of +generic accounts such as 'nobody' because it has the same consequences as using +'root' if other services use them. + +The 'chroot' parameter makes the process isolate itself in an empty directory +just before switching its UID. This type of isolation (chroot) can sometimes +be worked around on certain OS (Linux, Solaris), provided that the attacker +has gained 'root' priviledges and has the ability to use or create a directory. +For this reason, it's capital to use a dedicated directory and not to share one +between several services of different nature. To make isolation more resistant, +it's recommended to use an empty directory without any right, and to change the +UID of the process so that it cannot do anything there. + +Note: in the event where such a vulnerability would be exploited, it's most +likely that first attempts would kill the process due to 'Segmentation Fault', +'Bus Error' or 'Illegal Instruction' signals. Eventhough it's true that +isolating the server reduces the risks of intrusion, it's sometimes useful to +find why a process dies, via the analysis of a 'core' file, although very rare +(the last bug of this sort was fixed in 1.1.9). For security reasons, most +systems disable the generation of core file when a process changes its UID. So +the two workarounds are either to start the process from a restricted user +account, which will not be able to chroot itself, or start it as root and not +change the UID. In both cases the core will be either in the start or the chroot +directories. Do not forget to allow core dumps prior to start the process : + +# ulimit -c unlimited + +Example : +--------- + + global + uid 30000 + gid 30000 + chroot /var/chroot/haproxy + +1.4) Startup modes +------------------ +The service can start in several different : + - foreground / background + - quiet / normal / debug + +The default mode is normal, foreground, which means that the program doesn't +return once started. NEVER EVER use this mode in a system startup script, or +the system won't boot. It needs to be started in background, so that it +returns immediately after forking. That's accomplished by the 'daemon' option +in the 'global' section, which is the equivalent of the '-D' command line +argument. + +Moreover, certain alert messages are still sent to the standard output even +in 'daemon' mode. To make them disappear, simply add the 'quiet' option in the +'global' section. This option has no command-line equivalent. + +Last, the 'debug' mode, enabled with the 'debug' option in the 'global' section, +and which is equivalent of the '-d' option, allows deep TCP/HTTP analysis, with +timestamped display of each connection, disconnection, and HTTP headers for both +ways. This mode is incompatible with 'daemon' and 'quiet' modes for obvious +reasons. + +1.5) Increasing the overall processing power +-------------------------------------------- +On multi-processor systems, it may seem to be a shame to use only one processor, +eventhough the load needed to saturate a recent processor are far above common +usage. Anyway, for very specific needs, the proxy can start several processes +between which the operating system will spread the incoming connections. The +number of processes is controlled by the 'nbproc' parameter in the 'global' +section. It defaults to 1, and obviously works only in 'daemon' mode. + +Example : +--------- + + global + daemon + quiet + nbproc 2 + + +2) Declaration of a listening service +===================================== + +Service sections start with the 'listen' keyword : + + listen <instance_name> [ <IP_address>:<port_range>[,...] ] + +- <instance_name> is the name of the instance. This name will be reported in + logs, so it is good to have it reflect the proxied service. No unicity test + is done on this name, and it's not mandatory for it to be unique, but highly + recommended. + +- <IP_address> is the IP address the proxy binds to. Empty address, '*' and + '0.0.0.0' all mean that the proxy listens to all valid addresses on the + system. + +- <port_range> is either a unique port, or a port range for which the proxy will + accept connections for the IP address specified above. This range can be : + - a numerical port (ex: '80') + - a dash-delimited ports range explicitly stating the lower and upper bounds + (ex: '2000-2100') which are included in the range. + + Particular care must be taken against port ranges, because every <addr:port> + couple consumes one socket (=a file descriptor), so it's easy to eat lots of + descriptors with a simple range. The <addr:port> couple must be used only once + among all instances running on a same system. Please note that attaching to + ports lower than 1024 need particular priviledges to start the program, which + are independant of the 'uid' parameter. + +- the <IP_address>:<port_range> couple may be repeated indefinitely to require + the proxy to listen to other addresses and/or ports. To achieve this, simply + separate them with a coma. + +Examples : +--------- + listen http_proxy :80 + listen x11_proxy 127.0.0.1:6000-6009 + listen smtp_proxy 127.0.0.1:25,127.0.0.1:587 + listen ldap_proxy :389,:663 + +In the event that all addresses do not fit line width, it's preferable to +detach secondary addresses on other lines with the 'bind' keyword. If this +keyword is used, it's not even necessary to specify the first address on the +'listen' line, which sometimes makes multiple configuration handling easier : + + bind [ <IP_address>:<port_range>[,...] ] + +Examples : +---------- + listen http_proxy + bind :80,:443 + bind 10.0.0.1:10080,10.0.0.1:10443 + +2.1) Inhibiting a service +------------------------- +A service may be disabled for maintenance reasons, without needing to comment +out the whole section, simply by specifying the 'disabled' keyword in the +section to be disabled : + + listen smtp_proxy 0.0.0.0:25 + disabled + +Note: the 'enabled' keyword allows to enable a service which has been disabled + previously by a default configuration. + +2.2) Modes of operation +----------------------- +A service can work in 3 different distinct modes : + - TCP + - HTTP + - monitoring + +TCP mode +-------- +In this mode, the service relays TCP connections as soon as they're established, +towards one or several servers. No processing is done on the stream. It's only +an association of source(addr:port) -> destination(addr:port). To use this mode, +you must specify 'mode tcp' in the 'listen' section. This is the default mode. + +Example : +--------- + listen smtp_proxy 0.0.0.0:25 + mode tcp + +HTTP mode +--------- +In this mode, the service relays TCP connections towards one or several servers, +when it has enough informations to decide, which normally means that all HTTP +headers have been read. Some of them may be scanned for a cookie or a pattern +matching a regex. To use this mode, specify 'mode http' in the 'listen' section. + +Example : +--------- + listen http_proxy 0.0.0.0:80 + mode http + +Health-checking mode +-------------------- +This mode provides a way for external components to check the proxy's health. +It is meant to be used with intelligent load-balancers which can use send/expect +scripts to check for all of their servers' availability. This one simply accepts +the connection, returns the word 'OK' and closes it. To enable it, simply +specify 'health' as the working mode : + +Example : +--------- + listen health_check 0.0.0.0:60000 + mode health + + +2.3) Limiting the number of simultaneous connections +---------------------------------------------------- +The 'maxconn' parameter allows a proxy to refuse connections above a certain +amount of simultaneous ones. When the limit is reached, it simply stops +listening, but the system may still be accepting them because of the back log +queue. These connections will be processed further when other ones have freed +some slots. This provides a serialization effect which helps very fragile +servers resist to high loads. Se further for system limitations. + +Example : +--------- + listen tiny_server 0.0.0.0:80 + maxconn 10 + + +2.4) Soft stop +-------------- +It is possible to stop services without breaking existing connections by the +sending of the SIG_USR1 signal to the process. All services are then put into +soft-stop state, which means that they will refuse to accept new connections, +except for those which have a non-zero value in the 'grace' parameter, in which +case they will still accept connections for the specified amount of time, in +milliseconds. This allows to tell a load-balancer that the service is failing, +while still doing the job during the time it needs to detect it. + +Note: active connections are never killed. In the worst case, the user will have +to wait for all of them to close or to time-out, or simply kill the process +normally (SIG_TERM). The default 'grace' value is '0'. + +Example : +--------- + # enter soft stop after 'killall -USR1 haproxy' + # the service will still run 10 seconds after the signal + listen http_proxy 0.0.0.0:80 + mode http + grace 10000 + + # this port is dedicated to a load-balancer, and must fail immediately + listen health_check 0.0.0.0:60000 + mode health + grace 0 + + +2.5) Connections expiration time +-------------------------------- +It is possible (and recommended) to configure several time-outs on TCP +connections. Three independant timers are adjustable with values specified +in milliseconds. A session will be terminated if either one of these timers +expire. + + - the time we accept to wait for data from the client, or for the client to + accept data : 'clitimeout' : + + # client time-out set to 2mn30. + clitimeout 150000 + + - the time we accept to wait for data from the server, or for the server to + accept data : 'srvtimeout' : + + # server time-out set to 30s. + srvtimeout 30000 + + - the time we accept to wait for a connection to establish on a server : + 'contimeout' : + + # we give up if the connection does not complete within 4 seconds + contimeout 4000 + +Notes : +------- + - 'contimeout' and 'srvtimeout' have no sense on 'health' mode servers ; + - under high loads, or with a saturated or defective network, it's possible + that some packets get lost. Since the first TCP retransmit only happens + after 3 seconds, a time-out equal to, or lower than 3 seconds cannot + compensate for a packet loss. A 4 seconds time-out seems a reasonable + minimum which will considerably reduce connection failures. + +2.6) Attempts to reconnect +-------------------------- +After a connection failure to a server, it is possible to retry, potentially +on another server. This is useful if health-checks are too rare and you don't +want the clients to see the failures. The number of attempts to reconnect is +set by the 'retries' paramter. + +Example : +--------- + # we can retry 3 times max after a failure + retries 3 + + +2.7) Address of the dispatch server (deprecated) +------------------------------------------------ +The server which will be sent all new connections is defined by the 'dispatch' +parameter, in the form <address>:<port>. It generally is dedicated to unknown +connections and will assign them a cookie, in case of HTTP persistence mode, +or simply is a single server in case of generic TCP proxy. This old mode is only +provided for backwards compatibility, but doesn't allow to check remote servers +state, and has a rather limited usage. All new setups should switch to 'balance' +mode. The principle of the dispatcher is to be able to perform the load +balancing itself, but work only on new clients so that the server doesn't need +to be a big machine. + +Example : +--------- + # all new connections go there + dispatch 192.168.1.2:80 + +Note : +------ +This parameter has no sense for 'health' servers, and is incompatible with +'balance' mode. + + +2.8) Outgoing source address +---------------------------- +It is often necessary to bind to a particular address when connecting to some +remote hosts. This is done via the 'source' parameter which is a per-proxy +parameter. A newer version may allow to fix different sources to reach different +servers. The syntax is 'source <address>[:<port>]', where <address> is a valid +local address (or '0.0.0.0' or '*' or empty to let the system choose), and +<port> is an optional parameter allowing the user to force the source port for +very specific needs. If the port is not specified or is '0', the system will +choose a free port. Note that as of version 1.1.18, the servers health checks +are also performed from the same source. + +Examples : +---------- + listen http_proxy *:80 + # all connections take 192.168.1.200 as source address + source 192.168.1.200:0 + + listen rlogin_proxy *:513 + # use address 192.168.1.200 and the reserved port 900 (needs to be root) + source 192.168.1.200:900 + + +2.9) Setting the cookie name +---------------------------- +In HTTP mode, it is possible to look for a particular cookie which will contain +a server identifier which should handle the connection. The cookie name is set +via the 'cookie' parameter. + +Example : +--------- + listen http_proxy :80 + mode http + cookie SERVERID + +It is possible to change the cookie behaviour to get a smarter persistence, +depending on applications. It is notably possible to delete or modify a cookie +emitted by a server, insert a cookie identifying the server in an HTTP response +and even add a header to tell upstream caches not to cache this response. + +Examples : +---------- + +To remove the cookie for direct accesses (ie when the server matches the one +which was specified in the client cookie) : + + cookie SERVERID indirect + +To replace the cookie value with the one assigned to the server if any (no +cookie will be created if the server does not provide one, nor if the +configuration does not provide one). This lets the application put the cookie +exactly on certain pages (eg: successful authentication) : + + cookie SERVERID rewrite + +To create a new cookie and assign the server identifier to it (in this case, all +servers should be associated with a valid cookie, since no cookie will simply +delete the cookie from the client's browser) : + + cookie SERVERID insert + +To insert a cookie and ensure that no upstream cache will store it, add the +'nocache' option : + + cookie SERVERID insert nocache + +To insert a cookie only after a POST request, add 'postonly' after 'insert'. +This has the advantage that there's no risk of caching, and that all pages +seen before the POST one can still be cached : + + cookie SERVERID insert postonly + +Notes : +----------- +- it is possible to combine 'insert' with 'indirect' or 'rewrite' to adapt to + applications which already generate the cookie with an invalid content. + +- in the case where 'insert' and 'indirect' are both specified, the cookie is + never transmitted to the server, since it wouldn't understand it. This is + the most application-transparent mode. + +- it is particularly recommended to use 'nocache' in 'insert' mode if any + upstream HTTP/1.0 cache is susceptible to cache the result, because this may + lead to many clients going to the same server, or even worse, some clients + having their server changed while retrieving a page from the cache. + +- when the application is well known and controlled, the best method is to + only add the persistence cookie on a POST form because it's up to the + application to select which page it wants the upstream servers to cache. + In this case, you would use 'insert postonly indirect'. + +2.10) Associating a cookie value with a server +---------------------------------------------- +In HTTP mode, it's possible to associate a cookie value to each server. This +was initially used in combination with 'dispatch' mode to handle direct accesses +but it is now the standard way of doing the load balancing. The syntax is : + + server <identifier> <address>:<port> cookie <value> + +- <identifier> is any name which can be used to identify the server in the logs. +- <address>:<port> specifies where the server is bound. +- <value> is the value to put in or to read from the cookie. + +Example : the 'SERVERID' cookie can be either 'server01' or 'server02' +--------- + listen http_proxy :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 + +Warning : the syntax has changed since version 1.0 ! +--------- + +3) Autonomous load balancer +=========================== + +The proxy can perform the load-balancing itself, both in TCP and in HTTP modes. +This is the most interesting mode which obsoletes the old 'dispatch' mode +described above. It has advantages such as server health monitoring, multiple +port binding and port mapping. To use this mode, the 'balance' keyword is used, +followed by the selected algorithm. As of version 1.1.23, only 'roundrobin' is +available, which is also the default value if unspecified. In this mode, there +will be no dispatch address, but the proxy needs at least one server. + +Example : same as the last one, with internal load balancer +--------- + + listen http_proxy :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 + + +Since version 1.1.22, it is possible to automatically determine on which port +the server will get the connection, depending on the port the client connected +to. Indeed, there now are 4 possible combinations for the server's <port> field: + + - unspecified or '0' : + the connection will be sent to the same port as the one on which the proxy + received the client connection itself. + + - numerical value (the only one supported in versions earlier than 1.1.22) : + the connection will always be sent to the specified port. + + - '+' followed by a numerical value : + the connection will be sent to the same port as the one on which the proxy + received the connection, plus this value. + + - '-' followed by a numerical value : + the connection will be sent to the same port as the one on which the proxy + received the connection, minus this value. + +Examples : +---------- + +# same as previous example + + listen http_proxy :80 + mode http + cookie SERVERID + balance roundrobin + server web1 192.168.1.1 cookie server01 + server web2 192.168.1.2 cookie server02 + +# simultaneous relaying of ports 80, 81 and 8080-8089 + + listen http_proxy :80,:81,:8080-8089 + mode http + cookie SERVERID + balance roundrobin + server web1 192.168.1.1 cookie server01 + server web2 192.168.1.2 cookie server02 + +# relaying of TCP ports 25, 389 and 663 to ports 1025, 1389 and 1663 + + listen http_proxy :25,:389,:663 + mode tcp + balance roundrobin + server srv1 192.168.1.1:+1000 + server srv2 192.168.1.2:+1000 + + +3.1) Servers monitoring +----------------------- + +It is possible to check the servers status by trying to establish TCP +connections or even sending HTTP requests to them. A server which fails to +reply to health checks as expected will not be used by the load balancing +algorithms. To enable monitoring, add the 'check' keyword on a server line. +It is possible to specify the interval between tests (in milliseconds) with +the 'inter' parameter, the number of failures supported before declaring that +the server has fallen down with the 'fall' parameter, and the number of valid +checks needed for the server to fully get up with the 'rise' parameter. Since +version 1.1.22, it is also possible to send checks to a different port +(mandatory when none is specified) with the 'port' parameter. The default +values are the following ones : + + - inter : 2000 + - rise : 2 + - fall : 3 + - port : default server port + +The default mode consists in establishing TCP connections only. But in certain +types of application failures, it is often that the server continues to accept +connections because the system does it itself while the application is running +an endless loop, or is completely stuck. So in version 1.1.16 were introduced +HTTP health checks which only performed simple lightweight requests and analysed +the response. Now, as of version 1.1.23, it is possible to change the HTTP +method, the URI, and the HTTP version string (which even allows to send headers +with a dirty trick). To enable HTTP health-checks, use 'option httpchk'. + +By default, requests use the 'OPTIONS' method because it's very light and easy +to filter from logs, and does it on '/'. Only HTTP responses 2xx and 3xx are +considered valid ones, and only if they come before the time to send a new +request is reached ('inter' parameter). If some servers block this type of +request, 3 other forms help to forge a request : + + - option httpchk -> OPTIONS / HTTP/1.0 + - option httpchk URI -> OPTIONS <URI> HTTP/1.0 + - option httpchk METH URI -> <METH> <URI> HTTP/1.0 + - option httpchk METH URI VER -> <METH> <URI> <VER> + +See examples below. + +Since version 1.1.17, it is possible to specify backup servers. These servers +are only sollicited when no other server is available. This may only be useful +to serve a maintenance page, or define one active and one backup server (seldom +used in TCP mode). To make a server a backup one, simply add the 'backup' option +on its line. These servers also support cookies, so if a cookie is specified for +a backup server, clients assigned to this server will stick to it even when the +other ones come back. Conversely, if no cookie is assigned to such a server, +the clients will get their cookies removed (empty cookie = removal), and will +be balanced against other servers once they come back. Please note that there +is no load-balancing among backup servers. If there are several backup servers, +the second one will only be used when the first one dies, and so on. + +Since version 1.1.17, it is also possible to visually check the status of all +servers at once. For this, you just have to send a SIGHUP signal to the proxy. +The servers status will be dumped into the logs at the 'notice' level, as well +as on <stderr> if not closed. For this reason, it's always a good idea to have +one local log server at the 'notice' level. + +Examples : +---------- +# same setup as in paragraph 3) with TCP monitoring + 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 + +# same with HTTP monitoring via 'OPTIONS / HTTP/1.0' + listen http_proxy 0.0.0.0:80 + mode http + cookie SERVERID + balance roundrobin + option httpchk + 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 + +# same with HTTP monitoring via 'OPTIONS /index.html HTTP/1.0' + listen http_proxy 0.0.0.0:80 + mode http + cookie SERVERID + balance roundrobin + option httpchk /index.html + 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 + +# same with HTTP monitoring via 'HEAD /index.jsp? HTTP/1.1\r\nHost: www' + listen http_proxy 0.0.0.0:80 + mode http + cookie SERVERID + balance roundrobin + option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www + 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 + +# automatic insertion of a cookie in the server's response, and automatic +# deletion of the cookie in the client request, while asking upstream caches +# not to cache replies. + listen web_appl 0.0.0.0:80 + mode http + cookie SERVERID insert nocache indirect + balance roundrobin + server web1 192.168.1.1:80 cookie server01 check + server web2 192.168.1.2:80 cookie server02 check + +# same with off-site application backup and local error pages server + listen web_appl 0.0.0.0:80 + mode http + cookie SERVERID insert nocache indirect + balance roundrobin + server web1 192.168.1.1:80 cookie server01 check + server web2 192.168.1.2:80 cookie server02 check + server web-backup 192.168.2.1:80 cookie server03 check backup + server web-excuse 192.168.3.1:80 check backup + +# SMTP+TLS relaying with heakth-checks and backup servers + + listen http_proxy :25,:587 + mode tcp + balance roundrobin + server srv1 192.168.1.1 check port 25 inter 30000 rise 1 fall 2 + server srv2 192.168.1.2 backup + + +3.2) Redistribute connections in case of failure +------------------------------------------------ +In HTTP mode, if a server designated by a cookie does not respond, the clients +may definitely stick to it because they cannot flush the cookie, so they will +not be able to access the service anymore. Specifying 'redispatch' will allow +the proxy to break their persistence and redistribute them to working servers. + +Example : +--------- + 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 # send back to dispatch in case of connection failure + +Up to, and including version 1.1.16, this parameter only applied to connection +failures. Since version 1.1.17, it also applies to servers which have been +detected as failed by the health check mechanism. Indeed, a server may be broken +but still accepting connections, which would not solve every case. But it is +possible to conserve the old behaviour, that is, make a client insist on trying +to connect to a server even if it is said to be down, by setting the 'persist' +option : + + listen http_proxy 0.0.0.0:80 + mode http + option persist + 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 # send back to dispatch in case of connection failure + + +4) Additionnal features +======================= + +Other features are available. They are transparent mode, event logging and +header rewriting/filtering. + +4.1) Transparent mode +--------------------- +In HTTP mode, the 'transparent' keyword allows to intercept sessions which are +routed through the system hosting the proxy. This mode was implemented as a +replacement for the 'dispatch' mode, since connections without cookie will be +sent to the original address while known cookies will be sent to the servers. +This mode implies that the system can redirect sessions to a local port. + +Example : +--------- + 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 + +Note : +------ +If the port is left unspecified on the server, the port the client connected to +will be used. This allows to relay a full port range without using transparent +mode nor thousands of file descriptors, provided that the system can redirect +sessions to local ports. + +Example : +--------- + # redirect all ports to local port 65000, then forward to the server on the + # original port. + listen http_proxy 0.0.0.0:65000 + mode tcp + server server01 192.168.1.1 check port 60000 + server server02 192.168.1.2 check port 60000 + + # iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \ + -j REDIRECT --to-ports 65000 + + +4.2) Event logging +------------------ + + +- 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - - + + + +Les connexions TCP et HTTP peuvent donner lieu � une journalisation sommaire ou +d�taill�e indiquant, pour chaque connexion, la date, l'heure, l'adresse IP +source, le serveur destination, la dur�e de la connexion, les temps de r�ponse, +la requ�te HTTP, le code de retour, la quantit� de donn�es transmises, et m�me +dans certains cas, la valeur d'un cookie permettant de suivre les sessions. +Tous les messages sont envoy�s en syslog vers un ou deux serveurs. Se r�f�rer � +la section 1.1 pour plus d'information sur les cat�gories de logs. La syntaxe +est la suivante : + + log <adresse_ip_1> <cat�gorie_1> [niveau_max_1] + log <adresse_ip_2> <cat�gorie_2> [niveau_max_2] +ou + log 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 + +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). + +Exemple : +--------- + listen http_proxy 0.0.0.0:80 + mode http + option httplog + option dontlognull + log 192.168.2.200 local3 + +Depuis la version 1.1.18, un indicateur de compl�tude de la session a �t� ajout� +dans les logs HTTP. C'est un champ de 4 caract�res pr�c�dant la requ�te HTTP, +indiquant : + - sur le premier caract�re, un code pr�cisant le premier �v�nement qui a caus� + la terminaison de la session : + + C : fermeture de la session TCP de la part du client + S : fermeture de la session TCP de la part du serveur, ou refus de connexion + P : terminaison pr�matur�e des sessions par le proxy, pour cas d'erreur + interne ou de configuration (ex: filtre d'URL) + c : expiration du d�lai d'attente c�t� client : clitimeout + s : expiration du d�lai d'attente c�t� serveur: srvtimeout et contimeout + - : terminaison normale. + + - sur le second caract�re, l'�tat d'avancement de la session HTTP lors de la + fermeture : + + R : terminaison en attendant la r�ception totale de la requ�te du client + C : terminaison en attendant la connexion vers le serveur + H : terminaison en attendant la r�ception totale des ent�tes du serveur + D : terminaison durant le transfert des donn�es du serveur vers le client + L : terminaison durant le transfert des derni�res donn�es du proxy vers + le client, alors que le serveur a d�j� fini. + - : terminaison normale, apr�s fin de transfert des donn�es + + - le troisi�me caract�re indique l'�ventuelle identification d'un cookie de + persistence : + + N : aucun cookie de persistence n'a �t� pr�sent�. + I : le client a pr�sent� un cookie ne correspondant � aucun serveur + connu. + D : le client a pr�sent� un cookie correspondant � un serveur hors + d'usage. Suivant l'option 'persist', il a �t� renvoy� vers un + autre serveur ou a tout de m�me tent� de se connecter sur celui + correspondant au cookie. + V : le client a pr�sent� un cookie valide et a pu se connecter au + serveur correspondant. + - : non appliquable + + - le dernier caract�re indique l'�ventuel traitement effectu� sur un cookie de + persistence retrourn� par le serveur : + + N : aucun cookie de persistence n'a �t� fourni par le serveur. + P : un cookie cookie de persistence n'a �t� fourni par le serveur. + I : aucun cookie n'a �t� fourni par le serveur, il a �t� ins�r� par le + proxy. + D : le cookie pr�sent� par le serveur a �t� supprim� par le proxy pour + ne pas �tre retourn� au client. + R : le cookie retourn� par le serveur a �t� modifi� par le proxy. + - : non appliquable + +Le mot cl� "capture" permet d'ajouter dans des logs HTTP des informations +captur�es dans les �changes. La version 1.1.17 supporte uniquement une capture +de cookies client et serveur, ce qui permet dans bien des cas, de reconstituer +la session d'un utilisateur. La syntaxe est la suivante : + + capture cookie <pr�fixe_cookie> len <longueur_capture> + +Le premier cookie dont le nom commencera par <pr�fixe_cookie> sera captur�, et +transmis sous la forme "NOM=valeur", sans toutefois, exc�der <longueur_capture> +caract�res (64 au maximum). Lorsque le nom du cookie est fixe et connu, on peut +le suffixer du signe "=" pour s'assurer qu'aucun autre cookie ne prendra sa +place dans les logs. + +Exemples : +---------- + # capture du premier cookie dont le nom commence par "ASPSESSION" + capture cookie ASPSESSION len 32 + + # capture du premier cookie dont le nom est exactement "vgnvisitor" + capture cookie vgnvisitor= len 32 + +Dans les logs, le champ pr�c�dant l'indicateur de compl�tude contient le cookie +positionn� par le serveur, pr�c�d� du cookie positionn� par le client. Chacun de +ces champs est remplac� par le signe "-" lorsqu'aucun cookie n'est fourni par le +client ou le serveur. + +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 + capture cookie userid= len 20 + + +4.3) Modification des ent�tes HTTP +---------------------------------- +En mode HTTP uniquement, il est possible de remplacer certains en-t�tes dans la +requ�te et/ou la r�ponse � partir d'expressions r�guli�res. Il est �galement +possible de bloquer certaines requ�tes en fonction du contenu des en-t�tes ou de +la requ�te. Une limitation cependant : les en-t�tes fournis au milieu de +connexions persistentes (keep-alive) ne sont pas vus car ils sont consid�r�s +comme faisant partie des �changes de donn�es cons�cutifs � la premi�re requ�te. +Les donn�es ne sont pas affect�es, ceci ne s'applique qu'aux en-t�tes. + +La syntaxe est : + reqadd <string> pour ajouter un en-t�te dans la requ�te + reqrep <search> <replace> pour modifier la requ�te + reqirep <search> <replace> idem sans distinction majuscules/minuscules + reqdel <search> pour supprimer un en-t�te dans la requ�te + reqidel <search> idem sans distinction majuscules/minuscules + reqallow <search> autoriser la requ�te si un ent�te valide <search> + reqiallow <search> idem sans distinction majuscules/minuscules + reqdeny <search> interdire la requ�te si un ent�te valide <search> + reqideny <search> idem sans distinction majuscules/minuscules + reqpass <search> inhibe ces actions sur les ent�tes validant <search> + reqipass <search> idem sans distinction majuscules/minuscules + + 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 POSIX regexp supportant le +groupage par parenth�ses (sans les '\'). Les espaces et autres s�parateurs +doivent �tres pr�c�d�s d'un '\' pour ne pas �tre confondus avec la fin de la +cha�ne. De plus, certains caract�res sp�ciaux peuvent �tre pr�c�d�s d'un +backslach ('\') : + + \t pour une tabulation + \r pour un retour charriot + \n pour un saut de ligne + \ pour diff�rencier un espace d'un s�parateur + \# pour diff�rencier un di�se d'un commentaire + \\ pour utiliser un backslash dans la regex + \\\\ pour utiliser un backslash dans le texte + \xXX pour un caract�re sp�cifique XX (comme en C) + + +<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, + et faire en sorte que des caches ne m�morisent pas ce cookie. + - cacher ce cookie � l'application lors des requ�tes ult�rieures. + +Exemple : +--------- + listen application 0.0.0.0:80 + mode http + cookie SERVERID insert nocache indirect + balance roundrobin + server 192.168.1.1:80 cookie server01 check + server 192.168.1.2:80 cookie server02 check + +4.5) Personalisation des erreurs +-------------------------------- + +Certaines situations conduisent � retourner une erreur HTTP au client : + - requ�te invalide ou trop longue => code HTTP 400 + - requ�te mettant trop de temps � venir => code HTTP 408 + - requ�te interdite (bloqu�e par un reqideny) => code HTTP 403 + - erreur interne du proxy => code HTTP 500 + - le serveur a retourn� une r�ponse incompl�te ou invalide => code HTTP 502 + - aucun serveur disponible pour cette requ�te => code HTTP 503 + - le serveur n'a pas r�pondu dans le temps imparti => code HTTP 504 + +Un message d'erreur succint tir� de la RFC accompagne ces codes de retour. +Cependant, en fonction du type de client�le, on peut pr�f�rer retourner des +pages personnalis�es. Ceci est possible par le biais de la commande "errorloc" : + + errorloc <code_HTTP> <location> + +Au lieu de g�n�rer une erreur HTTP <code_HTTP> parmi les codes cit�s ci-dessus, +le proxy g�n�rera un code de redirection temporaire (HTTP 302) vers l'adresse +d'une page pr�cis�e dans <location>. Cette adresse peut �tre relative au site, +ou absolue. Comme cette r�ponse est tra�t�e par le navigateur du client +lui-m�me, il est indispensable que l'adresse fournie lui soit accessible. + +Exemple : +--------- + listen application 0.0.0.0:80 + errorloc 400 /badrequest.html + errorloc 403 /forbidden.html + errorloc 408 /toolong.html + errorloc 500 http://haproxy.domain.net/bugreport.html + errorloc 502 http://192.168.114.58/error50x.html + errorloc 503 http://192.168.114.58/error50x.html + errorloc 504 http://192.168.114.58/error50x.html + +4.6) Changement des valeurs par d�faut +-------------------------------------- + +Dans la version 1.1.22 est apparue la notion de valeurs par d�faut, ce qui �vite +de r�p�ter des param�tres communs � toutes les instances, tels que les timeouts, +adresses de log, modes de fonctionnement, etc. + +Les valeurs par d�faut sont positionn�es dans la derni�re section 'defaults' +pr�c�dent l'instance qui les utilisera. On peut donc mettre autant de sections +'defaults' que l'on veut. Il faut juste se rappeler que la pr�sence d'une telle +section implique une annulation de tous les param�tres par d�faut positionn�s +pr�c�demment, dans le but de les remplacer. + +La section 'defaults' utilise la m�me syntaxe que la section 'listen', aux +param�tres pr�s qui ne sont pas support�s. Le mot cl� 'defaults' peut accepter +un commentaire en guise param�tre. + +Dans la version 1.1.22, seuls les param�tres suivants peuvent �tre positionn�s +dans une section 'defaults' : + - log (le premier et le second) + - mode { tcp, http, health } + - balance { roundrobin } + - disabled (pour d�sactiver toutes les instances qui suivent) + - enabled (pour faire l'op�ration inverse, mais c'est le cas par d�faut) + - contimeout, clitimeout, srvtimeout, grace, retries, maxconn + - option { redispatch, transparent, keepalive, forwardfor, httplog, + dontlognull, persist, httpchk } + - redispatch, redisp, transparent, source { addr:port } + - cookie, capture + - errorloc + +Ne sont pas support�s dans cette version, les adresses de dispatch et les +configurations de serveurs, ainsi que tous les filtres bas�s sur les +expressions r�guli�res : + - dispatch, server, + - req*, rsp*, + +Enfin, il n'y a pas le moyen, pour le moment, d'invalider un param�tre bool�en +positionn� par d�faut. Donc si une option est sp�cifi�e dans les param�tres par +d�faut, le seul moyen de la d�sactiver pour une instance, c'est de changer les +param�tres par d�faut avant la d�claration de l'instance. + +Exemples : +---------- + defaults applications TCP + log global + mode tcp + balance roundrobin + clitimeout 180000 + srvtimeout 180000 + contimeout 4000 + retries 3 + redispatch + + listen app_tcp1 10.0.0.1:6000-6063 + server srv1 192.168.1.1 check port 6000 inter 10000 + server srv2 192.168.1.2 backup + + listen app_tcp2 10.0.0.2:6000-6063 + server srv1 192.168.2.1 check port 6000 inter 10000 + server srv2 192.168.2.2 backup + + defaults applications HTTP + log global + mode http + option httplog + option forwardfor + option dontlognull + balance roundrobin + clitimeout 20000 + srvtimeout 20000 + contimeout 4000 + retries 3 + + listen app_http1 10.0.0.1:80-81 + cookie SERVERID postonly insert indirect + capture cookie userid= len 10 + server srv1 192.168.1.1:+8000 cookie srv1 check port 8080 inter 1000 + server srv1 192.168.1.2:+8000 cookie srv2 check port 8080 inter 1000 + + defaults + # section vide qui annule tous les param�tes par d�faut. + +======================= +| 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 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 -- diff --git a/doc/haproxy.txt b/doc/haproxy.txt index e6bcfb360..5df305dfd 100644 --- a/doc/haproxy.txt +++ b/doc/haproxy.txt @@ -1,9 +1,9 @@ H A - P r o x y --------------- - version 1.1.22 + version 1.1.23 willy tarreau - 2003/09/11 + 2003/09/20 ================ | Introduction | @@ -112,7 +112,7 @@ optionnel <niveau_max> d valeurs suivantes : emerg, alert, crit, err, warning, notice, info, debug -Par compatibilit� avec les versions 1.1.16 et ant�rieures, La valeur par d�faut +Par compatibilit� avec les versions 1.1.16 et ant�rieures, la valeur par d�faut est "debug" si l'option n'est pas pr�cis�e. Les cat�gories possibles sont : @@ -138,12 +138,13 @@ param 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 par couple adresse/port d'�coute 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 +Dans le cas o� chaque proxy n'�coute que sur un couple adresse/port, 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 @@ -165,13 +166,13 @@ processus utilisent les m 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 puissent 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. Pour rendre l'isolement -plus robuste, il est conseill� d'utiliser un r�pertoire vide, sans aucun droit, -et de changer l'uid du processus de sorte qu'il ne puisse rien faire dans ledit -r�pertoire. +g�n�ralement contournable sur certains OS (Linux, Solaris) pour peu que +l'attaquant poss�de des droits 'root' et soit en mesure d'utiliser ou de cr�er +un r�pertoire. 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. Pour rendre l'isolement plus robuste, +il est conseill� d'utiliser un r�pertoire vide, sans aucun droit, et de changer +l'uid du processus de sorte qu'il ne puisse rien faire dans ledit r�pertoire. 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 @@ -297,16 +298,20 @@ Exemples : 2.1) Inhibition d'un service ---------------------------- -Un serveur peut �tre d�sactiv� pour des besoins de maintenance, sans avoir � +Un service 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 +Remarque: le mot cl� 'enabled' permet de r�activer un service pr�alablement + d�sactiv� par le mot cl� 'disabled', par exemple � cause d'une + configuration par d�faut. + 2.2) Mode de fonctionnement --------------------------- -Un serveur peut fonctionner dans trois modes diff�rents : +Un service peut fonctionner dans trois modes diff�rents : - TCP - HTTP - supervision @@ -470,7 +475,7 @@ pour permettre aux serveurs de trouver le chemin de retour dans des contextes de routage difficiles. Si l'adresse est '0.0.0.0' ou '*' ou vide, elle sera choisie librement par le systeme. Si le port est '0' ou vide, il sera choisi librement par le syst�me. Il est � noter que depuis la version 1.1.18, les tests de bon -foncitonnement des serveurs seront aussi effectu�s � partir de la source +fonctionnement des serveurs seront aussi effectu�s � partir de la source sp�cifi�e par ce param�tre. Exemples : @@ -540,14 +545,17 @@ 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. + - il est particuli�rement recommand� d'utiliser 'nocache' en mode insertion si des caches peuvent se trouver entre les clients et l'instance du proxy. Dans le cas contraire, un cache HTTP 1.0 pourrait cacher la r�ponse, incluant le cookie de persistence ins�r�, donc provoquer des changements de serveurs pour des clients partageant le m�me cache. + - lorsque l'application est bien connue, et que les parties n�cessitant de la persistence sont syst�matiquement acc�d�es par un formulaire en mode POST, il est plus efficace encore de combiner le mot cl� "postonly" avec "insert" @@ -680,7 +688,12 @@ serveur. Seules les r compris non-r�ponses) aboutissent � un �chec. Le temps maximal imparti pour une r�ponse est �gal � l'intervalle entre deux tests (param�tre "inter"). Pour activer ce mode, sp�cifier l'option "httpchk", �ventuellement suivie d'une -URI. Voir les exemples ci-apr�s. +m�thode et d'une URI. L'option "httpchk" accepte donc 4 formes : + - option httpchk -> OPTIONS / HTTP/1.0 + - option httpchk URI -> OPTIONS <URI> HTTP/1.0 + - option httpchk METH URI -> <METH> <URI> HTTP/1.0 + - option httpchk METH URI VER -> <METH> <URI> <VER> +Voir les exemples ci-apr�s. Depuis la version 1.1.17, il est possible de d�finir des serveurs de secours, utilis�s uniquement lorsqu'aucun des autres serveurs ne fonctionne. Pour cela, @@ -735,6 +748,15 @@ Exemples : 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 +# idem avec surveillance HTTP par 'HEAD /index.jsp? HTTP/1.1\r\nHost: www' + listen http_proxy 0.0.0.0:80 + mode http + cookie SERVERID + balance roundrobin + option httpchk HEAD /index.jsp? HTTP/1.1\r\nHost:\ www + 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, tout en indiquant aux caches de ne pas garder # ce cookie. @@ -745,15 +767,15 @@ Exemples : server web1 192.168.1.1:80 cookie server01 check server web2 192.168.1.2:80 cookie server02 check -# idem avec serveur applicatif de secours, et serveur de pages d'erreurs +# idem avec serveur applicatif de secours sur autre site, et serveur de pages d'erreurs listen web_appl 0.0.0.0:80 mode http cookie SERVERID insert nocache indirect balance roundrobin server web1 192.168.1.1:80 cookie server01 check server web2 192.168.1.2:80 cookie server02 check - server web-backup 192.168.1.3:80 cookie server03 check backup - server web-excuse 192.168.1.4:80 check backup + server web-backup 192.168.2.1:80 cookie server03 check backup + server web-excuse 192.168.3.1:80 check backup # relayage SMTP+TLS avec test du serveur et serveur de backup @@ -1140,15 +1162,15 @@ dans une section 'defaults' : - enabled (pour faire l'op�ration inverse, mais c'est le cas par d�faut) - contimeout, clitimeout, srvtimeout, grace, retries, maxconn - option { redispatch, transparent, keepalive, forwardfor, httplog, - dontlognull, persist } + dontlognull, persist, httpchk } - redispatch, redisp, transparent, source { addr:port } - -Ne sont pas support�s dans cette version, d'une mani�re g�n�rale, tous les -param�tres qui n�cessitent de m�moriser autre chose que des adresses IP uniques -et valeurs num�riques simples : - - dispatch, server, - cookie, capture - errorloc + +Ne sont pas support�s dans cette version, les adresses de dispatch et les +configurations de serveurs, ainsi que tous les filtres bas�s sur les +expressions r�guli�res : + - dispatch, server, - req*, rsp*, Enfin, il n'y a pas le moyen, pour le moment, d'invalider un param�tre bool�en diff --git a/examples/build.cfg b/examples/build.cfg new file mode 100644 index 000000000..2dd752729 --- /dev/null +++ b/examples/build.cfg @@ -0,0 +1,25 @@ +#!/bin/sh + +# build script for formilux >0.1.8 + +PATCH_LIST= +FILE_LIST= + +function do_compile_only { + $FLXMAKE CPU_OPTS="-march=$arch -mcpu=$cpu -Os -mpreferred-stack-boundary=2 -momit-leaf-frame-pointer -malign-jumps=0" \ + TARGET=linux24 +} + +function do_prepack { + mkdir -p $ROOTDIR/sbin/init.d ; cp examples/init.haproxy.flx0 $ROOTDIR/sbin/init.d/haproxy + mkdir -p $ROOTDIR/usr/sbin ; cp haproxy $ROOTDIR/usr/sbin + mkdir -p $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/haproxy/ + cp examples/haproxy.cfg $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/haproxy/haproxy.cfg + cp examples/rc.highsock $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/rc.highsock + cp examples/config.rc.haproxy $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/config.rc.haproxy + mkdir -p $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER + cp doc/haproxy.txt $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER + ln -s ../../examples/$PKGRADIX/$PKGRADIX-$PKGVER $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/examples + cp examples/debug2ansi examples/debug2html examples/debugfind $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/ + set_default_perm $ROOTDIR +} diff --git a/examples/config.rc.haproxy b/examples/config.rc.haproxy index c7aa83872..067f07a46 100644 --- a/examples/config.rc.haproxy +++ b/examples/config.rc.haproxy @@ -1,4 +1,3 @@ service haproxy config /etc/haproxy/haproxy.cfg - maxconn 1024 diff --git a/init.d/haproxy b/examples/init.haproxy similarity index 100% rename from init.d/haproxy rename to examples/init.haproxy diff --git a/examples/init.haproxy.flx0 b/examples/init.haproxy.flx0 new file mode 100644 index 000000000..aa5f0cb48 --- /dev/null +++ b/examples/init.haproxy.flx0 @@ -0,0 +1,20 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option /etc/haproxy/haproxy.cfg +option bin reserved_option /usr/sbin/haproxy +option cmdline reserved_option '$bin -q -D -f ${opt_config}' + +function do_help { + echo "Usage: ${0##*/} <status|start|stop|help>" + echo "List of config.rc options (name, type, default value, current value) :" + echo + echo " - config ; def=/etc/haproxy/haproxy.cfg ; cur=$opt_confdir" + echo + exit 1 +} + + +load_config + diff --git a/haproxy.c b/haproxy.c index 1d24a912b..43c4c65da 100644 --- a/haproxy.c +++ b/haproxy.c @@ -53,8 +53,8 @@ #include <linux/netfilter_ipv4.h> #endif -#define HAPROXY_VERSION "1.1.22" -#define HAPROXY_DATE "2003/09/11" +#define HAPROXY_VERSION "1.1.23" +#define HAPROXY_DATE "2003/09/20" /* this is for libc5 for example */ #ifndef TCP_NODELAY @@ -1475,7 +1475,7 @@ int connect_server(struct session *s) { /* if this server remaps proxied ports, we'll use * the port the client connected to with an offset. */ - if (s->srv->state & SRV_MAPPORTS) { + if (s->srv != NULL && s->srv->state & SRV_MAPPORTS) { struct sockaddr_in sockname; int namelen; @@ -4405,6 +4405,48 @@ int cfg_parse_listen(char *file, int linenum, char **args) { curproxy->maxconn = defproxy.maxconn; curproxy->conn_retries = defproxy.conn_retries; curproxy->options = defproxy.options; + + if (defproxy.check_req) + curproxy->check_req = strdup(defproxy.check_req); + curproxy->check_len = defproxy.check_len; + + if (defproxy.cookie_name) + curproxy->cookie_name = strdup(defproxy.cookie_name); + curproxy->cookie_len = defproxy.cookie_len; + + if (defproxy.capture_name) + curproxy->capture_name = strdup(defproxy.capture_name); + curproxy->capture_namelen = defproxy.capture_namelen; + curproxy->capture_len = defproxy.capture_len; + + if (defproxy.errmsg.msg400) + curproxy->errmsg.msg400 = strdup(defproxy.errmsg.msg400); + curproxy->errmsg.len400 = defproxy.errmsg.len400; + + if (defproxy.errmsg.msg403) + curproxy->errmsg.msg403 = strdup(defproxy.errmsg.msg403); + curproxy->errmsg.len403 = defproxy.errmsg.len403; + + if (defproxy.errmsg.msg408) + curproxy->errmsg.msg408 = strdup(defproxy.errmsg.msg408); + curproxy->errmsg.len408 = defproxy.errmsg.len408; + + if (defproxy.errmsg.msg500) + curproxy->errmsg.msg500 = strdup(defproxy.errmsg.msg500); + curproxy->errmsg.len500 = defproxy.errmsg.len500; + + if (defproxy.errmsg.msg502) + curproxy->errmsg.msg502 = strdup(defproxy.errmsg.msg502); + curproxy->errmsg.len502 = defproxy.errmsg.len502; + + if (defproxy.errmsg.msg503) + curproxy->errmsg.msg503 = strdup(defproxy.errmsg.msg503); + curproxy->errmsg.len503 = defproxy.errmsg.len503; + + if (defproxy.errmsg.msg504) + curproxy->errmsg.msg504 = strdup(defproxy.errmsg.msg504); + curproxy->errmsg.len504 = defproxy.errmsg.len504; + curproxy->clitimeout = defproxy.clitimeout; curproxy->contimeout = defproxy.contimeout; curproxy->srvtimeout = defproxy.srvtimeout; @@ -4421,6 +4463,19 @@ int cfg_parse_listen(char *file, int linenum, char **args) { return 0; } else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */ + /* some variables may have already been initialized earlier */ + if (defproxy.check_req) free(defproxy.check_req); + if (defproxy.cookie_name) free(defproxy.cookie_name); + if (defproxy.capture_name) free(defproxy.capture_name); + if (defproxy.errmsg.msg400) free(defproxy.errmsg.msg400); + if (defproxy.errmsg.msg403) free(defproxy.errmsg.msg403); + if (defproxy.errmsg.msg408) free(defproxy.errmsg.msg408); + if (defproxy.errmsg.msg500) free(defproxy.errmsg.msg500); + if (defproxy.errmsg.msg502) free(defproxy.errmsg.msg502); + if (defproxy.errmsg.msg503) free(defproxy.errmsg.msg503); + if (defproxy.errmsg.msg504) free(defproxy.errmsg.msg504); + + init_default_instance(); curproxy = &defproxy; return 0; } @@ -4460,15 +4515,16 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (!strcmp(args[0], "cookie")) { /* cookie name */ int cur_arg; - if (curproxy == &defproxy) { - Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); - return -1; - } +// if (curproxy == &defproxy) { +// Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); +// return -1; +// } if (curproxy->cookie_name != NULL) { - Alert("parsing [%s:%d] : cookie name already specified. Continuing.\n", - file, linenum); - return 0; +// Alert("parsing [%s:%d] : cookie name already specified. Continuing.\n", +// file, linenum); +// return 0; + free(curproxy->cookie_name); } if (*(args[1]) == 0) { @@ -4510,15 +4566,16 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } } else if (!strcmp(args[0], "capture")) { /* name of a cookie to capture */ - if (curproxy == &defproxy) { - Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); - return -1; - } +// if (curproxy == &defproxy) { +// Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); +// return -1; +// } if (curproxy->capture_name != NULL) { - Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", - file, linenum, args[0]); - return 0; +// Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", +// file, linenum, args[0]); +// return 0; + free(curproxy->capture_name); } if (*(args[4]) == 0) { @@ -4609,15 +4666,28 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (!strcmp(args[1], "httpchk")) { /* use HTTP request to check servers' health */ + if (curproxy->check_req != NULL) { + free(curproxy->check_req); + } curproxy->options |= PR_O_HTTP_CHK; - if (*args[2]) { + if (!*args[2]) { /* no argument */ + curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */ + curproxy->check_len = strlen(DEF_CHECK_REQ); + } else if (!*args[3]) { /* one argument : URI */ int reqlen = strlen(args[2]) + strlen("OPTIONS / HTTP/1.0\r\n\r\n"); curproxy->check_req = (char *)malloc(reqlen); curproxy->check_len = snprintf(curproxy->check_req, reqlen, "OPTIONS %s HTTP/1.0\r\n\r\n", args[2]); /* URI to use */ - } else { - curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */ - curproxy->check_len = strlen(DEF_CHECK_REQ); + } else { /* more arguments : METHOD URI [HTTP_VER] */ + int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n\r\n"); + if (*args[4]) + reqlen += strlen(args[4]); + else + reqlen += strlen("HTTP/1.0"); + + curproxy->check_req = (char *)malloc(reqlen); + curproxy->check_len = snprintf(curproxy->check_req, reqlen, + "%s %s %s\r\n\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0"); } } else if (!strcmp(args[1], "persist")) { @@ -5194,10 +5264,10 @@ int cfg_parse_listen(char *file, int linenum, char **args) { int errnum; char *err; - if (curproxy == &defproxy) { - Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); - return -1; - } + // if (curproxy == &defproxy) { + // Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); + // return -1; + // } if (*(args[2]) == 0) { Alert("parsing [%s:%d] : <errorloc> expects <error> and <url> as arguments.\n", file, linenum); @@ -5210,7 +5280,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { if (errnum == 400) { if (curproxy->errmsg.msg400) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg400); } curproxy->errmsg.msg400 = err; @@ -5218,7 +5288,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 403) { if (curproxy->errmsg.msg403) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg403); } curproxy->errmsg.msg403 = err; @@ -5226,7 +5296,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 408) { if (curproxy->errmsg.msg408) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg408); } curproxy->errmsg.msg408 = err; @@ -5234,7 +5304,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 500) { if (curproxy->errmsg.msg500) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg500); } curproxy->errmsg.msg500 = err; @@ -5242,7 +5312,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 502) { if (curproxy->errmsg.msg502) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg502); } curproxy->errmsg.msg502 = err; @@ -5250,7 +5320,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 503) { if (curproxy->errmsg.msg503) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg503); } curproxy->errmsg.msg503 = err; @@ -5258,7 +5328,7 @@ int cfg_parse_listen(char *file, int linenum, char **args) { } else if (errnum == 504) { if (curproxy->errmsg.msg504) { - Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); + //Warning("parsing [%s:%d] : error %d already defined.\n", file, linenum, errnum); free(curproxy->errmsg.msg504); } curproxy->errmsg.msg504 = err; @@ -5298,6 +5368,8 @@ int readcfgfile(char *file) { if ((f=fopen(file,"r")) == NULL) return -1; + init_default_instance(); + while (fgets(line = thisline, sizeof(thisline), f) != NULL) { linenum++; diff --git a/tests/defaults.cfg b/tests/defaults.cfg index 463ed6c6f..7621dc8d7 100644 --- a/tests/defaults.cfg +++ b/tests/defaults.cfg @@ -35,7 +35,7 @@ listen appli3-relais 127.0.0.1:10000-10100#,192.64.19.22:3129 #option httplog #option dontlognull #balance roundrobin - server app1_0 127.0.0.2 check port 113 inter 100 rise 2 fall 5 + server app1_0 127.0.0.1:+12000 check port 113 inter 100 rise 2 fall 5 # server app1_1 127.0.0.1:8000 check inter 100 rise 2 fall 5 #server app1_2 127.0.0.1:8001 check inter 100 rise 2 fall 5 backup #retries 1