* released 1.2.6

* clean-up patch from Alexander Lazic fixes build on Debian 3.1 (socklen_t).
This commit is contained in:
willy tarreau 2005-12-18 01:26:38 +01:00
parent 0fe396592d
commit c5f73ed21c
5 changed files with 1347 additions and 792 deletions

View File

@ -1,7 +1,10 @@
ChangeLog :
===========
2005/07/06 : 1.2.6 (1.1.32)
2005/08/07 : 1.2.6
- clean-up patch from Alexander Lazic fixes build on Debian 3.1 (socklen_t).
2005/07/06 : 1.2.6-pre5 (1.1.32)
- added the number of active sessions (proxy/process) in the logs
2005/07/06 : 1.2.6-pre4 (1.1.32-pre4)

View File

@ -2,9 +2,9 @@
H A - P r o x y
Architecture Guide
-------------------
version 1.1.30
version 1.1.32
willy tarreau
2004/11/28
2005/07/17
This document provides real world examples with working configurations.
@ -50,7 +50,7 @@ load across the new boxes.
Config on haproxy (LB1) :
-------------------------
listen 192.168.1.1:80
listen webfarm 192.168.1.1:80
mode http
balance roundrobin
cookie SERVERID insert indirect
@ -143,7 +143,7 @@ Now you don't want to add more cookies, but rather use existing ones. The
application already generates a "JSESSIONID" cookie which is enough to track
sessions, so we'll prefix this cookie with the server name when we see it.
Since the load-balancer becomes critical, it will be backed up with a second
one in VRRP mode using keepalived.
one in VRRP mode using keepalived under Linux.
Download the latest version of keepalived from this site and install it
on each load-balancer LB1 and LB2 :
@ -152,7 +152,7 @@ on each load-balancer LB1 and LB2 :
You then have a shared IP between the two load-balancers (we will still use the
original IP). It is active only on one of them at any moment. To allow the
proxy to bind to the shared IP, you must enable it in /proc :
proxy to bind to the shared IP on Linux 2.4, you must enable it in /proc :
# echo 1 >/proc/sys/net/ipv4/ip_nonlocal_bind
@ -171,7 +171,7 @@ proxy to bind to the shared IP, you must enable it in /proc :
Config on both proxies (LB1 and LB2) :
--------------------------------------
listen 192.168.1.1:80
listen webfarm 192.168.1.1:80
mode http
balance roundrobin
cookie JSESSIONID prefix
@ -188,7 +188,8 @@ Notes: the proxy will modify EVERY cookie sent by the client and the server,
so it is important that it can access to ALL cookies in ALL requests for
each session. This implies that there is no keep-alive (HTTP/1.1), thus the
"httpclose" option. Only if you know for sure that the client(s) will never
use keep-alive, you can remove this option.
use keep-alive (eg: Apache 1.3 in reverse-proxy mode), you can remove this
option.
Description :
@ -266,7 +267,7 @@ which will also check that the services run fine on both proxies :
Config on both proxies (LB1 and LB2) :
--------------------------------------
listen 0.0.0.0:80
listen webfarm 0.0.0.0:80
mode http
balance roundrobin
cookie JSESSIONID prefix
@ -287,24 +288,107 @@ logged.
Config on the Alteon :
----------------------
/c/slb/real 11
/c/slb/real 11
ena
name "LB1"
rip 192.168.1.3
/c/slb/real 12
/c/slb/real 12
ena
name "LB2"
rip 192.168.1.4
/c/slb/group 10
/c/slb/group 10
name "LB1-2"
metric roundrobin
health tcp
add 11
add 12
/c/slb/virt 10
/c/slb/virt 10
ena
vip 192.168.1.1
/c/slb/virt 10/service http
/c/slb/virt 10/service http
group 10
Note: the health-check on the Alteon is set to "tcp" to prevent the proxy from
forwarding the connections. It can also be set to "http", but for this the
proxy must specify a "monitor-net" with the Alteons' addresses, so that the
Alteon can really check that the proxies can talk HTTP but without forwarding
the connections to the end servers. Check next section for an example on how to
use monitor-net.
============================================================
2.2 Generic TCP relaying and external layer 4 load-balancers
============================================================
Sometimes it's useful to be able to relay generic TCP protocols (SMTP, TSE,
VNC, etc...), for example to interconnect private networks. The problem comes
when you use external load-balancers which need to send periodic health-checks
to the proxies, because these health-checks get forwarded to the end servers.
The solution is to specify a network which will be dedicated to monitoring
systems and must not lead to a forwarding connection nor to any log, using the
"monitor-net" keyword. Note: this feature expects a version of haproxy greater
than or equal to 1.1.32 or 1.2.6.
| VIP=172.16.1.1 |
+----+----+ +----+----+
| Alteon1 | | Alteon2 |
+----+----+ +----+----+
192.168.1.252 | GW=192.168.1.254 | 192.168.1.253
| |
------+---+------------+--+-----------------> TSE farm : 192.168.1.10
192.168.1.1 | | 192.168.1.2
+--+--+ +--+--+
| LB1 | | LB2 |
+-----+ +-----+
haproxy haproxy
Config on both proxies (LB1 and LB2) :
--------------------------------------
listen tse-proxy
bind :3389,:1494,:5900 # TSE, ICA and VNC at once.
mode tcp
balance roundrobin
server tse-farm 192.168.1.10
monitor-net 192.168.1.252/31
The "monitor-net" option instructs the proxies that any connection coming from
192.168.1.252 or 192.168.1.253 will not be logged nor forwarded and will be
closed immediately. The Alteon load-balancers will then see the proxies alive
without perturbating the service.
Config on the Alteon :
----------------------
/c/l3/if 1
ena
addr 192.168.1.252
mask 255.255.255.0
/c/slb/real 11
ena
name "LB1"
rip 192.168.1.1
/c/slb/real 12
ena
name "LB2"
rip 192.168.1.2
/c/slb/group 10
name "LB1-2"
metric roundrobin
health tcp
add 11
add 12
/c/slb/virt 10
ena
vip 172.16.1.1
/c/slb/virt 10/service 1494
group 10
/c/slb/virt 10/service 3389
group 10
/c/slb/virt 10/service 5900
group 10
@ -422,7 +506,7 @@ When an application is spread across several severs, the time to update all
instances increases, so the application seems jerky for a longer period.
HAproxy offers several solutions for this. Although it cannot be reconfigured
without being stopped, not does it offer any external command, there are other
without being stopped, nor does it offer any external command, there are other
working solutions.
@ -588,13 +672,13 @@ To soft-stop the service :
# kill $(</var/run/haproxy-checks.pid)
The port 81 will stop to respond and the load-balancer will notice the failure.
The port 81 will stop responding and the load-balancer will notice the failure.
4.2.2 Centralizing the server management
----------------------------------------
If one find it preferable to manage the servers from the load-balancer itself,
If one finds it preferable to manage the servers from the load-balancer itself,
the port redirector can be installed on the load-balancer itself. See the
example with iptables below.
@ -621,8 +705,8 @@ which is available for download here :
- health-checks will be sent twice as often, once for each standard server,
and once for reach backup server. All this will be multiplicated by the
number of processes if you use multi-process mode. You will have to check
that all the checks sent to the server do not load it.
number of processes if you use multi-process mode. You will have to ensure
that all the checks sent to the server do not overload it.
==================================================

View File

@ -2,9 +2,9 @@
H A - P r o x y
Reference Manual
-------------------
version 1.2.5
version 1.2.6
willy tarreau
2005/04/30
2005/08/07
============
| Abstract |
@ -104,8 +104,10 @@ the following ones :
- nopoll
- quiet
- pidfile <file>
- ulimit-n <number>
- stats
1.1) Event logging
------------------
Most events are logged : start, stop, servers going up and down, connections and
@ -138,14 +140,15 @@ Example :
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 :
connections using the 'maxconn' global keyword. 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
@ -155,8 +158,18 @@ sockets needed, all these parameters must be counted :
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.
(2 * maxconn + nbproxies + nbservers + 1). Starting with versions 1.1.32/1.2.6,
it is now possible to set the limit in the configuration using the 'ulimit-n'
global keyword, provided the proxy is started as root. This puts an end to the
recurrent problem of ensuring that the system limits are adapted to the proxy
values. Note that these limits are per-process.
Example :
---------
global
maxconn 32000
ulimit-n 65536
1.3) Drop of priviledges
------------------------
@ -203,6 +216,7 @@ Example :
gid 30000
chroot /var/chroot/haproxy
1.4) Startup modes
------------------
The service can start in several different :
@ -226,6 +240,7 @@ 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,
@ -358,6 +373,7 @@ Examples :
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
@ -370,6 +386,7 @@ section to be 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 :
@ -422,6 +439,38 @@ Example :
mode health
option httpchk
Monitoring
----------
Versions 1.1.32 and 1.2.6 provide a new solution to check the proxy's
availability without perturbating the service. The 'monitor-net' keyword was
created to specify a network of equipments which CANNOT use the service for
anything but health-checks. This is particularly suited to TCP proxies, because
it prevents the proxy from relaying the monitor's connection to the remote
server.
When used with TCP, the connection is accepted then closed and nothing is
logged. This is enough for a front-end load-balancer to detect the service as
available.
When used with HTTP, the connection is accepted, nothing is logged, the
following response is sent, then the session is closed : "HTTP/1.0 200 OK".
This is normally enough for any front-end HTTP load-balancer to detect the
service as available too, both with TCP and HTTP checks.
Proxies using the "monitor-net" keyword can remove the "option dontlognull", as
it will make them log empty connections from hosts outside the monitoring
network.
Example :
---------
listen tse-proxy
bind :3389,:1494,:5900 # TSE, ICA and VNC at once.
mode tcp
balance roundrobin
server tse-farm 192.168.1.10
monitor-net 192.168.1.252/31 # L4 load-balancers on .252 and .253
2.3) Limiting the number of simultaneous connections
----------------------------------------------------
@ -500,6 +549,7 @@ Notes :
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
@ -641,6 +691,7 @@ Notes :
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
@ -665,6 +716,7 @@ Example : the 'SERVERID' cookie can be either 'server01' or 'server02'
Warning : the syntax has changed since version 1.0 !
---------
2.11) Application Cookies
-------------------------
Since 1.2.4 it is possible to catch the cookie that comes from an
@ -692,6 +744,7 @@ Example :
.
.
3) Autonomous load balancer
===========================
@ -765,7 +818,6 @@ Examples :
3.1) Server monitoring
----------------------
It is possible to check the servers status by trying to establish TCP
connections or even sending HTTP requests to them. A server which fails to
reply to health checks as expected will not be used by the load balancing
@ -905,7 +957,7 @@ Examples :
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
# SMTP+TLS relaying with health-checks and backup servers
listen http_proxy :25,:587
mode tcp
@ -955,6 +1007,7 @@ option :
Other features are available. They are transparent mode, event logging and
header rewriting/filtering.
4.1) Network features
---------------------
4.1.1) Transparent mode
@ -1043,6 +1096,32 @@ Example :
4.2) Event logging
------------------
HAProxy's strength certainly lies in its precise logs. It probably provides the
finest level of information available for such a product, which is very
important for troubleshooting complex environments. Standard log information
include client ports, TCP/HTTP state timers, precise session state at
termination and precise termination cause, information about decisions to
direct trafic to a server, and of course the ability to capture arbitrary
headers.
In order to improve administrators reactivity, it offers a great transparency
about encountered problems, both internal and external, and it is possible to
send logs to different sources at the same time with different level filters :
- global process-level logs (system errors, start/stop, etc..)
- per-listener system and internal errors (lack of resource, bugs, ...)
- per-listener external troubles (servers up/down, max connections)
- per-listener activity (client connections), either at the establishment or
at the termination.
The ability to distribute different levels of logs to different log servers
allow several production teams to interact and to fix their problems as soon
as possible. For example, the system team might monitor system-wide errors,
while the application team might be monitoring the up/down for their servers in
real time, and the security team might analyze the activity logs with one hour
delay.
4.2.1) Log levels
-----------------
TCP and HTTP connections can be logged with informations such as date, time,
@ -1078,14 +1157,27 @@ the proxy will wait until the session ends to generate an enhanced log
containing more information such as session duration and its state during the
disconnection.
Example :
---------
Example of TCP logging :
------------------------
listen relais-tcp 0.0.0.0:8000
mode tcp
option tcplog
log 192.168.2.200 local3
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 --
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 -- 1/1
Field Format Example
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 listener_name relais-tcp
5 server_name Srv1
6 connect_time '/' total_time 0/5007
7 bytes_read 0
8 termination_state --
9 listener_conns '/' process_conns 1/1
Another option, 'httplog', provides more detailed information about HTTP
contents, such as the request and some cookies. In the event where an external
@ -1094,15 +1186,39 @@ full of useless lines. So it is possible not to log any session which didn't
transfer any data, by the setting of the 'dontlognull' option. This only has
effect on sessions which are established then closed.
Example :
---------
Example of HTTP logging :
-------------------------
listen http_proxy 0.0.0.0:80
mode http
option httplog
option dontlognull
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- "HEAD / HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- 3/3 "HEAD / HTTP/1.0"
More complete example
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
Field Format Example
1 process_name '[' pid ']:' haproxy[18989]:
2 client_ip ':' client_port 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 listener_name relais-http
5 server_name Srv1
6 Tq '/' Tc '/' Tr '/' Tt 3183/-1/-1/11215
7 HTTP_return_code 503
8 bytes_read 0
9 captured_request_cookie -
10 captured_response_cookie -
11 termination_state SC--
12 listener_conns '/' process_conns 202/205
13 '{' captured_request_headers '}' {w.ods.org|Mozilla}
14 '{' captured_response_headers '}' {}
15 '"' HTTP_request '"' "HEAD / HTTP/1.0"
Note for log parsers: the URI is ALWAYS the end of the line starting with the
first double quote '"'.
The problem when logging at end of connection is that you have no clue about
what is happening during very long sessions. To workaround this problem, a
@ -1127,8 +1243,7 @@ Example :
option logasap
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- "GET /image.iso HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
4.2.3) Timing events
--------------------
@ -1197,61 +1312,177 @@ Other cases ('xx' means any value to be ignored) :
4.2.4) Session state at disconnection
-------------------------------------
TCP and HTTP logs provide a session completion indicator. It's a 4-characters
(2 in TCP) field preceeding the HTTP request, and indicating :
TCP and HTTP logs provide a session completion indicator in the
<termination_state> field, just before the number of active
connections. It is 2-characters long in TCP, and 4-characters long in
HTTP, each of which has a special meaning :
- On the first character, a code reporting the first event which caused the
session to terminate :
C : the TCP session was aborted by the client.
S : the TCP session was aborted by the server, or the server refused it.
P : the session was abordted prematurely by the proxy, either because of
an internal error, because a DENY filter was matched, or because of
a security check which detected a dangerous error in server
response.
c : the client time-out expired first.
s : the server time-out expired first.
C : the TCP session was unexpectedly aborted by the client.
S : the TCP session was unexpectedly aborted by the server, or the
server explicitly refused it.
P : the session was prematurely aborted by the proxy, because of a
connection limit enforcement, because a DENY filter was matched,
or because of a security check which detected and blocked a
dangerous error in server response which might have caused
information leak (eg: cacheable cookie).
R : a resource on the proxy has been exhausted (memory, sockets, source
ports, ...). Usually, this appears during the connection phase, and
system logs should contain a copy of the precise error.
I : an internal error was identified by the proxy during a self-check.
This should NEVER happen, and you are encouraged to report any log
containing this, because this is a bug.
c : the client-side time-out expired first.
s : the server-side time-out expired first.
- : normal session completion.
- on the second character, the HTTP session state when it was closed :
- on the second character, the TCP/HTTP session state when it was closed :
R : waiting for complete REQUEST from the client (HTTP only). Nothing
was sent to any server.
C : waiting for CONNECTION to establish on the server. The server might
at most have noticed a connection attempt.
H : waiting for, receiving and processing server HEADERS (HTTP only).
D : the session was in the DATA phase.
R : waiting for complete REQUEST from the client
C : waiting for CONNECTION to establish on the server
H : processing server HEADERS
D : the session was in the DATA phase
L : the proxy was still transmitting LAST data to the client while the
server had already finished.
- : normal session completion after end of data transfer.
- the third character tells whether the persistence cookie was provided by
the client (only in HTTP mode) :
N : the client provided NO cookie.
I : the client provided an INVALID cookie matching no known server.
N : the client provided NO cookie. This is usually the case on new
connections.
I : the client provided an INVALID cookie matching no known
server. This might be caused by a recent configuration change,
mixed cookies between HTTP/HTTPS sites, or an attack.
D : the client provided a cookie designating a server which was DOWN,
so either the 'persist' option was used and the client was sent to
this server, or it was not set and the client was redispatched to
another server.
V : the client provided a valid cookie, and was sent to the associated
server.
- : does not apply (no cookie set in configuration).
- the last character reports what operations were performed on the persistence
cookie returned by the server (only in HTTP mode) :
N : NO cookie was provided by the server.
N : NO cookie was provided by the server, and none was inserted either.
I : no cookie was provided by the server, and the proxy INSERTED one.
P : a cookie was PROVIDED by the server and transmitted as-is.
I : no cookie was provided by the server, and one was INSERTED by the
proxy.
D : the cookie provided by the server was DELETED by the proxy.
R : the cookie provided by the server was REWRITTEN by the proxy.
D : the cookie provided by the server was DELETED by the proxy.
- : does not apply (no cookie set in configuration).
The 'capture' keyword allows to capture and log informations exchanged between
clients and servers. As of version 1.1.23, only cookies can be captured, which
makes it easy to track a complete user session. The syntax is :
The combination of the two first flags give a lot of information about what was
happening when the session terminated. It can be helpful to detect server
saturation, network troubles, local system resource starvation, attacks, etc...
The most common termination flags combinations are indicated here.
Flags Reason
CR The client aborted before sending a full request. Most probably the
request was done by hand using a telnet client, and aborted early.
cR The client timed out before sending a full request. This is sometimes
caused by too large TCP MSS values on the client side for PPPoE
networks which cannot transport full-sized packets, or by clients
sending requests by hand and not typing fast enough.
SC The server explicitly refused the connection (the proxy received a
TCP RST or an ICMP in return). Under some circumstances, it can
also be the network stack telling the proxy that the server is
unreachable (eg: no route, or no ARP response on local network).
sC The connection to the server did not complete during contimeout.
PC The proxy refused to establish a connection to the server because the
maxconn limit has been reached. The listener's maxconn parameter may
be increased in the proxy configuration, as well as the global
maxconn parameter.
RC A local resource has been exhausted (memory, sockets, source ports)
preventing the connection to the server from establishing. The error
logs will tell precisely what was missing. Anyway, this can only be
solved by system tuning.
cH The client timed out during a POST request. This is sometimes caused
by too large TCP MSS values for PPPoE networks which cannot transport
full-sized packets.
SH The server aborted before sending its full headers, or it crashed.
sH The server failed to reply during the srvtimeout delay, which
indicates too long transactions, probably caused by back-end
saturation. The only solutions are to fix the problem on the
application or to increase the 'srvtimeout' parameter to support
longer delays (at the risk of the client giving up anyway).
PR The proxy blocked the client's request, either because of an invalid
HTTP syntax, in which case it returned an HTTP 400 error to the
client, or because a deny filter matched, in which case it returned
an HTTP 403 error.
PH The proxy blocked the server's response, because it was invalid,
incomplete, dangerous (cache control), or matched a security filter.
In any case, an HTTP 502 error is sent to the client.
cD The client did not read any data for as long as the clitimeout delay.
This is often caused by network failures on the client side.
CD The client unexpectedly aborted during data transfer. This is either
caused by a browser crash, or by a keep-alive session between the
server and the client terminated first by the client.
sD The server did nothing during the srvtimeout delay. This is often
caused by too short timeouts on L4 equipements before the server
(firewalls, load-balancers, ...).
4.2.5) Non-printable characters
-------------------------------
As of version 1.1.29, non-printable characters are not sent as-is into log
files, but are converted to their two-digits hexadecimal representation,
prefixed by the character '#'. The only characters that can now be logged
without being escaped are between 32 and 126 (inclusive). Obviously, the
escape character '#' is also encoded to avoid any ambiguity. It is the same for
the character '"', as well as '{', '|' and '}' when logging headers.
4.2.6) Capturing HTTP headers and cookies
-----------------------------------------
Version 1.1.23 brought cookie capture, and 1.1.29 the header capture. All this
is performed using the 'capture' keyword.
Cookie capture makes it easy to track a complete user session. The syntax is :
capture cookie <cookie_prefix> len <capture_length>
This will enable cookie capture from both requests and responses. This way,
it's easy to detect when a user switches to a new session for example, because
the server will reassign it a new cookie.
The FIRST cookie whose name starts with <cookie_prefix> will be captured, and
logged as 'NAME=value', without exceeding <capture_length> characters (64 max).
When the cookie name is fixed and known, it's preferable to suffix '=' to it to
@ -1267,63 +1498,16 @@ Examples :
In the logs, the field preceeding the completion indicator contains the cookie
value as sent by the server, preceeded by the cookie value as sent by the
client. Each of these field is replaced with '-' when no cookie was seen.
client. Each of these field is replaced with '-' when no cookie was seen or
when the option is disabled.
4.2.5) Examples of logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- "HEAD / HTTP/1.0"
=> long request (6.5s) entered by hand through 'telnet'. The server replied
in 147 ms, and the session ended normally ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- "GET /image.iso HTTP/1.0"
=> request for a long data transfer. The 'logasap' option was specified, so
the log was produced just before transfering data. The server replied in
14 ms, 243 bytes of headers were sent to the client, and total time from
accept to first data byte is 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> the proxy blocked a server response either because of an 'rspdeny' or
'rspideny' filter, or because it blocked sensible information which risked
being cached. In this case, the response is replaced with a '502 bad
gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- ""
=> the client never completed its request and aborted itself ('C---') after
8.5s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- ""
=> The client never completed its request, which was aborted by the time-out
('c---') after 50s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server, but the proxy could send a 408 return code
to the client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
=> This is a 'tcplog' entry. Client-side time-out ('c----') occured after 5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- "HEAD / HTTP/1.0"
=> The request took 3s to complete (probably a network problem), and the
connection to the server failed ('SC--') after 4 attemps of 2 seconds
(config says 'retries 3'), then a 503 error code was sent to the client.
4.2.6) Non-printable characters
-------------------------------
As of version 1.1.29, non-printable characters are not sent as-is into log
files, but are converted to their two-digits hexadecimal representation,
prefixed by the character '#'. The only characters that can now be logged
without being escaped are between 32 and 126 (inclusive). Obviously, the
escape character '#' is also encoded to avoid any ambiguity. It is the same for
the character '"', as well as '{', '|' and '}' when logging headers.
4.2.7) Logging HTTP headers
---------------------------
As of version 1.1.29, it is now possible to log HTTP headers extracts. It is
both possible to include request headers and response headers. It is
particularly useful to know what virtual server the client requested, to know
the content length during a POST request, or a unique request ID set on a
previous proxy. In the response, one can search for information about the
response length, how the server asked the cache to behave, or an object location
during a redirection. The syntax is :
Header captures have a different goal. They are useful to track unique request
identifiers set by a previous proxy, virtual host names, user-agents, POST
content-length, referrers, etc. In the response, one can search for information
about the response length, how the server asked the cache to behave, or an
object location during a redirection. As for cookie captures, it is both
possible to include request headers and response headers at the same time. The
syntax is :
capture request header <name> len <max length>
capture response header <name> len <max length>
@ -1348,9 +1532,10 @@ within braces '{' and '}' in the same order as they were declared, and delimited
with a vertical bar '|' without any space. Response headers follow the same
representation, but are displayed after a space following the request headers
block. These blocks are displayed just before the HTTP request in the logs.
Example :
Config:
Config:
capture request header Host len 20
capture request header Content-Length len 10
@ -1361,11 +1546,53 @@ Config:
capture response header Via len 20
capture response header Location len 20
Log :
Log :
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.2.7) Examples of logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- 3/5 "HEAD / HTTP/1.0"
=> long request (6.5s) entered by hand through 'telnet'. The server replied
in 147 ms, and the session ended normally ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
=> request for a long data transfer. The 'logasap' option was specified, so
the log was produced just before transfering data. The server replied in
14 ms, 243 bytes of headers were sent to the client, and total time from
accept to first data byte is 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- 2/3 "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> the proxy blocked a server response either because of an 'rspdeny' or
'rspideny' filter, or because it blocked sensible information which risked
being cached. In this case, the response is replaced with a '502 bad
gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- 2/2 ""
=> the client never completed its request and aborted itself ('C---') after
8.5s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- 2/2 ""
=> The client never completed its request, which was aborted by the time-out
('c---') after 50s, while the proxy was waiting for the request headers ('-R--').
Nothing was sent to the server, but the proxy could send a 408 return code
to the client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
=> This is a 'tcplog' entry. Client-side time-out ('c----') occured after 5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 "HEAD / HTTP/1.0"
=> The request took 3s to complete (probably a network problem), and the
connection to the server failed ('SC--') after 4 attemps of 2 seconds
(config says 'retries 3'), then a 503 error code was sent to the client.
There were 202 connections on this proxy, and 205 on the global process.
It is possible that the server refused the connection because of too many
already established.
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.3) HTTP header manipulation
-----------------------------
@ -1500,6 +1727,7 @@ Example :
option forwardfor
option httpclose
4.4) Load balancing with persistence
------------------------------------
Combining cookie insertion with internal load balancing allows to transparently
@ -1561,6 +1789,7 @@ session state shows "PH--" meaning that the proxy blocked the response during
headers processing. Additionnaly, an alert will be sent in the logs so that
admins are told that there's something to be done.
4.6) Customizing errors
-----------------------
Some situations can make haproxy return an HTTP error code to the client :
@ -1601,8 +1830,8 @@ Location returned by a 302, which causes problems with the POST method.
The return code 303 was designed explicitly to force the client to fetch the
Location URL with the GET method, but there are some browsers pre-dating
HTTP/1.1 which don't support it. Anyway, most browsers still behave with 302 as
if it was a 303. In order to allow the user to chose, version 1.2.5 brings two
new keywords to replace 'errorloc' : 'errorloc302' and 'errorloc303'.
if it was a 303. In order to allow the user to chose, versions 1.1.31 and 1.2.5
bring two new keywords to replace 'errorloc' : 'errorloc302' and 'errorloc303'.
They are preffered over errorloc (which still does 302). Consider using
errorloc303 everytime you know that your clients support HTTP 303 responses..
@ -1721,7 +1950,7 @@ 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 1 > /proc/sys/net/ipv4/tcp_sack
echo 0 > /proc/sys/net/ipv4/tcp_dsack
# auto-tuned on 2.4

View File

@ -2,9 +2,9 @@
H A - P r o x y
Manuel de référence
-------------------
version 1.2.5
version 1.2.6
willy tarreau
2005/04/30
2005/08/07
================
| Introduction |
@ -17,7 +17,7 @@ environnement hautement disponible. En effet, il est capable de :
la persistence de session ;
- fournir une visibilité externe de son état de santé ;
- s'arrêter en douceur sans perte brutale de service ;
- modifier/ajouter/supprimer des entêtes dans la requête et la réponse ;
- modifier/ajouter/supprimer des en-têtes dans la requête et la réponse ;
- interdire des requêtes qui vérifient certaines conditions ;
- utiliser des serveurs de secours lorsque les serveurs principaux sont hors
d'usage.
@ -61,7 +61,7 @@ connexions TCP utilisables
confondus. Ce paramètre remplace le paramètre 'maxconn' de la section 'global'.
Le mode debug correspond à l'option 'debug' de la section 'global'. Dans ce
mode, toutes les connexions, déconnexions, et tous les échanges d'entêtes HTTP
mode, toutes les connexions, déconnexions, et tous les échanges d'en-têtes HTTP
sont affichés.
Les statistiques ne sont disponibles que si le programme a été compilé avec
@ -110,6 +110,8 @@ support
- nopoll
- quiet
- pidfile <fichier>
- ulimit-n <nombre>
1.1) Journalisation des événements
----------------------------------
@ -146,11 +148,13 @@ Exemple :
1.2) limitation du nombre de connexions
---------------------------------------
Il est possible et conseillé de limiter le nombre global de connexions par
processus. Les connexions sont comprises au sens 'acceptation de connexion',
donc il faut s'attendre en règle général à avoir un peu plus du double de
sessions TCP que le maximum de connexions fixé. C'est important pour fixer le
paramètre 'ulimit -n' avant de lancer le proxy. Pour comptabiliser le nombre
de sockets nécessaires, il faut prendre en compte ces paramètres :
processus à l'aide du mot clé global 'maxconn'. Les connexions sont comprises
au sens 'acceptation de connexion', donc il faut s'attendre en règle général à
avoir un peu plus du double de sessions TCP que le maximum de connexions fixé.
C'est important pour fixer le paramètre 'ulimit -n' avant de lancer le proxy.
Pour comptabiliser le nombre de sockets nécessaires, il faut prendre en compte
ces paramètres :
- 1 socket par connexion entrante
- 1 socket par connexion sortante
- 1 socket par couple adresse/port d'écoute par proxy
@ -159,8 +163,21 @@ de sockets n
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.
(2 * maxconn + nbproxy + nbserveurs + 1). A partir des versions 1.1.32/1.2.6,
il est possible de spécifier cette limite dans la configuration à l'aide du
mot-clé global 'ulimit-n', à condition bien entendu que le proxy ait été
démarré sous le compte root (ou avec des droits suffisants pour élever le
nombre de descripteurs de fichiers). Cette solution met un terme au problème
récurrent d'incertitude de l'adéquation entre les limites systèmes lors de la
dernière relance du proxessus et les limites en nombre de connexions. Noter que
cette limite s'applique par processus.
Exemple :
---------
global
maxconn 32000
ulimit-n 65536
1.3) Diminution des privilèges
------------------------------
@ -414,7 +431,7 @@ Mode HTTP
---------
Dans ce mode, le service relaye les connexions TCP vers un ou plusieurs
serveurs, une fois qu'il dispose d'assez d'informations pour en prendre la
décision. Les entêtes HTTP sont analysés pour y trouver un éventuel cookie, et
décision. Les en-têtes HTTP sont analysés pour y trouver un éventuel cookie, et
certains d'entre-eux peuvent être modifiés par le biais d'expressions
régulières. Pour activer ce mode, préciser le mode HTTP sous la déclaration du
relais.
@ -446,6 +463,38 @@ Exemple :
option httpchk
Les versions 1.1.32 et 1.2.6 apportent une nouvelle solution pour valider le
bon fonctionnement du proxy sans perturber le service. Le mot-clé 'monitor-net'
a été créé dans le butd de spécifier un réseau d'équipements qui ne PEUVENT PAS
utiliser le service pour autre chose que des tests de fonctionnement. C'est
particulièrement adapté aux proxies TCP, car cela empêche le proxy de relayer
des établissements de connexion émis par un outil de surveillance.
Lorsque c'est utilisé sur un proxy TCP, la connexion est acceptée puis refermée
et rien n'est logué. C'est suffisant pour qu'un répartiteur de charge en amont
détecte que le service est disponible.
Lorsque c'est utilisé sur un proxy HTTP, la connexion est acceptée, rien n'est
logué, puis la réponse suivante est envoyée et la session refermée :
"HTTP/1.0 200 OK". C'est normalement suffisant pour qu'un répartiteur de charge
HTTP en amont détecte le service comme opérationnel, aussi bien à travers des
tests TCP que HTTP.
Les proxies utilisant le mot-clé 'monitor-net' peuvent accessoirement se passer
de l'option 'dontlognull', ce qui permettra de loguer les connexions vides
émises depuis d'autres adresses que celles du réseau de tests.
Exemple :
---------
listen tse-proxy
bind :3389,:1494,:5900 # TSE, ICA and VNC at once.
mode tcp
balance roundrobin
server tse-farm 192.168.1.10
monitor-net 192.168.1.252/31 # L4 load-balancers on .252 and .253
2.3) Limitation du nombre de connexions simultanées
---------------------------------------------------
Le paramètre "maxconn" permet de fixer la limite acceptable en nombre de
@ -965,7 +1014,7 @@ tente de s'y connecter, il faut pr
D'autres fonctionnalités d'usage moins courant sont disponibles. Il s'agit
principalement du mode transparent, de la journalisation des connexions, et de
la réécriture des entêtes.
la réécriture des en-têtes.
4.1) Fonctionnalités réseau
---------------------------
@ -1056,6 +1105,35 @@ Exemple :
4.2) Journalisation des connexions
----------------------------------
L'un des points forts de HAProxy est indéniablement la précision de ses logs.
Il fournit probablement le plus fin niveau d'information disponible pour un
tel outil, ce qui est très important pour les diagnostics en environnements
complexes. En standard, les informations journalisées incluent le port client,
les chronométrages des états TCP/HTTP, des états de session précis au moment de
la terminaison et sa cause, des informations sur les décisions d'aiguillage du
trafic vers un serveur, et bien sûr la possibilité de capturer des en-têtes
arbitraires.
Dans le but d'améliorer la réactivité des administrateurs, il offre une grande
transparence sur les problèmes rencontrés, à la fois internes et externes, et
il est possible d'envoyer les logs vers des serveurs différents en même temps
avec des niveaux de filtrage différents :
- logs globaux au niveau processus (erreurs système, arrêts/démarrages, ...)
- erreurs système et internes par instance (manque de ressources, bugs, ...)
- problèmes externes par instance (arrêts/relance serveurs, limites, ...)
- activité par instance (connexions clients), aussi bien lors de leur
établissement qu'à leur terminaison.
La possibilité de distribuer différents niveaux de logs à différents serveurs
permet à plusieurs équipes de production d'intéragir et de corriger leurs
problèmes le plus tôt possible. Par exemple, l'équipe système peut surveiller
occasionnellement les erreurs système, pendant que l'équipe application
surveille les alertes d'arrêts/démarrages de ses serveurs en temps réel, et
que l'équipe sécurité analyse l'activité en différé d'une heure.
4.2.1) Niveaux de log
---------------------
Les connexions TCP et HTTP peuvent donner lieu à une journalisation sommaire ou
@ -1092,14 +1170,26 @@ la connexion ne sera journalis
sur son état lors de la déconnexion, ainsi que le temps de connexion et la
durée totale de la session.
Exemple :
---------
Exemple de journalisation TCP :
-------------------------------
listen relais-tcp 0.0.0.0:8000
mode tcp
option tcplog
log 192.168.2.200 local3
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 --
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 -- 1/1
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 127.0.0.1:34550
3 '[' date ']' [15/Oct/2003:15:24:28]
4 nom_instance relais-tcp
5 nom_serveur Srv1
6 temps_connect '/' temps_total 0/5007
7 octets lus 0
8 etat_terminaison --
9 conns_instance '/' conns_processus 1/1
Une autre option, 'httplog', fournit plus de détails sur le protocole HTTP,
notamment la requête et l'état des cookies. Dans les cas où un mécanisme de
@ -1108,15 +1198,40 @@ 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 :
---------
Exemple de journalisation HTTP :
--------------------------------
listen http_proxy 0.0.0.0:80
mode http
option httplog
option dontlognull
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- "HEAD / HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 9/7/147/723 200 243 - - ---- 3/3 "HEAD / HTTP/1.0"
Exemple plus complet :
haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 {w.ods.org|Mozilla} {} "HEAD / HTTP/1.0"
Champ Format / Description Exemple
1 nom_processus '[' pid ']:' haproxy[18989]:
2 ip_client ':' port_client 10.0.0.1:34552
3 '[' date ']' [15/Oct/2003:15:26:31]
4 nom_instance relais-http
5 nom_serveur Srv1
6 Tq '/' Tc '/' Tr '/' Tt 3183/-1/-1/11215
7 Code_retour_HTTP 503
8 octets lus 0
9 cookies_requête_capturés -
10 cookies_reponse_capturés -
11 etat_terminaison SC--
12 conns_instance '/' conns_processus 202/205
13 '{' entetes_requête_capturés '}' {w.ods.org|Mozilla}
14 '{' entetes_reponse_capturés '}' {}
15 '"' requête_HTTP '"' "HEAD / HTTP/1.0"
Note pour les analyseurs de logs : l'URI est TOUJOURS le dernier champ de la ligne, et
commence par un guillemet '"'.
Le problème de loguer uniquement en fin de session, c'est qu'il est impossible
de savoir ce qui se passe durant de gros transferts ou des sessions longues.
@ -1125,12 +1240,12 @@ la version 1.1.28 (1.2.1). Lorsqu'elle est activ
tôt possible, c'est à dire juste avant que ne débutent les transferts de
données. Cela signifie, dans le cas du TCP, qu'il loguera toujours le résultat
de la connexion vers le serveur, et dans le cas HTTP, qu'il loguera en fin de
traitement des entêtes de la réponse du serveur, auquel cas le nombre d'octets
représentera la taille des entêtes retournés au client.
traitement des en-têtes de la réponse du serveur, auquel cas le nombre d'octets
représentera la taille des en-têtes retournés au client.
Afin d'éviter toute confusion avec les logs normaux, le temps total de
transfert et le nombre d'octets transférés sont préfixés d'un signe '+'
rappeleant que les valeurs réelles sont certainement plus élevées.
rappelant que les valeurs réelles sont certainement plus élevées.
Exemple :
---------
@ -1142,7 +1257,7 @@ Exemple :
option logasap
log 192.168.2.200 local3
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- "GET /image.iso HTTP/1.0"
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
4.2.3) Chronométrage des événements
@ -1166,10 +1281,10 @@ la forme Tq/Tc/Tr/Tt :
vers le serveur.
- Tr: temps de réponse du serveur. C'est le temps que le serveur a mis pour
renvoyer la totalité des entêtes HTTP à partir du moment où il a acquitté
renvoyer la totalité des en-têtes HTTP à partir du moment où il a acquitté
la connexion. Ca représente exactement le temps de traitement de la
transaction sans le transfert des données associées. Une valeur '-1'
indique que le serveur n'a pas envoyé la totalité de l'entête HTTP.
indique que le serveur n'a pas envoyé la totalité de l'en-tête HTTP.
- Tt: durée de vie totale de la session, entre le moment où la demande de
connexion du client a été acquittée et le moment où la connexion a été
@ -1220,66 +1335,199 @@ Autres cas ('xx' repr
4.2.4) Conditions de déconnexion
--------------------------------
Les logs TCP et HTTP fournissent un indicateur de complétude de la session.
C'est un champ de 4 caractères (2 en TCP) 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 :
Les logs TCP et HTTP fournissent un indicateur de complétude de la session dans
le champ 'etat_terminaison', juste avant le nombre de connexions actives. C'est
un champ long de 2 caractères en TCP et de 4 caractères en HTTP, chacun ayant
une signification précise :
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, de configuration (ex: filtre d'URL), ou parce qu'un
contrôle de sécurité a détecté une anomalie dans la réponse du
serveur.
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 premier caractère, un code précisant le premier événement qui a causé
la terminaison de la session :
- sur le second caractère, l'état d'avancement de la session HTTP lors de la
fermeture :
C : fermeture inattendue de la session TCP de la part du client.
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 traitant les 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
S : fermeture inattendue de la session TCP de la part du serveur, ou
refus explicite de connexion de la part de ce dernier.
P : terminaison prématurée des sessions par le proxy, pour cause
d'imposition d'une limite sur le nombre de connexions, pour cause
de configuration (ex: filtre d'URL), ou parce qu'un contrôle de
sécurité a détecté et bloqué une anomalie dans la réponse du
serveur qui aurait pu causer une fuite d'informations (par exemple,
un cookie cachable).
R : une ressource sur le proxy a été épuisée (mémoire, sockets, ports
source, ...). Généralement, cela arrive au cours de l'établissement
d'une connexion, et les logs système doivent contenir une copie de
l'érreur précise.
I : une erreur interne a été identifiée par le proxy à la suite d'un
auto-contrôle. Ceci ne doit JAMAIS arriver, et vous êtes encouragés
à remonter n'importe quel log contenant ceci car il s'agira un bug.
c : le délai maximal d'attente du client a expiré (clitimeout).
s : le délai maximal d'attente du serveur a expiré (srvtimeout et contimeout)
- : terminaison normale de session.
- sur le second caractère, l'état d'avancement de la session TCP/HTTP lors de
la fermeture :
R : attente d'une REQUETE HTTP complète de la part du client. Rien n'a
été transmis au serveur.
C : attente de l'établissement d'une CONNEXION vers le serveur. Le
serveur peut au plus avoir vu la tentative de connexion, mais
aucune donnée n'a été échangée.
H : attente, réception ou traitement des en-têtes HTTP ("HEADERS").
D : transfert des DONNEES du serveur vers le client.
L : transfert des dernières ("LAST") 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 (uniquement en mode HTTP) :
N : aucun cookie de persistence n'a été présenté.
I : le client a présenté un cookie ne correspondant à aucun serveur
connu.
N : aucun cookie de persistence n'a été présenté. C'est généralement le
cas sur les NOUVELLES connexions clients.
I : le client a présenté un cookie INVALIDE ne correspondant à aucun
serveur connu. Ceci peut être dû à un changement de configuration
récent, à des mélanges de noms de cookies entre sites HTTP/HTTPS,
ou à une attaque.
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
d'usage ("DOWN"). 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
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 (uniquement en mode HTTP) :
- : non appliquable (pas de cookie positionné dans la configuration).
- le dernier caractère indique l'éventuel traitement effectué sur un cookie de
persistence retrourné par le serveur (uniquement en mode HTTP) :
N : aucun cookie de persistance n'a été fourni par le serveur, et aucun
n'a été inséré.
I : aucun cookie de persistance n'a été fourni par le serveur, et le
proxy en a INSERE un.
N : aucun cookie de persistence n'a été fourni par le serveur.
P : un cookie de persistence a été fourni par le serveur et transmis
tel quel.
I : aucun cookie n'a été fourni par le serveur, il a été inséré par le
proxy.
D : le cookie présenté par le serveur a été supprimé par le proxy pour
tel quel ("PASSIF").
R : le cookie retourné par le serveur a été REECRIT par le proxy.
D : le cookie présenté par le serveur a été DETRUIT 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 :
La combinaison des deux premiers indicateurs fournit une grande quantitié
d'informations sur ce qui se passait lorsque la session s'est terminée. Cela
peut notamment aider à détecter une saturation de serveur, des troubles réseau,
des épuisements de ressources système locales, des attaques, etc...
Les combinaisons d'indicateurs les plus fréquentes sont énumérées ici.
Indic Raison
CR Le client a abandonné avant d'émettre une requête complète. Il est
très probable que la requête ait été tapée à la main dans un client
telnet et abortée trop tôt.
cR Le temps imparti au client a expiré avant réception d'une requête
complète. Ceci est parfois causé par un paramètre TCP MSS trop élevé
sur le client pour des réseaux PPPoE sur ADSL qui ne peuvent pas
transporter des paquets entiers, ou par des clients qui énvoient des
requêtes à la main et ne tapent pas assez vite.
SC Le serveur a explicitement refusé la connexion (le proxy a reçu un
RST TCP ou un message ICMP en retour). Dans certains cas, cela peut
être la couche réseau qui indique au proxy que le serveur n'est pas
joignable (p.ex: pas de route, pas de réponse ARP en local, etc...)
sC La connexion au serveur n'a pas pu s'établir dans le temps imparti.
PC Le proxy a refusé d'établir une connexion au serveur parce que le
nombre de connexions a atteint la limite 'maxconn' (global ou de
l'instance). Le paramètre 'maxconn' de l'instance pourrait être
augmenté, tout comme le paramètre 'maxconn' global.
RC Une ressource locale a été épuisée (mémoire, sockets, ports source),
empêchant la connexion au serveur de s'établir. Les logs d'erreurs
diront précisément ce qui manquait. Dans tous les cas, le seul remède
consiste à affiner le paramétrage système.
cH Le temps imparti au client a expiré au cours d'une requête POST. Ceci
est parfois causé par un paramètre TCP MSS trop élevé sur le client
pour des réseaux PPPoE sur ADSL qui ne peuvent pas transporter des
paquets entiers.
SH Le serveur a aborté brutalement alors qu'il devait envoyer ses
en-têtes. En général, cela indique qu'il a crashé.
sH Le serveur n'a pas pu répondre durant le temps imparti, ce qui montre
des transactions trop longues, probablement causées par un back-end
saturé. Les seules solutions sont de corriger le problème sur
l'application, d'accroître le paramètre 'srvtimeout' pour supporter
des attentes plus longues au risque que les clients abandonnent à
leur tour, ou bien d'ajouter des serveurs.
PR Le proxy a bloqué une requête du client, soit à cause d'une syntaxe
HTTP invalide, auquel cas il a renvoyé une erreur HTTP 400 au client,
soit à cause d'une requête validant un filtre d'interdiction, auquel
cas le proxy a renvoyé une erreur HTTP 403.
PH Le proxy a bloqué la réponse du serveur parce qu'elle était invalide,
incomplète, dangereuse ('cache control'), ou parce qu'elle validait
un filtre de sécurité. Dans tous les cas, une erreur HTTP 502 est
renvoyée au client.
cD Le client n'a pas lu de données pendant le temps qui lui était
imparti. Ceci est souvent causé par des problèmes réseau côté client.
CD Le client a aborté sa connection de manière inattendue pendant le
transfert des données. Ceci est provoqué soit par le crash d'un
navigateur, ou par une session en HTTP keep-alive entre le serveur
et le client terminée en premier par le client.
sD Le serveur n'a rien fait durant le temps imparti par le paramètre
'srvtimeout'. Ceci est souvent causé par des timeouts trop courts
sur des équipements de niveau 4 (firewalls, répartiteurs de charge)
situés entre le proxy et le serveur.
4.2.5) Caractères non-imprimables
---------------------------------
Depuis la version 1.1.29, les caractères non-imprimables ne sont plus envoyés
tels quels dans les lignes de logs, mais inscrits sous la forme de deux chiffres
hexadécimaux, préfixés du caractère d'échappement '#'. Les seuls caractères
dorénavant logués tels quels sont compris entre 32 et 126. Bien évidemment, le
caractère d'échappement '#' est lui-même encodé afin de lever l'ambiguité. Il en
est de même pour le caractère '"', ainsi que les caractères '{', '|' et '}' pour
les en-têtes.
4.2.6) Capture d'en-têtes HTTP et de cookies
--------------------------------------------
La version 1.1.23 a apporté la capture des cookies, et la version 1.1.29 la
capture d'en-têtes. Tout ceci est effectué en utilisant le mot-clé 'capture'.
Les captures de cookies facilitent le suivi et la reconstitution d'une session
utilisateur. La syntaxe est la suivante :
capture cookie <préfixe_cookie> len <longueur_capture>
Ceci activera la capture de cookies à la fois dans les requêtes et dans les
réponses. De cette manière, il devient facile de détecter lorsqu'un utilisateur
bascule sur une nouvelle session par exemple, car le serveur lui réassignera un
nouveau cookie.
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
@ -1297,68 +1545,17 @@ Exemples :
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.
par le client ou le serveur, ou lorsque l'option est désactivée..
4.2.5) Exemples de logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- "HEAD / HTTP/1.0"
=> requête longue (6.5s) saisie à la main avec un client telnet. Le serveur a
répondu en 147 ms et la session s'est terminée normalement ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- "GET /image.iso HTTP/1.0"
=> requête pour un long transfert. L'option 'logasap' était spécifiée donc le
log a été généré juste avant le transfert de données. Le serveur a répondu
en 14 ms, 243 octets d'entêtes ont été transférés au client, et le temps
total entre l'accept() et le premier octet de donnée est de 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> le proxy a bloqué une réponse du serveur soit à cause d'un filtre 'rspdeny'
ou 'rspideny', soit parce qu'il a détecté un risque de fuite sensible
d'informations risquant d'être cachées. Dans ce cas, la réponse est
remplacée par '502 bad gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- ""
=> Le client n'a pas envoyé sa requête et a refermé la connexion lui-même
('C---') au bout de 8.5s, alors que le relais attendait l'entête ('-R--').
Aucune connexion n'a été envoyée vers le serveur.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- ""
=> Le client n'a pas envoyé sa requête et son time-out a expiré ('c---') au
bout de 50s, alors que le relais attendait l'entête ('-R--'). Aucune
connexion n'a été envoyée vers le serveur, mais le relais a tout de même
pu renvoyer un message 408 au client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
=> log en mode 'tcplog'. Expiration du time-out côté client ('c----') au bout
de 5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- "HEAD / HTTP/1.0"
=> La requête client met 3s à entrer (peut-être un problème réseau), et la
connexion ('SC--') vers le serveur échoue au bout de 4 tentatives de 2
secondes (retries 3 dans la conf), puis un code 503 est retourné au
client.
4.2.6) Caractères non-imprimables
---------------------------------
Depuis la version 1.1.29, les caractères non-imprimables ne sont plus envoyés
tels quels dans les lignes de logs, mais inscrits sous la forme de deux
chiffres hexadécimaux, préfixés du caractère d'échappement '#'. Les seuls
caractères dorénavant logués tels quels sont compris entre 32 et 126. Bien
évidemment, le caractère d'échappement '#' est lui-même encodé afin de lever
l'ambiguité. Il en est de même pour le caractère '"', ainsi que les caractères
'{', '|' et '}' pour les en-têtes.
4.2.7) Journalisation d'en-têtes
--------------------------------
Depuis la version 1.1.29, il est désormais possible de conserver des extraits
d'en-têtes HTTP dans les logs. On peut aussi bien extraire des en-têtes de la
requête que de la réponse. C'est particulièrement pratique pour savoir à quel
serveur virtuel une requête s'adressait, pour connaitre la longueur des données
émises lors d'un POST, ou encore loguer un identifiant unique de requête
positionné en amont. Dans la réponse, on peut chercher également à conserver
des informations relatives à la taille annoncée de la réponse, le
fonctionnement attendu du cache, ou encore la localisation d'un objet en cas
de redirection. La syntaxe est la suivante :
Les captures d'en-têtes ont un rôle complètement différent. Elles sont utiles
pour suivre un identifiant de requête globalement unique positionné par un
autre proxy en amont, pour journaliser les noms de serveurs virtuels, les types
de clients web, la longueur des POST, les 'referrers', etc. Dans la réponse, on
peut chercher des informations relatives à la longueur annoncée de la réponse,
le fonctionnement attendu du cache, ou encore la localisation d'un objet en cas
de redirection. Tout comme pour les captures de cookies, il est possible
d'inclure les en-têtes de requêtes et de réponse simultanément. La syntaxe est
la suivante :
capture request header <nom> len <longueur max>
capture response header <nom> len <longueur max>
@ -1377,15 +1574,14 @@ Exemples:
# noter l'URL de redirection
capture response header Location len 20
Les en-têtes non trouvés sont logués à vide, et si un en-tête apparait
plusieurs fois, seule la dernière occurence sera conservée. Les en-têtes de
requête sont regroupés entre deux accolades '{' et '}' dans l'ordre de leur
déclaration, et chacun séparés par une barre verticale '|', sans aucun espace.
Les en-têtes de réponse sont présentés de la même manière, mais après un
espace suivant le bloc d'en-tête de requête. Le tout précède la requête HTTP.
Exemple :
Les en-têtes non trouvés sont logués à vide, et si un en-tête apparait plusieurs
fois, seule la dernière occurence sera conservée. Les en-têtes de requête sont
regroupés entre deux accolades '{' et '}' dans l'ordre de leur déclaration, et
chacun séparés par une barre verticale '|', sans aucun espace. Les en-têtes de
réponse sont présentés de la même manière, mais après un espace suivant le bloc
d'en-tête de requête. Le tout précède la requête HTTP. Exemple :
Config:
Config:
capture request header Host len 20
capture request header Content-Length len 10
@ -1396,13 +1592,55 @@ Config:
capture response header Via len 20
capture response header Location len 20
Log :
Log :
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
Aug 9 20:26:09 localhost haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] relais-http netcache 0/0/162/+162 200 +350 - - ---- {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} "GET http://fr.adserver.yahoo.com/"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] relais-http netcache 0/0/182/+182 200 +279 - - ---- {w.ods.org||} {Formilux/0.1.8|3495|||} "GET http://w.ods.org/sytadin.html HTTP/1.1"
Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] relais-http netcache 0/2/126/+128 200 +223 - - ---- {www.infotrafic.com||http://w.ods.org/syt} {Apache/2.0.40 (Red H|9068|||} "GET http://www.infotrafic.com/images/live/cartesidf/grandes/idf_ne.png HTTP/1.1"
4.3) Modification des entêtes HTTP
4.2.7) Exemples de logs
-----------------------
- haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57] relais-http Srv1 6559/7/147/6723 200 243 - - ---- 3/5 "HEAD / HTTP/1.0"
=> requête longue (6.5s) saisie à la main avec un client telnet. Le serveur a
répondu en 147 ms et la session s'est terminée normalement ('----')
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/+30 200 +243 - - ---- 3/3 "GET /image.iso HTTP/1.0"
=> requête pour un long transfert. L'option 'logasap' était spécifiée donc le
log a été généré juste avant le transfert de données. Le serveur a répondu
en 14 ms, 243 octets d'en-têtes ont été transférés au client, et le temps
total entre l'accept() et le premier octet de donnée est de 30 ms.
- haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17] relais-http Srv1 9/7/14/30 502 243 - - PH-- 2/3 "GET /cgi-bin/bug.cgi? HTTP/1.0"
=> le proxy a bloqué une réponse du serveur soit à cause d'un filtre 'rspdeny'
ou 'rspideny', soit parce qu'il a détecté un risque de fuite sensible
d'informations risquant d'être cachées. Dans ce cas, la réponse est
remplacée par '502 bad gateway'.
- haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55] relais-http <NOSRV> -1/-1/-1/8490 -1 0 - - CR-- 2/2 ""
=> Le client n'a pas envoyé sa requête et a refermé la connexion lui-même
('C---') au bout de 8.5s, alors que le relais attendait l'en-tête ('-R--').
Aucune connexion n'a été envoyée vers le serveur.
- haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06] relais-http <NOSRV> -1/-1/-1/50001 408 0 - - cR-- 2/2 ""
=> Le client n'a pas envoyé sa requête et son time-out a expiré ('c---') au
bout de 50s, alors que le relais attendait l'en-tête ('-R--'). Aucune
connexion n'a été envoyée vers le serveur, mais le relais a tout de même
pu renvoyer un message 408 au client.
- haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28] relais-tcp Srv1 0/5007 0 cD
=> log en mode 'tcplog'. Expiration du time-out côté client ('cD') au bout de
5s.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- 202/205 "HEAD / HTTP/1.0"
=> La requête client met 3s à entrer (peut-être un problème réseau), et la
connexion ('SC--') vers le serveur échoue au bout de 4 tentatives de 2
secondes (retries 3 dans la conf), puis un code 503 est retourné au client.
Il y avait 202 connexions sur cette instance, et 205 sur l'ensemble des
instances pour ce processus. Il est possible que le serveur ait refusé la
connexion parce qu'il y en avait déjà trop d'établies.
4.3) Modification des en-tê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
@ -1418,11 +1656,11 @@ La syntaxe est :
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>
reqallow <search> autoriser la requête si un en-tête valide <search>
reqiallow <search> idem sans distinction majuscules/minuscules
reqdeny <search> interdire la requête si un entête valide <search>
reqdeny <search> interdire la requête si un en-tête valide <search>
reqideny <search> idem sans distinction majuscules/minuscules
reqpass <search> inhibe ces actions sur les entêtes validant <search>
reqpass <search> inhibe ces actions sur les en-têtes validant <search>
reqipass <search> idem sans distinction majuscules/minuscules
rspadd <string> pour ajouter un en-tête dans la réponse
@ -1431,7 +1669,7 @@ La syntaxe est :
rspdel <search> pour supprimer un en-tête dans la réponse
rspidel <search> idem sans distinction majuscules/minuscules
rspdeny <search> remplace la réponse par un HTTP 502 si un
entête valide <search>
en-tête valide <search>
rspideny <search> idem sans distinction majuscules/minuscules
@ -1472,7 +1710,7 @@ Remarques :
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.
en-têtes inutiles avant les ajouts.
- une requête bloquée produira une réponse "HTTP 403 forbidden" tandis qu'une
réponse bloquée produira une réponse "HTTP 502 Bad gateway".
@ -1522,7 +1760,7 @@ De plus, l'option 'forwardfor' ajoute l'adresse IP du client dans un champ
connaître l'adresse IP du client initial.
Enfin, l'option 'httpclose' apparue dans la version 1.1.28/1.2.1 supprime tout
entête de type 'Connection:' et ajoute 'Connection: close' dans les deux sens.
en-tête de type 'Connection:' et ajoute 'Connection: close' dans les deux sens.
Ceci simplifie la désactivation du keep-alive HTTP par rapport à l'ancienne
méthode impliquant 4 règles.
@ -1574,30 +1812,30 @@ puisse corriger le nom du cookie dans toutes les futures requ
4.5) Protection contre les fuites d'informations du serveur
-----------------------------------------------------------
Dans les versions 1.1.28 et 1.2.1, une nouvelle option 'checkcache' a été
créée. Elle sert à inspecter minutieusement les entêtes 'Cache-control',
créée. Elle sert à inspecter minutieusement les en-têtes 'Cache-control',
'Pragma', et 'Set-cookie' dans les réponses serveur pour déterminer s'il y a
un risque de cacher un cookie sur un proxy côté client. Quand cette option est
activée, les seules réponses qui peuvent être retournées au client sont :
- toutes celles qui n'ont pas d'entête 'Set-cookie' ;
- toutes celles qui n'ont pas d'en-tête 'Set-cookie' ;
- toutes celles qui ont un code de retour autre que 200, 203, 206, 300, 301,
410, sauf si le serveur a positionné un entête 'Cache-control: public' ;
410, sauf si le serveur a positionné un en-tête 'Cache-control: public' ;
- celles qui font suite à une requête POST, sauf si le serveur a positionné
un entête 'Cache-control: public' ;
- celles qui ont un entête 'Pragma: no-cache' ;
- celles qui ont un entête 'Cache-control: private' ;
- celles qui ont un entête 'Cache-control: no-store' ;
- celles qui ont un entête 'Cache-control: max-age=0' ;
- celles qui ont un entête 'Cache-control: s-maxage=0' ;
- celles qui ont un entête 'Cache-control: no-cache' ;
- celles qui ont un entête 'Cache-control: no-cache="set-cookie"' ;
- celles qui ont un entête 'Cache-control: no-cache="set-cookie,'
un en-tête 'Cache-control: public' ;
- celles qui ont un en-tête 'Pragma: no-cache' ;
- celles qui ont un en-tête 'Cache-control: private' ;
- celles qui ont un en-tête 'Cache-control: no-store' ;
- celles qui ont un en-tête 'Cache-control: max-age=0' ;
- celles qui ont un en-tête 'Cache-control: s-maxage=0' ;
- celles qui ont un en-tête 'Cache-control: no-cache' ;
- celles qui ont un en-tête 'Cache-control: no-cache="set-cookie"' ;
- celles qui ont un en-tête 'Cache-control: no-cache="set-cookie,'
(autorisant d'autres champs après set-cookie).
Si une réponse ne respecte pas ces pré-requis, alors elle sera bloquée de la
même manière que s'il s'agissait d'un filtre 'rspdeny', avec en retour un
message "HTTP 502 bad gateway". L'état de session montre "PH--" ce qui veut
dire que c'est le proxy qui a bloqué la réponse durant le traitement des
entêtes. De plus, un message d'alerte sera envoyé dans les logs de sorte que
en-têtes. De plus, un message d'alerte sera envoyé dans les logs de sorte que
l'administrateur sache qu'il y a une action correctrice à entreprendre.
4.6) Personalisation des erreurs
@ -1642,8 +1880,8 @@ dans le champ Location avec la m
navigateurs antérieurs à HTTP/1.1 ne connaissent pas ce code de retour. De
plus, la plupart des navigateurs se comportent déjà avec le code 302 comme ils
devraient le faire avec le 303. Donc, dans le but de laisser le choix à
l'utilisateur, la version 1.2.5 apporte deux nouvelles commandes visant à
remplacer 'errorloc' : 'errorloc302' et 'errorloc303'.
l'utilisateur, les versions 1.1.31 et 1.2.5 apportent deux nouvelles commandes
visant à remplacer 'errorloc' : 'errorloc302' et 'errorloc303'.
Leur usage non ambigü est recommandé à la place de la commande 'errorloc' (qui
utilise toujours 302). Dans le doute, préférez l'utilisation de 'errorloc303'
@ -1766,7 +2004,7 @@ 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 1 > /proc/sys/net/ipv4/tcp_sack
echo 0 > /proc/sys/net/ipv4/tcp_dsack
# auto-tuned on 2.4

View File

@ -77,7 +77,7 @@
#include "include/appsession.h"
#define HAPROXY_VERSION "1.2.6"
#define HAPROXY_DATE "2005/07/06"
#define HAPROXY_DATE "2005/08/07"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@ -1651,7 +1651,7 @@ static int maintain_proxies(void);
/* this either returns the sockname or the original destination address. Code
* inspired from Patrick Schaaf's example of nf_getsockname() implementation.
*/
static int get_original_dst(int fd, struct sockaddr_in *sa, int *salen) {
static int get_original_dst(int fd, struct sockaddr_in *sa, socklen_t *salen) {
#if defined(TPROXY) && defined(SO_ORIGINAL_DST)
return getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, (void *)sa, salen);
#else
@ -1767,7 +1767,7 @@ int connect_server(struct session *s) {
}
else if (s->proxy->options & PR_O_TRANSP) {
/* in transparent mode, use the original dest addr if no dispatch specified */
int salen = sizeof(struct sockaddr_in);
socklen_t salen = sizeof(struct sockaddr_in);
if (get_original_dst(s->cli_fd, &s->srv_addr, &salen) == -1) {
qfprintf(stderr, "Cannot get original server address.\n");
return SN_ERR_INTERNAL;
@ -1778,7 +1778,7 @@ int connect_server(struct session *s) {
* the port the client connected to with an offset. */
if (s->srv != NULL && s->srv->state & SRV_MAPPORTS) {
struct sockaddr_in sockname;
int namelen;
socklen_t namelen;
namelen = sizeof(sockname);
if (get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
@ -2441,7 +2441,7 @@ int event_accept(int fd) {
while (p->nbconn < p->maxconn) {
struct sockaddr_storage addr;
int laddr = sizeof(addr);
socklen_t laddr = sizeof(addr);
if ((cfd = accept(fd, (struct sockaddr *)&addr, &laddr)) == -1) {
switch (errno) {
case EAGAIN:
@ -2589,7 +2589,7 @@ int event_accept(int fd) {
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
struct sockaddr_storage sockname;
int namelen;
socklen_t namelen;
namelen = sizeof(sockname);
if (addr.ss_family != AF_INET ||
@ -2630,7 +2630,7 @@ int event_accept(int fd) {
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
struct sockaddr_in sockname;
int namelen;
socklen_t namelen;
int len;
namelen = sizeof(sockname);
if (addr.ss_family != AF_INET ||
@ -2754,7 +2754,8 @@ int event_srv_chk_w(int fd) {
struct task *t = fdtab[fd].owner;
struct server *s = t->context;
int skerr, lskerr;
int skerr;
socklen_t lskerr;
lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
/* in case of TCP only, this tells us if the connection succeeded */