|
|
----------------------5 U. V/ E8 d. w3 r, f$ ^3 F$ z' Q, Y
HAProxy, Z+ y4 [* h3 }- h, B* @- }5 Z+ x
Configuration Manual
% E3 P% {) L8 \7 o ---------------------- O+ J/ D; K0 D7 z+ F
version 1.4.27
0 {& W, O4 Y" o2 L& F3 X6 L willy tarreau
1 w& R" K$ k! T8 |/ b: u 2016/03/13* f! e# a# ]. A4 J9 f. Z
7 L) j+ F5 f3 T" g! A/ y+ J5 v7 T9 U$ M
This document covers the configuration language as implemented in the version3 r: \4 F) J1 `
specified above. It does not provide any hint, example or advice. For such7 w, w7 a: G5 M. ]% A" \
documentation, please refer to the Reference Manual or the Architecture Manual.
- c% H4 ?! R/ G* H, ~4 k) AThe summary below is meant to help you search sections by name and navigate1 S5 K' V5 F7 y! ^! F% a, W
through the document.. B7 p& E4 E# ^) c4 t
* K7 q* ~0 L2 k2 g$ l+ s- D% G0 { qNote to documentation contributors :' T4 o0 Q& V, Z
This document is formated with 80 columns per line, with even number of" `: Y6 V2 f2 Q: b# |
spaces for indentation and without tabs. Please follow these rules strictly
( y4 k5 ]1 q8 f$ S& I so that it remains easily printable everywhere. If a line needs to be
6 I- z! l3 `5 u9 ] printed verbatim and does not fit, please end each line with a backslash" n+ a- s3 g; t" s* ]- g& G
('\') and continue on next line. If you add sections, please update the4 [1 b2 r' k: _% {0 _
summary below for easier searching.
9 k' `! ^( }/ y4 F, }
4 U: a1 U# R! v" r5 I
. }# b. w6 c# Q' ^Summary1 ~* I+ B0 `6 Q; w
-------' j- ?" W1 t( [( |' k0 _6 J
' E0 @2 V \5 x( |6 b1 F
1. Quick reminder about HTTP% ~' z2 V6 k& T! v9 c
1.1. The HTTP transaction model
" i2 f7 \0 R @9 _. \& [7 n: ~1.2. HTTP request. X; j+ J$ ?% T4 X2 Q; p: Q
1.2.1. The Request line8 S/ \/ @2 B7 Y+ |6 V; z
1.2.2. The request headers! E R$ l4 d# D6 P
1.3. HTTP response
: q0 ?; @, g. A! p, Q+ ~0 ^1.3.1. The Response line
2 O8 {% }3 M9 ?% w5 a6 p6 \( A1.3.2. The response headers3 c! p4 n: B6 w, f! |0 H2 C
+ L3 j+ g2 c4 G3 b3 U" R# d4 W( ^2. Configuring HAProxy; L. Q. D0 G2 ]/ }! z3 z7 y
2.1. Configuration file format
0 ~7 N) n# i' F5 I2.2. Time format
2 T! r( |! Z. `8 M" t2.3. Examples5 N- x) b" p9 }- G- }+ s( S+ |
; x* l7 S& L4 H* i0 @! X8 Q3. Global parameters
) _' S5 A& V9 O7 O9 r7 o$ i2 r; x7 F3.1. Process management and security$ {0 \# Z4 Y/ z% h) ~
3.2. Performance tuning- ?9 u: M+ D/ M
3.3. Debugging# H" [# g4 T- X, E4 {6 _0 Q) a
3.4. Userlists
( t' J6 p6 L0 W/ O, U; p1 q9 n& U
4. Proxies, t" P. K* S* ~( S
4.1. Proxy keywords matrix
& F( }4 c/ A$ ~8 { L4.2. Alphabetically sorted keywords reference. o, d4 E" U# ?# f; p3 M5 M* } P% b
& ? l1 k& c5 e' s6 _5 Q% C4 R @5. Server and default-server options/ A) N [2 Y, U/ {: c
/ q2 G8 F1 G# N; V2 s" s6. HTTP header manipulation
3 T9 H8 j# [) t8 H' V- K8 p9 k. a6 Z0 ~7 f
7. Using ACLs and pattern extraction
/ o; |& d8 W! X7 W7.1. Matching integers
9 ^( i: s! r3 h0 n$ e7.2. Matching strings8 B: {+ E# M* i$ u9 U5 E1 Z# G U" a
7.3. Matching regular expressions (regexes)) D* n, D! A* m' D$ \- \( D" ^' }
7.4. Matching IPv4 addresses
3 O b t% v/ j4 q. \5 [/ \7.5. Available matching criteria. S7 ?3 p8 Q" ]' H
7.5.1. Matching at Layer 4 and below
: }) A' Q0 i6 P+ g; z. B: q7.5.2. Matching contents at Layer 40 q. B6 T% [& L8 V" V7 A. n. I
7.5.3. Matching at Layer 72 Z, Q5 E9 ^! N. C9 f, k3 N6 J
7.6. Pre-defined ACLs, ~+ ^8 K& S8 N1 }. C' m5 I7 z% s/ ~
7.7. Using ACLs to form conditions
# p5 }2 c3 R/ B4 l: ?. |; U, p8 d7.8. Pattern extraction& i y6 c& L: a9 e' ~2 z, ?) m
4 C3 E: k4 O" ]* J8. Logging
1 e9 g; P, h9 Y+ Q1 q2 [( {8.1. Log levels a: d: a" Y0 {& ]5 I, M
8.2. Log formats- R( j/ [8 h5 V4 w D) H* ?. A
8.2.1. Default log format
8 _7 P0 W" D' q8.2.2. TCP log format U$ W# ?. [0 C6 n; @! o9 z
8.2.3. HTTP log format
5 m: t! d; M, ?6 [ k# v8.3. Advanced logging options
6 {9 ]% o& T* C5 q R8.3.1. Disabling logging of external tests! q( V) X* D! n: n, M& ?$ N
8.3.2. Logging before waiting for the session to terminate. `. E& t" B' d' N" m7 J; }
8.3.3. Raising log level upon errors
3 J7 n6 {) ]4 D+ C5 b8.3.4. Disabling logging of successful connections0 k, f1 n% ?* k/ S
8.4. Timing events
' w7 n) `3 a3 \, y3 h8 g8.5. Session state at disconnection% B! L% a% y. ]' k* w" h# h- |. i- a
8.6. Non-printable characters1 Z7 y$ c- ?1 S6 J
8.7. Capturing HTTP cookies
7 f }, X+ X& K8.8. Capturing HTTP headers1 H. _( N7 [ d0 W/ V& @
8.9. Examples of logs
' N o9 N m8 ~/ R8 w4 m
" f+ J+ ~: F8 Y6 K/ y8 q; X6 @9. Statistics and monitoring$ q1 W2 p; Z( ^" M# T, T; k7 R
9.1. CSV format
K. C* B+ \* R4 v9.2. Unix Socket commands! f5 H" E9 S* b* ]% m; P, g
* @! m r% q" \' Y3 Q" T# q7 A6 I+ Q# s2 c3 {
1. Quick reminder about HTTP
( v- b: u% A9 G9 Q; u) c----------------------------
6 V+ e, S+ @' W! c: L8 w9 \, ~
" I0 b w8 E- z( `7 d- r7 HWhen haproxy is running in HTTP mode, both the request and the response are6 U! E- y7 y& E7 Y$ o
fully analyzed and indexed, thus it becomes possible to build matching criteria
- x# s3 D" Y: e6 f$ t9 O0 b5 z) M* Don almost anything found in the contents.) [' y- M' e/ K/ Q( z% c# G' x& J
1 @# U" ^2 M: k1 hHowever, it is important to understand how HTTP requests and responses are' X* D o4 W5 ]$ X; Y
formed, and how HAProxy decomposes them. It will then become easier to write( N' x, F9 @: @1 p
correct rules and to debug existing configurations.: l8 g7 b+ B0 O1 C3 |1 I, q5 \
4 j1 a$ m- h3 W4 P6 D
% L$ b3 P/ x0 Z6 t; s( [1.1. The HTTP transaction model2 P) s9 a- j" U: ?
-------------------------------
0 v& z* W* c+ J7 U6 I0 L0 L. ]- V5 u' I7 ^
The HTTP protocol is transaction-driven. This means that each request will lead4 h; K& W4 X# P" q: q, d
to one and only one response. Traditionally, a TCP connection is established8 E8 M" B3 B( l0 O- ]
from the client to the server, a request is sent by the client on the- a$ [$ U, V( `+ R4 [4 w
connection, the server responds and the connection is closed. A new request: E& n. v5 V6 U) o; ]5 O/ J
will involve a new connection :# z$ c, B A* ?0 |7 Y% u
/ j( Y+ |# U0 w [CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] .../ M# @5 G1 `& _. a/ c
/ `7 D3 [: O$ @6 i& g
In this mode, called the "HTTP close" mode, there are as many connection" R$ {2 Z0 G7 r0 K
establishments as there are HTTP transactions. Since the connection is closed
, h0 E* e! C& B0 o3 yby the server after the response, the client does not need to know the content
% @8 N0 h& ~$ R6 [3 N4 olength.3 O( Z( L0 u+ D5 f9 u- S
k7 o0 U$ q" K) Y( Y
Due to the transactional nature of the protocol, it was possible to improve it3 d2 n" H! d- l0 _( _6 r
to avoid closing a connection between two subsequent transactions. In this mode
/ h' w7 R$ H6 s- ?; Whowever, it is mandatory that the server indicates the content length for each
# C2 I4 J: m* Z' y' Dresponse so that the client does not wait indefinitely. For this, a special5 S( ^! {8 ]- a! W/ Y2 Z
header is used: "Content-length". This mode is called the "keep-alive" mode :# K% t- v: K$ s/ j. \: V
5 }# L' {$ I/ a9 q. K3 X [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...
) u2 [! Q3 L5 q m% [# Z' a1 ]; L7 T- e2 f: s [1 W
Its advantages are a reduced latency between transactions, and less processing
% a2 r! i0 u& M0 wpower required on the server side. It is generally better than the close mode,6 h A' Z# c( A2 b; I0 M
but not always because the clients often limit their concurrent connections to
; g8 `- g- ~9 Z! J) m' E: F5 A, s3 ta smaller value.
1 N3 h% C/ g" M `" {6 p: P# u; v9 G1 P* \0 B J- k) R% x
A last improvement in the communications is the pipelining mode. It still uses
' i( q. F9 i8 b- f) Qkeep-alive, but the client does not wait for the first response to send the
6 a, u% g, G' {second request. This is useful for fetching large number of images composing a
, e- N$ ^! m+ _( R- C3 b8 Spage :; l, N' r' W+ Y' I M! f; ^0 c
$ F! z2 ?8 O: q. M7 y2 J+ }
[CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] .../ _' Z2 m) w! M" d
) i+ s3 T& r" Q! NThis can obviously have a tremendous benefit on performance because the network# D- M) j7 q& `: w, B3 x
latency is eliminated between subsequent requests. Many HTTP agents do not
8 g( E7 o& q+ i# q) Rcorrectly support pipelining since there is no way to associate a response with a# N( R" d" T- J) A; y- {$ Z" a
the corresponding request in HTTP. For this reason, it is mandatory for the
5 t1 r" S P( Z- g4 Bserver to reply in the exact same order as the requests were received.5 x! p( {" N, F% ^
2 k: ~1 n2 t7 g4 a6 LBy default HAProxy operates in a tunnel-like mode with regards to persistent" E# [. s* G& E1 H$ w9 H6 H8 U
connections: for each connection it processes the first request and forwards- Z# ~3 c7 ]1 h% d
everything else (including additional requests) to selected server. Once/ i! x( L/ w" z! B) o- E( o
established, the connection is persisted both on the client and server
1 c9 _7 l. d6 qsides. Use "option http-server-close" to preserve client persistent connections
$ u2 H0 E' c" M9 wwhile handling every incoming request individually, dispatching them one after
2 ]# A5 C, d# q4 Q. ganother to servers, in HTTP close mode. Use "option httpclose" to switch both
0 M1 Y4 G' P% ?! ]% I$ y! rsides to HTTP close mode. "option forceclose" and "option
/ Y1 ?8 Z4 o3 ?http-pretend-keepalive" help working around servers misbehaving in HTTP close; d# j+ o1 r2 {! Y' F4 |' k: b+ ]$ Z
mode.
& J7 M2 H# C0 E8 e* _: A8 h
3 \. s# O/ @7 G( x# s7 V
. }3 y6 V6 d1 P) o- p! E- g% z1.2. HTTP request }, u/ z' {% n- C n, r6 o! X
-----------------; u6 |) v6 X+ x Z/ b
' ~( Y# d* ]! xFirst, let's consider this HTTP request :
& ~) t7 D, ^. b6 _9 U
& m8 N; s( E! m; j9 @ Line Contents) t$ E* Q2 F2 Q0 h0 l' G) U6 D( x
number) T, `% f5 B# e5 e( R W" s7 G* P& T
1 GET /serv/login.php?lang=en&profile=2 HTTP/1.19 ?# _; m5 d! {# m
2 Host: www.mydomain.com
( N' W# |; u4 S$ t! [2 Z: [ 3 User-agent: my small browser
4 s3 m. M. _: G+ P 4 Accept: image/jpeg, image/gif6 A$ I. [3 U0 o' d4 D: `
5 Accept: image/png
# c2 ?8 o/ C" `* n( I+ Y6 v
- x' h% |) B' h8 X6 `5 P- F- T f u( L7 |8 `
1.2.1. The Request line" ~ t' l4 N. A
-----------------------
8 @9 W8 [/ C* i* z# Y$ B. ~- q- N8 k D' g
Line 1 is the "request line". It is always composed of 3 fields :/ y! H. k8 m4 }( z+ H. y
8 n/ h& V( _' e3 ~9 o8 F) k - a METHOD : GET
9 K+ F: p8 s$ t - a URI : /serv/login.php?lang=en&profile=21 {5 p( P) r5 g1 g7 a
- a version tag : HTTP/1.1$ I* f; f- ~1 O( [
# N8 U9 G5 {3 B. \6 j7 MAll of them are delimited by what the standard calls LWS (linear white spaces),7 e, J- [4 D. m1 f7 ]; t G
which are commonly spaces, but can also be tabs or line feeds/carriage returns8 J. ~* d6 @' R
followed by spaces/tabs. The method itself cannot contain any colon (':') and
& f5 I6 ?2 d6 f2 }# a) m/ M6 P2 O# eis limited to alphabetic letters. All those various combinations make it$ s( C0 i, }% ~ X% r
desirable that HAProxy performs the splitting itself rather than leaving it to ~' X V" I x8 w* F
the user to write a complex or inaccurate regular expression.
! ^* V% F$ W" ^! V" b, Z. r& N' F; Q8 E* y3 O
The URI itself can have several forms :
4 X$ U0 ?+ X; Q6 ~+ b
0 C( U q$ `: r0 S5 q4 L9 O - A "relative URI" :
" _6 x' J( c, d W$ c& {( h
0 z! l9 w* |, t+ c T5 v& n; C /serv/login.php?lang=en&profile=24 Q3 Z* _' V# @3 l2 x) H
1 q3 ?4 s2 m. a; d It is a complete URL without the host part. This is generally what is; ` V1 O) E9 |, e" k4 B
received by servers, reverse proxies and transparent proxies.
! y6 z/ k; ], l- E
# _$ G( l0 S8 I9 P6 t2 ` - An "absolute URI", also called a "URL" :
" z+ x$ g0 V, K" f5 S' {
: j$ ?+ N2 n# L8 T http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
8 Q) ]9 a# j7 f) Q% ?, B
5 Z* D3 `9 @* D- e3 } It is composed of a "scheme" (the protocol name followed by '://'), a host6 u7 b6 W/ H. \9 V/ Z
name or address, optionally a colon (':') followed by a port number, then
7 H1 s* L, N4 l7 C a relative URI beginning at the first slash ('/') after the address part.- P" d# F3 K5 U
This is generally what proxies receive, but a server supporting HTTP/1.1
" ]! {8 t& ?3 n# s9 i must accept this form too.
, S$ j, d3 r$ F- s5 l y- @
n) q1 ^, Z. O4 c- L- Q {" d' u& { - a star ('*') : this form is only accepted in association with the OPTIONS
# W" p6 L/ S* V method and is not relayable. It is used to inquiry a next hop's
8 K6 W ?$ @+ ]- H4 K capabilities.
( b% s% G. C0 `, M1 B: k/ H7 f8 L( p1 Y) B8 o; U2 m- U
- an address:port combination : 192.168.0.12:80; T# W# I* j$ l4 S) t2 {
This is used with the CONNECT method, which is used to establish TCP; H6 }% ?6 N% p7 p3 T& Z: }
tunnels through HTTP proxies, generally for HTTPS, but sometimes for
" y+ n4 c X! Q E8 b7 U. k other protocols too.
: A# [* O: q% r ?( V; n' Y! ~
$ v6 b. b: a t& y& RIn a relative URI, two sub-parts are identified. The part before the question
* i4 f* h0 X" {- A, mmark is called the "path". It is typically the relative path to static objects I0 O9 `" N8 L$ q9 k& I
on the server. The part after the question mark is called the "query string".
# {) }( a3 C1 M2 B' NIt is mostly used with GET requests sent to dynamic scripts and is very
2 T9 r2 p& ~, D2 g7 x+ w% U0 d- C+ nspecific to the language, framework or application in use.8 o$ R9 n/ I" E8 B: C" F
4 B/ L5 D6 ?3 |
/ ~( n: P2 {6 l8 x/ U2 G
1.2.2. The request headers5 a5 s) ^" J+ X$ S+ Z
--------------------------, {0 L3 S E8 [# ? O
$ f0 l" N& J/ z$ y# d- ?+ z
The headers start at the second line. They are composed of a name at the1 ]* B7 e1 A* f
beginning of the line, immediately followed by a colon (':'). Traditionally,/ W6 N8 v; \ \8 Q' Z: d6 T
an LWS is added after the colon but that's not required. Then come the values., [ r) C) I9 N/ `
Multiple identical headers may be folded into one single line, delimiting the
; o$ B7 U# q8 H5 @* Yvalues with commas, provided that their order is respected. This is commonly
+ m9 H& l. I! ^ x2 U" J9 yencountered in the "Cookie:" field. A header may span over multiple lines if/ Q! v* A' G7 y$ x3 f5 u" r
the subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5
* ]; _, `) L. adefine a total of 3 values for the "Accept:" header.
% S' @6 l, V/ e9 m4 g* n, u/ S4 B# J) O9 A6 D
Contrary to a common mis-conception, header names are not case-sensitive, and5 E! R o% x) O6 C' U- [3 W$ B
their values are not either if they refer to other header names (such as the
4 e3 I1 Y$ r0 X- M) \"Connection:" header).
- R' Q9 Z* U' T* N
" b# M) ^, d) l% N0 oThe end of the headers is indicated by the first empty line. People often say
1 C4 r2 o* d! z% t4 K3 `: cthat it's a double line feed, which is not exact, even if a double line feed
& Q+ [/ l/ h* j$ E# ~$ N4 A3 [: Gis one valid form of empty line.& r4 _( h' g1 [3 L9 ?
/ H a* _9 T. x* W5 ~) P- r9 h" aFortunately, HAProxy takes care of all these complex combinations when indexing3 f+ b/ t3 t% F5 g+ @! t( n
headers, checking values and counting them, so there is no reason to worry6 _5 K3 k" S6 R1 j6 c% s
about the way they could be written, but it is important not to accuse an, Y% W$ Y: ]7 l
application of being buggy if it does unusual, valid things.
9 _ n1 T8 r2 H5 {4 X; |2 F% q0 g
# L/ c$ p3 W9 e2 P5 [" z* DImportant note:
/ E h& Q2 [1 v6 t* n$ y$ w As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks/ k; d: A1 X6 T% I" t
in the middle of headers by LWS in order to join multi-line headers. This) z5 T; M3 N' ^" ]
is necessary for proper analysis and helps less capable HTTP parsers to work
M$ ~! V2 M( _3 _1 A/ \, G correctly and not to be fooled by such complex constructs.6 i7 R6 v, A% l/ {4 l1 ?+ ~
5 P9 K) @/ j, B& \$ P2 h, D) K2 h
5 z3 G y N1 t; W
1.3. HTTP response! I/ Q" u) r6 | l
------------------
3 a) t n9 Y9 a* z, ~) o4 @3 V1 F5 k3 `1 @( b) e
An HTTP response looks very much like an HTTP request. Both are called HTTP
! f7 F! W# O9 s( M1 Cmessages. Let's consider this HTTP response :: i9 |9 o# y; D9 o
) l) H* \& ~& I0 \4 q2 S! x: x! T Line Contents5 R! f( O! {# `2 ~- Q0 ~
number. x/ x+ V" @, _1 f
1 HTTP/1.1 200 OK$ |/ p8 _8 t* s) \7 R
2 Content-length: 350
m& u# d7 q: b& J$ g$ V 3 Content-Type: text/html
E! \$ R3 H* X- y+ s1 x8 v, h; _+ M3 f7 c w/ v
As a special case, HTTP supports so called "Informational responses" as status
2 d: ]3 h( q0 A9 e5 Scodes 1xx. These messages are special in that they don't convey any part of the7 B' x2 V( c9 f8 |2 f, k
response, they're just used as sort of a signaling message to ask a client to
# {( s4 l* \0 U5 U$ x: Lcontinue to post its request for instance. In the case of a status 100 response2 G9 D( d: ?1 N+ W' u) k
the requested information will be carried by the next non-100 response message
5 ~3 P! H! ^8 ffollowing the informational one. This implies that multiple responses may be) l7 u O* b; H. \# O; ^: N6 q' ~4 r
sent to a single request, and that this only works when keep-alive is enabled
" Y; {. K4 ?) ?- n! K(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to
7 O; L4 Z0 \* U/ j H& Y7 ucorrectly forward and skip them, and only process the next non-100 response. As
8 h5 N7 g6 v- q7 O+ @/ `such, these messages are neither logged nor transformed, unless explicitly) p& ` Z/ f7 d3 B3 H1 I
state otherwise. Status 101 messages indicate that the protocol is changing# ~; W9 B+ Z. K" {
over the same connection and that haproxy must switch to tunnel mode, just as2 _. a2 @+ I' K# a3 m& L: n; o
if a CONNECT had occurred. Then the Upgrade header would contain additional3 K( i/ b( r$ c
information about the type of protocol the connection is switching to. q. ^% z9 q$ p
# d/ T3 s3 B, a9 ~. E( K9 c
3 A E* u! Q1 ?; {1 z$ @1.3.1. The Response line; K; G2 J! S( n& u. Q, {% [0 m5 f
------------------------. B. y2 Q$ K) ~- P c3 `) w7 ]
6 O, @7 l* b6 u9 b/ l. i: M/ [Line 1 is the "response line". It is always composed of 3 fields :
+ L9 N! S; h. F4 }* ^: F+ @8 d+ z) Q
- a version tag : HTTP/1.1
- {+ J" L6 u4 ?" @ - a status code : 200
6 [# d3 B0 C4 I" A T - a reason : OK6 D6 v( Q% Q# _ P4 c: e6 A8 u
- p, Q9 ~5 v8 p6 \' M
The status code is always 3-digit. The first digit indicates a general status :* }2 h9 M' |3 U1 a8 U: ^# f
- 1xx = informational message to be skipped (eg: 100, 101)( y7 R1 h1 p% j3 u; k
- 2xx = OK, content is following (eg: 200, 206)
& b+ J% ]3 X8 ] J) X - 3xx = OK, no content following (eg: 302, 304)
1 O2 m7 g/ |2 J( { - 4xx = error caused by the client (eg: 401, 403, 404)4 R$ o8 L; k! _, Y$ c2 E
- 5xx = error caused by the server (eg: 500, 502, 503)) C7 O! m, p4 p% w( G& ~ v
+ Z2 _1 ~( S( [3 C# E0 i: w- C0 \. t2 h
Please refer to RFC2616 for the detailed meaning of all such codes. The
# T" F! _- A) B' A7 ["reason" field is just a hint, but is not parsed by clients. Anything can be
% G- f9 F" A) Gfound there, but it's a common practice to respect the well-established
+ ?! [+ F' \5 q* @% z* zmessages. It can be composed of one or multiple words, such as "OK", "Found",8 p# M, o2 ?# m8 a. l/ @+ A
or "Authentication Required".
+ ?. q X7 [# G+ y! \+ ^( E. s0 t: |$ B+ i! t
Haproxy may emit the following status codes by itself :. m0 M2 ~+ }4 P. h n; q
6 x0 @7 i2 R. s
Code When / reason
, ^" K6 E8 t7 F 200 access to stats page, and when replying to monitoring requests
( i' S( {6 [5 F/ G6 R W% W- S 301 when performing a redirection, depending on the configured code# |/ V ]4 j9 G: @) F8 e
302 when performing a redirection, depending on the configured code1 u" O1 s1 z; ~, H: i" Q3 @
303 when performing a redirection, depending on the configured code6 y: ~8 g$ ^# j- n3 B& J5 a' W) q
307 when performing a redirection, depending on the configured code: {% M% z' R Z( `* V
308 when performing a redirection, depending on the configured code B: u/ P' \2 F+ X% U9 M
400 for an invalid or too large request
9 W( h0 l; Y8 Z. Z9 G 401 when an authentication is required to perform the action (when6 u& j, X" k+ R+ ?9 D: w
accessing the stats page)5 {# o N6 f1 }" W% H# e
403 when a request is forbidden by a "block" ACL or "reqdeny" filter
8 t9 h7 @; T, o6 b M 408 when the request timeout strikes before the request is complete
( `* q% D5 f4 \. D) Z 500 when haproxy encounters an unrecoverable internal error, such as a& ~" Q( v# I' F
memory allocation failure, which should never happen6 [1 g) t' t p I. W% c. m6 }/ M1 Y# i
502 when the server returns an empty, invalid or incomplete response, or
$ l) I9 J& X& @" m. N5 _ when an "rspdeny" filter blocks the response.2 v$ R& l( o0 B! } j* n, `: F
503 when no server was available to handle the request, or in response to& A* o" X% f# `' S& u1 B
monitoring requests which match the "monitor fail" condition
+ u- a" f: V, g8 l3 m 504 when the response timeout strikes before the server responds% \+ ]4 H" z* I: [- C
! m! t+ H0 K; b% a: `8 q$ m. V
The error 4xx and 5xx codes above may be customized (see "errorloc" in section. E |2 H4 a! C" n
4.2)./ `- f/ h- v7 h% R' k
2 t/ B# c- e( g. L: t! G- y) G6 c1 |: |2 n* o
1.3.2. The response headers4 I. ~3 o8 [' e, r( Q
---------------------------7 n! S0 R. F0 }! |8 n& _1 K: _( R
+ _7 b1 f$ a9 t; R) ]
Response headers work exactly like request headers, and as such, HAProxy uses
) a$ v1 V3 X% X9 _, R6 b% @- jthe same parsing function for both. Please refer to paragraph 1.2.2 for more
1 }, @3 @$ K! r; \1 vdetails.
$ b6 w& {4 }8 v/ V# r- a% I: R0 h7 R# O1 b9 b
3 R8 b; r- i9 I5 D1 ^% }/ ^5 t2. Configuring HAProxy4 G, X3 ]2 M* \7 p- m- m2 v
----------------------
* D0 g# d# k+ L( i M2 W; D: H4 d4 R. T) k
2.1. Configuration file format
" S4 ?/ }' y) ]! T$ l d' f4 C------------------------------
- x& d; P5 o1 S9 }( [3 m; u' C. l. W6 ?
HAProxy's configuration process involves 3 major sources of parameters :, x: N0 l- n! D0 _- E& `
) G0 K' n& p7 {
- the arguments from the command-line, which always take precedence
# g9 ?; {) r' A. W% S) \/ a - the "global" section, which sets process-wide parameters
8 M) t3 m* |1 q# p( \# ~+ ^, i - the proxies sections which can take form of "defaults", "listen",% `. n! |2 U8 @" N
"frontend" and "backend".* g4 d+ W* Z1 @5 N) Z$ e
; D6 j4 U6 F2 |0 n
The configuration file syntax consists in lines beginning with a keyword) i5 s7 Y: ]3 X3 l" i
referenced in this manual, optionally followed by one or several parameters
) ^5 H { P! f) l1 t. u9 gdelimited by spaces. If spaces have to be entered in strings, then they must be0 G4 H6 n: W. ^; i
preceded by a backslash ('\') to be escaped. Backslashes also have to be
* Y3 x Q8 {9 s3 e6 Yescaped by doubling them.- w( ^, [" r* O- V' ?
, o2 w8 O# G" p+ S" }( X& x g
/ u. B$ G+ K% f; {. D- v) e) g2.2. Time format1 h6 y5 e7 `1 \7 @- c
----------------' f7 [" i$ y' b
' {; Y3 _$ U) [0 T
Some parameters involve values representing time, such as timeouts. These4 d* q. k. V' K. v' O
values are generally expressed in milliseconds (unless explicitly stated2 z6 Z, J7 ?3 Q3 i ~
otherwise) but may be expressed in any other unit by suffixing the unit to the( t& g7 c; }# U: c& D1 Z
numeric value. It is important to consider this because it will not be repeated& h5 x" e* A8 I9 c5 E: y: L
for every keyword. Supported units are : i# @+ ~- {' W
# `/ y/ x0 ?( t. I6 M - us : microseconds. 1 microsecond = 1/1000000 second
9 s c; E/ b, D" J# d - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.# d) Y7 k: F& C
- s : seconds. 1s = 1000ms
+ S. Y [( F8 }& @7 i H - m : minutes. 1m = 60s = 60000ms) m; w- |1 J. H- S( l- J$ m4 `6 @& ]2 y
- h : hours. 1h = 60m = 3600s = 3600000ms
# B `, {4 h( f& I! x$ n1 @: P - d : days. 1d = 24h = 1440m = 86400s = 86400000ms
3 r! l, i- y2 w5 I: m4 ?% v, c6 z$ C9 H# F% [! Y7 |0 O/ W3 b
3 a$ J* A5 Z4 Z1 `4 G( P- p2.3. Examples
" \9 h4 {' Z0 H" i-------------. I1 _5 \% ?* m4 T7 u/ F! I3 z6 [
- y2 H0 Q0 U- i4 |/ {6 B8 c# Z # Simple configuration for an HTTP proxy listening on port 80 on all
0 q! q4 g# t w* h; C. ?( g; h # interfaces and forwarding requests to a single backend "servers" with a$ u; d4 ?, _7 ]$ X3 r
# single server "server1" listening on 127.0.0.1:8000( e$ g* Z7 E% c
global$ f, x( E% Z x- @& V E/ E
daemon
! f/ s1 M; x4 w8 E8 ?7 w# y2 ?* ^2 D maxconn 2560 j2 f+ h4 d# A. p4 I6 S
$ @5 @8 B- K3 c' e) g% T defaults
9 `4 I8 A( ~" U- G3 ` mode http. s6 N9 I$ @9 h1 {
timeout connect 5000ms3 U- B% F4 S& q: i# P; B9 l
timeout client 50000ms
# r7 d; R* R: j) I timeout server 50000ms) G/ g$ H: ?7 w+ g& e3 D
3 Z n5 v* }5 r, P
frontend http-in7 H$ r% M0 b" h4 v
bind *:80: W" t+ N2 j9 O) O5 }) w$ m) v
default_backend servers
# T9 R) z/ e' c
2 }, _+ O; W9 T! E) a. Y% f9 r( j backend servers$ A" T( x8 V: d! ~6 y2 o/ }, T$ q
server server1 127.0.0.1:8000 maxconn 328 q% i, z' D) w, ~# j; s
2 w, @5 u% }6 I/ t
: |7 O, I& z/ ]4 t* D; b7 X- Q9 C" \
# The same configuration defined with a single listen block. Shorter but
- a1 ]& u- ^4 l! g; F/ u # less expressive, especially in HTTP mode.& `$ J4 p; a) _+ l& ]" }. Q" f
global
, e1 \+ Q9 \. W' X# |) \ daemon+ r" F( u. Q9 w. ^- O/ S
maxconn 256
/ \( {' C l- ~: N6 ?7 K
9 z& l" r: G, Q5 | defaults6 V- q, a8 q1 b5 }# J
mode http
' b. t2 z4 Z6 X# B2 B timeout connect 5000ms
q! z* B' L" s9 B/ S timeout client 50000ms- D- h% b) h" r
timeout server 50000ms' }; H- a. G+ @0 @8 i
4 n4 c' O, F5 D1 \% T$ M& N& \
listen http-in
* H. o1 E; Y9 W# W, g" @8 ^: l! a. v bind *:80
3 s" X/ ]& p* j/ S server server1 127.0.0.1:8000 maxconn 32' {3 |( W( M; c3 B% Q9 q
- l: I5 l0 k8 [/ q, z" \
7 e! a( }; c$ J+ B# e/ m0 A$ k1 Z% yAssuming haproxy is in $PATH, test these configurations in a shell with:3 q; p) \* x: `. |
9 M* I9 J9 z6 G: r $ sudo haproxy -f configuration.conf -c2 {/ ~* `" T- B( ?1 V
. g! B! s" F/ e/ f8 C d
# q( a/ ]9 p6 F" O0 F: N3. Global parameters
$ _8 n8 I: y! ^* ]7 O) o--------------------
3 o6 |5 Y5 X/ F& X; a
/ C9 O/ c+ r) B0 Z% I! MParameters in the "global" section are process-wide and often OS-specific. They
( w3 a/ B. f2 ~& `; g: [4 mare generally set once for all and do not need being changed once correct. Some
$ O. }- k$ I+ c/ ]! q" N3 Nof them have command-line equivalents.9 ^2 u, w& `3 w3 l# _4 P" h
! |$ z7 K, P' I$ i; B+ j
The following keywords are supported in the "global" section :
9 f2 l8 W+ `, B) O
4 N- p: H% d$ Q2 x) G8 ] * Process management and security. a' o( G6 ~! @ \/ u: h
- chroot
6 }; v" \0 _- C# Y! {% B - daemon
1 v0 t) H/ [ F$ x) O* @" o - gid
4 ^) v5 ^2 |" A' g* C. I - group6 i3 K2 ? Y6 ~
- log+ Q1 z7 x! K ^# D& l; m9 ]1 j+ z
- log-send-hostname1 h K) ^( Z& `4 N; ?
- nbproc
- x( H9 x" I' ?7 F7 j! T5 `$ v' [ - pidfile
^. k* @+ I5 o( Z! ` - uid9 k2 H( I5 S' r* ~; h4 A& n9 `
- ulimit-n! d3 i( c' r$ c* y1 W
- user$ Z7 R* W1 h- s6 {: ?
- stats
3 _6 z6 o' g) T! \" H4 _' H - node1 v/ g# r R3 c/ @7 @, E
- description* Z( J+ n1 M5 v) R7 ~
6 ]4 k0 n! ?: f) }/ i' h6 l# ] * Performance tuning( P4 j, P6 `1 g, B9 R( N4 M- G
- maxconn
* k* q& x+ n" c - maxpipes
! z* k( w: K- x% }9 X0 z - noepoll
( c9 r; X6 }. [1 h6 R - nokqueue4 h, Y) c3 v1 S/ ^( W
- nopoll% f# C; ?. `; q- i' ]9 b
- nosepoll0 S$ R4 A$ _ C% v$ Z8 j5 _
- nosplice
$ H9 a5 g; \: G. @* M1 [. N - spread-checks2 F. B, r+ H: y0 J
- tune.bufsize& E6 q! }% [/ O2 ~5 j& Q
- tune.chksize% _! |4 \& v. v3 h/ {# O2 c) f' c
- tune.maxaccept! ]7 I4 x) ^) L; ~3 B) V
- tune.maxpollevents
- ?6 Q* L% H8 P U6 S - tune.maxrewrite
4 Q/ f4 q7 v" h% Q- U - tune.rcvbuf.client
$ `/ H7 y3 v) E; l; x1 i - tune.rcvbuf.server/ o5 _- U; x6 t: M S
- tune.sndbuf.client
5 u8 F! U( p1 k5 f$ j( @9 G( e! N - tune.sndbuf.server) T3 u: V* B5 R$ `
& P+ v: k g: }" q. c* Z7 U * Debugging# g3 I3 s1 R( F$ T
- debug$ s k+ ~1 q$ w8 m8 H) A) h
- quiet% b! H, { t- P$ i* s% I# q( D
+ E' |$ ?" F' q h/ _6 f$ r l
: F: E) j# I4 n9 T5 T% _0 F, r" E) @3.1. Process management and security
2 w' L8 P/ R; Z9 w; \) b------------------------------------3 M( [% g, s8 D9 h. P
2 R- y: \2 w% C: i% U' s/ pchroot <jail dir>
3 o# G: L( B/ t% O/ M1 \, s' C Changes current directory to <jail dir> and performs a chroot() there before
8 O- v# l* z% o) X) b5 ~) l4 f; X dropping privileges. This increases the security level in case an unknown
9 F( U+ E- u+ a vulnerability would be exploited, since it would make it very hard for the
$ ^/ f" h7 A+ D attacker to exploit the system. This only works when the process is started3 N' J! H. F/ w( E$ V/ e
with superuser privileges. It is important to ensure that <jail_dir> is both
4 b2 d3 P3 u7 t2 H% ]& i. _ empty and unwritable to anyone.! Q! ?: K5 w& t$ L3 A
& W- p8 y9 R$ b0 f; tdaemon
- k+ h* Y& c, U7 r# ] Makes the process fork into background. This is the recommended mode of
& l, \) A9 {+ G# u1 e operation. It is equivalent to the command line "-D" argument. It can be6 N2 n/ E) _6 z, x8 W
disabled by the command line "-db" argument.- h# U) n6 z( K7 V, r
' m3 h* k1 L( q0 D" D! Y: }gid <number>
7 r% o0 g# e# j0 C Changes the process' group ID to <number>. It is recommended that the group" @! }5 q' }6 @4 k
ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must
8 B2 x+ Z% O8 S) J1 q- q& h be started with a user belonging to this group, or with superuser privileges.7 M/ Z; s6 ?' b! F
Note that if haproxy is started from a user having supplementary groups, it
1 z- G# `) Z+ b6 n+ G; t will only be able to drop these groups if started with superuser privileges.
; @$ ~- }0 ^! e% s7 }. d8 o) D3 Q See also "group" and "uid".
0 V* p( u5 G3 h8 F) r+ W- Z7 w( }/ z! D; ]: L& J4 e3 f( ?
group <group name>
9 m) S+ z1 }" n% o% S Similar to "gid" but uses the GID of group name <group name> from /etc/group.
}' i1 k5 Y! ?3 {) s7 Q5 x See also "gid" and "user".+ P+ C9 p' I: y9 k \8 ^
) U0 f) p( i: A- G
log <address> <facility> [max level [min level]]& o( A$ c5 I$ d; D; |: V: z$ J( r
Adds a global syslog server. Up to two global servers can be defined. They
; ?" `% s" t) T# \2 a2 O: m will receive logs for startups and exits, as well as all logs from proxies8 a$ ?+ O/ d" y9 L& ?
configured with "log global".
' W4 x- i. E$ u* b+ N4 x6 [/ W
( X# @: n& Z) f3 m <address> can be one of:
# B \( D" a3 m
% r1 Q* Z# a+ P& A! U- K' ] - An IPv4 address optionally followed by a colon and a UDP port. If" Z' [ f/ c: A1 C+ S8 l8 @
no port is specified, 514 is used by default (the standard syslog& n, ]) B: ~- M; m
port).- T1 M" {9 ]& k* a3 t6 D1 o
, z6 r+ W: C6 M! i2 N) l x
- A filesystem path to a UNIX domain socket, keeping in mind# _( U% s: V5 m/ {+ e$ J6 W
considerations for chroot (be sure the path is accessible inside
" q$ G( W5 b( O* n the chroot) and uid/gid (be sure the path is appropriately/ r! @& P( g/ K% O |
writeable).1 Z0 [# U" N2 E* T$ i9 \, |
4 r8 k5 C5 ]" t9 q" g7 e8 x' ?/ } <facility> must be one of the 24 standard syslog facilities :! v" o4 R" Z0 z j) i( }
- B, s7 M) X6 l+ h* m kern user mail daemon auth syslog lpr news5 `4 V+ C7 i0 X8 ~% q7 H; \
uucp cron auth2 ftp ntp audit alert cron2: P6 x, V4 X8 Q/ S" l6 `, E2 w
local0 local1 local2 local3 local4 local5 local6 local7( z% G. m- H" ]5 {) w3 P
) B, n8 z, e) @% W An optional level can be specified to filter outgoing messages. By default,& A- O; @' V) O5 g& C5 N, ^
all messages are sent. If a maximum level is specified, only messages with a" B+ z+ k L) m) ^9 G3 k, V% @# w) R( R
severity at least as important as this level will be sent. An optional minimum
2 v& C" V3 j7 h o; O+ G' _+ J: V level can be specified. If it is set, logs emitted with a more severe level
+ S4 w/ m+ F$ n) ~ than this one will be capped to this level. This is used to avoid sending
1 i$ Y+ K! P8 o5 v2 V "emerg" messages on all terminals on some default syslog configurations.( q7 x7 A( y! p' G, J" V' v
Eight levels are known :: M+ @3 k6 {2 e2 _3 @* I5 f. r) h
4 g; G" j4 e) ]' S3 I emerg alert crit err warning notice info debug
5 D4 l) X0 g0 S: w5 r; |3 a2 K# q# T& d5 R
log-send-hostname [<string>]
- x) G, T6 B! y! e! x Sets the hostname field in the syslog header. If optional "string" parameter. n0 d$ t! _2 a
is set the header is set to the string contents, otherwise uses the hostname& x Q8 R7 y5 c( A, z! [- X
of the system. Generally used if one is not relaying logs through an/ _7 E$ O9 D, |2 z
intermediate syslog server or for simply customizing the hostname printed in
$ a# ~* Z9 q9 w9 m% q- J, s( Y the logs.
$ u" @2 l& ]4 w. N7 m
U3 r( e- k* Tlog-tag <string>6 ?7 H8 E- h, S1 g
Sets the tag field in the syslog header to this string. It defaults to the. S0 s$ p. V$ ^. l5 x
program name as launched from the command line, which usually is "haproxy".4 A7 L+ }. k6 l' o4 T+ [7 e. l
Sometimes it can be useful to differentiate between multiple processes1 }, y& w6 }% o$ A6 y. D; T
running on the same host.6 S1 i% @( E: V2 a8 T, C0 U
& f, m* o) b5 c! j3 m
nbproc <number>
) D7 S7 V: F- V+ a! ~ Creates <number> processes when going daemon. This requires the "daemon"
; h( a3 L6 B( \ mode. By default, only one process is created, which is the recommended mode
5 Y7 e$ n) n2 M$ G, q: p# S of operation. For systems limited to small sets of file descriptors per g8 s# {$ S: G% U4 E. [
process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
W0 K2 y" B# Z: M2 @ IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".: n! _5 l8 I! q3 Q: w- }# j4 E6 G
5 T( F- \" z- `* y, S2 v0 J
pidfile <pidfile>. B# t1 |; S/ ]( k1 z% L
Writes pids of all daemons into file <pidfile>. This option is equivalent to# F k& \ e0 p/ x; K/ e% t. q
the "-p" command line argument. The file must be accessible to the user: m3 \8 [$ S. s0 g1 d
starting the process. See also "daemon".5 C7 ~$ q" k! J- A6 ^, d+ u: [ O
& H0 \9 ?, R! Y: M/ V! Q$ S; I& L% I) s) Wstats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]
" G3 G) }3 O8 y% c [level <level>]
/ ]) O- e2 F, {' v/ K6 N
# e' h% a" n' ~7 z6 p& e* t/ j1 @ Creates a UNIX socket in stream mode at location <path>. Any previously! x, y; U+ B" x8 q
existing socket will be backed up then replaced. Connections to this socket9 ~' D- x5 D; ^6 y
will return various statistics outputs and even allow some commands to be
& S$ e1 u" _6 a& }) W1 S7 O% E issued. Please consult section 9.2 "Unix Socket commands" for more details.+ J/ s3 v0 a! T3 l' d9 M
' Y3 I! O" V$ s, l
An optional "level" parameter can be specified to restrict the nature of1 C8 V& G5 x1 s
the commands that can be issued on the socket :9 a% l1 b& S7 O& M1 q/ x
- "user" is the least privileged level ; only non-sensitive stats can be
& V |1 E1 I7 P5 Z read, and no change is allowed. It would make sense on systems where it
7 y. V, r k! F# N is not easy to restrict access to the socket.
. {+ q e" i" s8 O: [5 [% c6 V7 ]2 B+ P. `$ v
- "operator" is the default level and fits most common uses. All data can- Q( A L" |' R6 B* k* ~* H
be read, and only non-sensitive changes are permitted (eg: clear max
# J4 O$ j$ ~5 M4 ^1 @% O4 C counters).
. {: |( N5 }6 T" Y
( M. E4 j3 F; t5 H5 L - "admin" should be used with care, as everything is permitted (eg: clear
' Z' ^# M. U1 G, i' c all counters).5 w' c4 C' L8 M( J, B$ i4 Z S& L
]9 y3 h4 y+ |: t c
On platforms which support it, it is possible to restrict access to this: R6 M$ Y# ?/ Y: A4 g
socket by specifying numerical IDs after "uid" and "gid", or valid user and
$ m7 a4 I, e8 u group names after the "user" and "group" keywords. It is also possible to
; I7 G/ r M+ s5 F& V( e restrict permissions on the socket by passing an octal value after the "mode"
3 |+ Q, m0 k' B+ z keyword (same syntax as chmod). Depending on the platform, the permissions on' @3 R$ r }: ~- v0 u
the socket will be inherited from the directory which hosts it, or from the
6 S4 ~1 s- a9 q- G, ] user the process is started with.
0 R" c$ ~; ~, w% n, q
; f& t' g& G/ l4 i2 @$ ostats timeout <timeout, in milliseconds>1 [+ C B, T8 F2 a. h' H0 j6 p
The default timeout on the stats socket is set to 10 seconds. It is possible
1 {$ U( i; L' E& W4 q( }/ W to change this value with "stats timeout". The value must be passed in8 x* k; B! O' f: \6 l3 n! h( r
milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }., w1 n3 n% H, b) s4 M, x
! Q4 O# E' o6 H; m, hstats maxconn <connections>3 ^" t2 p5 W# c% J/ L
By default, the stats socket is limited to 10 concurrent connections. It is" F8 f2 H' M4 |7 s9 l l4 W
possible to change this value with "stats maxconn".
1 u2 A2 q! ^3 O
4 h. ~# [5 h8 V/ p/ wuid <number>
0 I' p4 i o4 g! V2 D4 U- P Changes the process' user ID to <number>. It is recommended that the user ID
# r2 y7 F/ z2 o7 ^! c is dedicated to HAProxy or to a small set of similar daemons. HAProxy must" y; i2 D) k5 _% X2 T( x8 v+ U# q
be started with superuser privileges in order to be able to switch to another3 U8 k1 T9 w2 w" V& H9 E8 u# Y/ Y
one. See also "gid" and "user".
" ^6 `! t. Q. v( F ]7 J! X0 @/ p% h+ ~, y% Q" _3 E, _$ X* M& J0 g: p
ulimit-n <number>
2 [) C% f% |3 a: u Sets the maximum number of per-process file-descriptors to <number>. By
+ j. e; \; b( T. P# Y" E# s default, it is automatically computed, so it is recommended not to use this; X. n9 B7 @; J7 B' ^' s
option." B, Q5 H* B, u% O, C
* ]) z) w' Q5 [* {: d4 Z+ H5 T, M& nuser <user name>9 h+ H0 Q% k3 m' x) I% ]' H- w! ], F
Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.) o! ]# G. V0 n% ]1 a# Y
See also "uid" and "group".
! D, i- _9 ?: |4 g" x/ w
6 O% L, L7 d/ w) C8 Y$ f, Znode <name>
% I8 C8 T9 g+ i$ s. Y7 m+ H Only letters, digits, hyphen and underscore are allowed, like in DNS names.1 g2 ~1 U. g" ~6 Y# T' \* {
/ q5 z% {1 ~7 I! z2 i- |" l- R
This statement is useful in HA configurations where two or more processes or0 E" H3 e4 J" R0 B6 {
servers share the same IP address. By setting a different node-name on all i/ @' t6 V7 X, s. C
nodes, it becomes easy to immediately spot what server is handling the2 U( w7 } a( O) {" u9 o/ a9 o8 e! a
traffic.
* O! \/ Z$ `4 a& F* G6 F+ T7 Y p
9 P6 V) E6 e$ x* y0 n8 Z2 M; [description <text>
5 D. H+ A4 a5 m" {, n1 K, r+ o Add a text that describes the instance.+ i, p0 l' w c* J
5 V; m+ _3 q; t Please note that it is required to escape certain characters (# for example)
C6 |5 `/ u7 V2 M" L0 V and this text is inserted into a html page so you should avoid using8 W6 K2 y* n2 v [3 g4 Z
"<" and ">" characters.. a1 b5 e. R) ?/ u' U
' ^1 I$ V- Q, H9 |
l, ^) s) ~1 }) a# Q3.2. Performance tuning' Z( A4 r, s/ Q. b6 W/ Z5 X* S6 b) o
-----------------------* N& J' o' k# J4 j0 |
$ w+ n* H* o5 X7 y6 X2 U1 _
maxconn <number>+ w! y! D7 |2 @! O
Sets the maximum per-process number of concurrent connections to <number>. It8 K$ b! t; N* y( H% f# K2 S1 q2 m
is equivalent to the command-line argument "-n". Proxies will stop accepting# O) |/ e$ h& P. k$ `: x
connections when this limit is reached. The "ulimit-n" parameter is
, H# ^/ E) p J$ w! Q! { automatically adjusted according to this value. See also "ulimit-n"./ L' _9 T% N+ O7 x/ Z
( @% h% `" Z: y# c
maxpipes <number>
1 M8 w1 x* o3 C8 }* _, q3 V Sets the maximum per-process number of pipes to <number>. Currently, pipes
+ ?, ]; G1 @2 K# Q, p are only used by kernel-based tcp splicing. Since a pipe contains two file
, c2 k* l/ A6 @' J" {; j& F Z descriptors, the "ulimit-n" value will be increased accordingly. The default, }) Z9 W& ~. n% b# D8 F8 Y
value is maxconn/4, which seems to be more than enough for most heavy usages.9 A. e# a# `% a% a5 ?0 S
The splice code dynamically allocates and releases pipes, and can fall back6 R2 X \" _- U
to standard copy, so setting this value too low may only impact performance.
( k, ~( ~# K# F' D
2 i, ~- c5 d' @5 p5 a, O8 r$ M; W. Vnoepoll
+ s$ o W; V, C Disables the use of the "epoll" event polling system on Linux. It is
0 T' @4 P+ K: ]8 w/ j, g: I equivalent to the command-line argument "-de". The next polling system
* F* r$ g" G# ] used will generally be "poll". See also "nosepoll", and "nopoll".( F5 }6 e. J- K
' M' g# p$ Y M3 \7 \3 [3 Y) P* u
nokqueue, G! [& Y1 N/ i- e* Z' x
Disables the use of the "kqueue" event polling system on BSD. It is
" r+ J! N7 B, Y% P. @- k$ d7 x equivalent to the command-line argument "-dk". The next polling system) P u" `9 f+ h3 p8 H- b
used will generally be "poll". See also "nopoll".7 R$ E! _! U; M
& t1 F) s1 J0 ]/ e6 H) Inopoll, B" N1 Y+ @# H1 s( ~7 |: F
Disables the use of the "poll" event polling system. It is equivalent to the
. P* r [/ m+ a command-line argument "-dp". The next polling system used will be "select".
" ~9 m) ]: l( K0 Y& u6 B* Y) \ Y+ J It should never be needed to disable "poll" since it's available on all
' z1 v, J6 p8 h2 i platforms supported by HAProxy. See also "nosepoll", and "nopoll" and
0 s) A6 H" ^1 h7 o# ~$ k" Y "nokqueue".
' X# I, z& B" F$ K+ w
# I6 C/ R5 Q0 Z0 ^- bnosepoll! M$ b) i! | l4 A8 _0 @! l; @. G
Disables the use of the "speculative epoll" event polling system on Linux. It
' j/ o( o6 \/ m! j6 q$ t is equivalent to the command-line argument "-ds". The next polling system
- c- X& } Z6 B4 `3 r used will generally be "epoll". See also "noepoll", and "nopoll".
0 I7 V- |1 |: J F | u
$ |( X) {' [7 J7 g9 a' J6 mnosplice8 x: C- o6 k2 L2 _! S
Disables the use of kernel tcp splicing between sockets on Linux. It is0 x2 M! t. k/ N" { ^+ h
equivalent to the command line argument "-dS". Data will then be copied1 a2 \+ w, j2 t
using conventional and more portable recv/send calls. Kernel tcp splicing is
% o; c0 d" H0 d# ?3 q( P( z3 }9 V limited to some very recent instances of kernel 2.6. Most versions between+ V. M; H+ R4 x3 F! Z" o$ m
2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not5 W; L* t& }' K0 O! E* s
be used. This option makes it easier to globally disable kernel splicing in
7 D" P1 r/ o6 K% x5 _2 F$ l case of doubt. See also "option splice-auto", "option splice-request" and& x. S: |; m% a4 N( o v& @
"option splice-response".
9 h; L! R1 w9 n) ?5 `% }7 e) g; F2 Z0 h( |! l
spread-checks <0..50, in percent>
+ q2 K' d$ L/ a8 e8 k+ z Sometimes it is desirable to avoid sending health checks to servers at exact7 W3 ]* `+ Q9 a9 X& G& g
intervals, for instance when many logical servers are located on the same$ Q6 y" E* l' ~' |% I6 V& {/ R( k
physical server. With the help of this parameter, it becomes possible to add
0 V, y6 z4 d* S; v( d0 O some randomness in the check interval between 0 and +/- 50%. A value between0 c3 y+ ]3 ~$ s$ k* p( `5 |% N
2 and 5 seems to show good results. The default value remains at 0.$ L: u, m3 G6 M2 x
; t6 p* ~9 h) M* z* itune.bufsize <number>
8 j+ _5 e1 h8 t/ U0 s3 P1 P Sets the buffer size to this size (in bytes). Lower values allow more
! ^" I- g5 a( ~3 U1 L sessions to coexist in the same amount of RAM, and higher values allow some- @' g% v9 g4 Q
applications with very large cookies to work. The default value is 16384 and
. `% @# d) B; H# p: _6 W3 B$ r can be changed at build time. It is strongly recommended not to change this
6 D# M1 l. m' ~; y: h from the default value, as very low values will break some services such as
- K5 _% T( N% j9 k# K statistics, and values larger than default size will increase memory usage,& Y9 J" t& I8 I/ m6 `. ?
possibly causing the system to run out of memory. At least the global maxconn/ J0 |, l6 o9 u2 z
parameter should be decreased by the same factor as this one is increased.. S+ g7 @# L2 K5 q
& l& K; c% f$ A7 h6 g' U, K" R
tune.chksize <number>2 s- t! ]# X7 J3 [
Sets the check buffer size to this size (in bytes). Higher values may help0 x: ? |5 o* x0 j0 Z' b
find string or regex patterns in very large pages, though doing so may imply' s+ c* D- [+ Q6 M2 u+ ^4 _
more memory and CPU usage. The default value is 16384 and can be changed at
- j1 d& X( }( L8 ~3 b7 ^ build time. It is not recommended to change this value, but to use better0 C" f5 ?. {# Q3 S% P& {
checks whenever possible.2 B; r4 S# V) Y( E, }& p
5 R, o) X- S: M1 x( q; A7 g' s- rtune.maxaccept <number>1 Z7 u' h i9 [: q' \
Sets the maximum number of consecutive accepts that a process may perform on
6 R8 W8 n" H. V4 j8 z a single wake up. High values give higher priority to high connection rates,4 c* a2 b6 k# x; A3 F
while lower values give higher priority to already established connections.
5 Z$ @1 C' `4 C6 H% g* j/ t2 L6 m# N This value is limited to 100 by default in single process mode. However, in
9 k6 Y% e4 Z/ |' p- W- _ multi-process mode (nbproc > 1), it defaults to 8 so that when one process& K2 q z( ]+ f4 B
wakes up, it does not take all incoming connections for itself and leaves a
/ U; `# M- v: Q. q% R part of them to other processes. Setting this value to -1 completely disables
: l0 n& r$ K- q q% t [ c9 F+ n# W the limitation. It should normally not be needed to tweak this value.
3 f" x1 o! ?* X m
, V+ V# g' @! w/ n2 q4 dtune.maxpollevents <number>) E* }6 \% |; s. H ]
Sets the maximum amount of events that can be processed at once in a call to0 ] j& C) R/ q& W0 J
the polling system. The default value is adapted to the operating system. It
y3 ^ T8 ?% T- Q5 s4 `1 X has been noticed that reducing it below 200 tends to slightly decrease
1 Z4 `8 L9 ~8 L0 F7 H" S latency at the expense of network bandwidth, and increasing it above 200
. Z/ Z7 \# ^$ N9 ^) c4 \ tends to trade latency for slightly increased bandwidth.' M& I% [' `4 f& k) g$ o& i! g$ U
( q8 M9 k. l+ T, O! h2 @
tune.maxrewrite <number>- _# ~- m. E( U) y
Sets the reserved buffer space to this size in bytes. The reserved space is! Z& D6 v; D+ D9 M; o& W) c" s9 T
used for header rewriting or appending. The first reads on sockets will never
! n& {: K4 ~+ ~9 E5 K fill more than bufsize-maxrewrite. Historically it has defaulted to half of
. b6 h5 M5 D$ o bufsize, though that does not make much sense since there are rarely large5 V$ J2 `0 J* R/ Q) u5 O) p
numbers of headers to add. Setting it too high prevents processing of large
I- T- c. @! \6 g4 o2 @6 S6 f requests or responses. Setting it too low prevents addition of new headers0 ^0 b% U( j5 ]+ M) q( m* L( a, J
to already large requests or to POST requests. It is generally wise to set it
}0 V8 }1 T9 V7 i) e0 C to about 1024. It is automatically readjusted to half of bufsize if it is
' c& y+ p8 a0 A6 Y' `+ E7 m larger than that. This means you don't have to worry about it when changing
- y9 O: g5 h. [; a$ Q bufsize. e# D) G+ v& b2 q. W
' A( ]2 J! V3 G+ r1 `
tune.rcvbuf.client <number>0 E% r, j9 t; F1 @8 S9 u
tune.rcvbuf.server <number>- i' g7 \" {; I3 J7 l9 y3 n
Forces the kernel socket receive buffer size on the client or the server side
2 w, R9 q. m: V$ | to the specified value in bytes. This value applies to all TCP/HTTP frontends$ _( v) d' f4 `2 }4 |
and backends. It should normally never be set, and the default size (0) lets( |8 I& o" h$ q& S' T" e
the kernel autotune this value depending on the amount of available memory.
. M t4 y, x$ A, \0 R; z0 q. d7 V. Y% L However it can sometimes help to set it to very low values (eg: 4096) in
& y( H( D; r, _# m/ G order to save kernel memory by preventing it from buffering too large amounts0 ]; I2 l; {$ D" o1 f- _
of received data. Lower values will significantly increase CPU usage though.. z n1 L4 C0 }6 T! a2 j
. ^$ E, A, v) i! d' Z
tune.sndbuf.client <number>0 X" U$ G! X3 L" o; |4 u
tune.sndbuf.server <number>, m# Z' M7 U% o+ r& a+ k
Forces the kernel socket send buffer size on the client or the server side to% w% K0 o3 q' K/ n2 D0 w" k* Q
the specified value in bytes. This value applies to all TCP/HTTP frontends
' b4 M5 ?9 w! @5 i V and backends. It should normally never be set, and the default size (0) lets
: U: o. q& g4 o5 f. l the kernel autotune this value depending on the amount of available memory.2 p: Y Y) {6 w! I7 `: y
However it can sometimes help to set it to very low values (eg: 4096) in' G. Y4 K8 f v
order to save kernel memory by preventing it from buffering too large amounts
$ [6 J) F0 _+ L. Z6 o# U# b of received data. Lower values will significantly increase CPU usage though.
* k4 h/ J6 P7 |9 ?3 A6 r3 O Another use case is to prevent write timeouts with extremely slow clients due; Q4 T0 `' F$ [( _3 Z- [
to the kernel waiting for a large part of the buffer to be read before+ a' j; N0 X ]6 g7 _( V1 v
notifying haproxy again.
7 ~6 w% ]) d- Y; A' J$ Q4 G+ A* \4 b6 w3 ~$ c7 p5 p3 u
, S7 ^. z2 m& n, M4 B3.3. Debugging
# i1 K g/ w- f--------------
2 [% \) L9 X, S3 O+ b8 P0 p/ v- `8 u5 y" v% U" N
debug
3 f2 K9 T4 F" ?" |! V8 B; z$ y1 [1 Y Enables debug mode which dumps to stdout all exchanges, and disables forking T2 u+ z2 d3 s" E/ y8 o
into background. It is the equivalent of the command-line argument "-d". It! e5 V* \: ?6 @1 o
should never be used in a production configuration since it may prevent full
+ @- D% i2 V! ^+ ^ system startup.
/ [& m- y: b1 x
0 s# D6 J4 A( m% ~& B9 v) i$ X$ Xquiet; ~" a3 M, d% W6 D+ A: O o( N
Do not display any message during startup. It is equivalent to the command-+ C- N5 q3 f9 o) w, Q
line argument "-q".9 Z7 g/ o7 o C8 \
' o) p' I4 e" Q1 [( t1 N% ~3.4. Userlists
" w9 u# s) U+ ?--------------0 m9 C! d. _& i0 {8 ~3 P
It is possible to control access to frontend/backend/listen sections or to
; W, E$ A" P( ?: _4 qhttp stats by allowing only authenticated and authorized users. To do this,/ _! D& q6 S8 u
it is required to create at least one userlist and to define users.
3 O% o# X! t4 j% w: Y- e
& C4 Q' G" S3 d; m0 h/ ruserlist <listname>
+ @7 Z0 a$ o% E) a2 w; m/ } Creates new userlist with name <listname>. Many independent userlists can be( H3 O4 F3 ~1 C! T3 w! z3 s+ J( G
used to store authentication & authorization data for independent customers.
$ d& s% u/ a9 m1 v! f
" D/ B# A4 d% fgroup <groupname> [users <user>,<user>,(...)]
& f- j& g0 e+ L- @4 D S/ t* R Adds group <groupname> to the current userlist. It is also possible to% K3 O! a2 `! @7 _! X( U. q
attach users to this group by using a comma separated list of names
3 d8 {1 U& e9 C# W1 a proceeded by "users" keyword.
! {: e8 V8 C! _) r0 B! A" f4 ?4 O* @. u1 }( i: c7 g
user <username> [password|insecure-password <password>]
9 a* q2 l1 A: M; e* E [groups <group>,<group>,(...)]
& k. n" ]/ r. o, p Adds user <username> to the current userlist. Both secure (encrypted) and
9 S4 [1 X2 t) r1 t3 Y' }/ H% m insecure (unencrypted) passwords can be used. Encrypted passwords are
- W: w; a0 t6 s) y evaluated using the crypt(3) function so depending of the system's8 o7 D" I, S! X
capabilities, different algorithms are supported. For example modern Glibc. C' W6 A h! [$ o6 T) I/ M7 X
based Linux system supports MD5, SHA-256, SHA-512 and of course classic,
7 b1 q( \4 B) y' T0 I DES-based method of crypting passwords.
) J. O% Z9 k4 s' G+ c% s7 c# b8 S4 L8 x- v V* L) M. ]
9 B1 k6 r' J" x/ N& F Example:9 ^) @4 z4 D) S6 w( s! W- ]
userlist L1
: X& E/ W8 y' L! V" y& m, g group G1 users tiger,scott6 r; t9 O$ I# K0 v; K' c1 m
group G2 users xdb,scott9 ^- h5 E# o- a& b; A# d9 ]$ l
, @) M% b: |" D
user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91
# t$ d I* y5 T r, X* Q user scott insecure-password elgato
* Y- Y2 n# t; Q user xdb insecure-password hello# ^4 u- M: Y: w4 F7 e0 G
2 }+ c1 B0 p- e; t- b. y$ z userlist L2
5 C) ]/ [! |0 |6 B3 S$ | group G1
( T( `' [. a( _1 ~4 |. `% K" P group G2
1 [6 i: ]! {7 ?5 q" I
6 r% t5 V- K( t+ x5 z' ?" d user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1: k; J5 D+ G4 r5 m! e# O! |
user scott insecure-password elgato groups G1,G29 |4 L+ R! G% F; ?2 r4 g
user xdb insecure-password hello groups G2/ A. R! M+ i7 c( t0 b
" {/ N; ?9 T& p; i) S) y: ^ Please note that both lists are functionally identical.5 Z7 Q# c+ k7 p1 S
, r3 j$ `" k8 f3 H1 O8 r6 j
4. Proxies- q# d* c+ @; n) @4 X# N
----------
9 N4 a/ m; X4 L- A% R4 e- l* z7 e$ l5 b* `
Proxy configuration can be located in a set of sections :
1 G0 Y- X1 G) z. i! l - defaults <name>7 Z2 h {* u0 b6 a6 t
- frontend <name>
* B* F7 O8 Z) G1 u* Q, d. D - backend <name>6 _& b7 b e9 f- b( ~' s! F8 ~8 S
- listen <name>
4 M6 y0 @$ c& B' \0 H: s$ W% e( \
A "defaults" section sets default parameters for all other sections following
: X9 Q9 l$ p1 M) Y- W. f* w& Nits declaration. Those default parameters are reset by the next "defaults"# n* { s& Z6 Q& \" W" t0 [# z5 K
section. See below for the list of parameters which can be set in a "defaults"
1 }* u) x. ^/ m- P4 m" ~) Usection. The name is optional but its use is encouraged for better readability.4 P Z1 }. i, B Q
: {. |4 p5 u8 y2 |" U5 E5 b0 V
A "frontend" section describes a set of listening sockets accepting client) H. u' i$ q% `+ \7 f$ T; d
connections.
4 v8 x) ]/ R7 x: i6 w2 C8 Q, n/ U |6 }, R p
A "backend" section describes a set of servers to which the proxy will connect
7 V4 K* s. G8 x3 Oto forward incoming connections.
" o( Y; M6 m K# j5 U1 `* ]& G+ X% |5 x4 W
A "listen" section defines a complete proxy with its frontend and backend4 f0 Y' o) a! w5 a1 i4 }
parts combined in one section. It is generally useful for TCP-only traffic.$ u! m* g( D5 K+ s
6 h" g# n6 N( W; o( S: b* j
All proxy names must be formed from upper and lower case letters, digits,% N# F# D0 e. g
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are
/ S5 n0 s/ H# T3 O& Z. N, s3 k7 Kcase-sensitive, which means that "www" and "WWW" are two different proxies.
% ]+ Q0 T6 ]* }2 t: ~- w) c( F9 ^# t: @( U/ D, f
Historically, all proxy names could overlap, it just caused troubles in the
" F- K9 j/ B) A1 n2 e- W0 Dlogs. Since the introduction of content switching, it is mandatory that two
d4 t8 Q0 A4 L' \7 h9 a* |( ]proxies with overlapping capabilities (frontend/backend) have different names.
- D/ f4 L4 N( ]6 U' E- ?7 nHowever, it is still permitted that a frontend and a backend share the same
5 e M7 c. s: g1 l: g$ @0 Oname, as this configuration seems to be commonly encountered.
" C9 g# a/ z. ?: [$ Z: V. j
% j1 t5 _0 |4 t+ LRight now, two major proxy modes are supported : "tcp", also known as layer 4,; Q6 f0 a/ o- ^9 V O* e @
and "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards i& R8 S( T6 E0 i6 e4 R; P2 O. z
bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the
8 }# S' p4 b9 F9 G" A6 t. _protocol, and can interact with it by allowing, blocking, switching, adding,
+ g+ t. Z7 Z! U: ?4 t, O. Gmodifying, or removing arbitrary contents in requests or responses, based on+ ~4 A6 V& s3 S4 K1 A. Q, l
arbitrary criteria.8 H2 ^/ K+ u3 k1 ]4 l; @, T# ]
! G) E6 e" M7 w. l! P) C; x
5 u9 b: t! a1 C. r. Z
4.1. Proxy keywords matrix
2 Z* q* Z/ a- T) d. w- N--------------------------
& r* R; K: s. `$ t9 Y8 T6 ?1 C- r6 c0 U( m2 n( i
The following list of keywords is supported. Most of them may only be used in a- H C+ W% K. T& l' i
limited set of section types. Some of them are marked as "deprecated" because% d, V) ~9 M( e# N) J& I3 g% C4 ~
they are inherited from an old syntax which may be confusing or functionally
}/ G: j& o9 ]# N# ?* {limited, and there are new recommended keywords to replace them. Keywords
: C7 \7 j6 c: G: \marked with "(*)" can be optionally inverted using the "no" prefix, eg. "no3 F8 j/ X3 ^& Z
option contstats". This makes sense when the option has been enabled by default& j. o& c2 k, s1 Q
and must be disabled for a specific instance. Such options may also be prefixed$ p! c$ d+ _. ?
with "default" in order to restore default settings regardless of what has been( s; Z- C* @$ E6 D
specified in a previous "defaults" section.0 c; d! _! _; b7 j& O# H
% a9 A( O, V9 M$ g2 v3 ~; r( S4 v5 C6 h g7 o6 j: @
keyword defaults frontend listen backend5 P$ t$ I: D2 E' |' `
------------------------------------+----------+----------+---------+---------6 K: U) P+ r( N! k, D
acl - X X X& u% N9 z# g' \% J, c
appsession - - X X) h8 d8 r! {/ M
backlog X X X -
9 Y- x$ m, ^# r8 Y3 v0 Obalance X - X X
) a! @0 t$ H6 G) p0 H' }1 ibind - X X -/ e1 l2 a0 X) S" Y
bind-process X X X X
% h) l5 a/ _5 g) G4 O( v4 Qblock - X X X
6 p, r4 Z4 X( V) Rcapture cookie - X X -
$ Q4 n8 e3 Y" {, Gcapture request header - X X -
$ ?4 y4 \9 V( W5 I/ d- U/ h: ocapture response header - X X -
/ f- d0 Q& m) H+ l+ L( ]. P! ~clitimeout (deprecated) X X X -7 Y- [$ l, A1 L( W
contimeout (deprecated) X - X X
( v3 S9 s( v3 U7 Ncookie X - X X
* Q* _% h+ q4 s! x1 ?: Zdefault-server X - X X# V* u3 R; D. ]' T: B& }" X9 a6 W
default_backend X X X -* A& F, }6 q) i
description - X X X
2 m8 g: e9 _: P3 jdisabled X X X X" K1 u& ?+ { U* M, K4 Q
dispatch - - X X
9 M% h: x" N: R- k# K. b5 F6 Venabled X X X X. x6 t. u m$ {5 ?( d/ I" f# q. k
errorfile X X X X
4 `3 Q" K4 \0 H, werrorloc X X X X
( t" h! J" p2 i( ?errorloc302 X X X X. i# |3 l4 S" a" y8 r& _( M* q
-- keyword -------------------------- defaults - frontend - listen -- backend -
1 k1 _1 j, I% rerrorloc303 X X X X2 {! A. d }( C* ]4 W( k, {
force-persist - X X X
* D- t7 G) `. X7 Nfullconn X - X X5 W2 b6 o5 h& i' p
grace X X X X& D4 }8 E$ d* b7 D5 G% f
hash-type X - X X
6 Q) P9 f, c$ `8 `( J! B2 Xhttp-check disable-on-404 X - X X
@6 A- ?: ], t) H; ~9 h: f. o: mhttp-check expect - - X X8 T: ~. k) I/ p, H& d
http-check send-state X - X X; b3 \. |# J3 w L
http-request - X X X8 a0 s" p& F2 P% s7 ?! P: x2 q* b
id - X X X8 s4 I5 w3 T6 w$ H" i" `
ignore-persist - X X X, b8 X7 e& Z" j" \8 E, m
log X X X X! v! w5 x# T; B1 k& S# q
maxconn X X X -
3 S7 u/ U* u! e1 D% N* h) f2 imode X X X X, G; |4 m( F$ y$ D6 X) ~, }
monitor fail - X X -5 Z' y: k( n: d
monitor-net X X X -
& L& ?/ X, e! L* K9 \3 Gmonitor-uri X X X -* \* N7 t5 `6 }1 R3 u7 o3 G
option abortonclose (*) X - X X+ |3 E& P/ @7 F" J% q. {
option accept-invalid-http-request (*) X X X -* l; q$ H, ~5 S* y# x7 g+ \# z" \& f
option accept-invalid-http-response (*) X - X X! e- k" @3 W, d6 j) l7 A# q: s! Z
option allbackups (*) X - X X
$ S" h; D0 O& v3 J. S! toption checkcache (*) X - X X
$ U, B. S6 `- b) r, [8 Z! \' ?option clitcpka (*) X X X -' W, q0 v `0 G: S% K, `
option contstats (*) X X X -
* B9 F! w! ?4 F9 F$ i, P9 eoption dontlog-normal (*) X X X -
1 s/ D/ w2 s3 T3 @4 z' r, o8 ooption dontlognull (*) X X X -
% ]/ i" h9 H6 P+ R9 N* \' Xoption forceclose (*) X X X X
* f* E; | I" ^. U-- keyword -------------------------- defaults - frontend - listen -- backend -
# L$ i6 T6 g/ o( ], ^# \option forwardfor X X X X7 m' \1 Q% U/ g% U0 v c( n% H
option http-no-delay (*) X X X X
2 ], Q. w/ C# o6 l! e1 K d0 U6 Foption http-pretend-keepalive (*) X X X X; Y P4 v5 m9 F. G; Q6 B2 K# Y
option http-server-close (*) X X X X
3 Y( }+ Y/ G& y" B* m: |option http-use-proxy-header (*) X X X -
8 s$ D; y2 ~. q/ {7 @* Boption httpchk X - X X
0 @: n8 D& J9 A% Q1 Z% Z# Z+ i! r Zoption httpclose (*) X X X X
?4 [* Z8 [1 N: A9 toption httplog X X X X. X2 D" C3 a$ c- j( e
option http_proxy (*) X X X X
" F& R, J1 s n, v7 g* {- Moption independant-streams (*) X X X X( ?- T2 k* ]( M5 j" |
option ldap-check X - X X
0 H4 v+ b$ l+ f0 ^. l7 d$ P. Moption log-health-checks (*) X - X X1 ~) O& G1 K+ v" n# \
option log-separate-errors (*) X X X -8 i8 s2 H/ C( p% D; i) b, h& X, Z
option logasap (*) X X X -
' [$ Q5 w7 v+ N! W0 z* i$ ?0 Ioption mysql-check X - X X
/ [: C( L" x, M+ ^7 Aoption nolinger (*) X X X X2 V" Y4 u+ S& S3 p% s, n" R
option originalto X X X X" j8 y4 ?9 Z: |2 O# ^" o6 b
option persist (*) X - X X
: H- }/ t, V$ p/ Eoption redispatch (*) X - X X
, [9 ]: H9 W/ A G( F8 }option smtpchk X - X X
) n* |" E* m9 g- w2 noption socket-stats (*) X X X -
7 [4 s& [# p+ Y3 N" J; hoption splice-auto (*) X X X X
c0 T% P# h! Hoption splice-request (*) X X X X3 { ]! H" i) D- C9 o, F
option splice-response (*) X X X X
! o3 o! v- P' Z8 Y7 i$ Poption srvtcpka (*) X - X X }" c1 U- `% m
option ssl-hello-chk X - X X
1 O5 u' V! k+ ~' V f-- keyword -------------------------- defaults - frontend - listen -- backend -+ \# ?) I6 P/ ? {7 s; ^( r9 P
option tcp-smart-accept (*) X X X -/ K8 A% r+ L. I: m! ]
option tcp-smart-connect (*) X - X X
' `: F! j; T3 H* l0 [option tcpka X X X X" A& Q) n1 @! z/ o$ z; u
option tcplog X X X X$ E6 f. E& d, }
option transparent (*) X - X X
* v( |0 E3 W+ ]* }4 { k& kpersist rdp-cookie X - X X* {5 }0 u2 b) j, w
rate-limit sessions X X X -8 x* n# a _, X- b$ s- W+ w
redirect - X X X
9 R. V' K2 G+ predisp (deprecated) X - X X4 j M/ R7 K( w& {/ U
redispatch (deprecated) X - X X
/ t+ f" M" G) f: S' Greqadd - X X X
1 b* I( ?! u. G' n4 t: s1 h- Oreqallow - X X X' A: Z2 c; N5 W# Z1 \( t
reqdel - X X X( ? V' n) X0 t- w4 I: G; \0 [
reqdeny - X X X
D/ N' i7 U2 X' ]reqiallow - X X X: }( [0 {2 X( _( C! M. j' j4 G! F
reqidel - X X X" m1 Y6 |2 I1 f
reqideny - X X X
. Q- W; U1 L) V5 Dreqipass - X X X H" f& u( k2 [2 s
reqirep - X X X
2 p7 b/ K; \1 D% l& @" greqisetbe - X X X
2 h8 f; ? O2 {' k8 i3 i- Z+ m( y! Xreqitarpit - X X X
8 e7 V- O. C' [* N3 Lreqpass - X X X
; o' o$ z8 n; breqrep - X X X; R& L1 n+ h1 I. g
-- keyword -------------------------- defaults - frontend - listen -- backend -1 S$ B0 k3 B0 ?% b) w' Y5 Y* _! |: A
reqsetbe - X X X
: D" I! E$ `- c: P3 ?reqtarpit - X X X& i+ _& \7 [! I. N) r
retries X - X X4 R0 X7 X# E1 P3 \( `1 M0 c+ @: Y6 z
rspadd - X X X
, Y3 n5 a) A. f$ X3 ]. {. _& Jrspdel - X X X
2 O+ O! @# W {; W* w6 ^( r' [rspdeny - X X X+ b3 _% s, x$ Z* x2 L
rspidel - X X X' k+ y4 S% [$ M5 a- p/ n
rspideny - X X X
; c( h# `% }2 \0 @ Srspirep - X X X5 ]4 D# @2 r$ |3 D7 P
rsprep - X X X
( i5 |( ^/ k G2 v% u: dserver - - X X
5 t; }* r1 m- g, J2 I( G1 G* Nsource X - X X' ?- l$ G9 N7 S6 i
srvtimeout (deprecated) X - X X. _2 j+ p! F5 H! H( Y# x0 [, a
stats admin - - X X
4 Q, r% e$ `: h1 y' o' Dstats auth X - X X: z8 {" i" s) b3 p t
stats enable X - X X
+ O' r( e5 }9 I. X3 T7 Hstats hide-version X - X X
9 n, S; @3 K. \" x7 n) P$ Cstats http-request - - X X
& \- R$ q1 a- n! Vstats realm X - X X
% _4 T* F% I0 U, o5 t. [/ W5 |stats refresh X - X X& a0 R( K A: L0 [" a
stats scope X - X X1 i# S) H" s8 \+ X6 Q9 g
stats show-desc X - X X' \4 a# K! k0 ]* O8 t) E1 V
stats show-legends X - X X4 |$ a8 z$ U& @4 ]) s/ d+ u
stats show-node X - X X2 m8 l0 s7 F6 H3 W
stats uri X - X X2 l( q2 i- O6 s; r2 ^/ @. N
-- keyword -------------------------- defaults - frontend - listen -- backend -
: w, [. K1 \1 Kstick match - - X X
$ U6 }/ |. }: b+ T& ]& i- Vstick on - - X X
& g( C0 ?4 O0 N) K+ \stick store-request - - X X
; B# s# J `' }! K( ^+ Qstick-table - - X X
2 b+ T) \6 u, m0 jtcp-request content accept - X X -! D" P8 v( h$ \" U3 [+ U
tcp-request content reject - X X -$ @. m$ X& G$ b
tcp-request inspect-delay - X X -2 v6 c9 h3 [* J1 H
timeout check X - X X
+ m3 I; i- J; Stimeout client X X X -
% u k$ c' C! z" ltimeout clitimeout (deprecated) X X X -
2 d- y3 b. p: h* m! Z3 }timeout connect X - X X
& F ^+ _/ d. w' @: [timeout contimeout (deprecated) X - X X
& k/ P- K4 J' @; Vtimeout http-keep-alive X X X X2 ]; X- y' y1 D; c. @
timeout http-request X X X X: ?$ H* U- s' q- R+ w/ I1 T' K x
timeout queue X - X X+ G/ j. ]2 F/ Q+ Y9 _* {5 D+ r
timeout server X - X X9 D: ^3 D: ]" [& n. R
timeout srvtimeout (deprecated) X - X X
! q8 z& q5 V5 ^6 H3 |# }: Utimeout tarpit X X X X
% W8 c& ~8 |% c& Q- z5 R0 [transparent (deprecated) X - X X
2 X6 E. _$ K1 Suse_backend - X X -+ C" W( |! ?7 j( `
------------------------------------+----------+----------+---------+---------
+ Z" A) {. o, f: Y" X- r u2 w keyword defaults frontend listen backend
, s( N. Z, a% q4 N( V6 V: N2 F+ o) A
$ s+ n, _6 v1 d, B* p$ \2 S& e* w0 x4.2. Alphabetically sorted keywords reference
3 }* Y3 q* G, e3 L4 q---------------------------------------------; [; S- S W, {) ^1 h. f3 J
/ t% \) j# l1 v. g r; VThis section provides a description of each keyword and its usage.$ ^0 F& e! P, B2 l
+ }/ a. G8 H' N. }2 F' h5 |; ]$ w$ H4 [
acl <aclname> <criterion> [flags] [operator] <value> ...
# i' ?: B% M3 l$ Q9 K1 z) V/ U Declare or complete an access list.
. B7 b* x3 l g! B; ]* @ May be used in sections : defaults | frontend | listen | backend( s0 A5 u/ K, { D
no | yes | yes | yes' Y3 G3 y, ^, A" u* \5 p" p7 J* [
Example:" w5 L. Y* A, G* e- k t% n' @. t
acl invalid_src src 0.0.0.0/7 224.0.0.0/3+ W% o% U& y, m L' N
acl invalid_src src_port 0:1023
9 B4 T* B% V+ d) @) Y! W; W6 j acl local_dst hdr(host) -i localhost" \/ d8 R& E2 m+ X/ Q' x6 X; d
b8 T l* ^4 J& N& ~) ~0 }: Y
See section 7 about ACL usage., B( v0 @4 r: y" e8 S+ f
% @4 [5 T- J: H. X8 W% q F8 A7 f% E
appsession <cookie> len <length> timeout <holdtime>
% W. i% D K/ H# G% K; _, f# @ [request-learn] [prefix] [mode <path-parameters|query-string>]$ D, v" ]" z3 S7 ]' `
Define session stickiness on an existing application cookie.- V' i2 n3 M3 Q) u* R9 @/ _+ C$ L
May be used in sections : defaults | frontend | listen | backend
- H# V# u* D6 e/ k& G+ i/ g no | no | yes | yes
, h! K" ^& A6 N/ r6 c" w Arguments :
* Z: Y! P$ G' p! i <cookie> this is the name of the cookie used by the application and which0 @# X9 ]$ {9 ]8 {% p0 ^
HAProxy will have to learn for each new session.
) q7 u9 G" |0 a5 Y& w
9 G$ s; n# o' K9 k b: k& b* {6 g' R <length> this is the max number of characters that will be memorized and% z/ _3 j% C' E1 i! [* g
checked in each cookie value.5 R- V: v$ b7 _, m1 d% [
7 p U2 _) K, ^. p& K* k <holdtime> this is the time after which the cookie will be removed from
) @+ S0 n* J* _" E8 \ memory if unused. If no unit is specified, this time is in
1 Q. l, c+ o, y9 g, q4 E- a. v- R milliseconds.* x" G- ]2 R1 V8 }+ Y) _
8 W( v0 H+ u" L( d. |7 n( T
request-learn" ^) i* ~: A' A$ u# T1 x& B+ ^
If this option is specified, then haproxy will be able to learn6 Z3 q* H$ q- N; [
the cookie found in the request in case the server does not' p* ~1 c& h- K' _( e6 C4 K
specify any in response. This is typically what happens with
, ^0 O/ A0 C5 D; Z* w PHPSESSID cookies, or when haproxy's session expires before
- _+ R# W$ k0 C# I. v9 ^5 ? the application's session and the correct server is selected.8 q: M l% ?( T% r2 `( B
It is recommended to specify this option to improve reliability.
: z, v% ?; |( X$ w
1 ]6 b$ L1 E; z prefix When this option is specified, haproxy will match on the cookie1 G: J p' `% @; H; Q( S/ ]
prefix (or URL parameter prefix). The appsession value is the
8 B2 x7 @- ?) M# B6 N% S data following this prefix.
% p% l$ B5 Y; e; P$ r1 h" n2 u& L* ]0 Y: C8 U% d1 Q5 }
Example :
; Q/ _2 e' c! q3 q appsession ASPSESSIONID len 64 timeout 3h prefix5 U7 d5 _5 f+ B) Q
4 F. W2 { f# T8 d9 T3 | This will match the cookie ASPSESSIONIDXXXX=XXXXX,0 W4 y; _" \- e5 `9 s
the appsession value will be XXXX=XXXXX.) x9 Q8 H+ ~( u+ n. H! {& m
, \ e! ?4 q! }+ }
mode This option allows to change the URL parser mode.7 F. r) D; G0 C9 [; P% E( m
2 modes are currently supported :; _# m* C+ q6 l3 R8 j; V+ w
- path-parameters :1 U2 q' t5 ?8 ~$ @& \# x! i, m
The parser looks for the appsession in the path parameters( x- J1 t3 Z/ G P) P
part (each parameter is separated by a semi-colon), which is* s9 p- S! i# }! S: _4 u
convenient for JSESSIONID for example.
/ V8 z G& o p r This is the default mode if the option is not set.
/ n0 ~0 c7 w* {, J0 f! P; b2 P7 v6 F - query-string :
' @, Q7 F" F5 u8 W4 K8 k In this mode, the parser will look for the appsession in the( d, \. M3 L9 u0 w
query string.* w( ?9 p# v+ F& P8 |1 P
) X- X2 ] l& E* ~- z% L When an application cookie is defined in a backend, HAProxy will check when0 t% C( m6 n" R
the server sets such a cookie, and will store its value in a table, and
! _! S) _- [0 [ associate it with the server's identifier. Up to <length> characters from
, L, o# f( v x z; Q1 x0 c2 A: x5 s4 g the value will be retained. On each connection, haproxy will look for this
7 H/ }9 D. _7 P8 \9 {8 e- ?0 | cookie both in the "Cookie:" headers, and as a URL parameter (depending on ?3 M. i6 |' W+ K2 |, K: p- s+ t
the mode used). If a known value is found, the client will be directed to the
/ A- E0 V6 P! k; ?- }9 V& M server associated with this value. Otherwise, the load balancing algorithm is, F9 ?6 a7 S: o' Z4 `
applied. Cookies are automatically removed from memory when they have been
' U+ t: ^% g4 e: W9 F; m unused for a duration longer than <holdtime>.
9 m; ^4 v' J. I) l, R" v7 |* q+ ~2 H" {; p t
The definition of an application cookie is limited to one per backend.
' B2 c) T8 o5 f3 o/ x
7 c3 A6 C& j4 M t+ {' v2 a5 x Note : Consider not using this feature in multi-process mode (nbproc > 1)
. J0 X# ?" E8 @* Y. P& n" F unless you know what you do : memory is not shared between the
! B/ D( M; D) p: o1 A; i processes, which can result in random behaviours.. g8 h% |3 B0 f, W4 k+ |
- M; M* E: D* K- s8 q% H Example :
9 G( |+ I( Y. ]: F2 k9 A9 _ appsession JSESSIONID len 52 timeout 3h. y2 B6 P/ c7 [" s# T& i
. t( w3 I( P1 g$ K1 p See also : "cookie", "capture cookie", "balance", "stick", "stick-table",3 l7 o0 _. V6 i4 t* r( Z4 }
"ignore-persist", "nbproc" and "bind-process".& }1 t3 g; E4 N; {# G
8 |$ \, y/ K9 g) W# L
7 J; ^ h. j6 P" i8 r8 W! n8 Gbacklog <conns>
, x4 M1 M* \! g* s5 N B Give hints to the system about the approximate listen backlog desired size" P2 K% }% W Q
May be used in sections : defaults | frontend | listen | backend" n7 ?0 I. I* l/ i: n7 ]; \
yes | yes | yes | no7 T; i7 H, m7 V' D
Arguments :9 V% R& g! j, z/ x( Y$ w
<conns> is the number of pending connections. Depending on the operating
+ g, \" n4 V W# y; g' R* F system, it may represent the number of already acknowledged9 p$ r% i1 H' |
connections, of non-acknowledged ones, or both.
% U) O# ^4 T$ W! R: M g
* |1 X% `6 ]4 \$ F In order to protect against SYN flood attacks, one solution is to increase
4 m: l1 G; c3 l2 M the system's SYN backlog size. Depending on the system, sometimes it is just
% W3 V2 o. d$ }8 R# ~ tunable via a system parameter, sometimes it is not adjustable at all, and
" j/ q7 u. D) a sometimes the system relies on hints given by the application at the time of
4 j6 l2 S1 G- ?5 g: Y6 y the listen() syscall. By default, HAProxy passes the frontend's maxconn value$ j" Q/ y& p1 S8 Y. o# ~
to the listen() syscall. On systems which can make use of this value, it can
: h4 T- ]7 W+ x- {5 {" A sometimes be useful to be able to specify a different value, hence this
- l$ n) Y1 t- n# v7 d$ u; m- m9 }# B backlog parameter.! D- F- L1 V8 X, s
" e# y5 j% m F* O8 y/ T- ]: r On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
9 X) H; A' l/ |$ L used as a hint and the system accepts up to the smallest greater power of+ j& W" N: V- U, W$ i: u
two, and never more than some limits (usually 32768).# a) k7 J- w) c. Y
0 r8 Z1 G' `7 [" D" P See also : "maxconn" and the target operating system's tuning guide.5 Z! i* ` d2 w Y/ z
) w$ I/ F) t3 j( W/ V
. X% R# g9 Z' K1 a* \9 Fbalance <algorithm> [ <arguments> ]5 z" \9 q# n0 h) Q w e. [
balance url_param <param> [check_post [<max_wait>]]7 ~& y, Y% C1 F. m B& x
Define the load balancing algorithm to be used in a backend.4 O. f8 _2 T* R8 q" Q7 @& D% H
May be used in sections : defaults | frontend | listen | backend4 D4 Q& r3 G. `" ?
yes | no | yes | yes$ h8 C& L" j. p* B$ T' S2 y b
Arguments :: U# _- P o6 H/ V# j) A7 ^
<algorithm> is the algorithm used to select a server when doing load
9 u6 U$ }2 V: u6 Q balancing. This only applies when no persistence information
9 i _- u) o* `/ b4 G; N$ E is available, or when a connection is redispatched to another8 L; `& g' E% ?% ]
server. <algorithm> may be one of the following :
! H o2 P+ a- H* V
( \0 R2 \% D: A7 U) X) u: g b roundrobin Each server is used in turns, according to their weights.7 J6 d- C3 a- Y/ T) [! p2 M
This is the smoothest and fairest algorithm when the server's
) r8 e- A4 v% h$ `- x1 ?, e3 G processing time remains equally distributed. This algorithm
" d! n: [& F4 m, D1 `( o is dynamic, which means that server weights may be adjusted
1 n! ^& ?+ s& N/ B% v1 W on the fly for slow starts for instance. It is limited by4 w' f( S2 {( E. W
design to 4095 active servers per backend. Note that in some
~0 }* j! n: v, x large farms, when a server becomes up after having been down t) B# p5 Y8 h
for a very short time, it may sometimes take a few hundreds0 I' t8 s# S* m( {
requests for it to be re-integrated into the farm and start
2 M4 R& ~( Q# P receiving traffic. This is normal, though very rare. It is; l: Z# _0 X) ?% V4 t3 I% {
indicated here in case you would have the chance to observe
7 p- j6 ]9 I6 }1 c7 Y( |$ V# U it, so that you don't worry.
! w+ C+ P: R- u6 w: c7 O+ E
/ ]9 D! k( G- o3 Z" \5 y+ e7 z$ f7 @ static-rr Each server is used in turns, according to their weights.
8 J: @8 @& s' `; Z, S This algorithm is as similar to roundrobin except that it is M. [# B/ u7 u9 ^) c2 M
static, which means that changing a server's weight on the
; I' w2 q' p B( v1 ] fly will have no effect. On the other hand, it has no design
8 u, V- {% f @% ? limitation on the number of servers, and when a server goes
1 d& x. o: d, n1 p7 O up, it is always immediately reintroduced into the farm, once+ }3 f: e, Y7 Z) {4 |
the full map is recomputed. It also uses slightly less CPU to8 D2 E6 W* W4 s3 F* }. b0 C
run (around -1%).3 A' V% I& x0 T+ `: B! m* L9 \
. ]1 O1 N" F% j! }" ^" i leastconn The server with the lowest number of connections receives the
! z1 [ \5 I; L) c4 {8 y connection. Round-robin is performed within groups of servers3 K! z( T4 c" `4 e/ o4 r4 K* a: c% K
of the same load to ensure that all servers will be used. Use1 N. S* U% G) u1 M" r/ q
of this algorithm is recommended where very long sessions are
# d' ~# k( q6 ]5 R0 \9 ?" D1 Z expected, such as LDAP, SQL, TSE, etc... but is not very well! H, [+ d2 F" l
suited for protocols using short sessions such as HTTP. This
5 P8 v6 @3 T! B i algorithm is dynamic, which means that server weights may be
* y0 }& H3 f: C adjusted on the fly for slow starts for instance.
# Y' u6 \% y2 y+ C3 B
- B0 }, o m$ c& P3 N- g source The source IP address is hashed and divided by the total- w+ a# C, F7 d: _
weight of the running servers to designate which server will
* t: X2 n# H0 P5 m' K% V$ X receive the request. This ensures that the same client IP' [$ Z0 J6 C7 N2 M; R* L. R
address will always reach the same server as long as no! Y3 U& l0 u3 k" l6 X
server goes down or up. If the hash result changes due to the
0 c9 l' c+ m' ?1 L0 S! [+ D. [ number of running servers changing, many clients will be
. A |6 x& t$ I! [ directed to a different server. This algorithm is generally5 E$ p H9 |! I6 ?
used in TCP mode where no cookie may be inserted. It may also
% t8 r% v& d4 ^, B5 p+ Z+ a8 v be used on the Internet to provide a best-effort stickiness& o5 E L9 Q$ |: n- ?" c
to clients which refuse session cookies. This algorithm is
0 s4 |9 @% p. m. }, P9 h/ W- r static by default, which means that changing a server's
/ Y* o9 I4 x0 ? B weight on the fly will have no effect, but this can be7 b6 f2 b. c. w7 d
changed using "hash-type".
8 {9 K' M A2 n8 L) T% l# L
4 C/ I: i9 F0 _4 Z1 g5 R uri This algorithm hashes either the left part of the URI (before
. l) f5 q& m* l# H5 S the question mark) or the whole URI (if the "whole" parameter
$ {- [$ v, ?: r: ? \ is present) and divides the hash value by the total weight of
P: z: N! a9 \$ f# u0 R the running servers. The result designates which server will
1 U$ v" c% z; P: s" E receive the request. This ensures that the same URI will
8 R0 w" k5 [1 K- Y7 R8 _ always be directed to the same server as long as no server- j; S$ @% Z8 H7 c
goes up or down. This is used with proxy caches and/ S$ P5 Q. t0 n" e' b5 v* x- a
anti-virus proxies in order to maximize the cache hit rate.- V( g" y7 `4 g0 }0 S. w5 ~9 A
Note that this algorithm may only be used in an HTTP backend.
3 v; ~" l8 }: @ This algorithm is static by default, which means that
; A0 F& [- c1 b6 X4 C changing a server's weight on the fly will have no effect,
1 P$ F# i) l9 S but this can be changed using "hash-type".
: }$ w6 M" O, @5 S- _) |: O5 s# q3 F7 D+ _
This algorithm supports two optional parameters "len" and2 o$ p2 C0 a# Y9 n" B- d
"depth", both followed by a positive integer number. These
+ H1 m' p' J$ x. ]- C8 _6 _8 A options may be helpful when it is needed to balance servers
8 P% U: l/ x1 q B based on the beginning of the URI only. The "len" parameter9 a8 [1 Q6 f9 i& f% [5 }
indicates that the algorithm should only consider that many+ v) E" ^6 x+ @4 ?& J- b$ l
characters at the beginning of the URI to compute the hash.
( J! X" K' ]7 }, K9 {; g) c Note that having "len" set to 1 rarely makes sense since most8 }6 F$ i0 [0 E" ?4 u' c
URIs start with a leading "/".
8 X6 b y5 O) }4 D- F2 Y
. m6 m4 o* z! T; c+ U" z The "depth" parameter indicates the maximum directory depth8 Z: y# P9 A6 ]4 [/ r( Z
to be used to compute the hash. One level is counted for each
6 L$ `. g; e: N4 k0 w8 a/ W slash in the request. If both parameters are specified, the
" J+ p2 a9 z7 H% J evaluation stops when either is reached., f5 [+ S6 u7 a3 q7 `! J5 n
, u" _- n; ]5 n$ L url_param The URL parameter specified in argument will be looked up in9 L7 G: k" Y1 X! n6 }
the query string of each HTTP GET request.
: o+ m/ z% r- z' ]4 l' G
) L( ]+ E0 W+ t If the modifier "check_post" is used, then an HTTP POST: s. S5 `4 c0 z0 j ~' n
request entity will be searched for the parameter argument,
6 n( c; o( p$ a& w* ?# } when it is not found in a query string after a question mark
. d2 Z5 S5 a+ e8 }% A. J5 d8 X) ` ('?') in the URL. Optionally, specify a number of octets to9 h( x% I7 M; Y' s0 `9 s
wait for before attempting to search the message body. If the S2 p7 c3 u; f
entity can not be searched, then round robin is used for each0 M& C- E, L) F s* C
request. For instance, if your clients always send the LB- P0 g2 v) c8 Q: g2 y3 e% {/ E* `
parameter in the first 128 bytes, then specify that. The
! r! h5 Z" R9 ~5 B: k default is 48. The entity data will not be scanned until the6 m- l+ z" u) z. Y$ \' V
required number of octets have arrived at the gateway, this _# a# b" F- ~5 U1 {
is the minimum of: (default/max_wait, Content-Length or first
& W9 d& k- G, m& y: u7 W: D: @2 q1 ` chunk length). If Content-Length is missing or zero, it does" D' g8 w0 n& u6 j6 R
not need to wait for more data than the client promised to& p) v) q9 `, ?( l U U! ~
send. When Content-Length is present and larger than: ~0 j) i7 h9 D* s/ {* D
<max_wait>, then waiting is limited to <max_wait> and it is7 B$ J3 g, K* q9 o) u8 D6 k
assumed that this will be enough data to search for the
0 H$ h. k" H" ^: s" c presence of the parameter. In the unlikely event that
5 m! W' r6 q6 k Transfer-Encoding: chunked is used, only the first chunk is
9 C" \* M/ I2 @, |9 i9 \8 { scanned. Parameter values separated by a chunk boundary, may
$ J% E5 s: k# N be randomly balanced if at all.
+ g+ f8 m# W- X# A: e5 X* ?
3 Z, a8 s8 {% w0 n; _ If the parameter is found followed by an equal sign ('=') and
$ Q/ Q4 b7 v5 p a value, then the value is hashed and divided by the total
8 f& Q1 S- D: e" W5 ?8 X' {) Y Z weight of the running servers. The result designates which8 O3 ?3 [! W1 n! q ]' ~
server will receive the request.
. W O7 m. f& Z; J8 L A ^6 ?0 u: q/ i# ?9 b9 u. w# @4 `- X
This is used to track user identifiers in requests and ensure) w/ W. B' y4 h8 I; l
that a same user ID will always be sent to the same server as
; g" ~) ]/ `+ h long as no server goes up or down. If no value is found or if! ?2 e+ `5 }$ \: A- L/ t
the parameter is not found, then a round robin algorithm is
" m4 @# b4 [+ W. ^* \2 Y5 t+ S applied. Note that this algorithm may only be used in an HTTP# D6 d4 Q6 X/ T# _- X3 a
backend. This algorithm is static by default, which means
& z, w% a5 o# n; ?" H; b' c that changing a server's weight on the fly will have no% \2 I/ r3 T' {) H: P( H
effect, but this can be changed using "hash-type".
8 ?& S6 E! B# {9 N/ B. a: O( R1 Z. B2 V( `1 H
hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.
- ~! H/ {$ p% Y( @ Just as with the equivalent ACL 'hdr()' function, the header" i- w/ O0 ^) k4 z# a% Y
name in parenthesis is not case sensitive. If the header is6 P5 Y! y' }, F; A5 q- j3 ^# e
absent or if it does not contain any value, the roundrobin; m" K% q2 y# S' a# X
algorithm is applied instead.
/ G, Y6 w" h2 I! N q2 a7 A! Y! _$ M* E
An optional 'use_domain_only' parameter is available, for
. e Y. M, G) Q reducing the hash algorithm to the main domain part with some$ L! s' \" l$ R
specific headers such as 'Host'. For instance, in the Host/ Z5 K5 S! z/ s" G% |. S
value "haproxy.1wt.eu", only "1wt" will be considered.
; ^ p" n& N1 M2 x+ t9 h; j! P5 e
) O6 g3 U/ h4 R' Q0 ^8 j This algorithm is static by default, which means that& v. S" ^) c/ F% S) k3 S) i- J
changing a server's weight on the fly will have no effect,' Q( T7 \2 U" {% `' d
but this can be changed using "hash-type".
* o! f. k% g9 X+ x" ?. r, x
6 O; i! {* d L h; E* r- y3 X rdp-cookie
) f+ m9 K) O' r* v rdp-cookie(name)8 r, \/ M1 W9 d- U4 ]7 |' r2 j
The RDP cookie <name> (or "mstshash" if omitted) will be
2 H# ?3 L5 \& {0 l looked up and hashed for each incoming TCP request. Just as
9 g4 G5 D1 w m with the equivalent ACL 'req_rdp_cookie()' function, the name1 P7 H' O5 \. Z. T9 q: N0 f
is not case-sensitive. This mechanism is useful as a degraded
8 \% K( y9 ]" J- C persistence mode, as it makes it possible to always send the7 [# w3 B7 ]+ D5 ~' M4 H( O
same user (or the same session ID) to the same server. If the0 p' l9 E$ R9 ^0 h1 ?
cookie is not found, the normal roundrobin algorithm is
! I; V% k/ Z) O) |5 G' Z+ `, @& d used instead.
! H; w5 i1 w( s# d" @1 j9 K" A+ e w- i6 t1 Z
Note that for this to work, the frontend must ensure that an
/ X. J1 [( K5 _ RDP cookie is already present in the request buffer. For this
+ k: F2 c. k% l& L* a. q you must use 'tcp-request content accept' rule combined with
7 o/ w9 e5 |- G a 'req_rdp_cookie_cnt' ACL.; S1 K# L B) F
+ d$ G1 M; I: P& Z3 W2 ]
This algorithm is static by default, which means that1 ?7 M* c4 w* Q# L
changing a server's weight on the fly will have no effect,& D4 ^" Q0 ]4 ~3 b
but this can be changed using "hash-type".& g0 |4 v' e4 ~3 k, k5 m8 K) Z6 L
. d, r3 z: b4 R6 g1 Q
<arguments> is an optional list of arguments which may be needed by some( r# \+ B5 T8 t, O5 L. [
algorithms. Right now, only "url_param" and "uri" support an1 x) [& p& a& x0 C6 |* W
optional argument. k- `9 B G, g" P
# f, B4 W! o, J1 s: O8 y. l( c' J
balance uri [len <len>] [depth <depth>]
/ z$ C) l! O/ @. e- [8 d# a balance url_param <param> [check_post [<max_wait>]]; [+ P* S) l4 K) F4 K
8 u0 O; D8 c& z+ p The load balancing algorithm of a backend is set to roundrobin when no other1 {& U! h8 X; @9 }. E' s' ]# U. t, T9 b
algorithm, mode nor option have been set. The algorithm may only be set once6 p+ G5 i/ A7 H: K! w8 Z
for each backend.2 f) ^$ u9 r8 Z/ j% \/ h
! f% h5 T+ X ~+ V0 @
Examples :
" y7 ~: R3 E) k$ B9 m balance roundrobin
N# [7 Y; E2 |& \+ k balance url_param userid
+ x( `7 q1 n3 ` balance url_param session_id check_post 644 u8 w7 [* m5 I" e, w
balance hdr(User-Agent)* L8 }( Y5 y4 B- }
balance hdr(host)
1 U" ~" V4 j( K3 } balance hdr(Host) use_domain_only
2 @( D; P8 w5 b+ J+ @5 p! g9 s: E2 f, D8 G/ R
Note: the following caveats and limitations on using the "check_post"
. k5 D( p& Y0 T9 p0 o extension with "url_param" must be considered :; Q: Z& ~2 x, s" x
8 ~8 y) U6 V5 U - all POST requests are eligible for consideration, because there is no way
. u e s. a% j; T% Q6 Z: J. G to determine if the parameters will be found in the body or entity which
/ u0 a6 c, F" @. C may contain binary data. Therefore another method may be required to; @ g# O7 \3 z/ S
restrict consideration of POST requests that have no URL parameters in
( D0 V- Z: Z' N2 ~0 k0 m4 Q the body. (see acl reqideny http_end)
0 i' J. ]; C y( p, q0 @# R1 _! R' e% Y5 s
- using a <max_wait> value larger than the request buffer size does not$ i2 w1 U! u7 ^& Q6 K/ U* r4 u
make sense and is useless. The buffer size is set at build time, and5 Z, d7 q! i) [. J- A" d2 d
defaults to 16 kB. I J% b' l- u8 I
- T$ g! X; C; \$ P8 x
- Content-Encoding is not supported, the parameter search will probably
+ Q1 f) C- @, X# G) {$ @% B4 n fail; and load balancing will fall back to Round Robin.
$ R. ?) M6 t, F* _2 h5 p6 k- X0 E+ y3 ]: |
- Expect: 100-continue is not supported, load balancing will fall back to' F5 C' k- R6 K8 G2 C
Round Robin.& m0 {. b7 U4 a5 r" ?. g' U
- O/ B, q1 r8 l/ n& a) w - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.
' w" s* J: q$ n( \, W. a5 e If the entire parameter value is not present in the first chunk, the* X( `1 Z8 p1 `, `* t% o7 Z
selection of server is undefined (actually, defined by how little) v% S* j2 _# h% X( U
actually appeared in the first chunk).* R& j7 V! U4 k1 q8 L0 i+ Q9 Z0 E" p
$ w' @! w1 {7 U2 K$ J7 f% j4 f& H
- This feature does not support generation of a 100, 411 or 501 response. z4 m7 K6 D, [2 V! Q! D9 S
# ?& Q; V% c5 A# ]8 M: a
- In some cases, requesting "check_post" MAY attempt to scan the entire, T, e8 Q, ^; X. q5 L; T
contents of a message body. Scanning normally terminates when linear4 y7 r! ^! }' @
white space or control characters are found, indicating the end of what
6 C. r* {4 _5 z, S; {' S might be a URL parameter list. This is probably not a concern with SGML2 |* d! _, T. \4 `0 w/ x" q
type message bodies.5 @, V" H8 L$ S& d
* \0 w6 `! N' T4 `1 h
See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and
- Q* J4 v( r. }" f; V) S# B& t "http_proxy".
6 j# M' ]5 }( b1 _
9 x& _" z8 A# m* D/ ?" p9 I0 P
( W3 L: v: m4 m1 B* vbind [<address>]:<port_range> [, ...]
2 s9 d- W4 d1 fbind [<address>]:<port_range> [, ...] interface <interface>' j0 a* K3 a& h7 X
bind [<address>]:<port_range> [, ...] mss <maxseg>$ m3 ~2 R) Y, v2 z! M* N" v
bind [<address>]:<port_range> [, ...] transparent O- `2 [/ D& w) U0 P W
bind [<address>]:<port_range> [, ...] id <id>( s" I3 m8 {# M# i
bind [<address>]:<port_range> [, ...] name <name>" B# ]" G# t E2 H. X$ [! p
bind [<address>]:<port_range> [, ...] defer-accept4 t4 t1 F' O) U ]6 X+ Z+ w5 s* X; v% F
Define one or several listening addresses and/or ports in a frontend.2 a4 n4 a! Z- t
May be used in sections : defaults | frontend | listen | backend2 N |: M$ P+ d s/ Q7 C1 Z
no | yes | yes | no
" s3 s& g, \8 t" D4 s Arguments :3 S" Y' l A2 s
<address> is optional and can be a host name, an IPv4 address, an IPv6
, w2 @' [3 Z f- N& U/ E* } address, or '*'. It designates the address the frontend will2 y1 ]5 p M: i, b. h8 Z
listen on. If unset, all IPv4 addresses of the system will be8 h5 L0 O/ n( H* y) M, S; F1 Q& \
listened on. The same will apply for '*' or the system's z: k! }! a9 [5 X, o! H
special address "0.0.0.0"., N7 e( e( F" ]/ b9 D8 M6 d
2 N: l1 a% F- S! C8 c; I
<port_range> is either a unique TCP port, or a port range for which the
* M( h1 {, f8 z( A5 n! H6 w# u4 H proxy will accept connections for the IP address specified
* N% O4 R* `9 ]1 L8 X8 v above. The port is mandatory. Note that in the case of an+ ]- t3 l( Y- C4 ~& Z
IPv6 address, the port is always the number after the last5 S. B! M$ {" H8 M0 w# O) {
colon (':'). A range can either be :/ \+ }' M% j. N- P2 j/ M1 b4 ~
- a numerical port (ex: '80')
% `! k: u) Q* y4 j; T& F4 u - a dash-delimited ports range explicitly stating the lower' _# K9 q2 g, J3 H6 m: Q/ w$ v6 H
and upper bounds (ex: '2000-2100') which are included in) B! m$ e$ @' O/ o& r
the range.
& Z* ^* n; u* o0 w9 Y* E Z7 u# q4 `* \
Particular care must be taken against port ranges, because ~* R9 L, i4 }$ G. B9 a4 `9 A
every <address:port> couple consumes one socket (= a file
+ r, u& l5 H/ T2 Y descriptor), so it's easy to consume lots of descriptors
- O9 V& y5 K( _9 I, P with a simple range, and to run out of sockets. Also, each
1 T y+ ]( _0 \( G3 D% e <address:port> couple must be used only once among all+ `! Y3 }( w, T8 S
instances running on a same system. Please note that binding
; @6 b6 G8 T6 M/ `& \& k1 h to ports lower than 1024 generally require particular- a6 |8 W3 ^9 m$ x' |5 Z
privileges to start the program, which are independant of
$ D; s( U+ z, [& Q. z; S the 'uid' parameter.
- `, I# b' d. ]4 e8 Z8 |/ A3 y! g. ]9 h6 F
<interface> is an optional physical interface name. This is currently) v% x2 w( N& ^' |( o5 ^
only supported on Linux. The interface must be a physical
6 O# z* A) v& J4 n; m* S5 |0 \ W8 L interface, not an aliased interface. When specified, all
5 ]6 j- d3 _6 y/ h. x& \ addresses on the same line will only be accepted if the
1 ?$ E q5 h, \! f( C- F' N incoming packet physically come through the designated2 c/ V; Q* _/ g4 i
interface. It is also possible to bind multiple frontends to
% w4 k V" B( z. J- Q7 \ the same address if they are bound to different interfaces.3 D5 `7 n7 w: Q; V& U. d
Note that binding to a physical interface requires root- r* W# }) b! J) {
privileges.
# Z; F9 @- w1 z$ S% I
9 O% `8 w |9 V& f/ X9 B j9 t3 D2 B1 P <maxseg> is an optional TCP Maximum Segment Size (MSS) value to be
$ \# w# I/ n& t6 h, h advertised on incoming connections. This can be used to force
* i I, z# H! P- u a lower MSS for certain specific ports, for instance for' A F4 F0 c7 ~: ~
connections passing through a VPN. Note that this relies on a
, A# L, S% I* [5 l- K5 p3 O kernel feature which is theorically supported under Linux but
# Y& P9 v$ U0 g- t was buggy in all versions prior to 2.6.28. It may or may not
- s3 l) x' d$ o work on other operating systems. The commonly advertised4 [; p" \* c1 H- S( o& V4 L
value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP)./ c' Y& |) l y; Y
; |# B. D. U1 C <id> is a persistent value for socket ID. Must be positive and/ w t2 D8 ~( |
unique in the proxy. An unused value will automatically be
6 I6 i& U/ v/ v* T2 A assigned if unset. Can only be used when defining only a
7 W7 ?& E" E" `6 P H single socket.
+ ^2 G- ?) H5 S3 P3 {, U2 I: Z& V6 g4 B4 G0 Z6 I* l$ [# d. F
<name> is an optional name provided for stats8 O# m1 x/ `+ x5 z
! ~2 `: b# |! ?9 e+ s E/ b transparent is an optional keyword which is supported only on certain% t6 y* R6 x% E1 v4 C: p. @& V! w
Linux kernels. It indicates that the addresses will be bound+ U7 |& v+ l& b9 x
even if they do not belong to the local machine. Any packet" U* V0 Y( K1 N" t' K
targeting any of these addresses will be caught just as if
% v3 ` ~8 h/ V+ ?) V' }$ o# u the address was locally configured. This normally requires6 R/ c6 U0 a/ x; g$ F1 F4 d
that IP forwarding is enabled. Caution! do not use this with
% ^9 b; X' V0 @# d. E0 ^/ I- v' n the default address '*', as it would redirect any traffic for
% J5 q9 p' E& M$ \ a# L the specified port. This keyword is available only when
9 L8 A: U% A6 Z4 K/ M2 I: W HAProxy is built with USE_LINUX_TPROXY=1.# U) t2 R$ T; ~- v: G( o( l
+ }9 a: \) z; Z8 ~8 ~) Q defer-accept is an optional keyword which is supported only on certain) q# j" Z9 C9 V: C2 e0 L
Linux kernels. It states that a connection will only be
1 K4 m/ t# R8 O4 k8 J/ R accepted once some data arrive on it, or at worst after the5 h" H* `1 F7 i( @. D3 B
first retransmit. This should be used only on protocols for% g2 e7 k' i, ^& p
which the client talks first (eg: HTTP). It can slightly9 S2 Z& l( G+ G! a( i
improve performance by ensuring that most of the request is7 H+ S1 F3 m! U8 A
already available when the connection is accepted. On the {; l( [# N9 T: o2 D# o
other hand, it will not be able to detect connections which
# T$ q H* D+ e don't talk. It is important to note that this option is
# q \0 F. P, e! i/ T" t broken in all kernels up to 2.6.31, as the connection is2 w' F& B7 z" P: m' |
never accepted until the client talks. This can cause issues. a* \0 b! w1 V2 y0 m
with front firewalls which would see an established5 s4 A9 I* k% Z: ]) B0 x$ ?3 A
connection while the proxy will only see it in SYN_RECV.
) O1 g1 S% u6 \& |8 b# x3 H3 I1 }5 H: A! u4 t& _
It is possible to specify a list of address:port combinations delimited by6 L+ R5 A$ K6 O4 g( Z* t0 n
commas. The frontend will then listen on all of these addresses. There is no; g; o) W s3 i. Y! h
fixed limit to the number of addresses and ports which can be listened on in
* D% ]1 v9 m Q) u+ ?$ `/ h a frontend, as well as there is no limit to the number of "bind" statements6 G: j b ^9 L5 W
in a frontend.9 n! L h+ F" y1 |6 S' Y2 z$ U
. B$ F2 n r/ L$ B/ I" C+ l Example :
! c1 p! K' \( n3 e8 a# C& @ listen http_proxy
- V1 R6 v1 ]6 } bind :80,:443
$ U- t0 D9 L% W9 C& }5 g1 r bind 10.0.0.1:10080,10.0.0.1:10443
5 e6 o, J2 T. g$ ~
3 d& v; G$ v) _: I. L" ~ See also : "source".
2 y+ Z' A8 m ^% G
7 j( n" b2 P7 Z. A# \4 U; \
+ q8 B$ B' t$ wbind-process [ all | odd | even | <number 1-32> ] ...
. `+ o4 D' \( k Limit visibility of an instance to a certain set of processes numbers.1 `. R1 L( O6 D
May be used in sections : defaults | frontend | listen | backend5 E: f3 f. I! Z- f
yes | yes | yes | yes3 |' Z7 |1 ^( m7 Y
Arguments :0 Y _7 h s" v0 N( ` Z
all All process will see this instance. This is the default. It9 W+ c" R. ]# p' c5 s
may be used to override a default value.
: Y: q9 a- M* {0 H5 ^2 m& x) t, K3 |$ c$ r+ P @
odd This instance will be enabled on processes 1,3,5,...31. This& y1 u/ F& b0 i1 Z* T; I
option may be combined with other numbers.
% C7 s2 \: T6 I# d) @ `3 M3 J
% i7 I9 q& O3 w/ m$ b/ u- c even This instance will be enabled on processes 2,4,6,...32. This
, k$ g# F3 l, u% E+ ] option may be combined with other numbers. Do not use it0 b5 g) U* ?5 A( O5 ]
with less than 2 processes otherwise some instances might be- t, v* N6 j3 F4 v4 a/ E# y2 ^* D
missing from all processes.
4 i# [+ J* h' U6 P: p# z
% C6 t* J0 p0 B3 y number The instance will be enabled on this process number, between
, C& `, T8 m: V0 f" y; P" e+ B 1 and 32. You must be careful not to reference a process/ C/ R+ u) B9 n+ A$ ]- [
number greater than the configured global.nbproc, otherwise- Z A5 X% D6 _1 c3 K* j4 E+ w* n
some instances might be missing from all processes.
6 X. w5 D+ k- g2 f8 k/ K+ u8 E" n9 v2 d3 l
This keyword limits binding of certain instances to certain processes. This
# e+ g8 [, g: N is useful in order not to have too many processes listening to the same% G' a3 X$ K, B
ports. For instance, on a dual-core machine, it might make sense to set
" J; T0 a1 i& K8 D; K 'nbproc 2' in the global section, then distributes the listeners among 'odd'" o2 d# g/ h1 Y+ I
and 'even' instances.
2 \: a& I9 \- k
# A! { I+ o: w1 G At the moment, it is not possible to reference more than 32 processes using' N( B( P& H+ E' \
this keyword, but this should be more than enough for most setups. Please
; X. S6 I6 s8 x& e note that 'all' really means all processes and is not limited to the first4 p/ n4 I. F- r) E
32.
2 s* y1 M. L" y' J7 u1 U7 h: j2 d/ i# P- q/ T5 t& s
If some backends are referenced by frontends bound to other processes, the
7 Y8 h }2 G7 a8 @" t) R( y backend automatically inherits the frontend's processes.
! B4 ?0 [9 g. C' \6 O% f
6 t' L0 c- j' L% m Example : C/ H9 |0 g2 d0 N/ m
listen app_ip1
9 D4 ^) E8 E3 `/ V+ Z bind 10.0.0.1:80
! Q6 d/ e5 h7 S, g bind-process odd* p" D$ d' c9 a: H. J) h, _" c& i
. Y# t" q) }# q2 l4 j
listen app_ip2% w. J J' z- n" [3 C( W$ g( {
bind 10.0.0.2:80 v$ E4 Q) s( M- s w4 c
bind-process even
( U! E0 Y; ]4 j5 T" }2 _
+ n+ T9 a3 c) S3 c8 T- ~7 h listen management
6 [8 p0 o3 `- N6 ~9 d* t6 t( n bind 10.0.0.3:80
, R8 }: t' z+ X0 W bind-process 1 2 3 4
0 O) _( b+ }; L, z
( B1 F1 @% n' }3 ^ See also : "nbproc" in global section.
- C2 n, Q/ l* {/ |9 G5 E# x* L9 G5 F7 a8 f; d* I) I7 a, a
- S' b( G& Q" B* h% Eblock { if | unless } <condition>
3 n+ }6 ]/ a2 g6 s7 D! I2 B7 d0 z Block a layer 7 request if/unless a condition is matched0 [! ]7 h& {9 e" l8 g
May be used in sections : defaults | frontend | listen | backend
7 f) Q+ `0 E, K$ H, d2 ^: B no | yes | yes | yes
M& p) V! O- t3 H5 O! _# L6 P% h9 y R+ T! @/ e" _, _
The HTTP request will be blocked very early in the layer 7 processing$ ]0 Z7 h; p D
if/unless <condition> is matched. A 403 error will be returned if the request
8 V9 p. g7 Z. K: n# q4 E3 m' ]4 _ is blocked. The condition has to reference ACLs (see section 7). This is
6 j. B' Q* L( f+ c2 L typically used to deny access to certain sensitive resources if some
" P; r2 N8 S9 O$ e conditions are met or not met. There is no fixed limit to the number of' R1 @/ U5 v1 |' j
"block" statements per instance.. U, m S% o5 M+ U# P# Z- r2 C$ @
) {1 g: e7 ?8 t, V
Example:9 p/ T' ?; |" C9 d/ ^# l4 i
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
. p- \8 w+ t$ |2 T% r a acl invalid_src src_port 0:1023
2 q; V1 N% [" R0 {- K) n3 s- } acl local_dst hdr(host) -i localhost
; Y9 f: B- u6 V- Q2 H2 [9 p3 r block if invalid_src || local_dst, G N/ G: c% L
& x2 J5 _6 V, X: @( o See section 7 about ACL usage.# d/ W% [+ }& z+ Q; N6 `7 x
3 Z7 ]* N: @% T3 ?
' a2 f+ L; N/ c ~5 B8 c. Icapture cookie <name> len <length>. I. S2 E6 X% B% M
Capture and log a cookie in the request and in the response.! _* Q7 P7 x# x8 a9 K
May be used in sections : defaults | frontend | listen | backend
) w9 x) ]. C- X! Y6 F' } no | yes | yes | no% q1 O7 \% w9 j) g) F% O
Arguments :
+ k6 D* ~' @# |+ z% ?! |$ U* r: J <name> is the beginning of the name of the cookie to capture. In order3 W- ?( g8 S8 K9 x! {
to match the exact name, simply suffix the name with an equal
, r+ k3 `0 L: R9 s( O4 p sign ('='). The full name will appear in the logs, which is% p. Y g6 u; G7 t H0 {; s
useful with application servers which adjust both the cookie name
6 s2 n. }" j8 Z o and value (eg: ASPSESSIONXXXXX).
) T9 A. ^; j. V) k, _' k6 W$ B. R/ f# K4 D! q- z5 `
<length> is the maximum number of characters to report in the logs, which
* c x3 r* o. O7 S; m include the cookie name, the equal sign and the value, all in the7 \, x3 x2 b/ d6 D* ^! a
standard "name=value" form. The string will be truncated on the4 |) B* X. X* [' M
right if it exceeds <length>.
# T) B, {$ \# z3 h& K2 }9 E5 a
! k' F- c# j2 g) U Only the first cookie is captured. Both the "cookie" request headers and the
- ]* K$ Y5 e! @7 R& o "set-cookie" response headers are monitored. This is particularly useful to S5 H0 D6 b: x% V7 \/ B% B
check for application bugs causing session crossing or stealing between
2 _' {7 Q2 M! q+ w' n users, because generally the user's cookies can only change on a login page.
% R% U9 j1 r( q! r1 v; x4 ]( b6 h. v- Y/ L8 j, @
When the cookie was not presented by the client, the associated log column
2 X" O( a% X J1 ^! M9 Y will report "-". When a request does not cause a cookie to be assigned by the
2 Q# ~2 O* D' T* O) | server, a "-" is reported in the response column.3 @5 ]4 y/ A6 }& P
9 l3 A, h$ C- F7 v6 T9 M6 \
The capture is performed in the frontend only because it is necessary that- y( {( k7 ^; g% F
the log format does not change for a given frontend depending on the
! V& d0 h/ M& S- f a6 J backends. This may change in the future. Note that there can be only one
; \6 |; ~+ U8 {# r6 L "capture cookie" statement in a frontend. The maximum capture length is: C/ t K# s5 j1 A5 R$ G
configured in the sources by default to 64 characters. It is not possible to
0 O2 O# j0 S' [! Y' l$ ? specify a capture in a "defaults" section.+ j' ?( ]% k0 \2 R% j4 G4 e- @0 p5 u
2 Q6 ]5 M+ h' u4 z" A3 c
Example:
$ l h# n, W7 e) ?5 N capture cookie ASPSESSION len 32) S0 a3 ]; I$ o
0 d( s& Y2 c9 N" p5 a See also : "capture request header", "capture response header" as well as) `0 W- _7 L; i9 y5 O9 c
section 8 about logging.( B) F, p0 d& {* l) D) y
( W2 P6 }5 Q8 G% {
1 D! a5 X2 r( f, y. o# S3 V, F* Y
capture request header <name> len <length>
$ K& U- N+ r( s2 X7 [7 x6 a* n# c Capture and log the first occurrence of the specified request header.' g7 K b/ R# z/ o" r/ ~4 Q
May be used in sections : defaults | frontend | listen | backend5 { o: N0 G) V" X9 ]! c
no | yes | yes | no
- Z. { d( b5 w& s Arguments :6 o. X& V m& i1 o) m
<name> is the name of the header to capture. The header names are not
' V" o3 W7 [6 i% k# _* k/ v case-sensitive, but it is a common practice to write them as they
6 N, `9 r Y" R3 n appear in the requests, with the first letter of each word in! A/ h# v& q9 k. a6 M1 h$ F
upper case. The header name will not appear in the logs, only the1 d% x7 _4 K$ y" g7 ?
value is reported, but the position in the logs is respected.
6 j/ p; h2 `* z
% r( l$ U9 x+ K1 D% s, V+ S3 _- U <length> is the maximum number of characters to extract from the value and
& j* y) q# p' A3 @, l6 s! w9 | report in the logs. The string will be truncated on the right if
; w* b, R& E+ q2 T6 Q0 E it exceeds <length>.
0 l! I I3 l/ R- g' S* s: i8 v3 J L |- ]
Only the first value of the last occurrence of the header is captured. The
+ ^# t) V4 a0 G7 N, s value will be added to the logs between braces ('{}'). If multiple headers
/ j3 c# V) |" X are captured, they will be delimited by a vertical bar ('|') and will appear
% \% Y6 K9 r! \ in the same order they were declared in the configuration. Non-existent" y6 y$ }2 y( d! k7 l
headers will be logged just as an empty string. Common uses for request2 z+ K4 r& z8 H d
header captures include the "Host" field in virtual hosting environments, the3 d* G- f) W: ]" {
"Content-length" when uploads are supported, "User-agent" to quickly$ t/ I! h( F- l9 q
differentiate between real users and robots, and "X-Forwarded-For" in proxied! v; X, Y5 P# U: F, k
environments to find where the request came from.
/ [* e' \+ v5 h* j/ J( F! I3 d3 \4 J
0 p9 l9 }- G2 s! u7 w0 D6 M$ D2 o Note that when capturing headers such as "User-agent", some spaces may be
! U6 N L/ A& S0 w \5 P logged, making the log analysis more difficult. Thus be careful about what1 K% q* N# m6 }, O7 d2 o
you log if you know your log parser is not smart enough to rely on the
3 T8 u4 j5 g- c braces.: i# L9 ~+ N- [4 o6 M
( r* {$ q1 d, h" z, f8 Z8 g
There is no limit to the number of captured request headers, but each capture
7 S1 J$ H8 |+ s+ j( i/ S2 u5 w is limited to 64 characters. In order to keep log format consistent for a
6 u3 n; G- ^- k% N0 m4 D7 V same frontend, header captures can only be declared in a frontend. It is not8 L3 c& }8 _8 k! o2 c
possible to specify a capture in a "defaults" section.
e2 W$ _4 c: }0 }# g! i- B) ~/ ~( J; D& M8 l! i% b, H
Example:
" ]3 z, p8 g0 z% [5 l n* K% I1 M4 l. u capture request header Host len 15
+ h' F+ e% v% W! d( W, u ? capture request header X-Forwarded-For len 15! n4 _4 G- o' P0 A
capture request header Referer len 15
) T7 {, M1 V( A5 n* p5 {2 _
3 z* W- \8 i8 W9 `# V% X( n% k See also : "capture cookie", "capture response header" as well as section 8
: O7 ?% n; |5 N0 v9 B9 G: w1 P about logging.6 j3 _, ~ L, d1 U
7 T, o) s7 y; {
( G; L" j# E0 X! c- Dcapture response header <name> len <length>
1 m3 ]) g4 N4 i) j Capture and log the first occurrence of the specified response header.
& h* `5 F6 x' | May be used in sections : defaults | frontend | listen | backend
8 m7 k: D9 W8 U' M no | yes | yes | no
7 R# ~- K2 X& X/ b% a2 ^0 y Arguments :# U" y% |0 v, C
<name> is the name of the header to capture. The header names are not
: q+ I4 s% H. z case-sensitive, but it is a common practice to write them as they
6 P- `3 \+ b& M$ R appear in the response, with the first letter of each word in
; Z7 y3 K9 [2 r% I' L- e& t) t upper case. The header name will not appear in the logs, only the0 h8 R1 W$ R) C" A/ E+ _0 m
value is reported, but the position in the logs is respected.+ o* r) U! U- Z( @2 @
: O6 Z4 m" o0 u3 n <length> is the maximum number of characters to extract from the value and
5 t5 d+ Y; l; ]5 u7 Y7 n report in the logs. The string will be truncated on the right if
3 _# ]. Y6 J3 X& E) `# j it exceeds <length>.5 W( m6 m' Z: D7 m- u8 B
5 u3 Q2 ^ C! j. L J
Only the first value of the last occurrence of the header is captured. The
: Y) m$ x3 G) M# R4 @7 p" j1 W result will be added to the logs between braces ('{}') after the captured* Z% t6 ]& {5 \* J
request headers. If multiple headers are captured, they will be delimited by
0 j6 r: `& V F2 J3 Y5 R a vertical bar ('|') and will appear in the same order they were declared in+ `, S) ?1 k% m+ h9 h1 p. y
the configuration. Non-existent headers will be logged just as an empty
- ~; {2 p6 x/ q5 b+ O( @) ] string. Common uses for response header captures include the "Content-length"
( L5 b) d6 C7 D" B6 Q header which indicates how many bytes are expected to be returned, the
( j1 {% B3 j+ F t "Location" header to track redirections.2 t% \- i# M- L7 z; U' x
" q. p' L& i; y: E8 S. i/ Z/ Z
There is no limit to the number of captured response headers, but each7 A" O# |+ _2 M9 X" W# ? ]
capture is limited to 64 characters. In order to keep log format consistent- k2 }9 N- j, x2 G+ k, Z, }* f
for a same frontend, header captures can only be declared in a frontend. It+ `9 ^; V9 I8 ^2 R
is not possible to specify a capture in a "defaults" section.5 X( ^1 J; I9 H+ `7 c3 U8 j
Z7 ^' h: I2 Q0 N Example:2 x7 ~; V7 V( Y: g
capture response header Content-length len 9: [- W/ v; R9 x/ q
capture response header Location len 15
. h& y3 L( e, T: L2 V
8 v9 y" a$ C* V* F! j, t& _9 i See also : "capture cookie", "capture request header" as well as section 82 k6 t; @. \, G/ p: |
about logging.- E2 {* y4 r$ `. S
0 q: K, p, }" h8 S1 b$ d
$ s) B0 s6 f1 e' @# }0 P
clitimeout <timeout> (deprecated)
% G5 c7 E0 \. h5 }1 { Set the maximum inactivity time on the client side.: }9 A* v% x B4 H0 `
May be used in sections : defaults | frontend | listen | backend
' ^) K3 k5 z/ @. H yes | yes | yes | no2 O9 ]+ O% x3 }, v0 W z! L" R
Arguments :8 t. W$ z1 Z& O2 `7 I. Y5 ~. {1 R$ G
<timeout> is the timeout value is specified in milliseconds by default, but/ h! ]8 x+ J, l9 z* N
can be in any other unit if the number is suffixed by the unit,
$ Q' W7 W4 G; \& P- b; `, } as explained at the top of this document.6 \7 i' `! z7 o; c
( r1 ?+ Z' ~% F1 T8 r+ a
The inactivity timeout applies when the client is expected to acknowledge or
4 d! T; S: ]0 p) |; K* R: ^ send data. In HTTP mode, this timeout is particularly important to consider
6 u2 h# ^. ?- k. N5 A during the first phase, when the client sends the request, and during the
" @* z6 ~$ Z4 J. S4 m' p* f response while it is reading data sent by the server. The value is specified# i3 i4 b3 ?) T5 `
in milliseconds by default, but can be in any other unit if the number is
7 |/ ^ L( W3 k! R d1 o \ suffixed by the unit, as specified at the top of this document. In TCP mode
5 Y5 X j, g7 l5 a! |1 Q (and to a lesser extent, in HTTP mode), it is highly recommended that the0 Z1 q, D9 W! V* F% ^" C
client timeout remains equal to the server timeout in order to avoid complex
, X* E1 n$ U+ X situations to debug. It is a good practice to cover one or several TCP packet0 q+ a$ @2 c' i5 U' b
losses by specifying timeouts that are slightly above multiples of 3 seconds( U% u/ ], d- I5 l
(eg: 4 or 5 seconds).
* X' D7 G8 {# l, j' ~$ u# Z4 k; `' T: s, h, k& u- X2 r6 j
This parameter is specific to frontends, but can be specified once for all in
( q' J) M% }3 s' f; m4 H "defaults" sections. This is in fact one of the easiest solutions not to" T! R1 M( `6 J1 z
forget about it. An unspecified timeout results in an infinite timeout, which; s, h4 m6 d( ~5 m3 k
is not recommended. Such a usage is accepted and works but reports a warning
) Z( q; R8 j [ during startup because it may results in accumulation of expired sessions in {+ F5 p6 ~$ U7 d
the system if the system's timeouts are not configured either.6 E5 e& B" [; Q; X, G/ m
{+ ~! W0 Z' u- V This parameter is provided for compatibility but is currently deprecated.3 a9 [5 x1 f4 w( O$ b0 f
Please use "timeout client" instead.
, K) |0 h/ p% K6 H- ?0 C! d6 _2 n" B- n2 a- O
See also : "timeout client", "timeout http-request", "timeout server", and
' E; B3 g+ P; x$ d: s; u; N "srvtimeout".
4 e$ E% K! D1 p" x# V' Y9 q3 l' S/ _' E
5 ?. ]9 O; K7 Hcontimeout <timeout> (deprecated): B5 j8 x5 a- s
Set the maximum time to wait for a connection attempt to a server to succeed.
4 {1 l! t$ g; E" x3 }2 ?, G May be used in sections : defaults | frontend | listen | backend! A! k* K; x1 R! D+ Z% ?$ v/ g
yes | no | yes | yes
( p- x7 ?- J: g9 a3 s Arguments :9 ]5 u; C5 ^; t# [! L- X3 g+ q
<timeout> is the timeout value is specified in milliseconds by default, but
. l. L9 J/ v6 d0 Y* W1 Q can be in any other unit if the number is suffixed by the unit," F6 `- S8 u" G9 T h) Z: n
as explained at the top of this document.
( `; Z0 W5 x9 G. J2 h$ q6 a4 N* Z' R
If the server is located on the same LAN as haproxy, the connection should be. ` B3 O' u# _
immediate (less than a few milliseconds). Anyway, it is a good practice to
) M4 I; B8 u4 _3 `' Q X; h( d cover one or several TCP packet losses by specifying timeouts that are
^- ]% j# _8 p0 _- L slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the+ d' z$ d! _' \' M8 M/ ?$ H
connect timeout also presets the queue timeout to the same value if this one, ~* A8 W `9 K# Y2 ^
has not been specified. Historically, the contimeout was also used to set the
1 ~5 I# u. p) V6 x$ g. Q" L$ p) ^1 j tarpit timeout in a listen section, which is not possible in a pure frontend.
! e+ M8 b$ h3 |+ e3 Y; k! D3 k2 P1 P/ {+ ^1 q0 H
This parameter is specific to backends, but can be specified once for all in
! |9 f# @, z" |% W: q0 B; ` "defaults" sections. This is in fact one of the easiest solutions not to
& H% G; F' c. q; M- E w) R forget about it. An unspecified timeout results in an infinite timeout, which7 ?0 Z1 A' _+ M& `' H
is not recommended. Such a usage is accepted and works but reports a warning
J$ [, Q% h9 ?# t6 D/ ` during startup because it may results in accumulation of failed sessions in
; X# u0 r. r v+ @ the system if the system's timeouts are not configured either." V/ f" Y" q, s+ p$ P5 W& g) p
% s1 P& q( `0 c k* k- v$ u2 k This parameter is provided for backwards compatibility but is currently) F' ^: n5 G1 L9 {* u0 e/ |
deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit"1 P7 `) I1 k4 e+ B$ z$ W1 J1 J
instead.* y$ _( e7 o! R5 ^
* b5 L. u: S) x& q9 T
See also : "timeout connect", "timeout queue", "timeout tarpit",& w. C# L* y$ {2 X
"timeout server", "contimeout".* a8 \% o8 `# v- Y% I; g% a! d
. u Y% x* u0 i9 Z$ T( @
* d' n; e9 t0 {. q7 W9 f; b5 k& O; xcookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]$ \) h! V, l3 S
[ postonly ] [ preserve ] [ httponly ] [ secure ]0 R! Q( t: u4 ~- ~8 P# h
[ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
' o4 D7 Y1 ^2 `% G8 d# ^ Enable cookie-based persistence in a backend.+ H: ]# D* n* W- ^' [
May be used in sections : defaults | frontend | listen | backend4 U U, q( z1 o! N% S
yes | no | yes | yes" G, ^2 ?- ~: C. I
Arguments :
+ y2 H+ h2 |9 H; O <name> is the name of the cookie which will be monitored, modified or; {+ w) _# n" h- P5 x1 R
inserted in order to bring persistence. This cookie is sent to
7 U' M* P, ?! h5 H( X& ` the client via a "Set-Cookie" header in the response, and is) f( ^/ n! y1 M+ R
brought back by the client in a "Cookie" header in all requests.9 ]) n. g4 S% |) N
Special care should be taken to choose a name which does not1 N/ M, m7 I0 h1 L
conflict with any likely application cookie. Also, if the same
5 J* _: @# F0 \5 G, t) P8 O6 N backends are subject to be used by the same clients (eg:; W6 |4 j7 ?# b7 U' c
HTTP/HTTPS), care should be taken to use different cookie names( W* }* ?5 e/ m& n
between all backends if persistence between them is not desired.& G0 n8 C# _2 e; [5 R
* g: ^/ `; z* H2 i% r6 X" Z rewrite This keyword indicates that the cookie will be provided by the) Q7 W0 i d& e/ O2 y. t; U) ^
server and that haproxy will have to modify its value to set the1 e& Q2 S/ i) q1 h% M( M
server's identifier in it. This mode is handy when the management% f' H/ L' O. j/ S
of complex combinations of "Set-cookie" and "Cache-control"
8 R/ y# a" ~2 y headers is left to the application. The application can then, [8 o! h$ W" U5 m2 z/ `
decide whether or not it is appropriate to emit a persistence Q3 a& E. K& J9 h6 c
cookie. Since all responses should be monitored, this mode only
& S2 P0 x) G" J' x/ w) l3 |. {4 i works in HTTP close mode. Unless the application behaviour is
' ?6 r, i9 K5 A! D very complex and/or broken, it is advised not to start with this
/ \0 U1 @7 F& D3 F' _ mode for new deployments. This keyword is incompatible with
$ V$ C) M! D- u$ b+ R w "insert" and "prefix".
3 \: P. E+ S: e+ Y3 _+ ]
- c0 v- r: i! G3 r. l, C4 U insert This keyword indicates that the persistence cookie will have to
+ A* b) x6 s- [9 r/ @: G be inserted by haproxy in server responses if the client did not
8 {7 u3 {: n2 g& C: U y! V1 }5 \& o% k
already have a cookie that would have permitted it to access this/ }5 T; t( |$ u& l
server. When used without the "preserve" option, if the server
|, o5 o. y3 F* y7 j8 x& |1 y* ^6 z emits a cookie with the same name, it will be remove before
8 k, r. ]- B) T3 y8 n4 [5 S processing. For this reason, this mode can be used to upgrade9 ^! P7 A% p; v. x& D& U7 ^" v2 X
existing configurations running in the "rewrite" mode. The cookie
+ R; E' `( J' H* [! F will only be a session cookie and will not be stored on the
, P% p3 ]) x1 h* I6 n client's disk. By default, unless the "indirect" option is added,# v8 S0 h* U; j
the server will see the cookies emitted by the client. Due to
8 o6 k" g8 V) d7 T, o0 i2 r caching effects, it is generally wise to add the "nocache" or b8 o2 X& O& M$ L( k
"postonly" keywords (see below). The "insert" keyword is not& R+ V& k! W- W6 p& ]) N
compatible with "rewrite" and "prefix".. L" r9 Q0 b/ f4 V. p/ Z
1 s+ o+ J) I, q+ A B5 ^
prefix This keyword indicates that instead of relying on a dedicated
" j8 k8 L; B: b Q cookie for the persistence, an existing one will be completed.
3 R8 W& o& ]/ y% L: B) ~ This may be needed in some specific environments where the client
) y F; G) ~, A# b, j does not support more than one single cookie and the application' V" `+ a' p% d. [; Z( i% D
already needs it. In this case, whenever the server sets a cookie
! l. l1 K. _! J5 D$ E5 S% n( e named <name>, it will be prefixed with the server's identifier( i- g5 v+ Y0 y o" ^
and a delimiter. The prefix will be removed from all client9 V2 J/ @" n# k+ e5 V$ t- a
requests so that the server still finds the cookie it emitted.7 p, T, M( i4 i. t
Since all requests and responses are subject to being modified,( ?& }2 N# k. w* I/ W
this mode requires the HTTP close mode. The "prefix" keyword is7 Y2 G9 T; A2 [7 e. N) p
not compatible with "rewrite" and "insert"./ F, W: X: `2 v2 d! U* C
. q' S! e6 q/ s; B5 z indirect When this option is specified, no cookie will be emitted to a( U; w# c: d/ t0 ]2 t0 d, I: E$ r
client which already has a valid one for the server which has2 Q, R( y( D0 c2 v4 f6 ?0 J4 b
processed the request. If the server sets such a cookie itself,
! E9 s" `% ~* A it will be removed, unless the "preserve" option is also set. In
]! S) E! Q$ }9 O9 Y8 L "insert" mode, this will additionally remove cookies from the- l1 {8 N4 T h) P, a
requests transmitted to the server, making the persistence
) I u8 [! q3 M% q) T: i9 |9 D mechanism totally transparent from an application point of view.
$ I. z: S2 [) ]+ M4 x6 a
2 H! ]! J) [% w6 _1 E nocache This option is recommended in conjunction with the insert mode7 ~* b7 J) B1 Q7 p* P, x
when there is a cache between the client and HAProxy, as it k( D1 B1 M% O, D0 G7 W5 v
ensures that a cacheable response will be tagged non-cacheable if' X: E# [" ]& K& K$ t& L2 j0 D
a cookie needs to be inserted. This is important because if all/ p! E- I0 }9 f9 f7 `
persistence cookies are added on a cacheable home page for
) `: f, a# Z3 r& T5 ~ instance, then all customers will then fetch the page from an5 I' t, R0 y0 C2 d/ j
outer cache and will all share the same persistence cookie,
1 B" z8 d/ u R( s% O p6 v leading to one server receiving much more traffic than others.- U6 L1 ^; [5 B4 K
See also the "insert" and "postonly" options.2 f5 h0 X% o7 W' `2 D) ^% u& h
9 y' @* U0 ]% Z/ Z( [, F postonly This option ensures that cookie insertion will only be performed
8 B) h: v* A; W, t8 C on responses to POST requests. It is an alternative to the, ?" r5 {4 i6 \# N. }7 T
"nocache" option, because POST responses are not cacheable, so
, v6 F) Z+ j; v4 M% ? this ensures that the persistence cookie will never get cached.% w5 ]) H% w* j; \" ~ {, z
Since most sites do not need any sort of persistence before the
6 L, P) l/ [* r first POST which generally is a login request, this is a very6 a) P9 S; ?) Y% n% q
efficient method to optimize caching without risking to find a
, i- A. v- M9 k( E; F. i+ \ persistence cookie in the cache.
j6 K- a; o% W0 { See also the "insert" and "nocache" options.; V4 E8 m6 ?8 f
1 Y5 R& m+ C" J" m8 U preserve This option may only be used with "insert" and/or "indirect". It8 ?; e* D7 R' J3 b& v/ F8 l
allows the server to emit the persistence cookie itself. In this# S1 ]6 O3 Z4 Q N9 A* c, K# U }
case, if a cookie is found in the response, haproxy will leave it
4 K4 }: {4 `9 t. K v untouched. This is useful in order to end persistence after a
2 A5 [5 D- ]/ t4 X: {% I0 j logout request for instance. For this, the server just has to8 O; P8 K+ o9 _, @( |: _
emit a cookie with an invalid value (eg: empty) or with a date in$ j3 l9 ~* u* n/ j- z
the past. By combining this mechanism with the "disable-on-404"
0 i) a$ X/ D+ w$ ]% |; d+ T& u check option, it is possible to perform a completely graceful- D: H5 M% p8 x, P" V5 O s
shutdown because users will definitely leave the server after
+ k [+ S" {" P+ l% k; Z$ M they logout.2 p3 ?9 y( c, u( H7 Y
/ Q: c3 c, p& s# m4 a$ A
httponly This option tells haproxy to add an "HttpOnly" cookie attribute
$ `6 @& o1 B9 L$ H when a cookie is inserted. This attribute is used so that a
- u$ w# |7 f( Z, n" L" y user agent doesn't share the cookie with non-HTTP components.
1 e" D' Q; q" \8 U& D$ S# ]! @ Please check RFC6265 for more information on this attribute.! u2 z; s* {+ z J& S/ b3 D3 b) x
. @: x# f* Q' ?$ U" ] secure This option tells haproxy to add a "Secure" cookie attribute when
$ g" V9 W7 D/ \. i( T h; `" Q: U a cookie is inserted. This attribute is used so that a user agent
) U# s2 y, S& g7 g! I: I never emits this cookie over non-secure channels, which means
3 v* u$ s0 \6 J" J7 ?3 D2 d" M that a cookie learned with this flag will be presented only over
: e3 X* O6 {3 q: V- p" d& q4 h: \' p SSL/TLS connections. Please check RFC6265 for more information on
) }3 X6 J0 |4 g9 H2 z this attribute." j9 y' f7 i/ I. t
7 ?( J6 ~$ f; @/ i! S) W! a O6 M
domain This option allows to specify the domain at which a cookie is
# n% A$ F% x! l2 I9 r0 y inserted. It requires exactly one parameter: a valid domain
3 K1 X! T4 X: a name. If the domain begins with a dot, the browser is allowed to
- Q! u; }/ `# O3 p2 M6 T ~ use it for any host ending with that name. It is also possible to( b4 F" Y/ y! k
specify several domain names by invoking this option multiple7 R! {$ @# K, }* r
times. Some browsers might have small limits on the number of
* Y. f4 \, |" ?, W8 D domains, so be careful when doing that. For the record, sending
; P# T6 O9 ?6 W 10 domains to MSIE 6 or Firefox 2 works as expected.
' x T+ O- K% X9 X7 l6 g0 D3 v& R8 `5 U! ~4 d) v
maxidle This option allows inserted cookies to be ignored after some idle, b5 f" i' N8 Z
time. It only works with insert-mode cookies. When a cookie is V0 l& d8 i" K6 D* \% I' X/ e
sent to the client, the date this cookie was emitted is sent too.& `: d. v& T9 S6 S, a
Upon further presentations of this cookie, if the date is older: i0 S# h- S# E
than the delay indicated by the parameter (in seconds), it will5 {2 F$ p% U* O5 i0 J/ n! ~
be ignored. Otherwise, it will be refreshed if needed when the
7 Z3 b% J* g, n \0 W. k7 B response is sent to the client. This is particularly useful to0 V" j5 _: Z* T
prevent users who never close their browsers from remaining for
( C$ k2 E! p( `8 h# ?/ K$ _7 Z too long on the same server (eg: after a farm size change). When
% N9 O8 l; O G this option is set and a cookie has no date, it is always1 g$ @; ^0 }0 E8 G2 I: T7 m( R& ?3 I3 [
accepted, but gets refreshed in the response. This maintains the( c2 U) ~" h+ j1 h% ]
ability for admins to access their sites. Cookies that have a
" k; M( n! s- P( s0 Z1 w date in the future further than 24 hours are ignored. Doing so
7 u6 {$ \3 b- o lets admins fix timezone issues without risking kicking users off
4 d& B- X7 n! C! e the site.
0 k |7 S& J1 a$ h( P d( }
( R- o! K- h. [( f5 h' W. T' p' F/ w& z maxlife This option allows inserted cookies to be ignored after some life6 J/ H# }5 ^7 _9 ] _0 B
time, whether they're in use or not. It only works with insert# t; O/ w( p8 N* W# ~' ~4 f
mode cookies. When a cookie is first sent to the client, the date
n- c. V; O8 k this cookie was emitted is sent too. Upon further presentations' Z0 N7 U3 A* R
of this cookie, if the date is older than the delay indicated by
" A' Y4 D! K2 T- L4 [) `7 ` the parameter (in seconds), it will be ignored. If the cookie in* |6 ~, ^, [7 u! P s0 H7 _
the request has no date, it is accepted and a date will be set.
1 `; O& I/ A. E) J8 \ Cookies that have a date in the future further than 24 hours are
& P0 ~! c# g9 N/ b1 v6 }4 ]& Q ignored. Doing so lets admins fix timezone issues without risking, q3 s& H' I$ f8 l2 R, K. q3 x6 J$ z
kicking users off the site. Contrary to maxidle, this value is( i9 G* j3 Y( U6 N3 q& p" a5 q* N; X
not refreshed, only the first visit date counts. Both maxidle and
1 k2 K% o* [6 } maxlife may be used at the time. This is particularly useful to' Y2 c# ^* B) e$ k; T
prevent users who never close their browsers from remaining for, h: e. h* j" e' m5 K2 u% S
too long on the same server (eg: after a farm size change). This
* _# v7 N# \; X; C. M- D) t/ T+ z$ w is stronger than the maxidle method in that it forces a- K4 z3 R8 @5 S+ x
redispatch after some absolute delay.
4 D! s5 H: D1 C" U. V. c7 a( X8 x: E3 p& T5 w
There can be only one persistence cookie per HTTP backend, and it can be
2 b4 z) r- h' \( _7 ^3 Z# I4 V declared in a defaults section. The value of the cookie will be the value' j. g5 e8 i$ A) C/ I1 T
indicated after the "cookie" keyword in a "server" statement. If no cookie
* j; y5 y$ |. a9 b2 R# W is declared for a given server, the cookie is not set.
! }) C* @- }9 @3 ?/ B/ W1 N
3 j0 e8 @9 A( ?( R* A Examples :3 v, D8 m7 U# c. c, v
cookie JSESSIONID prefix
# p# ~/ e* ^# h3 E% J/ B" I! G cookie SRV insert indirect nocache
7 G" g% w" H! i cookie SRV insert postonly indirect
: c9 V& Q& M0 f cookie SRV insert indirect nocache maxidle 30m maxlife 8h# `5 T" @1 t$ a
1 h$ a1 U' T! {* z1 w3 k' i' k- J See also : "appsession", "balance source", "capture cookie", "server"
1 O5 O) Y' _! V$ Q and "ignore-persist".
{$ g1 \: ]# J$ E1 ^. D
0 o! k" P; W! G1 x4 b: U& B9 g# T% W3 a3 p7 N
default-server [param*]$ V: \ Z O3 z: P
Change default options for a server in a backend
2 A) q0 }; Z E) i May be used in sections : defaults | frontend | listen | backend$ H* ~/ T+ i/ @* @( k: p' ]" y
yes | no | yes | yes
' }9 S, V5 m+ o Arguments:
$ f: \% d* V5 e0 [* d <param*> is a list of parameters for this server. The "default-server"
8 A/ H1 k0 Z4 n. L keyword accepts an important number of options and has a complete9 n6 l2 f$ C4 h0 U/ X1 m3 K
section dedicated to it. Please refer to section 5 for more+ Z; ^; D" g$ }9 O; r* ]+ [$ U( S
details.
* g6 ^" E& ]# ]* q A) S- o
+ K) A) y! u) p" `) k Example :
% { C) j7 d/ l( e G2 P l default-server inter 1000 weight 13) b" L/ L0 |) R( y: u$ U. V5 h
7 m5 X+ }0 T3 K% i; t- {6 m
See also: "server" and section 5 about server options2 }4 I. W* k) z. `. } f3 d
" p4 B$ _, W* c7 {" W; x2 Y# j3 j9 D d% Q; ]1 d! d8 h
default_backend <backend>
. O2 Q' u0 e1 t: z/ Q Specify the backend to use when no "use_backend" rule has been matched.
" W; @* {! t* t3 t; q6 K May be used in sections : defaults | frontend | listen | backend& ]3 J' d8 P( J9 J, J/ A# T4 v
yes | yes | yes | no, d5 J A3 t5 c2 }- E2 i; Q$ O! e0 X
Arguments :
$ n6 {% _* m+ o <backend> is the name of the backend to use.
, [, O$ e, s5 B {! d$ [( @8 a0 d' f7 l. }/ N
When doing content-switching between frontend and backends using the
% [ m1 Q; T# d, \ "use_backend" keyword, it is often useful to indicate which backend will be
1 i! l$ j7 U8 q2 R used when no rule has matched. It generally is the dynamic backend which
, [2 m; Q6 H% }+ ?( P will catch all undetermined requests.$ ]+ T f! `# a$ h# ]8 M% m
/ i/ c% x7 r/ X' t9 T* o" i. w Example :
8 _1 U( {. R5 ?) C! j- B4 F* s! c0 q8 p# R7 }! M' N8 y/ i
use_backend dynamic if url_dyn
9 F: W* o6 U: g* F2 e use_backend static if url_css url_img extension_img) ~% P8 W( t9 x" C: U
default_backend dynamic! `3 Z0 Z$ t& ?! ?/ D
5 t+ D% V& g, z See also : "use_backend", "reqsetbe", "reqisetbe"$ y! |0 p* X e3 R; t* `
/ z' |2 e/ T6 ~ x! j" B3 Y3 H
* a' Q5 p% e. ]8 w9 }disabled$ e7 Q" U( l+ Q7 g7 L
Disable a proxy, frontend or backend., \8 D! q# m# L1 \4 o
May be used in sections : defaults | frontend | listen | backend$ k, I+ G! N% d* _; G1 l& p3 `: O
yes | yes | yes | yes$ {/ [6 Q9 T F0 d$ m
Arguments :6 k4 n. ~1 N. A/ ^% |+ g
9 z0 i- t+ z0 g4 I+ r4 |( r& G The "disabled" keyword is used to disable an instance, mainly in order to" b; X; _$ ]) ]2 q
liberate a listening port or to temporarily disable a service. The instance0 K# Z, [6 e1 H" l8 f* O
will still be created and its configuration will be checked, but it will be% C' n* f# z2 G
created in the "stopped" state and will appear as such in the statistics. It
X0 c9 ]7 E1 F! i will not receive any traffic nor will it send any health-checks or logs. It5 h7 s _, B( @( [1 W
is possible to disable many instances at once by adding the "disabled"; H ^: p; J7 V5 d5 h
keyword in a "defaults" section.- R: Z3 G! ]: f
1 E) j4 r/ f( W% T( v2 k7 g
See also : "enabled"
- D' w0 q* L2 `2 s2 }% s8 j. [. L W9 I4 r
8 P6 [/ F( C9 P Q
dispatch <address>:<port>* q$ Y7 Q" B/ j7 f3 b) I2 x
Set a default server address( T$ ~+ s( c5 p7 y1 a, M% n( [
May be used in sections : defaults | frontend | listen | backend
6 y. S+ l+ W" Q- o/ ^2 R no | no | yes | yes8 N1 `' u0 `) {/ c
Arguments : none
. _7 Z: `, y" v- o2 J# x8 G' h7 l& m1 X+ |1 @
<address> is the IPv4 address of the default server. Alternatively, a
3 p% o m: m8 Q resolvable hostname is supported, but this name will be resolved
' h6 Y! _) u6 E7 w2 R during start-up.3 \- @- f# K& {9 c. r u
4 O/ T/ ?' v" r! w7 M <ports> is a mandatory port specification. All connections will be sent2 k* d3 R) _. R- s3 L$ I/ u
to this port, and it is not permitted to use port offsets as is* z. N$ p0 [& F! Q9 b3 E( t( t
possible with normal servers./ A/ t! n: d3 a3 s# A' B: z
4 i* C. f: B1 P' l8 o" z
The "dispatch" keyword designates a default server for use when no other
! g! _% B! o5 T2 b2 U1 O% P- Y. R% l server can take the connection. In the past it was used to forward non
; k! v$ F) d) l6 j! ^" p+ G4 H9 ] persistent connections to an auxiliary load balancer. Due to its simple: Q. \) @3 h, o# e: H, m
syntax, it has also been used for simple TCP relays. It is recommended not to
2 {" \1 }' N L, F use it for more clarity, and to use the "server" directive instead.: \, Q5 t& X6 D6 j" \2 q
0 k" J% ]+ s- I
See also : "server"
/ }0 Q$ v0 j) [% P/ x' V+ E0 d1 m Q" R% \& J$ @
, O% N* u T% C. p# e) D! ~. e
enabled
8 q6 ~ D( y& ^1 @( ]0 [ Enable a proxy, frontend or backend.
P2 N; R5 X+ n; g May be used in sections : defaults | frontend | listen | backend) o7 p& a, i6 k8 s' m5 M# [
yes | yes | yes | yes% E0 X# F! I |7 k! |* P
Arguments : none
- Z( |) k7 r" C: `* M$ A: ^
6 X" A0 v$ h. n The "enabled" keyword is used to explicitly enable an instance, when the
( _# b7 a5 V' d6 P4 [ defaults has been set to "disabled". This is very rarely used./ O t9 \! v$ [* W0 o6 d# C
& E. {' h+ X0 `! J3 H& O See also : "disabled"
/ ?& q2 F/ |, a0 S$ |
* A8 Z4 Q9 t4 {( Q9 G% B" ]6 a( d- N8 A1 T
errorfile <code> <file>
$ t4 r* B& X, i2 T* c2 }, X H0 X Return a file contents instead of errors generated by HAProxy
2 T: |8 M$ e8 l: b, G3 e May be used in sections : defaults | frontend | listen | backend
( u2 B* t- D! k& E v& n9 k% ^ yes | yes | yes | yes
; k9 ~" s3 C& }( X, [8 T) r Arguments :% t( |( c% z& j( c" j
<code> is the HTTP status code. Currently, HAProxy is capable of. v# {- M/ X) ?
generating codes 200, 400, 403, 408, 500, 502, 503, and 504.
5 O& A) ~' a/ Y( }: ]* i* a: [, K" H
<file> designates a file containing the full HTTP response. It is
7 e }5 H3 _6 L% J3 V recommended to follow the common practice of appending ".http" to: I9 z U+ g9 v" n! @" o
the filename so that people do not confuse the response with HTML
0 N% o- P. I, u+ w* I error pages, and to use absolute paths, since files are read
+ V5 a8 Z6 U9 p. G before any chroot is performed.
! ]+ \) U. ^6 n+ L
3 S0 N% A+ `6 u; V9 U3 Z3 A* s It is important to understand that this keyword is not meant to rewrite
" r# k* e( _* P; y errors returned by the server, but errors detected and returned by HAProxy.
; }1 {) K) y6 e2 n8 l" s ?' W This is why the list of supported errors is limited to a small set." V( E* S0 F+ J
2 l; ?, S J7 ~ Code 200 is emitted in response to requests matching a "monitor-uri" rule.
# h( V9 m) \/ Q) J3 T& E" i p" I; @; t' I
The files are returned verbatim on the TCP socket. This allows any trick such
4 r- W) V. K: z$ _ as redirections to another URL or site, as well as tricks to clean cookies,
6 C7 p \& h: G% @( _' A7 D8 i force enable or disable caching, etc... The package provides default error" a' G/ G+ c1 P1 Q# p: H
files returning the same contents as default errors.# D) ~1 w& }$ |/ y% u/ K+ k ~
/ ~. i4 F3 r- `' n The files should not exceed the configured buffer size (BUFSIZE), which8 ~, B/ }2 F+ @9 M" z
generally is 8 or 16 kB, otherwise they will be truncated. It is also wise
* ]+ J& C& w n8 A not to put any reference to local contents (eg: images) in order to avoid* {; t& C7 _! o, H% f0 h
loops between the client and HAProxy when all servers are down, causing an
: X- Q, I+ V) W, _ error to be returned instead of an image. For better HTTP compliance, it is
9 M1 a, r- P; ? recommended that all header lines end with CR-LF and not LF alone.
, m) x" [" H; b8 h% @1 S7 Q' Q" m" v" G, C" k. l; O
The files are read at the same time as the configuration and kept in memory.
6 X6 J- R# a5 g: v9 V4 W: ] For this reason, the errors continue to be returned even when the process is# W# T) ^& S4 B3 _5 ~) g
chrooted, and no file change is considered while the process is running. A! k+ L; |7 F3 v* R8 J
simple method for developing those files consists in associating them to the
1 F+ N" X: r/ n 403 status code and interrogating a blocked URL.
" w0 ^9 V: z* @6 L* `0 ~9 B
. i7 z- r0 H. x1 i2 d) a7 j See also : "errorloc", "errorloc302", "errorloc303"0 U( H6 g- k2 |8 {9 [. v
; s: t4 n1 @' y# ~5 V* {( q Example :6 E" n3 ?1 _+ p- a
errorfile 400 /etc/haproxy/errorfiles/400badreq.http! M9 D0 o* X( ?, }- B( N
errorfile 403 /etc/haproxy/errorfiles/403forbid.http+ Y0 ^, n! Q% a7 h2 N: G% d7 L9 g
errorfile 503 /etc/haproxy/errorfiles/503sorry.http% E( T- V$ \& S" |, ]
2 C$ O6 `8 S/ S# r2 e+ a8 a! T3 T: [2 V; _
errorloc <code> <url>
' w, t( B- g7 T2 x! m3 lerrorloc302 <code> <url>
# s1 q2 ^' o& {3 m; o. i Return an HTTP redirection to a URL instead of errors generated by HAProxy
- I1 u4 J6 x/ z1 d2 r2 V May be used in sections : defaults | frontend | listen | backend1 Z- V- R6 O/ ?" G
yes | yes | yes | yes9 i9 M( B# p$ B
Arguments :
. g o) ^2 C; N6 z! n2 u- A" \3 M4 J1 d <code> is the HTTP status code. Currently, HAProxy is capable of: O( \6 `/ H' H; Q
generating codes 200, 400, 403, 408, 500, 502, 503, and 504.' u( F4 t9 w- o* a
2 ?3 U7 q2 |8 E7 O0 H1 `* o2 r
<url> it is the exact contents of the "Location" header. It may contain
% N( o* h5 D) a% L7 O either a relative URI to an error page hosted on the same site,
, o" a4 U+ n, e) G) G or an absolute URI designating an error page on another site.) {9 L( Z e+ Y4 m
Special care should be given to relative URIs to avoid redirect j c5 Y9 |- t
loops if the URI itself may generate the same error (eg: 500).* k5 d& a2 o% z! t
7 C% ]0 x# m6 P# _! N! n
It is important to understand that this keyword is not meant to rewrite
& g3 o- |8 W; [; b# j1 j5 [& H( R* j errors returned by the server, but errors detected and returned by HAProxy.
1 k, Q" k/ f* ]7 A- V! f7 L This is why the list of supported errors is limited to a small set.# y# u& S- p! r/ z
" a" d( F2 i, B( \9 l+ x Code 200 is emitted in response to requests matching a "monitor-uri" rule.5 k: k& `7 @+ @ j; U9 t
$ I" a+ x6 L+ M& b: e6 o; [! e3 n. x
Note that both keyword return the HTTP 302 status code, which tells the3 ^: n/ I. \0 X, H' K2 s
client to fetch the designated URL using the same HTTP method. This can be
. F2 g( I" ?7 `8 R/ N quite problematic in case of non-GET methods such as POST, because the URL
- W8 P. p3 e+ Z! z% N sent to the client might not be allowed for something other than GET. To
f0 m$ X3 d! H& h8 p# D/ B& f) L+ a workaround this problem, please use "errorloc303" which send the HTTP 303
7 P$ v' |' I; O) s! B status code, indicating to the client that the URL must be fetched with a GET b2 _8 K' g4 f! ~/ y) J: @3 W
request.
9 W; I; Y2 f! a% r" ] s3 P& y0 K. C9 A+ h, ]# I3 e
See also : "errorfile", "errorloc303"
& a$ U1 z+ ]* ?! I9 t6 h5 b$ F# ~- O7 h9 b: R
6 |2 i& T4 C( ?, x; o
errorloc303 <code> <url>
4 `6 R- d2 F9 `; ` Return an HTTP redirection to a URL instead of errors generated by HAProxy4 e \2 l+ ]& d% Z0 C! B! K& M# J
May be used in sections : defaults | frontend | listen | backend# { s& ~$ ]3 @! \9 R
yes | yes | yes | yes* _7 ]! x2 _6 k0 f/ l6 e
Arguments :
7 t4 K. x @$ P7 T& D4 [( ] <code> is the HTTP status code. Currently, HAProxy is capable of" [$ H* ?: H7 X% f1 B$ R; k
generating codes 400, 403, 408, 500, 502, 503, and 504.# s& y c) _9 g" F+ a
. ~. ]/ o( [( @- p ]( h
<url> it is the exact contents of the "Location" header. It may contain) v# l) _/ q! h, e
either a relative URI to an error page hosted on the same site,8 w9 j. \1 \9 Y" R3 d8 M
or an absolute URI designating an error page on another site.
) P4 h; g" l. B; s5 b* [& C Special care should be given to relative URIs to avoid redirect8 _- J. z7 {9 |1 m3 ^
loops if the URI itself may generate the same error (eg: 500).
2 d3 x) v' y$ T( U, Y+ z" c( ?8 V/ {: F8 i
It is important to understand that this keyword is not meant to rewrite
1 g! j6 \; n/ O errors returned by the server, but errors detected and returned by HAProxy.% s/ P' d' ^- t1 `" m5 j- k8 X1 `
This is why the list of supported errors is limited to a small set.
( S0 M' t& ~2 \2 `8 n" b5 q/ `4 V' F. M8 M4 x8 k0 Q; N) N- z8 I
Code 200 is emitted in response to requests matching a "monitor-uri" rule.1 k" l F1 V# \/ w+ y3 {9 p
1 t W) X- l' c) f' N4 R9 C Note that both keyword return the HTTP 303 status code, which tells the
5 o9 |+ \5 y. {2 Z client to fetch the designated URL using the same HTTP GET method. This- V( t$ y4 i% p1 K# n4 n
solves the usual problems associated with "errorloc" and the 302 code. It is
) r: ]5 I6 L) H Q3 J( [& i$ e0 s possible that some very old browsers designed before HTTP/1.1 do not support
6 m5 {5 R) f6 @8 Q- |. K it, but no such problem has been reported till now.
8 b3 m( }# K& k8 M5 }- S1 G
! p2 ]( k7 Q) m9 a5 e See also : "errorfile", "errorloc", "errorloc302"3 |6 D! `. |- a( J' o
- t3 L. C# E/ h5 i; P8 B/ [
: J( p* B7 O+ [5 @% ?force-persist { if | unless } <condition>
9 g) r; s' ~6 }& D2 h1 S Declare a condition to force persistence on down servers/ ]' L+ e9 i- V' K& o/ m
May be used in sections: defaults | frontend | listen | backend, u. s6 t$ ^7 ^5 ]% {2 c( ^
no | yes | yes | yes
6 i8 W x" H4 S: p0 n' e
$ M- v+ D; }! Q- b. h( w0 y By default, requests are not dispatched to down servers. It is possible to
; C x, {* `4 B force this using "option persist", but it is unconditional and redispatches
$ i- ?& `5 d- _9 F to a valid server if "option redispatch" is set. That leaves with very little, X5 E: C0 T+ Q5 y
possibilities to force some requests to reach a server which is artificially4 c7 W) }) P9 ]1 l9 e+ T1 Q
marked down for maintenance operations.
( U/ i2 y' m, ?9 Y* l1 @1 B3 W
9 \9 o+ h, ]/ Z$ I The "force-persist" statement allows one to declare various ACL-based
$ v O* N) R. M conditions which, when met, will cause a request to ignore the down status of( k* z7 U$ b! L. F/ {
a server and still try to connect to it. That makes it possible to start a
, ^3 [9 w( m+ |4 K6 z- h server, still replying an error to the health checks, and run a specially
: A5 k8 W, J6 c z- a4 M9 r8 h7 @ configured browser to test the service. Among the handy methods, one could
+ p0 V' U+ C b1 L0 D% e use a specific source IP address, or a specific cookie. The cookie also has. W* U4 G& m' m0 H0 y3 |; o6 V
the advantage that it can easily be added/removed on the browser from a test5 E, S3 N" I4 Y4 h2 q
page. Once the service is validated, it is then possible to open the service
0 K7 t* i" s( n/ P: @% i) F7 ` to the world by returning a valid response to health checks.
0 D9 q3 R' K; i; y* e6 z) U
! i, W' ]0 O. d& W: o5 w The forced persistence is enabled when an "if" condition is met, or unless an
& }, z- O$ n- f0 W* ]$ v( ]1 I "unless" condition is met. The final redispatch is always disabled when this- A, \8 |7 r" o: c7 |( [6 U: I
is used.
! i/ k7 \9 F* y
# X$ ^! c6 E l, F; a0 v See also : "option redispatch", "ignore-persist", "persist",
( g% V2 [- g9 P; H. N: y4 R and section 7 about ACL usage.+ V( j1 s9 L8 d% @: [2 H* E. x
. u& l+ H" `" X, u# B3 }. I0 o. h, u
fullconn <conns>& {/ p+ Y( w2 c' ?* B/ i5 E9 A: @. {
Specify at what backend load the servers will reach their maxconn
! J. E5 d1 U/ L) o+ w" |, M May be used in sections : defaults | frontend | listen | backend- I1 E$ `' Y5 p( |9 _
yes | no | yes | yes
) r1 g- \: @" c: r- W Arguments :) M" ], I+ G7 E, D( D+ ^
<conns> is the number of connections on the backend which will make the
6 M& e& W3 F h9 s- v; b$ w servers use the maximal number of connections.6 I$ S% L1 `5 c# l7 G
0 M- c, r# K$ R C. Y/ w! Q4 |
When a server has a "maxconn" parameter specified, it means that its number
( l( `8 f: _% Y0 B0 M: s of concurrent connections will never go higher. Additionally, if it has a7 [8 q- i9 g6 I0 I% V6 E, u
"minconn" parameter, it indicates a dynamic limit following the backend's
' x6 F+ E0 B& J7 G/ }4 |, I load. The server will then always accept at least <minconn> connections,
1 |! y" G: H' o2 q9 }9 `, K never more than <maxconn>, and the limit will be on the ramp between both1 H0 G k6 k& e9 v0 t) K+ T
values when the backend has less than <conns> concurrent connections. This3 p$ P! I; Y6 ^ H2 g7 [$ \2 Y
makes it possible to limit the load on the servers during normal loads, but: e P, O. z3 ^* V$ _; O+ j
push it further for important loads without overloading the servers during0 W2 w D6 C. L5 j/ n$ n
exceptional loads.
3 N6 ?+ p/ t% C2 Q' @: ^7 C) h1 l2 v$ {0 K/ \4 T. q
Example :
9 G+ ?! x# Z/ o # The servers will accept between 100 and 1000 concurrent connections each
( l) }+ {3 K8 W9 x # and the maximum of 1000 will be reached when the backend reaches 10000
" O) _6 o; A, s% w" d; P # connections.3 S) A9 \2 j3 q) p: b$ ]! E/ N: C
backend dynamic
) f6 U" }; v2 B" K4 p$ ` fullconn 100005 [$ P6 F* I( `2 |" n! w
server srv1 dyn1:80 minconn 100 maxconn 1000: Z2 J7 h0 i \" T, k- n
server srv2 dyn2:80 minconn 100 maxconn 1000
5 P' O1 ^, H( _# X* M8 W" N q0 M
See also : "maxconn", "server"
& |4 Z3 E, O& B% `# ~ F, A
$ ~& x: v% n7 }& Q' I' ]% V+ X+ H# p) g6 p& }( \
grace <time>
) S; E' e7 |. L G0 ~5 O: _; ^: P Maintain a proxy operational for some time after a soft stop
9 }/ V l/ G8 [8 y- W. A May be used in sections : defaults | frontend | listen | backend
! y" v! G+ B% b yes | yes | yes | yes
+ X, x8 Y; l9 g& B, A' H1 N( D+ _1 Q Arguments :9 G- A8 K" C0 @( G( a: X5 c* J
<time> is the time (by default in milliseconds) for which the instance1 v& _+ e5 t7 i" N- I
will remain operational with the frontend sockets still listening- K+ e9 @3 X% p4 `$ Q
when a soft-stop is received via the SIGUSR1 signal.
) c8 H* S7 J) B4 H
9 e/ w! j: u* x This may be used to ensure that the services disappear in a certain order.
8 ^, z. H: h! t9 M: y This was designed so that frontends which are dedicated to monitoring by an
: i' m# Y$ |! ^& ^5 H8 ?8 P8 M' b- [ external equipment fail immediately while other ones remain up for the time
, u6 h/ D7 E* D0 |# Z! y5 Q needed by the equipment to detect the failure.& `2 @0 G" p8 c) Y0 T
( L3 q8 H5 a' s
Note that currently, there is very little benefit in using this parameter,, f7 v/ m* s% i. e) S
and it may in fact complicate the soft-reconfiguration process more than/ a% O' L; _) z+ Z8 ]$ ?
simplify it.
. Y; K4 Q0 s& T5 X( e& L
9 K7 j5 b# \. ^+ K" w) z: u" ]7 \
& X6 o+ l9 }# H; t/ b/ k( bhash-type <method>
" H! g3 u4 Q$ O3 y Specify a method to use for mapping hashes to servers. K: L) Y- P I$ O1 @
May be used in sections : defaults | frontend | listen | backend
. X! `- E" r5 |7 [6 v yes | no | yes | yes- m& a( u& j: ]2 J
Arguments :, u( [2 p5 S% n# n8 r
map-based the hash table is a static array containing all alive servers.
4 E2 a8 |' ^; A9 }! P& a: E The hashes will be very smooth, will consider weights, but will
0 S, a) G- T1 P x) U" Z3 D* q be static in that weight changes while a server is up will be- j; L$ Z* s$ }/ I' e. J
ignored. This means that there will be no slow start. Also,6 E l; s' ?7 [1 ]0 Q, l% M8 u
since a server is selected by its position in the array, most! `4 ]1 O4 u e) C
mappings are changed when the server count changes. This means
; F/ j; w( V: v/ x {+ i* R that when a server goes up or down, or when a server is added
( `6 _8 `6 e' C1 m to a farm, most connections will be redistributed to different, c* }: ~' F- J+ e1 R3 Z1 i6 K r
servers. This can be inconvenient with caches for instance.
7 C8 c8 h( r8 U9 M+ z4 k7 O7 N [# Z1 `0 e; W" W& F. D9 p
consistent the hash table is a tree filled with many occurrences of each
, K. [% _& w$ o server. The hash key is looked up in the tree and the closest
; k6 C& w$ M& P2 B8 \1 ~5 J+ { server is chosen. This hash is dynamic, it supports changing
- n- t0 _' L) C+ R' h weights while the servers are up, so it is compatible with the
5 u6 S) ^, ?2 L1 X slow start feature. It has the advantage that when a server9 s7 W @# R6 t1 r; r
goes up or down, only its associations are moved. When a server
" w) H) Q. t7 A% \3 j is added to the farm, only a few part of the mappings are
% r+ t& B# D; ^ redistributed, making it an ideal algorithm for caches.3 C8 m9 o2 f; Y, B: \
However, due to its principle, the algorithm will never be very, }: _' Y% H/ O- {* a6 C% t
smooth and it may sometimes be necessary to adjust a server's: o0 p2 Y, z# P J* I ~: C
weight or its ID to get a more balanced distribution. In order9 A8 c/ @$ \3 R; Z
to get the same distribution on multiple load balancers, it is) s6 t; M' T$ r/ Y
important that all servers have the same IDs.( }' R) t5 H2 l
" T; _9 |% i$ |- d! M8 g& Z2 } The default hash type is "map-based" and is recommended for most usages.
; d6 n% I0 |' g. d8 A8 G" Y, b' @' A
See also : "balance", "server"- T: @. r& v) J2 p
8 L& O0 K3 J6 A/ N4 `
& p; \0 T. t2 d5 H6 Y3 hhttp-check disable-on-404
) u9 D7 X- O& k2 W1 B! H% q1 z Enable a maintenance mode upon HTTP/404 response to health-checks
/ r: M' H! g, ~/ j- | m' E/ t May be used in sections : defaults | frontend | listen | backend
+ X/ |1 r4 c, b- i7 y4 n$ Y yes | no | yes | yes; E% K% j4 w v6 i9 ^8 l: P- Y2 l* l8 f
Arguments : none
$ t# O* Y7 d$ Y0 O6 u& }
& o- y+ b8 C5 p+ j9 e When this option is set, a server which returns an HTTP code 404 will be& s; |' N }3 [& ?
excluded from further load-balancing, but will still receive persistent
2 u0 C: \# E3 ^( J6 r connections. This provides a very convenient method for Web administrators5 g/ b# o( m7 q2 q% S; Y! H
to perform a graceful shutdown of their servers. It is also important to note
; ~4 k# F6 |- K/ x ?% s* J that a server which is detected as failed while it was in this mode will not0 f5 Z3 [3 [3 L; k
generate an alert, just a notice. If the server responds 2xx or 3xx again, it( v7 k- |) T' i5 H
will immediately be reinserted into the farm. The status on the stats page7 \: v- e) _0 L* s3 M
reports "NOLB" for a server in this mode. It is important to note that this
4 j/ s7 j, T7 W option only works in conjunction with the "httpchk" option. If this option0 P' [; s! n5 f
is used with "http-check expect", then it has precedence over it so that 404
; y8 q4 s. Y4 I( w# L$ g, t responses will still be considered as soft-stop.
: {2 m; u8 y* F1 u ?$ u8 H: [* r7 V v' }5 r% ~# I; l& h
See also : "option httpchk", "http-check expect"
6 ?6 ?% }# w: z. o% Z a: ^
: H1 Q+ H! I# L8 K! \9 @' j
/ {7 |' Q# ?" h1 T; bhttp-check expect [!] <match> <pattern>
4 X% U, i, s6 p* v5 Z# G" [- U Make HTTP health checks consider reponse contents or specific status codes2 Z. A+ w0 W: S: j' O: `
May be used in sections : defaults | frontend | listen | backend- T8 f6 D' ]+ A# s9 A. p1 {
yes | no | yes | yes4 R4 T2 I c% A# f5 S- [+ e
Arguments :
5 }) @6 b4 ?, S9 J1 i <match> is a keyword indicating how to look for a specific pattern in the
' i7 _* `9 r; n6 }2 P3 ~# e response. The keyword may be one of "status", "rstatus",. {9 q& J$ A8 P7 z
"string", or "rstring". The keyword may be preceeded by an
7 q: T/ M: D" t$ y* a) I) J a9 u4 j exclamation mark ("!") to negate the match. Spaces are allowed( e+ l" Y2 T% e+ E' r( V c7 D+ l# Y
between the exclamation mark and the keyword. See below for more
W) F/ y% y; r9 O details on the supported keywords.
( k+ G$ A) i1 @1 ?- k% |7 f9 P4 U% D5 C _1 O
<pattern> is the pattern to look for. It may be a string or a regular
# [+ E) m1 ` x) R, C9 Y8 v expression. If the pattern contains spaces, they must be escaped1 ]# o" Z" Y; {' Z
with the usual backslash ('\').
- }5 U' A& {; G
' s K8 t: r6 `# Z By default, "option httpchk" considers that response statuses 2xx and 3xx* [1 M: ~) E9 x
are valid, and that others are invalid. When "http-check expect" is used,; I. A6 U3 W% C; }% _3 r
it defines what is considered valid or invalid. Only one "http-check"
9 ~ t( u) v# ]( i- L statement is supported in a backend. If a server fails to respond or times
6 N6 s/ m/ v. l7 _. ] out, the check obviously fails. The available matches are :
C- c0 g; y! a, r2 z; f! e
0 S) A) a3 f3 z; {4 H status <string> : test the exact string match for the HTTP status code. m" Q% j' k/ U, Q. e& B
A health check respose will be considered valid if the# C* R% Y; W0 U o- u
response's status code is exactly this string. If the8 e0 k# b* S+ {6 s
"status" keyword is prefixed with "!", then the response" q" f" }& I9 _2 M: y' X
will be considered invalid if the status code matches." m; M' v- j8 ~/ B% E7 c) h7 j3 j
5 F+ [5 I$ x% b/ H+ ~ rstatus <regex> : test a regular expression for the HTTP status code.
+ f/ \' d+ [, W A health check respose will be considered valid if the
7 u) [* N2 A' v7 ^% D- \ response's status code matches the expression. If the
/ e3 a7 q7 I' T8 T "rstatus" keyword is prefixed with "!", then the response
5 @. ]/ U* f$ ]3 r2 X! W6 N will be considered invalid if the status code matches.9 M& J- b- l6 w( i
This is mostly used to check for multiple codes.& C- u# l) h- k9 W' r S
" [9 U% g; H9 j" N0 b string <string> : test the exact string match in the HTTP response body.
4 a1 p6 c- U% ^$ h A health check respose will be considered valid if the
+ w/ P' K5 {; ^( O3 C response's body contains this exact string. If the" B1 w3 J# {" ~6 j
"string" keyword is prefixed with "!", then the response" L& T0 Y; G. C. F8 A( r
will be considered invalid if the body contains this! E8 b) G4 I. ~4 K% ~
string. This can be used to look for a mandatory word at
& t% z1 B7 e4 g4 ^+ M the end of a dynamic page, or to detect a failure when a
; m0 ]2 G0 }8 ?1 l specific error appears on the check page (eg: a stack' B) x6 q, l& q
trace).
" `6 i/ s, n ]& {: V' f( n2 t! T: t9 Y1 g; Z
rstring <regex> : test a regular expression on the HTTP response body.2 h5 h W% D% {3 G" Z" _
A health check respose will be considered valid if the
- L+ T( r% n, \5 o1 u' x3 e& _7 [ response's body matches this expression. If the "rstring"
2 p- i& `* ]7 \6 Y( P, ~" u keyword is prefixed with "!", then the response will be
2 l7 I7 L# R3 t- p; ^# O considered invalid if the body matches the expression./ F* a/ g8 ]2 F1 j) X! n6 s
This can be used to look for a mandatory word at the end+ X1 m U3 v1 j) {9 ?" s3 L
of a dynamic page, or to detect a failure when a specific* d4 g1 v* F& L0 n8 |
error appears on the check page (eg: a stack trace).6 Q/ b* F" g0 V% J/ P, [
$ C) V- P! c! k# q9 g
It is important to note that the responses will be limited to a certain size1 I8 P$ N1 q+ Z" y+ \* _6 x$ ~
defined by the global "tune.chksize" option, which defaults to 16384 bytes.
9 ?/ z5 j0 ^; Q2 v Thus, too large responses may not contain the mandatory pattern when using
8 P+ B' F8 P8 h9 w3 y6 }2 m "string" or "rstring". If a large response is absolutely required, it is
) P7 t/ I9 ]" ~ possible to change the default max size by setting the global variable.
6 j( M) w# m# I However, it is worth keeping in mind that parsing very large responses can# y X, a' a8 j4 _5 Y
waste some CPU cycles, especially when regular expressions are used, and that4 I! e) ~, q1 f$ H9 ~/ Y
it is always better to focus the checks on smaller resources.% [" L2 a: [& S7 l
9 P8 Q3 z4 F# Z1 _ Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it5 k3 g( y% r& \0 Y8 v8 [; |1 [
will automatically append a "Connection: close" header, meaning that this
' b, p2 ?" F! U9 \ header should not be present in the request provided by "option httpchk".5 O( ~4 Q) D& c0 I2 G
, H) m1 a; H+ J" N+ j& k1 v6 I Last, if "http-check expect" is combined with "http-check disable-on-404",
7 \' Y$ k x" G7 i then this last one has precedence when the server responds with 404.
N1 d2 c5 d8 f5 n. H& E0 |' Y
. e4 ]0 n1 l9 T4 z1 y O- P# C Examples :
( V3 Y2 U: z E; h" W # only accept status 200 as valid
% Z- w* M* W4 D5 u8 Q http-check expect status 200# m& x- t/ p7 {
% }& E5 q9 K }; V2 K+ M # consider SQL errors as errors# b* A3 \3 Z0 ?2 O0 M& x8 A
http-check expect ! string SQL\ Error+ s. R- s! y% E9 {
% E5 Q. K5 I; r0 C# G( g # consider status 5xx only as errors* C4 p4 I" S* g+ l6 H3 P$ Y
http-check expect ! rstatus ^5; L) ]( d' j9 J8 J
- o" ^9 N5 |2 |5 S# F* p5 I # check that we have a correct hexadecimal tag before /html. Q3 L. K1 {, |7 G- T, X
http-check expect rstring <!--tag:[0-9a-f]*</html>
: F# u9 Q0 k) Z1 E9 W( a- |, R$ C2 x9 D: w! U4 U+ W1 D% [6 m
See also : "option httpchk", "http-check disable-on-404"
$ k' G, r! u5 F8 b+ e
" t6 X t; b1 I2 p5 M* @% ?1 c# D% ~8 M5 d& @( y$ A8 W- O
http-check send-state
. r: f+ g/ `8 v' l5 L8 X+ N! a Enable emission of a state header with HTTP health checks
/ @5 M$ [) H0 @7 Z May be used in sections : defaults | frontend | listen | backend; Z6 E1 T' O0 Y' H) ~. \' B8 M5 `
yes | no | yes | yes0 S& Q( X, s6 H( O, ~
Arguments : none
5 b* m) K+ i: `- y0 r; W+ S5 K5 H* h8 h
When this option is set, haproxy will systematically send a special header7 c1 o* D) [8 Z0 h& y0 P
"X-Haproxy-Server-State" with a list of parameters indicating to each server% ?0 L. S8 ^& I- I
how they are seen by haproxy. This can be used for instance when a server is# b* l' M4 }) `
manipulated without access to haproxy and the operator needs to know whether
+ z1 |$ B! E& u7 g/ d' f" i2 p haproxy still sees it up or not, or if the server is the last one in a farm.
' w6 X r8 r6 a# h4 |# R5 D% Q' Z, S
The header is composed of fields delimited by semi-colons, the first of which
# J' L3 A5 [& \. I" i is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid
7 h4 \: w4 F# p# m% h( R checks on the total number before transition, just as appears in the stats
& N0 N7 @: M; o* j9 L; N interface. Next headers are in the form "<variable>=<value>", indicating in- d8 U" g0 L0 q7 G) D$ l7 {
no specific order some values available in the stats interface :) Q* A" R4 H& h
- a variable "name", containing the name of the backend followed by a slash
0 m0 x7 s, P& n& [ ("/") then the name of the server. This can be used when a server is
3 f# j4 a+ \0 J, }1 G3 N5 h checked in multiple backends.
; K: ]9 d# Q0 h( J" u5 H: j l% w& b7 M1 z; r+ R6 E
- a variable "node" containing the name of the haproxy node, as set in the; F. u$ L1 i+ v( e
global "node" variable, otherwise the system's hostname if unspecified.
5 v% `$ B$ u: d* C6 ?' {6 {( B" T, p; b2 T0 L6 v: p* B
- a variable "weight" indicating the weight of the server, a slash ("/")
" N$ F- y% X0 Y6 a and the total weight of the farm (just counting usable servers). This
& l& h/ ~+ t( v/ s( s helps to know if other servers are available to handle the load when this
9 M# c5 `8 t: G) n* A7 E one fails.. \: q; X" @7 P" t) Z1 A
; ~* S; ?1 p; a5 X
- a variable "scur" indicating the current number of concurrent connections3 A3 Z' }7 |, u: G/ `3 G9 l
on the server, followed by a slash ("/") then the total number of ]6 J- d- H5 q6 _6 |) i4 i6 Z
connections on all servers of the same backend.
8 E6 C9 J1 i M" x9 a; f5 b
# D- j# m2 A8 L" V1 M, K% I - a variable "qcur" indicating the current number of requests in the% _9 Q* y9 J/ `1 F4 u0 U
server's queue.
. `$ y7 ?7 k) b& L* I! W0 o
8 I1 L! t, [/ j# t1 l+ v Example of a header received by the application server :
& Q6 l- [6 H1 N1 j( ? >>> X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \9 x2 j7 f/ a( _* k# \( E y- s
scur=13/22; qcur=0
% m/ h/ b! ^7 Y3 V, Y) k1 N8 q3 t Z& m; Y' Z* ? I' r
See also : "option httpchk", "http-check disable-on-404"
% }6 U: y( R! @) S) q9 w
1 v4 K3 s% G: o- lhttp-request { allow | deny | auth [realm <realm>] }2 a7 h8 Y% ^2 e+ h% J! e4 n
[ { if | unless } <condition> ]/ ?. S; \# S5 v. k
Access control for Layer 7 requests
, N/ _' y. Y8 r. e& D" V3 Z" i+ H2 z
May be used in sections: defaults | frontend | listen | backend' s' \/ _, e8 P, G7 ]3 z6 ^- B
no | yes | yes | yes) t) f: F5 K9 G P6 D
1 p# @- B' L P9 v
These set of options allow to fine control access to a& t4 Q1 W( p: }. ^( |
frontend/listen/backend. Each option may be followed by if/unless and acl.
) o8 s+ f. ~! N% a First option with matched condition (or option without condition) is final.& T# D6 q( u1 v2 o8 N# ?
For "deny" a 403 error will be returned, for "allow" normal processing is {$ U" ?1 ~# H: H2 M0 S) Y
performed, for "auth" a 401/407 error code is returned so the client
~( E8 V+ [, f% A. O$ ~ should be asked to enter a username and password." q: l- G( h5 o/ A, I
% X0 a. m; m5 [7 e, f There is no fixed limit to the number of http-request statements per( I' p% n+ O% s, H0 O
instance.- j# j' p; y1 B4 I. F
/ f$ _. j2 B# h5 |- ?) w1 K
Example:
) i+ c7 o+ I# ]& v acl nagios src 192.168.129.3& `% q8 v( y0 H/ m% P. c& F
acl local_net src 192.168.0.0/16- @2 F: d8 Y; _3 `- i% ?0 O
acl auth_ok http_auth(L1)/ O. S: `1 [( x$ |, O5 b1 ^
; _$ J- l2 }0 S1 y4 k
http-request allow if nagios6 e0 Z. c d5 u. y" G2 |; |" C8 R
http-request allow if local_net auth_ok
, u1 M# Z( U" c9 |0 b! I7 P http-request auth realm Gimme if local_net auth_ok1 y- C9 H( o5 d2 ]* R, [4 H' O$ K+ D
http-request deny
" U3 q4 h% f) w% `+ A( |' @) m, R/ G# p Q% d+ u7 H' ^# |
Example:: {) {) v _. U( `2 M; X a5 g+ Z
acl auth_ok http_auth_group(L1) G11 i# m D9 u6 G) g
7 N! U$ Q7 M7 ] http-request auth unless auth_ok
2 \& W1 g8 F9 E, t h- q+ w3 M, z; Q6 c( |; n) {) W: M& K
See also : "stats http-request", section 3.4 about userlists and section 72 ]: }0 v* v' Y0 b* U* C
about ACL usage.
v4 m8 h* U5 J
( ?% q8 ?2 K. p/ fhttp-send-name-header [<header>]
% |( b- |5 ~) J7 P$ M1 |0 T Add the server name to a request. Use the header string given by <header>5 f, G. @" o, ?: O+ c) C3 h
( K5 T9 s/ C" v5 a7 \. w9 n
May be used in sections: defaults | frontend | listen | backend
; h+ g4 D$ s2 \4 b# f2 Z yes | no | yes | yes7 v" Z- k$ Y( d5 T3 \
/ ^2 H% B, f) H0 R( s
Arguments :
/ L$ ~/ T% i/ q' \ l1 g6 E4 S5 P: D1 T
<header> The header string to use to send the server name
$ j# K0 G$ t: m7 Z% V6 l
2 v% e- Y) m0 ]. [, m The "http-send-name-header" statement causes the name of the target p- I+ a9 A1 ]7 J2 y* y
server to be added to the headers of an HTTP request. The name
0 ?- X1 u! V8 S- t& |8 i) v is added with the header string proved.6 |0 P5 E' Q5 v; b! `# W. z
. ?/ r! w z% K, [! i# \6 K See also : "server"
# e; }7 b0 y: k( |+ ^% S) D; E9 i5 q7 M0 I& i o9 R$ r
id <value>
' \( a* V5 y9 y+ L: b Set a persistent ID to a proxy.
% R2 S+ Q; u$ ]8 O! J4 J+ B2 N8 Z May be used in sections : defaults | frontend | listen | backend1 h! c/ }: r7 N& |0 @( B
no | yes | yes | yes
0 t8 P1 Y& k% N% D Arguments : none
( }; [& {" N n, p& z4 {$ g( c8 h+ p
Set a persistent ID for the proxy. This ID must be unique and positive.
, a6 g/ {/ J3 h An unused ID will automatically be assigned if unset. The first assigned
' _' w/ q {7 h5 F; b9 E value will be 1. This ID is currently only returned in statistics.1 z) k Q- }) }
: S5 Q% |9 u: D* t9 T! o/ J9 W/ V1 A+ h7 c" i
ignore-persist { if | unless } <condition># z' a# [- \2 d7 ^% l
Declare a condition to ignore persistence9 Q. P2 z( }/ {* p- |* r
May be used in sections: defaults | frontend | listen | backend# |! f' b) V- C
no | yes | yes | yes
; o* W8 h& l) x; L5 ?5 O1 P; ~8 i) P9 j4 x
By default, when cookie persistence is enabled, every requests containing
& i8 I5 I" Q5 w4 ] o the cookie are unconditionally persistent (assuming the target server is up$ \" j4 A- `% u. n$ e/ q% h3 d
and running).4 E( M3 K7 v% a/ |; z0 Z
" K V" s- v5 r- r1 _, v a The "ignore-persist" statement allows one to declare various ACL-based
B2 K2 y- X: y+ y) f! k P conditions which, when met, will cause a request to ignore persistence.6 I- z, t( @) ^8 _$ f
This is sometimes useful to load balance requests for static files, which
5 r v( T, x& l+ L. u oftenly don't require persistence. This can also be used to fully disable5 L) j0 V' T0 h9 H( h0 }
persistence for a specific User-Agent (for example, some web crawler bots).
. G& S4 l* ~* w& A6 r6 x' }7 I& v+ \0 `+ d
Combined with "appsession", it can also help reduce HAProxy memory usage, as# t( H: b1 P( O# d' l
the appsession table won't grow if persistence is ignored.+ o+ C% \9 l+ P. }* z: R! J6 |
& ?, Y, ]# S* U; x0 u2 D4 N The persistence is ignored when an "if" condition is met, or unless an
4 s7 L# ]% L9 n8 }7 Q7 e "unless" condition is met.
& }& ?, W. K, [7 r1 S6 J' W, N4 ^9 B& l6 q! M2 h6 z1 S
See also : "force-persist", "cookie", and section 7 about ACL usage.2 P% q l/ [' G; W$ {- _6 O
4 s; W; J; `' a8 l; ^7 @# A
4 J$ x$ G7 g0 `( Y+ Jlog global
9 q# ]8 j6 _; I$ R7 rlog <address> <facility> [<level> [<minlevel>]]" d N0 I9 B& b ^' M. d
Enable per-instance logging of events and traffic.$ T9 M( e% z/ Y2 D. [+ z
May be used in sections : defaults | frontend | listen | backend! S- u2 @( @5 K1 {8 T& ]
yes | yes | yes | yes! X; w9 _6 y5 i: A7 E
Arguments :
+ F" p3 B/ ]$ b global should be used when the instance's logging parameters are the: x2 G9 i, G4 a; _/ O0 ^2 x
same as the global ones. This is the most common usage. "global": L6 O$ ^. ~$ O9 o2 H
replaces <address>, <facility> and <level> with those of the log7 e6 v! e9 S1 `3 p' W
entries found in the "global" section. Only one "log global"% i1 U+ m1 t* t3 d3 f9 J. J' N( ]
statement may be used per instance, and this form takes no other/ ^/ S& p. B; i* p3 j) `" Z8 W
parameter.# A: s) e) P1 F# _2 O, B
3 S! X& O, D4 f <address> indicates where to send the logs. It takes the same format as9 t9 _/ J; k- m
for the "global" section's logs, and can be one of :. T) k7 P+ C0 [0 N; x8 x
& u1 I7 k/ t( X& f/ d: U; {
- An IPv4 address optionally followed by a colon (':') and a UDP
3 |# b- ?1 h* e4 n& n" w; ~ port. If no port is specified, 514 is used by default (the
5 B7 p. d* A( D' ^ ^, G' s; w6 Y3 H standard syslog port).
# o/ `: K3 c K) B% T4 R9 w$ n5 D- [# J) B
- A filesystem path to a UNIX domain socket, keeping in mind
- V+ S7 t, k& i* J8 G9 P5 d4 k/ @2 H considerations for chroot (be sure the path is accessible6 C' F P' f# Z# B
inside the chroot) and uid/gid (be sure the path is
" v$ X( D7 F' J4 O appropriately writeable).9 |1 q5 ^# K" G
9 H! d/ X& T8 E4 u! g
<facility> must be one of the 24 standard syslog facilities :. O! q; Y4 [5 m3 F# G! q7 E
6 u6 W' M3 y2 l# s- M5 t
kern user mail daemon auth syslog lpr news
+ {' f2 i+ ?$ k& w( I uucp cron auth2 ftp ntp audit alert cron2: a9 z& w4 k$ ?8 M5 o6 a
local0 local1 local2 local3 local4 local5 local6 local7# y; g& `; ~, N- Q& Q+ t3 b
% m2 l" S" i. J6 y/ g <level> is optional and can be specified to filter outgoing messages. By0 V* G$ G! I2 f
default, all messages are sent. If a level is specified, only6 B9 g, s# U9 T* V, B
messages with a severity at least as important as this level
3 _* x7 u" Z1 ]' |8 C will be sent. An optional minimum level can be specified. If it7 z0 N% \: n- J2 D1 p' t2 g
is set, logs emitted with a more severe level than this one will
' l6 S) ?. s8 }* q be capped to this level. This is used to avoid sending "emerg"* L, d. w4 b0 a* B, @/ T
messages on all terminals on some default syslog configurations.
9 u2 ^8 @+ x7 h5 ^7 D8 o; i" @ Eight levels are known :0 l4 D8 I; B5 L8 P, K
" Y! g7 U1 m/ Q- i: Z# O emerg alert crit err warning notice info debug
0 ~. L. L5 Z6 Y {5 m# L9 U" N+ I$ |
Note that up to two "log" entries may be specified per instance. However, if
) }0 P# z6 P' K9 E$ D "log global" is used and if the "global" section already contains 2 log
2 m( C9 _* l6 t entries, then additional log entries will be ignored.! q2 h. X$ S3 B8 o- O$ P1 \
% t+ T/ f5 G( [5 x5 Z
Also, it is important to keep in mind that it is the frontend which decides" ^' ] x. m+ N3 c
what to log from a connection, and that in case of content switching, the log
2 l1 A2 Z; E5 N; B; E* ~ entries from the backend will be ignored. Connections are logged at level) _: F: j0 p( `3 c% L j% E( L
"info".
3 l6 Y: o: F- _6 R7 G, H! p
; e4 m+ |7 d4 m5 ~ However, backend log declaration define how and where servers status changes8 m4 Q1 p) B/ [; p) Y3 P$ d+ a
will be logged. Level "notice" will be used to indicate a server going up,4 f+ X" ^# x/ i$ Z# K, ^) I
"warning" will be used for termination signals and definitive service2 I. X6 Y2 k! ^- ?" D. q. s" n
termination, and "alert" will be used for when a server goes down.7 j9 R. Q7 ~/ b. a P
) \/ d5 `' }$ H/ w% _4 F+ e: W
Note : According to RFC3164, messages are truncated to 1024 bytes before) i6 [: ?" U3 J2 r
being emitted.4 I6 X7 c0 }! H0 t. ?% p. L
' ^8 m# v# Y2 e* K* y; Y
Example :# H1 i. e" u* n7 j: N1 a# G0 m9 h
log global. W4 r8 C$ J0 n# \" K5 V
log 127.0.0.1:514 local0 notice # only send important events
' {' r3 ?5 s- H" Q* v log 127.0.0.1:514 local0 notice notice # same but limit output level
8 A+ s; F9 Y+ N) g k7 a& ]; \2 T' w% D% E+ t6 b' O
1 h1 Q2 s* R* P; n' {' l" emaxconn <conns>& w% `' z6 Y0 R( i9 U" v
Fix the maximum number of concurrent connections on a frontend* B! d. n/ A' \0 C) M7 c% m$ E6 ?
May be used in sections : defaults | frontend | listen | backend4 L3 k( N- d0 `
yes | yes | yes | no
8 ?' P+ o! M. N; S- |+ a Arguments :% H" P3 D& ~. ~8 i6 g( M
<conns> is the maximum number of concurrent connections the frontend will6 u! d7 j0 G; [0 a
accept to serve. Excess connections will be queued by the system
- q* G; w& V' y2 x# P: ~- W in the socket's listen queue and will be served once a connection! K, s& g- @! \3 S! W8 ]/ `3 l* S
closes.- A8 Y& p1 l% z4 e/ {* w5 ^" y
+ f, F& _" q( v, _# q If the system supports it, it can be useful on big sites to raise this limit# d3 s- M# g7 V
very high so that haproxy manages connection queues, instead of leaving the
. x, I( n4 T. s) c) | clients with unanswered connection attempts. This value should not exceed the* B/ V# ^, L+ L1 a+ u# o9 a; v
global maxconn. Also, keep in mind that a connection contains two buffers
& l# T' p( B: \" I3 o3 f1 w of 8kB each, as well as some other data resulting in about 17 kB of RAM being; }! K# i# x, S+ M$ \+ D2 U9 d
consumed per established connection. That means that a medium system equipped
0 U0 F: n8 w" G with 1GB of RAM can withstand around 40000-50000 concurrent connections if
, p; L8 c9 l# J3 D properly tuned.% `+ c P" X$ [
& C5 X' K# X9 l* F6 I0 t Also, when <conns> is set to large values, it is possible that the servers9 I( a( m2 q8 w$ x, u9 T9 g
are not sized to accept such loads, and for this reason it is generally wise
2 H; I. ?/ C5 i" m. |2 o# a to assign them some reasonable connection limits.
4 j9 i; e) H0 A; ?* I% z% U" d5 u; x; P' j% e& m2 l
By default, this value is set to 2000.
( n. j7 e5 M/ x, A& y( N# C: B, E* i; W
See also : "server", global section's "maxconn", "fullconn"' ?9 `3 Y8 t9 x% _2 Z. g) A7 J
6 K5 v5 D* V& e) k
1 P; A8 d( e# ^% j. U
mode { tcp|http|health }
3 y4 M" l0 v! U2 o3 b$ V0 @) w Set the running mode or protocol of the instance
- x& Y( a; {% X% V, {1 z- E May be used in sections : defaults | frontend | listen | backend/ b) I& x3 j9 M# @; P
yes | yes | yes | yes
; i8 W) Z* q" I+ O! K9 B# D6 q Arguments :* ~ Z& j9 O' j. b
tcp The instance will work in pure TCP mode. A full-duplex connection: e) Z( C) \" `5 H
will be established between clients and servers, and no layer 7
/ ^! d- m4 J/ X: {8 h2 l examination will be performed. This is the default mode. It
. ?/ `! S9 p. X6 H0 |+ @ should be used for SSL, SSH, SMTP, ...
, g/ m) ]! |! o U4 p$ u3 I; t. g2 O
http The instance will work in HTTP mode. The client request will be
6 E$ s" D1 H8 u0 p. U8 b analyzed in depth before connecting to any server. Any request
6 ^: ?+ |; x4 w3 Q& {% b7 } which is not RFC-compliant will be rejected. Layer 7 filtering,
2 e$ a7 i& }; y# ^% X4 V processing and switching will be possible. This is the mode which& @8 s+ O6 P! @" T+ D* ?
brings HAProxy most of its value.9 ^8 M- X' I' y' F, F, D+ u
" J" ]( ^4 p! A
health The instance will work in "health" mode. It will just reply "OK"
. n6 P; ]; K" x% G4 o to incoming connections and close the connection. Nothing will be8 f2 p) S) v9 k; ?3 u
logged. This mode is used to reply to external components health
0 M$ j' a& D( K6 ~$ f) j checks. This mode is deprecated and should not be used anymore as2 V7 ^/ J! I: w; D& `: B f0 T, w
it is possible to do the same and even better by combining TCP or3 F9 S, N/ h0 `- y! e. G5 v
HTTP modes with the "monitor" keyword.3 P$ M; x" ?8 J( `
# V7 x1 _3 Q5 w. H% A) R( J When doing content switching, it is mandatory that the frontend and the
6 z) n6 X: R) n4 a* U" O backend are in the same mode (generally HTTP), otherwise the configuration' p8 `! G& }( z; G9 y
will be refused.0 _' [) b- D3 f' n
( z- {. ~9 r3 H- O( c
Example :* v. W: `; w: L( C
defaults http_instances$ r0 M+ N+ r9 v0 {% v7 d- |
mode http9 r& R. A1 K' L5 `
! b" t% E& _, N& Y& p6 d2 E( @ See also : "monitor", "monitor-net"
" _% @& L! a( J2 Y# {+ Y& L. O% F$ k1 r' g6 Q `6 F3 n
6 R. p4 d$ p. A9 ]2 o" p5 {
monitor fail { if | unless } <condition>
+ }& N$ B( ~2 {1 Y8 D+ f Add a condition to report a failure to a monitor HTTP request.9 m" k4 k, ?4 J: t8 x. _( Z4 I
May be used in sections : defaults | frontend | listen | backend' r C$ n& u' s( j4 e
no | yes | yes | no. K# q7 k) P1 R6 X& L. R% Y8 `4 C' i
Arguments :
5 y1 e0 R) s9 V8 A' t if <cond> the monitor request will fail if the condition is satisfied,
; \ `2 z* C1 |* U& R and will succeed otherwise. The condition should describe a
0 x9 g) C5 Q, }, W+ ?$ @7 B combined test which must induce a failure if all conditions l$ q |7 s m! z5 G6 K% \: ]- X$ O
are met, for instance a low number of servers both in a
+ {, ?- A3 s7 i( v8 A' d0 a backend and its backup.
- _' Z0 H9 H4 e3 C) q" C9 Q( K8 r, @- B
unless <cond> the monitor request will succeed only if the condition is) c% I% e& Z2 |2 ?( a' I
satisfied, and will fail otherwise. Such a condition may be
/ N0 B1 p# \. `* K" T8 h+ h8 m based on a test on the presence of a minimum number of active
' Z) e# O( k9 t7 Y, k, f+ l+ K servers in a list of backends.
$ x3 X! P+ d# r, c' f3 \" m3 c4 M7 f+ \" O
This statement adds a condition which can force the response to a monitor6 y5 K# o i* o% A& k- S
request to report a failure. By default, when an external component queries( d |8 Z. n s+ p, V4 S
the URI dedicated to monitoring, a 200 response is returned. When one of the7 F2 Z6 G$ K) i$ R/ E
conditions above is met, haproxy will return 503 instead of 200. This is
9 v4 w$ A; `6 B" n! [ very useful to report a site failure to an external component which may base' L% }8 c: i) m- p. U$ t+ J8 Q
routing advertisements between multiple sites on the availability reported by
5 F8 |( `; x* j- X! L6 Z haproxy. In this case, one would rely on an ACL involving the "nbsrv", i' W7 m& q4 [9 {7 w
criterion. Note that "monitor fail" only works in HTTP mode. Both status
9 R- C! [ m5 Z. }" \6 s messages may be tweaked using "errorfile" or "errorloc" if needed.6 }% y1 N. z8 P
: c2 u( `$ b# q6 e6 H6 S Example:
) p- F1 e" ?5 y9 H0 f! n% q* T1 | frontend www
, `$ Y8 v& B, p A mode http4 G1 C# o, r& u$ F, x1 U# B$ Y3 X0 Q
acl site_dead nbsrv(dynamic) lt 2
/ Z d( x3 q, J; r* i6 A3 K0 h H acl site_dead nbsrv(static) lt 2* ?9 Y- B0 j3 N4 s
monitor-uri /site_alive2 S l. c$ B" c7 X2 K. \1 z2 I. _- h
monitor fail if site_dead2 f) @ C+ F# g: M& o
3 \! Y4 ]% ]' W! Y* `" M6 }- y
See also : "monitor-net", "monitor-uri", "errorfile", "errorloc" b* a' X( z9 e
% o2 } F: h- P4 x1 ]
8 o7 K8 A1 H0 r# z9 h3 Ymonitor-net <source>
% H, b! l- }7 M Declare a source network which is limited to monitor requests' f! C( S Z# ^. R6 Y" B
May be used in sections : defaults | frontend | listen | backend
# t( o: o/ W5 A* X7 o yes | yes | yes | no
( H& Q5 E/ ?: ^ Arguments :* |- V: P% t$ ?2 C& c
<source> is the source IPv4 address or network which will only be able to
' Y; M+ D: j0 v0 o$ } get monitor responses to any request. It can be either an IPv45 G7 _, Q, m- d7 ~7 [
address, a host name, or an address followed by a slash ('/')
% G7 w0 y3 o# s# h ?; {& r followed by a mask.2 j$ k+ {' a0 P" ~, S
- F# r0 _+ n- Q+ v
In TCP mode, any connection coming from a source matching <source> will cause
0 `7 K: y( v. @ the connection to be immediately closed without any log. This allows another
+ _0 N7 j k- n, R7 U equipment to probe the port and verify that it is still listening, without
8 o% V+ I# Q: | forwarding the connection to a remote server.
( `: N' ^6 _ j' y2 w' X* K6 f( H1 X! W( A! X
In HTTP mode, a connection coming from a source matching <source> will be! z+ k% S: K1 i8 i
accepted, the following response will be sent without waiting for a request,5 |4 \/ z, [5 F4 N% x; D
then the connection will be closed : "HTTP/1.0 200 OK". This is normally" U0 C+ W: e9 o# [# T
enough for any front-end HTTP probe to detect that the service is UP and
. F( e- y3 H: r" \; r) V running without forwarding the request to a backend server.3 O7 [! R/ l! N9 E8 r$ p) |
, k' t! N3 |0 h2 @9 @- ]: h5 ` Monitor requests are processed very early. It is not possible to block nor4 f3 m4 C& e0 n* B7 j" U
divert them using ACLs. They cannot be logged either, and it is the intended
4 F8 b. b! z. X9 b0 @/ \: Q purpose. They are only used to report HAProxy's health to an upper component,, k" k5 ^' [; i5 x
nothing more. Right now, it is not possible to set failure conditions on) a4 c* t0 `" M; L" N
requests caught by "monitor-net".# \; u0 r, Y, j: {% c) Z
' L2 M2 p( Q. J! y% V Last, please note that only one "monitor-net" statement can be specified in% i$ |- Q0 H9 L/ j" u
a frontend. If more than one is found, only the last one will be considered.$ M/ J9 L' L, w" o7 _& G
0 y2 h: O; q* [4 P M# ?/ C, [ Example :
8 ]7 r/ T+ \5 \; B9 l' \ # addresses .252 and .253 are just probing us.
}# n7 \# F: B& a. d( z+ `0 i# {: W frontend www
' c% g& I1 p/ T0 M2 ?0 Y$ T" W. |* n monitor-net 192.168.0.252/31) R+ j$ F. L4 Z4 r6 B7 p1 C
8 O. \, u7 C3 Q! m. \
See also : "monitor fail", "monitor-uri"$ v* o- U% q* l0 ]
* C, Y1 X. j$ p4 b4 u3 F R
J2 U% T% D k/ X4 \& b+ imonitor-uri <uri>
% t8 s" [4 c4 K2 I Intercept a URI used by external components' monitor requests
|+ s% f/ y2 P, e/ Y: N May be used in sections : defaults | frontend | listen | backend U& p# z0 R, G" c+ X# ^
yes | yes | yes | no
# H5 D( j4 _7 q" s' r3 M) S. F2 R Arguments :
. X1 Z6 T% T( e4 I# o4 S+ c$ q <uri> is the exact URI which we want to intercept to return HAProxy's0 @# Y' g3 l5 s1 w9 V8 S$ r- P i
health status instead of forwarding the request.
) [( x6 a0 U" @) v
' l' D4 ]) N3 L1 h When an HTTP request referencing <uri> will be received on a frontend,
S1 P/ ]' w. ~0 w HAProxy will not forward it nor log it, but instead will return either8 q- e0 `7 a* w l
"HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure
9 @4 k) O5 K# X1 ]! ^6 I' f" O# @ conditions defined with "monitor fail". This is normally enough for any7 u9 w/ a0 L% ?2 I
front-end HTTP probe to detect that the service is UP and running without
" ]2 `* S6 ]0 J, W) r { forwarding the request to a backend server. Note that the HTTP method, the
+ A6 A6 g+ T5 n) u# `/ h. ` version and all headers are ignored, but the request must at least be valid* H3 [/ [2 A& o7 O; m# d
at the HTTP level. This keyword may only be used with an HTTP-mode frontend.
% r$ p. c4 j: a2 }$ \
" ~: b% T& w/ @: K Monitor requests are processed very early. It is not possible to block nor
; d, Y- c. T5 N0 H' j( ^7 m' F divert them using ACLs. They cannot be logged either, and it is the intended6 T- E2 j- }. O; g- {/ R" X
purpose. They are only used to report HAProxy's health to an upper component,
# B$ _% C! w0 w& U A. \ nothing more. However, it is possible to add any number of conditions using+ i+ e" b! O% ] {1 o* ^# k
"monitor fail" and ACLs so that the result can be adjusted to whatever check
/ r9 }: }9 ?2 m$ R, F+ z" ] can be imagined (most often the number of available servers in a backend).
1 H5 y/ g8 v9 G# x2 _ T* A- q2 x8 t2 `
Example :
/ i5 f- c, }" n# X # Use /haproxy_test to report haproxy's status9 e* U( r" `- b- H( }- E
frontend www: R/ z2 w- G8 V' g ~ b
mode http
t1 g. t" X" Q i m' P monitor-uri /haproxy_test
& m9 N2 @. _: R
) J! d9 J, e- N. Y! C2 {5 Q See also : "monitor fail", "monitor-net"
. X2 ~! T, ~3 r8 T: ^$ f( s& Y& S7 V7 @+ P9 J8 }
- r4 }2 ]: j: Z# t/ o
option abortonclose
( j0 L& i* j/ L8 g4 Y0 x( ?no option abortonclose
' s3 D% h6 z6 \5 f: Y Z0 s Enable or disable early dropping of aborted requests pending in queues.' z( W3 G/ R) U
May be used in sections : defaults | frontend | listen | backend1 _9 ~! }. D* u& e5 i. A2 L$ b
yes | no | yes | yes
2 Q" J, x1 A* K# d& A Arguments : none
/ B' [4 p1 a& a. E6 k. r+ B. g3 ^6 b+ l# ?+ _
In presence of very high loads, the servers will take some time to respond.8 |8 L. F7 w; Q* S8 q" J" W
The per-instance connection queue will inflate, and the response time will+ T9 b- p3 ^5 F- P7 n
increase respective to the size of the queue times the average per-session# M. F: R7 J3 F+ X9 E6 Z2 |% _
response time. When clients will wait for more than a few seconds, they will
- |: g' D- {# L* [6 R j often hit the "STOP" button on their browser, leaving a useless request in
! ^& `$ a) \# H the queue, and slowing down other users, and the servers as well, because the' n6 L3 I W! ?- P, `
request will eventually be served, then aborted at the first error/ A8 W. j5 D% `6 q& W6 d Q
encountered while delivering the response.
$ f' a3 b0 `3 C; V1 w2 h k, H/ Z' u: T4 \4 A
As there is no way to distinguish between a full STOP and a simple output
4 X2 y. S. I. r+ L3 Z5 W9 l close on the client side, HTTP agents should be conservative and consider
7 L7 f% O" i7 v G' _- _ that the client might only have closed its output channel while waiting for" C4 q. g+ q2 m7 k3 f
the response. However, this introduces risks of congestion when lots of users: m/ U& {) H# M5 G; o1 N j
do the same, and is completely useless nowadays because probably no client at6 n% x7 L- v" H* c/ j M
all will close the session while waiting for the response. Some HTTP agents3 j6 S# ^+ ~0 o* s) c9 ?4 i+ P% P
support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most3 F( N1 [3 l0 ?! q5 G2 d! ? n* E
hardware-based load balancers). So the probability for a closed input channel
* g* R( O) C8 ^5 f8 F8 ] to represent a user hitting the "STOP" button is close to 100%, and the risk
, K, Y* u( d* \ of being the single component to break rare but valid traffic is extremely
$ L; ^( p& o; V7 D5 g& S low, which adds to the temptation to be able to abort a session early while7 l6 j# i' ]' J1 b+ n* D
still not served and not pollute the servers.: b& r! i! V8 ]
% _ h. j1 A; d
In HAProxy, the user can choose the desired behaviour using the option$ ^7 ^; Y8 ?! D! F( i/ }5 ^1 n8 B4 Y
"abortonclose". By default (without the option) the behaviour is HTTP
, t- D7 H2 l9 E# ~: k* Q compliant and aborted requests will be served. But when the option is
' Y! O' H P; a0 v# F specified, a session with an incoming channel closed will be aborted while
6 u: I) h# D. Q it is still possible, either pending in the queue for a connection slot, or
& `9 j1 P4 j4 x0 b" o- P _ during the connection establishment if the server has not yet acknowledged" O# V1 |! }7 a0 x3 [6 K
the connection request. This considerably reduces the queue size and the load$ p( `. p; s. g4 p5 K
on saturated servers when users are tempted to click on STOP, which in turn4 x# b# {8 f- e7 u/ e8 U, E/ B% Z
reduces the response time for other users. q, t" A2 r8 Z
( j9 d; y* S S C- f9 n1 ]& H If this option has been enabled in a "defaults" section, it can be disabled2 ]0 D0 M* q; r% l( E7 h
in a specific instance by prepending the "no" keyword before it.
! T8 r/ e5 V/ Y2 T7 L
6 _4 U' z4 o& U7 x t) P1 |: P0 P5 B See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters
1 [9 z3 G/ b6 C+ @# G% o V6 g1 d& w6 H/ X9 k( Z* G* x0 ?4 D0 V
3 H7 C5 n. f) U1 u. q3 L
option accept-invalid-http-request
- O# P: z }. x# K7 E# H2 g, Xno option accept-invalid-http-request
/ g. _+ n% g% |% g& U8 y9 S" ~( ] Enable or disable relaxing of HTTP request parsing
* q/ D& q3 c2 I6 \$ @- D2 ] May be used in sections : defaults | frontend | listen | backend
% w" M2 T3 X5 ` yes | yes | yes | no
3 L5 a% d* [( J$ s Arguments : none
% z( |/ y( d# z! i9 R7 S d
) q: ] J# S* u8 w By default, HAProxy complies with RFC7230 in terms of message parsing. This/ H/ \3 e- N7 r; S6 f$ ?) [
means that invalid characters in header names are not permitted and cause an
3 [% j+ k( [# H+ ]$ E n( [& p error to be returned to the client. This is the desired behaviour as such
D: A8 Y9 ~( D: k1 h# [( J# Z forbidden characters are essentially used to build attacks exploiting server" |. k& o( F# t# I) h
weaknesses, and bypass security filtering. Sometimes, a buggy browser or
$ o0 b8 R/ R0 ]. `2 R server will emit invalid header names for whatever reason (configuration," v% o1 e5 E8 O: R) l' e
implementation) and the issue will not be immediately fixed. In such a case,
) s! V( A0 U' \9 X0 c$ f$ q, t it is possible to relax HAProxy's header name parser to accept any character
) Z" T4 A' E! \: u/ S even if that does not make sense, by specifying this option. This option also
! x. l z$ R c2 j relaxes the test on the HTTP version format, it allows multiple digits for
' x" I( T( r' c; b! _" Y2 W$ G B# S both the major and the minor version.1 D, e1 y' `6 N6 j4 {& n
! d' r. }# f& C, V This option should never be enabled by default as it hides application bugs x6 r# p7 @; W( O8 F4 S! W
and open security breaches. It should only be deployed after a problem has9 I$ T; l M. P4 X- [; k
been confirmed.
2 S1 {7 f' M% c! p V0 m0 _# Q3 i- X0 X0 ]9 a& `# Q
When this option is enabled, erroneous header names will still be accepted in7 w; K+ C; T+ j; U# _( P9 b
requests, but the complete request will be captured in order to permit later* \4 Z0 B5 Y$ V4 I! J
analysis using the "show errors" request on the UNIX stats socket. Doing this
7 A$ s8 B3 W- f* F) W* u! ~0 Q also helps confirming that the issue has been solved.% V+ {( `9 _8 B0 b/ ^) [) ?
( k* n# ^. P, y. O& f
If this option has been enabled in a "defaults" section, it can be disabled
8 r& s/ a1 Y0 r6 D+ i in a specific instance by prepending the "no" keyword before it.
: a& N3 C+ {, B4 V: @1 M' W2 Z0 c/ _+ o8 ^. |( e5 F
See also : "option accept-invalid-http-response" and "show errors" on the* c4 d9 W7 L4 o7 _; r+ w
stats socket.2 g2 h" k/ h& a$ _+ s, H
7 N$ C6 U6 h/ j. `9 k
$ P! P* \, E5 I+ A6 _2 Doption accept-invalid-http-response
: ]9 i$ k* K" i% {9 fno option accept-invalid-http-response( h/ o2 v9 \/ `& R: f, C
Enable or disable relaxing of HTTP response parsing" s! N% e" ?: f8 M
May be used in sections : defaults | frontend | listen | backend5 X# p/ n+ r. T' C
yes | no | yes | yes
; s+ r" `9 Y( S5 k$ q2 m8 \ Arguments : none
6 o0 |4 a# w! x) L$ |
+ X* a' L) N$ d" p( w8 I5 X$ ~ By default, HAProxy complies with RFC7230 in terms of message parsing. This
K7 O6 ?* \$ K3 @) F7 P( Z" ] means that invalid characters in header names are not permitted and cause an
' x! G- K# L' F. { error to be returned to the client. This is the desired behaviour as such
1 Z% O/ B/ a+ _. M1 l5 H/ Y forbidden characters are essentially used to build attacks exploiting server
3 v& h- R8 U7 ? d. {1 f weaknesses, and bypass security filtering. Sometimes, a buggy browser or2 P8 M- I1 A0 F+ `' g+ q
server will emit invalid header names for whatever reason (configuration,
. z& G X# J8 x! ?2 w% n implementation) and the issue will not be immediately fixed. In such a case,& q! a- L. k# m, ^" U0 Z
it is possible to relax HAProxy's header name parser to accept any character, ~5 g) m c- M/ }, z
even if that does not make sense, by specifying this option. This option also# D7 K. |0 V& F2 d7 G4 @9 j3 y. Z
relaxes the test on the HTTP version format, it allows multiple digits for
' \0 U; \0 b7 q: G, n! E- f both the major and the minor version./ V3 R# z! V: z, J; @$ T# b
9 L# ?3 i5 P8 w+ H5 r This option should never be enabled by default as it hides application bugs* Z8 J: ]- C' a$ `3 A6 I
and open security breaches. It should only be deployed after a problem has
8 U' C2 x1 Y- R been confirmed.
7 ?: u4 w8 q0 _0 J& V c Q8 K9 @" L2 h; t
When this option is enabled, erroneous header names will still be accepted in
3 k+ r/ {. Y2 k+ U; g& F8 v+ | responses, but the complete response will be captured in order to permit
* W0 Y- L3 M& p later analysis using the "show errors" request on the UNIX stats socket. C( j9 A& c. Y: k) X9 W! h
Doing this also helps confirming that the issue has been solved.
% A8 B3 w& {: c# Z" j7 E6 O' M4 I- q/ ?8 W1 t- S; a
If this option has been enabled in a "defaults" section, it can be disabled
7 W$ ]% ~! x3 i% m& R* {# | in a specific instance by prepending the "no" keyword before it.9 N8 v* I# U$ x! k; @
, U0 M8 p& Q. Q
See also : "option accept-invalid-http-request" and "show errors" on the; Y4 M3 {9 m# r5 p# I! d) f# L
stats socket.; W5 {* E# N/ [; y$ @
% i9 B! L5 D! M( K8 S' m: s/ w: S$ l4 u1 M' o
option allbackups
# F1 {9 e7 U3 |& J! cno option allbackups" j% e' Y' A) d
Use either all backup servers at a time or only the first one- |* V9 q; x/ a2 s
May be used in sections : defaults | frontend | listen | backend
- v5 v; S( I+ Q9 X3 Y, l/ ]' } yes | no | yes | yes
1 d9 r( K- g3 t r! ^ Arguments : none2 r7 C% Q Z( q7 _0 l
* ?* i+ [+ ~6 s2 X) R& [
By default, the first operational backup server gets all traffic when normal! n& X( H+ _* M; U; c* [3 K0 ]
servers are all down. Sometimes, it may be preferred to use multiple backups
6 B8 b7 u+ c5 c2 h at once, because one will not be enough. When "option allbackups" is enabled,
& {6 {* B8 w4 I* O2 }: ? the load balancing will be performed among all backup servers when all normal
4 B; A3 g' R3 z: V, A/ _' I& \# I8 @ ones are unavailable. The same load balancing algorithm will be used and the
: @/ W2 { j# X2 D) c servers' weights will be respected. Thus, there will not be any priority% i6 B+ V3 u) K5 ^3 b; _2 ^
order between the backup servers anymore.
0 y+ q8 Y8 u" H2 E1 M5 s: N3 K8 D4 ]' `' a* Q) S3 r$ j, K
This option is mostly used with static server farms dedicated to return a
5 A0 w) q. M1 L* G3 n' }/ D "sorry" page when an application is completely offline.
! ^2 P+ l) K* U" }
. `/ M4 I5 x# ~% G If this option has been enabled in a "defaults" section, it can be disabled
) j# Y( b0 R' K8 D5 M in a specific instance by prepending the "no" keyword before it.
2 K. \3 A" _. X2 I6 [1 j+ H K( x
3 t% @+ g/ ?% U5 v! N9 h1 w. j4 k) y- U5 C8 _, v
option checkcache
: f: K+ E p& ~0 Ino option checkcache
) k* i; T) N* ]) K! t) f7 b Analyze all server responses and block requests with cacheable cookies
% L3 p- d% u: N; @5 ?( E May be used in sections : defaults | frontend | listen | backend# b2 X, Q4 `+ D7 N4 _% m8 Y2 q. |
yes | no | yes | yes
2 S( F* W! Y2 A( ^$ P& o Arguments : none
+ J. o$ {. s- i3 H6 f+ u! Q5 \
9 Q) G1 \! r" \+ K+ g Some high-level frameworks set application cookies everywhere and do not
0 Q+ O' }; }: I always let enough control to the developer to manage how the responses should+ s! }4 X0 j' p* ~* o% I) ~# P
be cached. When a session cookie is returned on a cacheable object, there is a7 k% [8 c2 a$ W. i3 s
high risk of session crossing or stealing between users traversing the same
5 Y' Q/ S/ J7 f8 ^ caches. In some situations, it is better to block the response than to let
9 v1 a3 G9 l3 i- ?# @ some sensitive session information go in the wild.$ a; |& O" c( P& ^) H& |, o
7 x5 J8 s- T+ w The option "checkcache" enables deep inspection of all server responses for
6 p; F4 _9 x2 Y- o7 J4 J6 I( O strict compliance with HTTP specification in terms of cacheability. It4 p; W, u& E J# S
carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
% _. M5 D+ M! j V; L response to check if there's a risk of caching a cookie on a client-side
2 |3 V7 c( Z6 v6 q- R proxy. When this option is enabled, the only responses which can be delivered$ r6 b# J' i. t
to the client are :; S: u5 B2 w; {8 D9 m
- all those without "Set-Cookie" header ;
' s" g ]2 o" E; t9 m8 G. y$ H - all those with a return code other than 200, 203, 206, 300, 301, 410,
0 m6 A& z, J) P7 r g, W provided that the server has not set a "Cache-control: public" header ;
, C: a& A5 n2 u- _4 L& I( Q - all those that come from a POST request, provided that the server has not2 S3 C, S: l; h6 K1 a G8 i
set a 'Cache-Control: public' header ;+ m+ y5 n0 f5 p; O3 g8 s
- those with a 'Pragma: no-cache' header3 `' I2 ~: W/ q: Y+ p
- those with a 'Cache-control: private' header/ O/ @1 D5 }" r
- those with a 'Cache-control: no-store' header1 H* V$ g' Z; V) j% d& k
- those with a 'Cache-control: max-age=0' header
$ g4 |( w4 X+ Z n( v6 v - those with a 'Cache-control: s-maxage=0' header, C8 r7 c4 A5 F! ~; N$ Y
- those with a 'Cache-control: no-cache' header. }; X/ X4 A; }# D& J2 ]/ f7 S' f
- those with a 'Cache-control: no-cache="set-cookie"' header
, `. u6 R1 `2 V1 g - those with a 'Cache-control: no-cache="set-cookie,' header b3 }/ M8 M5 u
(allowing other fields after set-cookie)5 Y" J5 E0 \2 k" U- P4 h U
) z9 D+ f2 \5 i% N4 m$ z0 q" A& G If a response doesn't respect these requirements, then it will be blocked* h f4 D8 H. y2 ?
just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".
" T" n9 g6 R: n$ Q0 i1 ~' ^ The session state shows "PH--" meaning that the proxy blocked the response
' h }$ y+ D/ B/ s2 u' l during headers processing. Additionally, an alert will be sent in the logs so2 L, f9 T2 F- G
that admins are informed that there's something to be fixed.
) b7 [+ T( u, a' @% g& f1 n& m! X1 A9 c) D7 d
Due to the high impact on the application, the application should be tested
1 d3 ~5 o( `4 O! a in depth with the option enabled before going to production. It is also a- l) _ g# g. k2 F% E- v
good practice to always activate it during tests, even if it is not used in% F% Z1 s) H% @: u* E0 J! H) i
production, as it will report potentially dangerous application behaviours.9 S/ {- _! _# p @* Y x
% l7 R7 W; O/ v& t( q If this option has been enabled in a "defaults" section, it can be disabled
r' m: B$ i1 j- {+ n1 k in a specific instance by prepending the "no" keyword before it.
/ n. V/ T% U* s6 V$ S/ e4 F
; f. M+ p4 z* ^ O9 \2 b- s
" h/ l+ }. T) h6 Woption clitcpka
) g; p6 {# l1 c7 gno option clitcpka/ a" B4 }1 ^7 y. l) \1 a# M1 r
Enable or disable the sending of TCP keepalive packets on the client side# O+ `5 I# Q; g, k+ r5 q
May be used in sections : defaults | frontend | listen | backend
6 W6 u P- K- Z# B- D9 F9 M0 l yes | yes | yes | no% B) T; G7 `5 |; e
Arguments : none
: @5 I' t6 r7 e
7 [, `1 Y1 H: w5 e7 g* w& g When there is a firewall or any session-aware component between a client and
) \' X" h) b, ?# n, f( V a server, and when the protocol involves very long sessions with long idle' `4 h: E/ F; y M
periods (eg: remote desktops), there is a risk that one of the intermediate& @% H( X5 g' \* U( m9 y5 B: m
components decides to expire a session which has remained idle for too long.& R3 F8 y9 P3 M
. O# g) g' ~! o1 |/ h
Enabling socket-level TCP keep-alives makes the system regularly send packets
" c# @% R2 z2 l- I* C to the other end of the connection, leaving it active. The delay between
0 J! K( B! I. H keep-alive probes is controlled by the system only and depends both on the
; ]& u& ?6 F1 o) a) `) [8 | operating system and its tuning parameters.$ g: ~) ]( |: ]) X% `
& N1 _* k' X- Y6 V( `) M
It is important to understand that keep-alive packets are neither emitted nor
. c" }1 q$ M' S ?* [& | received at the application level. It is only the network stacks which sees7 P0 m5 t; m# _; A0 R
them. For this reason, even if one side of the proxy already uses keep-alives' r G' @. e( C% o1 q7 }
to maintain its connection alive, those keep-alive packets will not be. ? G0 e; ]' n6 g3 n( X
forwarded to the other side of the proxy.( G( s. a0 h2 V4 g
" K( T8 Y' E A l; ?9 i' @* e
Please note that this has nothing to do with HTTP keep-alive.7 A# A7 g1 @! D6 h! r- U
) @' G; _2 U# D' S/ y1 h) Q* y. ], R Using option "clitcpka" enables the emission of TCP keep-alive probes on the
2 I7 Z# p( |# G, U client side of a connection, which should help when session expirations are
4 A! Y$ e( i8 T% ~( r1 `8 ]" n0 L noticed between HAProxy and a client.* \4 T; |3 B+ a0 c, ^7 g; R& O
% c4 x$ Z" M' S+ t1 ^# T- D
If this option has been enabled in a "defaults" section, it can be disabled
, h* v" Q: e+ R# F2 G; v6 n" x, ` in a specific instance by prepending the "no" keyword before it.# P. I/ t6 q" B9 u- y
5 u: }! M4 h$ N
See also : "option srvtcpka", "option tcpka", K$ C6 B; N* F& H
6 d# s: o) R0 y
- E# g# `$ a+ \8 r5 `2 B2 z, Q0 koption contstats
( l! N: z2 C) a% d3 c Enable continuous traffic statistics updates5 Y: q6 k1 o y7 w( K
May be used in sections : defaults | frontend | listen | backend* K. R0 [- Y! H `/ j' @
yes | yes | yes | no
! F* x& d$ p& x Arguments : none8 c4 I: E7 }# b9 ]
$ l+ v5 j9 H2 h8 P' [
By default, counters used for statistics calculation are incremented
( }: a4 h0 |2 V- C. O only when a session finishes. It works quite well when serving small
- A' d" `* S& C+ [% |8 l+ ~ objects, but with big ones (for example large images or archives) or
' N& z1 a& M9 K$ Z: c8 _1 F with A/V streaming, a graph generated from haproxy counters looks like1 ~ e; ?7 g8 ~5 z' \) o
a hedgehog. With this option enabled counters get incremented continuously,
7 v; V* V8 h4 `* C1 V during a whole session. Recounting touches a hotpath directly so
* k& \1 E+ P$ p* G3 Y: Q l4 ` it is not enabled by default, as it has small performance impact (~0.5%).0 U. m0 K! n- @* p/ g9 ^* s
# Q% o6 E P9 R" P( V
: Q1 C! _* Y* d1 l, C: [3 G4 V$ t
option dontlog-normal
( d/ I3 j+ ]1 n2 Vno option dontlog-normal; y* x' k+ E& ^! M5 D
Enable or disable logging of normal, successful connections; g9 Z4 m1 l6 U8 [; z9 b- D
May be used in sections : defaults | frontend | listen | backend B, T2 Y# p% W2 Q- `
yes | yes | yes | no- r: ^7 u, x& t( `+ Z- v' S8 A
Arguments : none
% w+ Z* f4 q: P/ U* K8 I( Y; G
$ G5 u8 [9 i& I" M) p! t There are large sites dealing with several thousand connections per second
* E; G) Q, c& i* C% I and for which logging is a major pain. Some of them are even forced to turn4 ~2 ~2 L" }4 a9 B- f
logs off and cannot debug production issues. Setting this option ensures that* E2 Y# ~* c, v9 Z0 o
normal connections, those which experience no error, no timeout, no retry nor
; n$ p! X% W# m u$ T0 @ redispatch, will not be logged. This leaves disk space for anomalies. In HTTP
$ ]4 E5 ?0 M* O" { U mode, the response status code is checked and return codes 5xx will still be
& Q: A0 A8 c6 `1 {9 w logged.9 D7 } \4 j! E% Q9 w
/ j& h# s T- \ It is strongly discouraged to use this option as most of the time, the key to* ^6 r- L9 j- G, L' {1 `
complex issues is in the normal logs which will not be logged here. If you
2 E, T* b6 ?5 M8 H need to separate logs, see the "log-separate-errors" option instead.) d9 X. f1 @! j* C6 Z& F; A
/ V- \& }! X! I# W* d
See also : "log", "dontlognull", "log-separate-errors" and section 8 about
$ t; w( B+ ?6 R5 Z: B logging.
0 d6 T; D# S, D1 e5 }1 [) ]
0 ]4 f8 i; i: T# [2 s& b8 b8 h) V- j, D2 ~3 _
option dontlognull
# x$ n* x8 B& {# g4 u0 jno option dontlognull
0 H5 \ H' q2 G! u6 o7 _7 f$ _+ C Enable or disable logging of null connections& N' Y2 D& A& V/ K# L# X6 h9 d! ^
May be used in sections : defaults | frontend | listen | backend3 z& {# f" w* Z' |$ C6 i( U: ]/ p0 U
yes | yes | yes | no4 p3 Z# O1 c% |+ g* z0 M! k# h
Arguments : none
, }9 U K, t' p- `
+ @# g. i* ]2 Z5 V In certain environments, there are components which will regularly connect to
: ?- @- Q7 R |- A" v/ R, J1 g various systems to ensure that they are still alive. It can be the case from3 e; o2 F2 s: P9 p/ n: @
another load balancer as well as from monitoring systems. By default, even a8 V* {8 n1 c9 y# M0 ^8 c% I
simple port probe or scan will produce a log. If those connections pollute- I: q+ z# }$ F5 _
the logs too much, it is possible to enable option "dontlognull" to indicate
5 D; w# X+ X+ K( J that a connection on which no data has been transferred will not be logged,
( o7 w8 A& v* [. n3 \ which typically corresponds to those probes.) m% O" @* U$ C! i% E, K+ e
- ~& t7 U) ~/ n/ R3 H7 U
It is generally recommended not to use this option in uncontrolled
* i) S3 D! w( ]/ ^1 k environments (eg: internet), otherwise scans and other malicious activities
3 ?7 y" A+ i: T( ?1 w2 c% f0 |$ `6 U8 C would not be logged.' ?6 y6 m4 |( T. k& F& p# Z
X7 P$ M' M- O$ D: \6 ~
If this option has been enabled in a "defaults" section, it can be disabled
8 p2 Q8 v4 v/ C" a in a specific instance by prepending the "no" keyword before it.
% V) R9 D/ ^ H2 s5 V0 e( k1 Y5 y2 a6 K+ ^* H4 Q, \7 ]( C/ n0 F
See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
, }8 \$ t. ]6 c) H. j. x. ]' y5 Y$ \
! e0 q6 F/ {) u# Y. ?: t8 {
9 D' ?6 V) q* a0 u3 ~option forceclose
: Q2 E5 s d7 u7 D, l* Bno option forceclose
+ L) C9 w' }, }" A9 X; k Enable or disable active connection closing after response is transferred.% @7 d- S+ B! b+ A5 n
May be used in sections : defaults | frontend | listen | backend
" } f$ H, [" I! t8 y! n. ^ yes | yes | yes | yes! I. x, g: b/ h9 c, U) X
Arguments : none9 V4 D# r ? r2 z6 }3 `
- |# a7 i( s) l1 g0 E5 W
Some HTTP servers do not necessarily close the connections when they receive- V0 S( O+ G5 I; I( U
the "Connection: close" set by "option httpclose", and if the client does not; B- d, l! f+ e. C
close either, then the connection remains open till the timeout expires. This7 _$ i( E. o4 A* n* j/ E
causes high number of simultaneous connections on the servers and shows high0 G6 @5 g2 Y( A5 K% B0 T% M
global session times in the logs.1 l: {% f: Y+ O `# ? Z
9 u* x4 Z: f% U3 \5 m" p6 r* f When this happens, it is possible to use "option forceclose". It will
- V! B1 C! q* a: Q$ @ actively close the outgoing server channel as soon as the server has finished9 Z+ c) m8 A, k* I/ H8 A
to respond. This option implicitly enables the "httpclose" option. Note that7 j/ h* ]' Q; E. ]
this option also enables the parsing of the full request and response, which5 F+ x8 i8 I/ _7 g( @
means we can close the connection to the server very quickly, releasing some# z( k3 |/ K) }5 @( q7 l+ y2 P$ y8 v
resources earlier than with httpclose.
: G8 S2 ~: N# y$ q
& f: h L- w! c! E& E4 u5 Q This option may also be combined with "option http-pretend-keepalive", which
y( S- K1 K7 d1 ^3 V. b will disable sending of the "Connection: close" header, but will still cause8 d# m2 M) M7 s
the connection to be closed once the whole response is received.: V' Y* D" ^, L) A* V4 w8 k: l0 N
/ i8 ~- K' }) g7 I) Q
If this option has been enabled in a "defaults" section, it can be disabled
1 b" t# E" g* {* b in a specific instance by prepending the "no" keyword before it.
6 ?6 ?9 n5 n/ ^ C/ W) ?
: h% Y% q8 ?6 Z" O9 h5 f See also : "option httpclose" and "option http-pretend-keepalive"' j2 A" g" f* X6 |: f( e
. {* c( a+ T! B
, b. _& t5 ~$ m" h! u0 Coption forwardfor [ except <network> ] [ header <name> ] [ if-none ] z9 S6 n) }) }* e* Q2 q2 a/ K6 I. p
Enable insertion of the X-Forwarded-For header to requests sent to servers
/ M" v# u- c% i t May be used in sections : defaults | frontend | listen | backend
7 s" `8 j/ a# T! a5 w8 ~- y3 E& l yes | yes | yes | yes, h$ o5 E8 j/ h0 s8 H# F
Arguments :
) \1 a4 J( C+ F$ ~6 W+ n- c( o <network> is an optional argument used to disable this option for sources$ [4 r, f1 n- F
matching <network>8 m- l% k3 O9 B( [. B! p; y
<name> an optional argument to specify a different "X-Forwarded-For", Y5 J- G. m, n' `- ^
header name.
& @$ g% Z9 S: y# H6 U; y0 q' Q% Y! `) g, |. L t: s! T
Since HAProxy works in reverse-proxy mode, the servers see its IP address as) i$ V1 M4 f- d7 n0 u9 Y
their client address. This is sometimes annoying when the client's IP address( T! K5 Z5 ^, e. z7 n
is expected in server logs. To solve this problem, the well-known HTTP header4 E) \/ T2 q2 c. \: B, U5 N
"X-Forwarded-For" may be added by HAProxy to all requests sent to the server.
D C2 @/ T! ` This header contains a value representing the client's IP address. Since this1 _) _9 }8 A& @
header is always appended at the end of the existing header list, the server
, B. O; c T7 y! q& c must be configured to always use the last occurrence of this header only. See
% x% u3 G( u. X the server's manual to find how to enable use of this standard header. Note( k: \8 C5 |9 u3 h( |3 G& |
that only the last occurrence of the header must be used, since it is really, b4 O8 s$ Y6 u) S0 |* D7 l
possible that the client has already brought one. L7 P _" k" a5 P
- h) D. c ~; E. s( w The keyword "header" may be used to supply a different header name to replace' ?5 Z1 G" m: Y- T" x3 r, e v
the default "X-Forwarded-For". This can be useful where you might already
9 h% I; R6 q% H e have a "X-Forwarded-For" header from a different application (eg: stunnel),
$ A& W5 D) J1 m5 H4 `" X and you need preserve it. Also if your backend server doesn't use the8 k0 r1 }) G; d$ L, C% r
"X-Forwarded-For" header and requires different one (eg: Zeus Web Servers
- j% l, P# W0 \ require "X-Cluster-Client-IP").
+ j) |# G& C% s' B$ E7 b- H8 k/ Y0 S. M9 V" b0 f
Sometimes, a same HAProxy instance may be shared between a direct client
6 M+ ~0 `0 x5 p5 \ access and a reverse-proxy access (for instance when an SSL reverse-proxy is% U# }. u; ~% h
used to decrypt HTTPS traffic). It is possible to disable the addition of the
2 v5 M& j( v! a$ p# ] o header for a known source address or network by adding the "except" keyword
( F& O5 e D. i' f8 B, I followed by the network address. In this case, any source IP matching the
, R% _9 l( v* M4 _5 \ network will not cause an addition of this header. Most common uses are with
+ {, c& W- H; Y# ]" ^ private networks or 127.0.0.1.
' {9 Y6 n+ V7 L9 G' l1 {( t$ x
; R# b3 o5 C1 C Alternatively, the keyword "if-none" states that the header will only be# Q2 O% o$ U3 \1 D' p8 h( t
added if it is not present. This should only be used in perfectly trusted: D1 A- w6 @ [ E7 ]
environment, as this might cause a security issue if headers reaching haproxy* [2 ]) [: m% i
are under the control of the end-user.
! |! ^+ ~7 B0 [9 O) b8 X9 v2 `) G* P
This option may be specified either in the frontend or in the backend. If at% [. k3 l: [1 @6 ^( A) J7 [
least one of them uses it, the header will be added. Note that the backend's
, V% G q# |. m+ Q J9 m& O setting of the header subargument takes precedence over the frontend's if8 H' i! H7 U, j$ ]3 Z2 C
both are defined. In the case of the "if-none" argument, if at least one of
1 m/ B! p% z9 I g8 t the frontend or the backend does not specify it, it wants the addition to be
C. y( N/ y% X3 L+ L mandatory, so it wins.
( p7 H! D* R# t: N$ [7 ^7 }
1 R6 A$ {/ u O ?! G' o/ r It is important to note that by default, HAProxy works in tunnel mode and
, ?& b! P9 v/ u& t( [ only inspects the first request of a connection, meaning that only the first6 t2 R5 \ y5 Y0 ~1 q0 G
request will have the header appended, which is certainly not what you want.- \+ C p8 Z# X$ x- r
In order to fix this, ensure that any of the "httpclose", "forceclose" or& G1 N: l4 }, m/ c8 V; A
"http-server-close" options is set when using this option.
' v+ B) s& I ?+ m& Y! N4 ?# c" Z& v; }+ s" L# m
Examples :* ]2 ?9 x: h: f1 K& P1 T: [
# Public HTTP address also used by stunnel on the same machine
" s8 z5 E5 Q( B6 {8 U0 k: r frontend www
2 J) N$ ?5 K/ Y1 o" S: D mode http
1 o$ J& z @+ k option forwardfor except 127.0.0.1 # stunnel already adds the header
: ?/ @" N; @: b- v
' u& \( W; X5 t/ Q9 f # Those servers want the IP Address in X-Client( `4 f1 i4 @* N
backend www5 Y) ]4 c( S7 d: t' m% K9 }, q+ D3 T
mode http) H0 ?& B Y0 |6 j9 K' l
option forwardfor header X-Client& k& X# c& s7 Z+ i l) `0 u
. J8 T& O8 b E% P See also : "option httpclose", "option http-server-close",/ K' v: K2 `, O* k
"option forceclose"
' }3 w6 v9 y6 C+ Y: ?4 z; U) z- Y6 d( {5 m) q& v% ^
: S; i& A$ F# @ c/ boption http-no-delay; D& y$ Q) k4 N/ |
no option http-no-delay
0 C1 m( I& i' g5 \ Instruct the system to favor low interactive delays over performance in HTTP
; | y1 i* e' v# a; M May be used in sections : defaults | frontend | listen | backend' ?7 d7 P2 N _ X4 f1 [& A
yes | yes | yes | yes
u( c! }/ B$ n% M, m Arguments : none
. `' ^; h& W3 ^0 K- R) l9 O' M+ X4 Z7 {; X h5 n
In HTTP, each payload is unidirectional and has no notion of interactivity.9 V- Q: @9 q/ l# R% ^" N6 V
Any agent is expected to queue data somewhat for a reasonably low delay.
8 _. V# z9 R" L g0 q There are some very rare server-to-server applications that abuse the HTTP
7 ~: V+ }3 r, W0 U; T( H1 W protocol and expect the payload phase to be highly interactive, with many
# t# F g, j' j, R8 W( s" w# v interleaved data chunks in both directions within a single request. This is- n0 \, ]$ F' O3 o% N
absolutely not supported by the HTTP specification and will not work across* }( Y* F1 `' O, ?) a
most proxies or servers. When such applications attempt to do this through8 t- ]1 ?$ U+ ?! [& d
haproxy, it works but they will experience high delays due to the network8 h ]& V7 ?, b5 Y
optimizations which favor performance by instructing the system to wait for
6 L; H$ z5 t4 d1 \, |5 `6 O; w enough data to be available in order to only send full packets. Typical1 n' C* S3 ~5 p$ S' G- x& |
delays are around 200 ms per round trip. Note that this only happens with
" j) r! t* e# ~0 k/ o. ^3 t5 q abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
! ~9 U8 C; w: i( h8 j9 _ affected.
4 M$ n% X, i0 ~3 |% C3 K: F. M3 k8 y6 z' F |" x& e z, n
When "option http-no-delay" is present in either the frontend or the backend
% ?4 ?- f- b1 }2 D$ m used by a connection, all such optimizations will be disabled in order to3 A4 G0 G; k. R6 O
make the exchanges as fast as possible. Of course this offers no guarantee on
8 A$ B! i+ e5 _, g; S% E the functionality, as it may break at any other place. But if it works via
3 O6 V' m4 Z* P/ D HAProxy, it will work as fast as possible. This option should never be used" |5 A$ [ m( c
by default, and should never be used at all unless such a buggy application$ h& M* c) r- S" Q2 P* o, M
is discovered. The impact of using this option is an increase of bandwidth
) f& e5 M/ y. l4 U5 W) f usage and CPU usage, which may significantly lower performance in high0 W% ]' G5 M, t% P/ U9 N; c7 [
latency environments.
6 E# m6 f2 v" {" y
& [. F- D& Q2 R1 K2 S' ~6 v4 `6 b! t7 E. f* c7 u$ @
option http-pretend-keepalive
2 `% S" H ^$ ?9 f4 h, E# Qno option http-pretend-keepalive
8 n* j& s8 o) j% J' U1 d. Q4 O; s& z Define whether haproxy will announce keepalive to the server or not: p5 D2 H! {' n5 c& ^; z6 j- l
May be used in sections : defaults | frontend | listen | backend# V: E; i9 \3 A2 W/ N
yes | yes | yes | yes
3 W" `2 l' k6 {% x Arguments : none
* p4 \* Q7 V6 V
# l2 z4 @8 J7 ]5 _' q0 D% O, z When running with "option http-server-close" or "option forceclose", haproxy
5 h7 a, h" d0 [9 ?. p6 m adds a "Connection: close" header to the request forwarded to the server.0 r0 t& F9 s( l7 i4 z0 w; C
Unfortunately, when some servers see this header, they automatically refrain/ u9 M" Q! @% i5 B7 `, n2 V
from using the chunked encoding for responses of unknown length, while this8 I/ o' u* X! o* g
is totally unrelated. The immediate effect is that this prevents haproxy from* \- k7 O% J- p* G. v& I
maintaining the client connection alive. A second effect is that a client or
& Z" ~: B7 i& _( ? a cache could receive an incomplete response without being aware of it, and( y$ i- z+ G, P# w' v% z5 b
consider the response complete.
& ?1 m1 U& E) K/ L5 ]- t# K; u' _3 }' D7 N" {
By setting "option http-pretend-keepalive", haproxy will make the server7 {9 w Z$ l( I
believe it will keep the connection alive. The server will then not fall back$ B, f" E4 v9 ?0 B R2 l% ]
to the abnormal undesired above. When haproxy gets the whole response, it* w7 D" O7 [* Y, ] x
will close the connection with the server just as it would do with the6 P' L1 ^4 Z( J. b& R
"forceclose" option. That way the client gets a normal response and the
& {2 A- Y/ c" r2 j- Q3 `8 h connection is correctly closed on the server side.
% q6 U8 l2 [% @9 X, e' |0 I; D4 j- \# ~% s4 T2 n4 ^/ O
It is recommended not to enable this option by default, because most servers, ^ G$ n4 |$ f7 a% L
will more efficiently close the connection themselves after the last packet,
) _2 J2 F, V; u0 j0 h: ^ L and release its buffers slightly earlier. Also, the added packet on the; j0 a' `- g) U
network could slightly reduce the overall peak performance. However it is
' e0 K& w5 A) F0 M worth noting that when this option is enabled, haproxy will have slightly
5 q3 W# \: Q- ^6 V% S# g) ^: a0 G less work to do. So if haproxy is the bottleneck on the whole architecture,
" n- s7 g# G6 \$ j" q+ K: E" Q8 q# u enabling this option might save a few CPU cycles.. |" p& L1 ^3 `! Q8 l/ Z" E
% i' {3 f; \& {% n/ ?$ T7 A3 Y$ x This option may be set both in a frontend and in a backend. It is enabled if
$ y7 b8 ^# l0 w o* E at least one of the frontend or backend holding a connection has it enabled.$ H, S* n; g. L6 p `" c: J
This option may be compbined with "option httpclose", which will cause
I' a/ V7 C3 P keepalive to be announced to the server and close to be announced to the
/ E/ R0 y# j5 U. e( G! Z$ s client. This practice is discouraged though.
# Q, Y+ {/ Y4 h6 ~: r2 S# Q0 G$ u
: X9 g' R! _; Y3 [% e# L If this option has been enabled in a "defaults" section, it can be disabled) w/ r, Z* _. P+ B a3 P" g2 @
in a specific instance by prepending the "no" keyword before it.
+ P$ d# s3 r& k6 e2 {! O0 k- d9 k5 A: t/ d7 ~; t3 O
See also : "option forceclose" and "option http-server-close"4 E8 r% s8 L" F. G2 C
. R+ w: f# ^" A' N: p- s
! }1 }/ {# X7 J) f7 Voption http-server-close
, D2 p: c( _* Wno option http-server-close9 q3 H' c- k: T. g, t& J' _7 v: X9 v
Enable or disable HTTP connection closing on the server side
$ Y7 F9 P/ D( ]) [ May be used in sections : defaults | frontend | listen | backend
% C: j1 m2 Y; s& y8 _ yes | yes | yes | yes# e& n0 e8 q( r9 y7 [3 z# M* }, |+ l
Arguments : none
) N9 X) V/ u3 J1 h% U) k/ d, H6 Q D" a( e$ u/ q& A2 i U
By default, when a client communicates with a server, HAProxy will only. D5 _, X X- j3 a
analyze, log, and process the first request of each connection. Setting
: S/ W7 e' \6 `/ | "option http-server-close" enables HTTP connection-close mode on the server) R' g" u. }. k2 h8 [% @0 f
side while keeping the ability to support HTTP keep-alive and pipelining on! F' I# \# K% n$ z6 q, I7 _, Q
the client side. This provides the lowest latency on the client side (slow9 O& O5 S' l {3 b, m) t `( Y
network) and the fastest session reuse on the server side to save server
6 u; B7 L! D: A" w resources, similarly to "option forceclose". It also permits non-keepalive9 O3 h* `% Y4 }) k; ?6 L. D
capable servers to be served in keep-alive mode to the clients if they
0 u/ Q" |8 J+ n. B8 I conform to the requirements of RFC2616. Please note that some servers do not1 P' o w# ?7 m' m; g! B6 Q
always conform to those requirements when they see "Connection: close" in the
. q+ x& E/ y) r9 ]% Q: X2 n6 f5 ^ request. The effect will be that keep-alive will never be used. A workaround
8 ]% a2 [+ z' ~$ m% v4 M consists in enabling "option http-pretend-keepalive".
6 ]$ z o) Q ?. B8 d
* X8 Q" m; D! t& u8 E At the moment, logs will not indicate whether requests came from the same
3 L% \* w x; N( R+ C) L2 _3 n6 C session or not. The accept date reported in the logs corresponds to the end
& Q3 e% Y2 ^3 I- _8 U of the previous request, and the request time corresponds to the time spent0 N3 G! A* u/ M' b$ r+ Q
waiting for a new request. The keep-alive request time is still bound to the! [3 ]1 v" Y; p& Q
timeout defined by "timeout http-keep-alive" or "timeout http-request" if
8 M; n' `5 _7 k& q3 Z/ j not set.( O. K: f- L5 E' }2 ]! p
/ R3 R" \7 q6 I/ h
This option may be set both in a frontend and in a backend. It is enabled if0 h# Z3 h0 d* U
at least one of the frontend or backend holding a connection has it enabled.
3 N; m1 s9 m% c+ X1 L A It is worth noting that "option forceclose" has precedence over "option4 t9 r( n, k) _6 s3 P1 M9 e5 o
http-server-close" and that combining "http-server-close" with "httpclose"
% X x8 F) X2 `4 j9 \ basically achieve the same result as "forceclose"./ A0 o! V! N' s$ O4 N8 v
' [# ^$ \7 {0 m% ^! x1 J* w If this option has been enabled in a "defaults" section, it can be disabled, ^* }* G- c4 J; ]3 I
in a specific instance by prepending the "no" keyword before it.
5 Z- u: h2 d8 N; k; H
% b6 b, x: n- e/ L1 Z: ~0 ? e See also : "option forceclose", "option http-pretend-keepalive",
: Q/ x: a% i! X& l5 o2 m* [ "option httpclose" and "1.1. The HTTP transaction model".
% Z6 l" _4 m# A/ t0 ?) X; ]6 e( x2 c7 z4 Z9 c
+ S9 y) ~' z" E. m3 W' Z
option http-use-proxy-header$ T# _( J) \9 R
no option http-use-proxy-header: r5 R& y+ ^7 ^# e/ T
Make use of non-standard Proxy-Connection header instead of Connection* N& t$ p$ b0 O) c; R" D* [
May be used in sections : defaults | frontend | listen | backend
8 ], L% v9 w- G( } v: ] z yes | yes | yes | no
, n; l* ~" a" z$ Z Arguments : none
) A% S2 T! h* { J+ d. N
4 h3 u* d, M* y# w While RFC2616 explicitly states that HTTP/1.1 agents must use the
0 m! f! n' z* Y1 g: c% u Connection header to indicate their wish of persistent or non-persistent
* v$ t( P& V) s9 a: \8 y: f$ A4 E) d* G connections, both browsers and proxies ignore this header for proxied
7 a Q: F9 M3 C. B/ z+ ^$ V connections and make use of the undocumented, non-standard Proxy-Connection" j% _# p" r- A' B3 W- y
header instead. The issue begins when trying to put a load balancer between' `9 e* l) n) J- i, a3 y
browsers and such proxies, because there will be a difference between what
; k) M s& C+ t, J- L* @ haproxy understands and what the client and the proxy agree on.
, ?7 F/ {" d T; `# t) ]* A: t" d3 ~) W" f8 z9 ^% t
By setting this option in a frontend, haproxy can automatically switch to use
0 }9 n/ [! W# L! ~ that non-standard header if it sees proxied requests. A proxied request is+ U' o3 w& H$ i1 w" Y. a7 V! y
defined here as one where the URI begins with neither a '/' nor a '*'. The' F9 _9 C" }. W% q# P# e
choice of header only affects requests passing through proxies making use of
$ K% Y# K1 E* y! i4 K4 {2 e one of the "httpclose", "forceclose" and "http-server-close" options. Note9 Z; z& I* W; b; a$ C( f% L
that this option can only be specified in a frontend and will affect the
8 t+ R0 \% t, g& o$ \6 Z/ H) v( j3 j request along its whole life.7 E) J" [ g8 i/ I/ d/ }( X
/ {: @" z1 R2 x% P5 m
Also, when this option is set, a request which requires authentication will( E( u/ I, W! l4 I
automatically switch to use proxy authentication headers if it is itself a
8 n V% H" a% V. x' s- M! C# P proxied request. That makes it possible to check or enforce authentication in" u9 y& d& x" U7 N/ w. `1 D
front of an existing proxy.& L, n4 v. [6 B: R( }0 f" ~1 X5 E
5 x+ Y# Y/ r# c1 V {' e2 K This option should normally never be used, except in front of a proxy.
2 U4 w# `; Q9 m$ }" z& t, l: G* x( u1 W g0 J
See also : "option httpclose", "option forceclose" and "option
' w8 ]8 p) l% j! [ http-server-close".) R5 d" \. s9 Z; x& O
& s% r" O, ^. N, `5 a! R
6 _( o! M5 P8 ?: Z# m$ c( |. poption httpchk
$ O. N p. z5 A7 ]3 Q7 e( hoption httpchk <uri>* q. w" h& M, H" Y/ f* ~
option httpchk <method> <uri>
: K; L$ t O2 _7 [+ u/ qoption httpchk <method> <uri> <version>
) Z! z% u' k1 D- { Enable HTTP protocol to check on the servers health
$ d }' B1 J% y% M May be used in sections : defaults | frontend | listen | backend# z: O t# H$ \7 g7 T
yes | no | yes | yes, A3 _. f* A) J J: g
Arguments :4 v' _; S8 O9 q
<method> is the optional HTTP method used with the requests. When not set,
6 j$ f8 C. y/ p* Q2 ] the "OPTIONS" method is used, as it generally requires low server
. @: d% e, w0 ^1 _( X7 M processing and is easy to filter out from the logs. Any method
7 b, a: o$ p, }9 |0 |' E7 W may be used, though it is not recommended to invent non-standard
7 Y* U$ Z q8 W2 k; l+ w0 j ones.
8 x+ @+ F m0 z* A2 ?6 p# x0 G0 y) R* ]' ]! H
<uri> is the URI referenced in the HTTP requests. It defaults to " / "0 l2 r/ G( t- t. z7 Q# R/ P9 P
which is accessible by default on almost any server, but may be9 Y/ y3 M7 g6 S* C$ w& \1 m7 m
changed to any other URI. Query strings are permitted.
) V R$ L# S; Z
1 x8 A; c V$ y9 O0 c <version> is the optional HTTP version string. It defaults to "HTTP/1.0"
5 `, h$ I. X; t8 _, w6 t) B- M# g/ Q but some servers might behave incorrectly in HTTP 1.0, so turning, R9 N4 i U* D
it to HTTP/1.1 may sometimes help. Note that the Host field is
' T, W# T& C2 e' W& G- \% f mandatory in HTTP/1.1, and as a trick, it is possible to pass it
3 X ]$ ]( O* X/ i+ M% [ after "\r\n" following the version string.
; b" b. ?) X9 V5 L3 U* S9 ?& Y. B2 x% p7 l& u% Q
By default, server health checks only consist in trying to establish a TCP- c/ `, L9 Q0 ^3 w
connection. When "option httpchk" is specified, a complete HTTP request is
( F1 P" N5 v- G8 m) h" ` sent once the TCP connection is established, and responses 2xx and 3xx are+ b2 C4 `' v+ J a
considered valid, while all other ones indicate a server failure, including
; c* L7 f+ K7 k& t. D the lack of any response.
- @8 D. m9 y9 Q' J& c% H7 b$ L4 c) |4 v/ r# E9 m& k
The port and interval are specified in the server configuration.
1 g. U" F* x+ ^2 c/ S. t( J C! y8 y
This option does not necessarily require an HTTP backend, it also works with
& g8 L S$ N' G+ r" K P: |" ]4 p plain TCP backends. This is particularly useful to check simple scripts bound. x( Y' e" ~& ]/ E+ Z
to some dedicated ports using the inetd daemon.
3 v8 w( S8 b) `- I5 E+ y
* ~7 U, N7 z" |2 c. b6 [ Examples :! [" Y* W1 L, {2 B# y' F
# Relay HTTPS traffic to Apache instance and check service availability; c% [; [. j# g& d+ l* \ m
# using HTTP request "OPTIONS * HTTP/1.1" on port 80.
7 B% r C: c6 J6 P( N$ n backend https_relay3 X: N9 J# s$ }$ Q8 t8 e5 T! V
mode tcp
; g; O3 O0 S5 p# m7 o option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
8 T$ s/ E: V* |. g2 r- I( ` server apache1 192.168.1.1:443 check port 80
; u4 Z; ^- U5 o- A. `$ \% H) u6 s% K- `# t4 Y! S3 @; [
See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
. e$ [! {% d% {- A" _ | "http-check" and the "check", "port" and "inter" server options.7 v K, ]7 r- |0 O
2 J' Q! q4 p# t4 ~. }; O, |
$ {; \$ w' F+ b: M( m
option httpclose! ?# h) w9 f2 L
no option httpclose( ]9 s. o8 ?7 Z. T+ o
Enable or disable passive HTTP connection closing
) }; v% e. I+ {8 ] l) w! c May be used in sections : defaults | frontend | listen | backend# Z" Y! R7 g, E5 N$ h
yes | yes | yes | yes# @9 K/ }7 y$ U ]" Z, p: w6 m0 Q
Arguments : none# Z$ V" C1 i4 ]6 u- M: M
7 [/ c0 I6 d0 V! \) ] By default, when a client communicates with a server, HAProxy will only4 i5 m6 Y9 m' Y( {$ Z
analyze, log, and process the first request of each connection. If "option6 d; ` n9 `+ b2 k/ c. T4 n
httpclose" is set, it will check if a "Connection: close" header is already
; E r7 U8 z9 J( k: R) F0 ] set in each direction, and will add one if missing. Each end should react to# J0 S- I$ t( _$ F0 L- y
this by actively closing the TCP connection after each transfer, thus L+ M3 I7 s0 Z l1 L( L2 `" V
resulting in a switch to the HTTP close mode. Any "Connection" header) V$ N: c. i2 Q* Z, I8 Z
different from "close" will also be removed.& X; A$ O! {- I; y3 Q+ q. Z9 b: M
# U" Y% ^% e8 [3 U; E1 o% P2 Y
It seldom happens that some servers incorrectly ignore this header and do not4 U. g/ N" s( b& i, N! H
close the connection eventhough they reply "Connection: close". For this
' l. ?$ N! ^/ i9 ^1 {5 N) b reason, they are not compatible with older HTTP 1.0 browsers. If this happens9 c a# G2 y/ q1 u/ K
it is possible to use the "option forceclose" which actively closes the
' t1 q8 v, r9 ]4 ~7 Z' R request connection once the server responds. Option "forceclose" also; f1 L# G7 F) Y7 y2 Z9 Q
releases the server connection earlier because it does not have to wait for
8 t R: K2 M; [! A. K, z* U' ^$ z the client to acknowledge it.4 h4 x; x9 v# O( T/ D# g; J
. E3 Z: T4 d0 n0 U M/ M! G7 }+ u This option may be set both in a frontend and in a backend. It is enabled if- ]" ~' C* {% ~& @' F9 G0 Y( v
at least one of the frontend or backend holding a connection has it enabled.
, K' Z) W# Y7 e6 L8 ? If "option forceclose" is specified too, it has precedence over "httpclose".' j& D( X0 V! ^3 z' \' `
If "option http-server-close" is enabled at the same time as "httpclose", it) F+ P0 [) R) b
basically achieves the same result as "option forceclose".
. n) t7 E' p0 K! [3 _. F. r, Y
" O. Z7 N' E- `7 J+ q" u If this option has been enabled in a "defaults" section, it can be disabled
6 A9 Y: _* g" q0 z in a specific instance by prepending the "no" keyword before it.; J0 B) R, n$ x& b; g# C( ?! G8 L8 D
; E V V/ i+ k
See also : "option forceclose", "option http-server-close" and/ P) A% R2 @$ M+ Z- I
"1.1. The HTTP transaction model".. L" z* q) y1 e, P% V) q3 X
, I1 ?& S: V, E6 E0 q7 h' x
. ^$ d/ O3 {+ J2 K+ ]- \option httplog [ clf ]& U5 ~: \6 W" y+ L4 G6 B: o* @& d0 \9 G
Enable logging of HTTP request, session state and timers# J: t) p2 R% X r# \
May be used in sections : defaults | frontend | listen | backend
+ d2 v' Z' n* M' }, C yes | yes | yes | yes# q% t7 [/ T0 R) m0 i+ c
Arguments :
1 o" q* i* j+ @$ o9 J3 | clf if the "clf" argument is added, then the output format will be/ y+ s; Q, z; T
the CLF format instead of HAProxy's default HTTP format. You can! q ], R" }& B& q& Y
use this when you need to feed HAProxy's logs through a specific$ C' a3 {3 s0 q M0 B- J
log analyser which only support the CLF format and which is not
! e5 C6 b& L5 O" j$ c5 |& s extensible.
7 B9 q. f* B! @2 s8 _& t! ~9 e' J1 `8 ?: a
By default, the log output format is very poor, as it only contains the# I7 C: z3 y1 W4 D! U
source and destination addresses, and the instance name. By specifying/ X' j5 i! Q9 ^' m
"option httplog", each log line turns into a much richer format including,
: S, _7 _9 L3 a1 X, c but not limited to, the HTTP request, the connection timers, the session" `& B- P# U5 `9 x2 q; \2 q
status, the connections numbers, the captured headers and cookies, the8 Q& \, Y( t5 U+ m& _
frontend, backend and server name, and of course the source address and1 q, T [( D" r0 Y, O
ports.
$ C/ B) p- `; G; N O$ w& C! s' m
% s3 n5 p+ @2 i* A6 ]: x This option may be set either in the frontend or the backend.) H% w9 p A( E5 n: J( K
{5 i8 j7 D7 Q I- q: A: P: z Specifying only "option httplog" will automatically clear the 'clf' mode. Y3 m! @/ I% ?! `6 v
if it was set by default.1 Q! J1 i0 Z5 j4 M& H: Z t' Y
n5 _$ Q2 T7 D9 y- E F- @ See also : section 8 about logging.; {2 d' U: {* w0 N# Q* ~' n, [
. A. T* A# x- Z0 ]/ d: x( d
. h) F$ Q; [$ Y* G5 a9 boption http_proxy
+ [4 q, H! ?6 ^- u9 X( R2 A* ?no option http_proxy& ?# ]. u& V( d0 ?7 P
Enable or disable plain HTTP proxy mode& n; F+ w2 v0 s
May be used in sections : defaults | frontend | listen | backend
4 c/ D3 j( T6 M* o' n5 N yes | yes | yes | yes7 ?7 I5 B7 @0 t2 L
Arguments : none& U! }- Y9 B3 l u/ o
, w/ ~5 H8 [' E, H! P
It sometimes happens that people need a pure HTTP proxy which understands8 j7 C( |) b8 z, I, Z" y
basic proxy requests without caching nor any fancy feature. In this case,9 c' X6 k; _5 f, p& ^8 n
it may be worth setting up an HAProxy instance with the "option http_proxy"
- Z# e3 o! t7 B1 c8 t; O7 z- g set. In this mode, no server is declared, and the connection is forwarded to& V' I+ A0 y( Q' t( H
the IP address and port found in the URL after the "http://" scheme.5 _& I& \2 V/ q) r. a, [5 T1 v
) G7 O5 ~2 B" f No host address resolution is performed, so this only works when pure IP: u; ~. P$ E0 ?& a
addresses are passed. Since this option's usage perimeter is rather limited,
& ~/ x$ \4 S& S2 u it will probably be used only by experts who know they need exactly it. Last,
0 Z, F; z2 e. G, \& C if the clients are susceptible of sending keep-alive requests, it will be
( v& j' N9 z5 Z& n) Z/ J1 V, U needed to add "option httpclose" to ensure that all requests will correctly! d$ f( I7 Z- i8 M
be analyzed.
0 g4 @7 C% D5 o5 `' O* M4 s' d& R0 j- {8 ~
If this option has been enabled in a "defaults" section, it can be disabled/ c' G1 X# T. {& ^; m
in a specific instance by prepending the "no" keyword before it.- b' t* A/ t+ P" }- N9 G
; }, n1 B. y( Y- K5 y, j C, U
Example :
& c2 P0 j) I2 A; S; |$ h # this backend understands HTTP proxy requests and forwards them directly.
+ h' `1 Q1 Q/ [8 G* w9 ] backend direct_forward5 w3 P$ t( h% s1 b
option httpclose
- ^* p8 b% |4 P# H: j4 t* s+ D option http_proxy+ y4 p& a2 a: v% n2 k6 a6 E
. c4 L' p* E0 H A( d- Y$ q See also : "option httpclose"6 @8 w) [2 Z* C& h" W5 R& \$ r7 t* A; Q
/ u; K" ]# f t) J5 W
4 K- i8 g8 V7 f/ \/ H- }3 L
option independant-streams
" e+ `9 h1 ]$ x1 O3 Z- q% ]no option independant-streams
5 b3 E, x ^ y% Z+ f Enable or disable independant timeout processing for both directions6 @5 j9 o: g+ ?5 {) J. Y3 k3 B
May be used in sections : defaults | frontend | listen | backend
6 K* J, e" q; Q F yes | yes | yes | yes
) h* s, `" p; t+ B$ E6 V$ J& \! v Arguments : none/ \; J2 g5 E: F9 @5 Q
5 ~$ y2 N# R" ^0 K0 Q2 {+ `7 ? W
By default, when data is sent over a socket, both the write timeout and the$ f5 o' z/ s2 Q K8 w
read timeout for that socket are refreshed, because we consider that there is$ ?1 p$ w( E3 y" I
activity on that socket, and we have no other means of guessing if we should j3 d0 H* Z' u, B
receive data or not.
! ~( e, L( H5 b/ `% t* h0 V% D& \& n! _' X8 c! R; |
While this default behaviour is desirable for almost all applications, there& g5 |% r) [" V: y" K# x
exists a situation where it is desirable to disable it, and only refresh the: T8 r0 {! K1 }) m9 h
read timeout if there are incoming data. This happens on sessions with large
e8 B6 O3 J- l timeouts and low amounts of exchanged data such as telnet session. If the5 ~ _2 w# Y+ C5 A" V9 S
server suddenly disappears, the output data accumulates in the system's% J# x' U0 N' v' |( k+ r; u5 ]
socket buffers, both timeouts are correctly refreshed, and there is no way- \- H% b2 H1 U
to know the server does not receive them, so we don't timeout. However, when
; D( `) I! S4 h2 z7 O# s1 w' a the underlying protocol always echoes sent data, it would be enough by itself
* M# ]# D& @. M% t/ \ to detect the issue using the read timeout. Note that this problem does not
: t, x/ {9 |/ ?, Y$ r# r happen with more verbose protocols because data won't accumulate long in the
( W1 r' y7 |$ Q) N! A, Q9 E' f9 T socket buffers.
4 I! u; y- `& o/ @: B, d3 f% Z3 k. k1 C& y/ j
When this option is set on the frontend, it will disable read timeout updates
. ]# b, ]( d9 \- X on data sent to the client. There probably is little use of this case. When3 Z# p; m$ x6 E
the option is set on the backend, it will disable read timeout updates on1 P9 f0 I: ~9 C/ q8 p% l3 Z
data sent to the server. Doing so will typically break large HTTP posts from4 _8 |2 m' g4 H4 \, ?# v
slow lines, so use it with caution.; X7 w, ?" G7 T9 D: n! f1 q" I
- J5 r. J0 c9 {6 t/ |5 M See also : "timeout client" and "timeout server"
2 D0 f' @/ r; k9 Z' c& i2 S- V8 t( R. s$ p2 n' t) c5 W) R
( k' @9 M6 ~. }# V% V/ b0 r
option ldap-check
# a8 ^9 I& x% L: ?$ C Use LDAPv3 health checks for server testing
3 l' y3 L3 a6 K( g; g May be used in sections : defaults | frontend | listen | backend! U; M2 u- X" c+ f4 _3 t# s- s
yes | no | yes | yes
$ q. M7 s8 Z2 K: @ Arguments : none. G$ K% u5 o a+ s, {1 q8 }' B
+ x5 w# G/ k9 b
It is possible to test that the server correctly talks LDAPv3 instead of just" O- m4 X, d# J" J9 `! R5 g. d# K
testing that it accepts the TCP connection. When this option is set, an, `5 O6 h* |& V" k
LDAPv3 anonymous simple bind message is sent to the server, and the response
# _; w3 ?; J$ K0 D7 ~ is analyzed to find an LDAPv3 bind response message.
5 i- W% N7 r# F. n: u/ Z H+ V2 G
) i ]& I* X) M The server is considered valid only when the LDAP response contains success
$ x1 W7 _* H1 w+ W resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).
. I, k* p* l4 i1 r6 e. w
& d, {) N c, R$ ]# x. ` Logging of bind requests is server dependent see your documentation how to' r% F1 h, y6 b7 ?) P+ u
configure it.
& }( t, v& Z. s! m
: N4 x) }% g8 T4 x) {( J! Q2 } Example :
1 N" ?4 O' H) w0 n+ B option ldap-check& l3 m3 |) }' v: u6 c! r. `/ |
: Q* J" B+ D3 j: A1 [
See also : "option httpchk"
% ?5 Y8 i# L# O
+ S2 B% C5 I: o# Q+ k# V& i& e1 M$ l, ~
option log-health-checks+ T: K7 P& ?9 E
no option log-health-checks$ K$ s$ [7 r n% |3 \6 ?
Enable or disable logging of health checks9 N" |: a+ N! C0 k
May be used in sections : defaults | frontend | listen | backend" R; Z1 D2 z) j, L* r6 \+ k
yes | no | yes | yes
6 S6 @- }" c. g" `: L4 Z/ h. X, h Arguments : none' K$ P+ a' C" _: K! |
+ n0 u4 B8 Z8 Y. Z5 @# t Enable health checks logging so it possible to check for example what- f2 Y6 ^% N4 T. i" o+ `9 R: N
was happening before a server crash. Failed health check are logged if
/ B. P. ], q/ i4 | server is UP and succeeded health checks if server is DOWN, so the amount9 b+ P% Y' }8 _8 F
of additional information is limited.& Q5 e( C3 z: M. `4 I0 U
! f* y0 n* Z4 K" A) B If health check logging is enabled no health check status is printed
$ |4 P+ w; p8 }) T when servers is set up UP/DOWN/ENABLED/DISABLED.
% Z6 p% x: A) G! O W/ C. m) V0 |7 s" K3 \' C9 u6 M( e
See also: "log" and section 8 about logging., ?6 \! i& q- H5 P
: B, R; _7 G2 K* Q/ w! B
) U1 A2 Q+ E& _+ V5 L5 E2 |% _8 q: M2 @
option log-separate-errors% {2 \* v: R4 D3 H1 ?
no option log-separate-errors8 H2 L/ D& h1 S! ]
Change log level for non-completely successful connections
' C' b- g: u/ ]" Q May be used in sections : defaults | frontend | listen | backend) o0 u& g$ K) j D& Y: d9 K# ]
yes | yes | yes | no
/ ~- Q4 C8 V$ B" c2 \( g Arguments : none @9 R/ f" S% I8 G. _" m
1 Z* J9 o* N% H6 j- y! R Sometimes looking for errors in logs is not easy. This option makes haproxy+ A. C) o. e# _" d- T: U
raise the level of logs containing potentially interesting information such
% ^- D4 N4 s* w" H+ N as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The. n' o* d8 O2 i/ j
level changes from "info" to "err". This makes it possible to log them
0 L# o" j; D) V separately to a different file with most syslog daemons. Be careful not to9 e3 N ^, l# a$ h! F0 N8 R
remove them from the original file, otherwise you would lose ordering which
o- u8 E, w$ s& C' w4 R) g0 D provides very important information.
! {' G% [: K0 ~. W# e- `6 \' T
3 [1 {: k( p/ Q( z b' i Using this option, large sites dealing with several thousand connections per
: m& ]" l8 s5 O second may log normal traffic to a rotating buffer and only archive smaller
1 w' c1 b* f. l5 b$ f9 i error logs.- K6 z+ I) V9 s2 F6 \# M4 }9 I+ z
( H0 a* N5 h2 |8 p% \% e See also : "log", "dontlognull", "dontlog-normal" and section 8 about% H* @2 D7 S3 z4 E6 e5 m
logging.
! ]: ]0 V( p' w; J3 ^4 u
0 L9 n* K) A: n3 j, c/ g: g$ a& u; r. l' g
option logasap
2 W V. [+ G% m2 ~no option logasap
" x4 C' _4 m' S- D( F: K' ^# C3 u6 a Enable or disable early logging of HTTP requests
) F. T6 ^' p7 ]* l* Y' P* {4 F* V May be used in sections : defaults | frontend | listen | backend
, D$ e" G. s# A! U' X5 J yes | yes | yes | no
- Q' n7 ^; ^$ Y Arguments : none) L, H9 D# [, B
# {& T( O, E3 A+ n! i By default, HTTP requests are logged upon termination so that the total2 W0 ~) y% P+ h/ F
transfer time and the number of bytes appear in the logs. When large objects
, c b4 @! y% t; p$ _ g are being transferred, it may take a while before the request appears in the# f# r& I5 x1 w, y
logs. Using "option logasap", the request gets logged as soon as the server; ~" b- s- U# L& f
sends the complete headers. The only missing information in the logs will be* m- K" g; v- F) b; l- L6 }
the total number of bytes which will indicate everything except the amount, c( t- s/ _+ p! U, l
of data transferred, and the total time which will not take the transfer
6 O4 L, r# c+ l9 m+ O* b- _ time into account. In such a situation, it's a good practice to capture the' n% \! g4 k: p5 T- q0 b
"Content-Length" response header so that the logs at least indicate how many# z9 g# F2 \$ \0 C$ a. x
bytes are expected to be transferred.
( K8 z- N" S1 f; X+ ^. I
9 i3 X ?4 P# r6 u Examples :
; S& g6 l, V' p' w! [ listen http_proxy 0.0.0.0:80
`% F% q( T- i# S9 s mode http
* R& i$ R. \. e& @ option httplog1 g( M& a h) ? K% F3 m
option logasap5 x3 \# P0 H1 p; x: G) i0 `
log 192.168.2.200 local3
4 N; h) j! v: O0 `% x( G- B
: Q% a5 m0 a. ^3 a& `4 h2 e1 ` J/ F >>> Feb 6 12:14:14 localhost \
" S1 y7 l2 z( g7 Y N# [- h# ^) C haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \1 u! F( Z* {8 ^3 `7 r0 e
static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \: f# m F& b% w. x
"GET /image.iso HTTP/1.0"
4 }1 F, t/ Z2 ~: x8 E5 e U% O9 C' t$ U! ~4 x
See also : "option httplog", "capture response header", and section 8 about
; E$ q, y6 x% V+ z, l logging.
; f# H# Y6 c, y# W4 J6 Q# d- z7 W0 u, d2 E* t8 Q
3 m9 a \8 H0 u- z& uoption mysql-check [ user <username> ]* K; h8 X9 a. R8 v6 ~: X- B6 S
Use MySQL health checks for server testing) F9 |: W9 i- P9 ]8 g" G' {
May be used in sections : defaults | frontend | listen | backend
7 x; I+ h& `5 E8 ]3 { F yes | no | yes | yes! F+ j- G* `: f& f K
Arguments :# n, o) Z3 Q! V# g) g3 o
<username> This is the username which will be used when connecting to MySQL
+ K$ _& Y1 r8 x: T. G, a server. j5 \$ r! E6 ^0 g( z
3 y6 N6 x; Z. O9 P3 u! q. H If you specify a username, the check consists of sending two MySQL packet,
% l6 r% `+ M$ f) w one Client Authentication packet, and one QUIT packet, to correctly close
& b- c1 M/ v8 v( ? q% a! p$ i MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
, `3 v, g v% P3 P Error packet. It is a basic but useful test which does not produce error nor
; s) p( a9 w$ n' B, t0 {, X3 G' U aborted connect on the server. However, it requires adding an authorization) n4 k" N8 V3 L: }. }% k, `. k4 k
in the MySQL table, like this :
: F9 ~: C* }% f
1 B' m* l6 b4 _0 ?, } USE mysql;
* x) G( _& y3 H) H: F( n INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
6 \9 Q: S) N# }7 i+ X FLUSH PRIVILEGES;+ R% [7 h( S9 M7 n* u0 E
) m2 M1 Q. d& m C; ?6 V7 F; J2 E0 D If you don't specify a username (it is deprecated and not recommended), the
/ t+ Z5 S2 h: K. D0 u check only consists in parsing the Mysql Handshake Initialisation packet or, i9 [# G7 l. v; k4 r& B
Error packet, we don't send anything in this mode. It was reported that it5 u& s- j7 [6 T; @0 m2 W4 |
can generate lockout if check is too frequent and/or if there is not enough
' k& U8 |3 C6 Z: f traffic. In fact, you need in this case to check MySQL "max_connect_errors"
; T* ~( F, K- Y# R. Z value as if a connection is established successfully within fewer than MySQL
% ]" T% v! \) b) d "max_connect_errors" attempts after a previous connection was interrupted,+ w% J* D) ~+ D. d, `0 h
the error count for the host is cleared to zero. If HAProxy's server get' T0 d% a4 w( f+ O+ E/ y
blocked, the "FLUSH HOSTS" statement is the only way to unblock it.
9 h- m5 `9 K2 y& ]+ X7 z) g" c5 R+ S4 X! W G8 _' L# v
Remember that this does not check database presence nor database consistency., L2 u6 l' m% _+ `3 h
To do this, you can use an external check with xinetd for example.
3 U7 y. [" [% |+ v4 o1 L$ ~: X! R! h# \) f* j0 p' _- @( w
The check requires MySQL >=3.22, for older version, please use TCP check.* d3 a9 \5 d# A: [
- c5 O G2 l( _ Most often, an incoming MySQL server needs to see the client's IP address for o$ _: o# z; T( o! a/ _
various purposes, including IP privilege matching and connection logging.
4 F0 i, v" V- { When possible, it is often wise to masquerade the client's IP address when
1 r; E8 v) I4 B( i5 Z, { connecting to the server using the "usesrc" argument of the "source" keyword,
5 }9 L8 x: A( D which requires the cttproxy feature to be compiled in, and the MySQL server
# X6 e# t% P8 n1 j% Y8 ? to route the client via the machine hosting haproxy.
/ B0 A$ Z' U: ~- Q0 @& O k0 I X H3 a
See also: "option httpchk"
' u9 B8 L3 {+ L: Q. A' ?
0 q0 ^2 O+ z' M3 h" Q% N; c! @( t7 [" v
option nolinger& b) F5 ~* h; j$ \9 n3 G$ E
no option nolinger4 @: @* Q4 a1 l! \3 p
Enable or disable immediate session resource cleaning after close
- {( Y: D- v" ^! N6 W May be used in sections: defaults | frontend | listen | backend
4 p+ }/ A' L r& E+ @8 i yes | yes | yes | yes
" B( e" \3 `8 O9 [# a6 P5 ~6 L9 d Arguments : none( V# v0 I+ ]$ ]3 b1 S9 W B- b" Y7 F6 p, W
& I1 B2 K" S' r( |+ B. @, k
When clients or servers abort connections in a dirty way (eg: they are
1 v9 E B L& Q1 _2 @ physically disconnected), the session timeouts triggers and the session is/ Q+ L- H& ]4 U8 T' q1 @. u
closed. But it will remain in FIN_WAIT1 state for some time in the system,
Z8 O1 o8 A. j. h% Y' P2 P using some resources and possibly limiting the ability to establish newer/ ^) G! K( N6 I& o! q
connections.
6 ^& D) G0 _' I% _# r
6 J7 Q- J2 }7 J9 F/ m7 z, U8 S When this happens, it is possible to activate "option nolinger" which forces
8 R4 i# `. Q3 v) Q9 l the system to immediately remove any socket's pending data on close. Thus,
7 y) |3 e; q1 [/ w the session is instantly purged from the system's tables. This usually has+ ^% S G) Y7 l
side effects such as increased number of TCP resets due to old retransmits4 L# ~6 [5 p8 v% h* j/ |' l: ?
getting immediately rejected. Some firewalls may sometimes complain about
% Y4 H* H: F2 w: i& y/ M% { this too.6 I# l; p2 B$ b& P9 K& c
& m" M4 Q7 P8 u( K+ B) M8 r- Z
For this reason, it is not recommended to use this option when not absolutely) M2 E0 G# O& r' i
needed. You know that you need it when you have thousands of FIN_WAIT1
+ b2 l8 M0 g& u% a* _& ^% q5 R/ F sessions on your system (TIME_WAIT ones do not count).5 T6 J7 X8 ~8 e( {% Y
6 [' e0 Z _5 K, q. M% b This option may be used both on frontends and backends, depending on the side
! ^) D9 C* M( x5 j& d" _% M) j& { where it is required. Use it on the frontend for clients, and on the backend
% t% |3 z. r9 w for servers.
2 R6 m4 R& r2 x* p$ a7 d' Z6 K. p4 o9 j6 \1 ^* ~
If this option has been enabled in a "defaults" section, it can be disabled9 ^% x6 ?* I! b5 p- P; y
in a specific instance by prepending the "no" keyword before it.8 r5 ~6 ~* X" f1 t: G
5 w' c* V' } X# b
0 F: R2 Q/ w8 z6 `1 S0 `, {: poption originalto [ except <network> ] [ header <name> ]
+ G' K: }# m! g7 Y/ F+ X& [: m5 t Enable insertion of the X-Original-To header to requests sent to servers
9 Z- p" Q5 ~9 u May be used in sections : defaults | frontend | listen | backend& j; c, F% ~% T0 v w% n0 F6 ?
yes | yes | yes | yes
6 t6 Q; {- K( V: ?, k Arguments :5 p7 o+ I4 q# t; T1 y$ J8 E1 Z- `
<network> is an optional argument used to disable this option for sources
' ~/ D( u6 w) t1 c p6 u matching <network>
2 l" W( R1 Y: ~ <name> an optional argument to specify a different "X-Original-To"5 i1 p6 {+ b0 Y
header name.
- [) d, e4 y8 C: @, W* Q, l& K- n1 j9 ]9 y/ R Y# F
Since HAProxy can work in transparent mode, every request from a client can
1 z& \, X( W% ]) @! F be redirected to the proxy and HAProxy itself can proxy every request to a' v% R. R2 v1 J# k
complex SQUID environment and the destination host from SO_ORIGINAL_DST will4 F- c5 X* G; y4 J/ Y
be lost. This is annoying when you want access rules based on destination ip( w/ r3 [6 U! H9 @7 u+ o8 f- e% O. d
addresses. To solve this problem, a new HTTP header "X-Original-To" may be+ [9 h+ X" g. ~& ~' h0 d8 t2 z
added by HAProxy to all requests sent to the server. This header contains a
! _' X5 |/ P/ R$ S3 Y value representing the original destination IP address. Since this must be
' w( z m& ~8 ?" K, |% E+ x" O& z configured to always use the last occurrence of this header only. Note that
- W, O5 w( C2 P7 O# h# v* N only the last occurrence of the header must be used, since it is really
/ I1 W& q- C9 r+ v' X& Y9 p N0 } possible that the client has already brought one.
: s! g( [; }" ]* a
+ p, K3 H# J5 O4 p* R5 V( `, U' y The keyword "header" may be used to supply a different header name to replace# \$ l% b3 g6 _+ W+ ^; V n& G! t
the default "X-Original-To". This can be useful where you might already
" F0 V, n# f. V. X have a "X-Original-To" header from a different application, and you need
7 I# `9 l- Z0 g2 ?, n preserve it. Also if your backend server doesn't use the "X-Original-To"1 c2 ^, A/ l( l
header and requires different one.4 ]/ } t6 x% z
! b1 D2 o! s4 H Sometimes, a same HAProxy instance may be shared between a direct client
5 \' `2 K' S1 O0 ` access and a reverse-proxy access (for instance when an SSL reverse-proxy is
2 w: Q; N: _7 k' G; r1 @ used to decrypt HTTPS traffic). It is possible to disable the addition of the
( L( L ]; { h header for a known source address or network by adding the "except" keyword. h. G/ e: A+ @" B* q6 ]( U
followed by the network address. In this case, any source IP matching the
6 F; U m X7 W: u- P/ M" J network will not cause an addition of this header. Most common uses are with2 Q! i. r9 b) A8 N
private networks or 127.0.0.1.
( f X/ E$ I8 H% L( D9 \ k2 v- K+ M4 g4 j4 x+ j- f' t
This option may be specified either in the frontend or in the backend. If at
. N( J5 L* P9 @6 {$ V" h least one of them uses it, the header will be added. Note that the backend's
2 h* y$ X- ], _/ y# J- y setting of the header subargument takes precedence over the frontend's if
0 s7 y$ i' D" S both are defined.( B) x, m4 C' q
! S( J/ }8 x2 M: h7 O" N
It is important to note that by default, HAProxy works in tunnel mode and0 q) s6 R; ?7 `* M+ D6 l
only inspects the first request of a connection, meaning that only the first( w4 @6 ^9 y0 [2 z5 Z" h' e. Q
request will have the header appended, which is certainly not what you want.
8 Y" |! f4 c3 t) \: ?2 X- k, w In order to fix this, ensure that any of the "httpclose", "forceclose" or0 ^$ y, A g* w) U, F* o! D* P
"http-server-close" options is set when using this option.
' x- K- n+ l2 X, R7 d, P, w
. C' q: O* V: u6 Y d0 Z Examples :
/ C8 [0 H' C' K3 g* I2 d* W # Original Destination address: D4 V2 U# Z1 U- T
frontend www
5 x8 H& r# |/ w2 k H! H mode http
6 ~3 b% ]$ J+ L option originalto except 127.0.0.1! N( U) Z; ~; O' a5 i. Z
' L' x# o- p5 N. N @5 B& O) l # Those servers want the IP Address in X-Client-Dst
4 R" X: N x9 L% `! E7 a% _ x backend www9 @! W( ^' O# g! j
mode http0 u, O2 a7 }. j8 ]5 }" N" d) Q% L
option originalto header X-Client-Dst$ G& E# E9 Q1 m) V( v
: m) Z& n9 w r( P! | See also : "option httpclose", "option http-server-close",
: X6 C3 I9 {7 V+ k0 a1 t! o "option forceclose"
" K r8 c' j5 _/ H
3 r9 C( \4 s9 z" e) S% I. ^3 P) r/ J
; l8 X5 O1 }# z: n$ I( voption persist
( x/ u1 A( ?7 L" @9 }& ono option persist' H% E. O, F. S+ ` g. B3 ~
Enable or disable forced persistence on down servers5 T2 P$ ?* A% Q' @1 P8 y: x. a
May be used in sections: defaults | frontend | listen | backend
# {6 L$ C, L( i) @! m& j0 j$ F5 P yes | no | yes | yes
" S8 e6 r' o; o* r Arguments : none" G% B7 C6 G; f/ F
- N' w- ~7 b3 z* D' O! x, X( \) [ When an HTTP request reaches a backend with a cookie which references a dead2 }; ? Y3 m1 J# L- Y( O
server, by default it is redispatched to another server. It is possible to
8 O/ P( ?# d d1 P1 p2 Q6 n. B force the request to be sent to the dead server first using "option persist"; p1 A& E/ t) H, c. }, B
if absolutely needed. A common use case is when servers are under extreme3 ~, H7 |; s- ~0 o
load and spend their time flapping. In this case, the users would still be
+ b( n. H( @. Q) u! V8 `3 q directed to the server they opened the session on, in the hope they would be
7 a6 b% g/ U e& S; O# g& ] correctly served. It is recommended to use "option redispatch" in conjunction
% _# M4 u8 B y with this option so that in the event it would not be possible to connect to* ^" \! Q; n& P% O! n2 s8 t, X' a
the server at all (server definitely dead), the client would finally be# C* m s& V& K) S6 F
redirected to another valid server.
5 x j7 w, @5 I3 B2 |6 D8 C# x5 y2 ^' L1 P4 K4 a+ g
If this option has been enabled in a "defaults" section, it can be disabled
: u6 b- N: F& P1 B# k' z7 Y& l in a specific instance by prepending the "no" keyword before it.' a1 e; Y- v% _( D1 O5 [9 W
1 \6 [8 _$ K1 l2 P8 ^( f) M
See also : "option redispatch", "retries", "force-persist"
: {- R( O9 X/ q0 t) l3 \) C, L9 p J
, V3 c B$ J* W d, y7 Yoption redispatch1 P: U6 D* D/ j4 M3 g1 C: T
no option redispatch
" l) h3 f. `1 Y8 ] Enable or disable session redistribution in case of connection failure
+ l o) e$ X9 Q May be used in sections: defaults | frontend | listen | backend
W$ ^/ k1 Q, C: G3 S% ~; V" w yes | no | yes | yes# @6 C: r' j4 h5 D
Arguments : none# U& |. s/ V3 L- Q5 ~3 V, W
- D& F* }, ]0 f. k1 F! c
In HTTP mode, if a server designated by a cookie is down, clients may; b* v% H' L! @( Q: d5 v3 C( \
definitely stick to it because they cannot flush the cookie, so they will not8 ^1 T3 N; N) k8 e5 I1 |3 V' R
be able to access the service anymore.. ]; z( E& W+ o+ T- C$ v9 w
x+ A9 K# V* x, e: O
Specifying "option redispatch" will allow the proxy to break their
! h+ y0 L4 M1 x3 `3 G! T persistence and redistribute them to a working server./ |2 D1 Z' T* J0 y
5 K( c: [: v7 m6 G, Z/ [" C7 l It also allows to retry last connection to another server in case of multiple
8 c& `' r9 u$ s4 G connection failures. Of course, it requires having "retries" set to a nonzero9 a+ P Q" e7 ?& l# H. `: x( p' `
value.
& ^. T6 D& e9 t* c# }5 n% [
% v; w$ `) n) u: t" l This form is the preferred form, which replaces both the "redispatch" and! D9 |& t( {8 H0 x. b8 N+ l
"redisp" keywords.6 B- W. r7 W! `6 C' K
& M3 y7 v# j4 G' |# O1 B5 S If this option has been enabled in a "defaults" section, it can be disabled% A s/ R$ y% S% l m
in a specific instance by prepending the "no" keyword before it.
{2 n4 m* B) ]3 q z. `' D
2 o5 k4 _+ }5 {7 X. ]' a$ ` See also : "redispatch", "retries", "force-persist"7 C7 C' e7 Q) }2 a- b& s% m5 A4 B
( X" ^- w8 ]7 Y2 b9 n# J+ |0 U/ K$ T" m
option smtpchk
. T# e8 Y0 i/ l* ]( S" Qoption smtpchk <hello> <domain>
2 y7 q( [3 J7 W Use SMTP health checks for server testing
2 W1 W" k, h$ v* @, J: Q* v8 ~, V May be used in sections : defaults | frontend | listen | backend# ]1 [0 w- G, m# B
yes | no | yes | yes
; F4 ~: o9 J. ^2 O; r' J Arguments :
+ L! f6 }, A5 m( L! p7 s+ i <hello> is an optional argument. It is the "hello" command to use. It can: W, w3 g1 G$ d4 R. w( M
be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other
b \$ E$ m- J# L* t/ L- o6 i values will be turned into the default command ("HELO").0 V* v3 l' \7 u l: w
! c) O \' ~$ i) l
<domain> is the domain name to present to the server. It may only be; k; T0 f! F _% s6 O$ _5 Y
specified (and is mandatory) if the hello command has been: v& ^. y0 u6 o
specified. By default, "localhost" is used.: H6 U) N; ]% s3 l5 i0 @6 w
* |! Y# l3 l. s/ J' A# w: U
When "option smtpchk" is set, the health checks will consist in TCP
! C0 P+ G0 T7 }9 x5 x connections followed by an SMTP command. By default, this command is
! g, Q4 g6 w$ ]: W% H: v! {7 R$ r7 { "HELO localhost". The server's return code is analyzed and only return codes5 B/ V/ n( ^; k& W
starting with a "2" will be considered as valid. All other responses,$ y8 s* Q* O3 E
including a lack of response will constitute an error and will indicate a
4 \; K+ e. `; m, W9 ] dead server.
* ?6 y2 ]4 q6 h8 ~: G
: D0 l! \* o/ r8 l8 L This test is meant to be used with SMTP servers or relays. Depending on the7 E. K/ P8 |7 S1 `% R- {
request, it is possible that some servers do not log each connection attempt,
! e5 f" F+ @# y3 l, l8 A4 j so you may want to experiment to improve the behaviour. Using telnet on port" j! z/ u+ y" u' b
25 is often easier than adjusting the configuration.) N9 ^ h" k& ^" m" ]; x
/ g0 D$ {2 A! I$ u3 r
Most often, an incoming SMTP server needs to see the client's IP address for# K3 ?$ K* q% ^) F
various purposes, including spam filtering, anti-spoofing and logging. When0 i. _% }3 F* G5 N3 M3 Y& J
possible, it is often wise to masquerade the client's IP address when6 e; f# _ q6 r; c$ c' E! z9 D2 C
connecting to the server using the "usesrc" argument of the "source" keyword,' C& h! A! E4 D) `1 q) y
which requires the cttproxy feature to be compiled in.3 W% U/ n h/ |( W/ v
3 c& L) L. |. Z: }6 k: s: h1 K Example :2 w5 d- I( S0 c J; ]& t
option smtpchk HELO mydomain.org
. W/ p- P$ S% A; V+ S8 p* n1 v8 q+ Y% m7 @/ E# J" l! N# ^
See also : "option httpchk", "source"
* b* P) a; X+ i2 q$ X8 d$ M* {1 q5 k2 y# [6 H" i E0 ?
" r. I$ K1 A+ }9 B" Q
option socket-stats
, |9 d4 Y* _1 Ano option socket-stats
! a/ T1 X) o$ G% R+ h% k2 G7 U0 d: i9 S7 L; V
Enable or disable collecting & providing separate statistics for each socket.' Z; W0 \% [% m) _6 o: t
May be used in sections : defaults | frontend | listen | backend$ W/ I/ |/ p/ `. Q0 W
yes | yes | yes | no
* q# J; I9 G2 c( L" g0 w! H
( s f/ T" c. F @6 s/ d( A Arguments : none. ^( x2 {' R! W2 k ]( f6 J
% ^' k0 ~6 {( L% O
) Q& e% I4 m! g2 E( w1 v, w2 s7 Zoption splice-auto
* o0 {$ d. V1 f5 {no option splice-auto! u6 U% v8 b* M- N
Enable or disable automatic kernel acceleration on sockets in both directions s5 v( w0 w7 h5 c2 ~
May be used in sections : defaults | frontend | listen | backend
0 G4 ?* N4 Z, a6 `. U. A yes | yes | yes | yes* q4 W9 r& D7 x$ t) D$ q
Arguments : none
: V. m' Y' j3 i2 v2 j
3 f0 G; @, ~( ^ When this option is enabled either on a frontend or on a backend, haproxy# P( f6 e3 p: X( \' |6 c2 [
will automatically evaluate the opportunity to use kernel tcp splicing to
" S3 ^+ r1 o) z$ J' A/ m0 E2 \( F forward data between the client and the server, in either direction. Haproxy
0 \0 f% e/ {. }* }5 v% i( |- ^/ F1 J uses heuristics to estimate if kernel splicing might improve performance or0 e( i/ N4 ~- V, V9 f3 z
not. Both directions are handled independently. Note that the heuristics used
w8 n1 s; s4 z8 }: o are not much aggressive in order to limit excessive use of splicing. This
: A4 d+ V) s4 Y$ M; T: {7 ~6 o option requires splicing to be enabled at compile time, and may be globally
2 S1 f9 b* z& a" s% O# Q8 R disabled with the global option "nosplice". Since splice uses pipes, using it
) q5 W/ k1 A( |: D9 e- [ requires that there are enough spare pipes.
- v2 R/ i/ C% a; n+ A, _" t4 I9 ~% S5 |
Important note: kernel-based TCP splicing is a Linux-specific feature which
$ `" {3 ]! `3 Y- \/ V0 ^5 Z0 Y9 @ first appeared in kernel 2.6.25. It offers kernel-based acceleration to2 s6 C- X% w/ X7 \+ b; X
transfer data between sockets without copying these data to user-space, thus7 i) [6 p- ~0 b' @7 i$ I; z
providing noticeable performance gains and CPU cycles savings. Since many' A+ J# V. m7 }8 n
early implementations are buggy, corrupt data and/or are inefficient, this, A! F r4 f/ p/ D* f3 j
feature is not enabled by default, and it should be used with extreme care.
# g. J; g- W" @$ e8 I# R7 Y' [8 u While it is not possible to detect the correctness of an implementation,
; g! L/ Z1 E. F. L% J/ e& \" }4 S 2.6.29 is the first version offering a properly working implementation. In' z, j$ Q+ }$ \9 T
case of doubt, splicing may be globally disabled using the global "nosplice"
. N4 R8 M/ `, w [ keyword.& t X7 m: t5 t4 u |! y
6 n$ Y6 m7 [- s; l9 q9 o2 z
Example :3 p& p1 p9 f; J: d; j% p0 \
option splice-auto E5 d5 @* S& G% x1 _3 m
. k" I5 G6 `. W& x: x If this option has been enabled in a "defaults" section, it can be disabled
/ q* i! K+ d1 @ in a specific instance by prepending the "no" keyword before it./ c9 ^3 p' }+ S' C
% N* {; S/ |, {6 e4 S See also : "option splice-request", "option splice-response", and global. B H P, [; a7 N- U
options "nosplice" and "maxpipes") l. a# m% j `+ U. j2 o" A9 I
& Y" t2 x0 f5 B& { K% E9 k% {
- C4 Y2 z- c/ N- J/ j- `
option splice-request
$ e1 O! t( P$ `5 J* k4 eno option splice-request
, T6 x4 X# t8 d1 i: X Enable or disable automatic kernel acceleration on sockets for requests: ? {/ O. ~: I, F' v7 R
May be used in sections : defaults | frontend | listen | backend
5 y" x( _. [" d yes | yes | yes | yes3 O' G S( e7 Q$ Z! @& R
Arguments : none9 t2 D5 C, u f n, T d/ r; N
: z8 B6 a* r- X- ]
When this option is enabled either on a frontend or on a backend, haproxy- c0 l" r- l! {
will user kernel tcp splicing whenever possible to forward data going from
. t& z7 q3 d) y7 V5 Z: J) j the client to the server. It might still use the recv/send scheme if there7 s% s( _% T4 I( G
are no spare pipes left. This option requires splicing to be enabled at
) V2 C' {& b' }, S3 } compile time, and may be globally disabled with the global option "nosplice".
# Z+ G' u. s( o Since splice uses pipes, using it requires that there are enough spare pipes.1 l# M# E: W- t3 o. s
" @& _* h7 _/ D& n/ `2 G! {) Q/ L
Important note: see "option splice-auto" for usage limitations.% w- e* C: r8 G% ^0 p+ M, W Q
2 i' {9 C' ~+ d" h% z1 |
Example :& u, R0 e3 H; G2 C: L* V8 e6 F
option splice-request
# g/ H& B6 {8 s3 {( d; |+ N1 ?. |0 |8 C3 t
If this option has been enabled in a "defaults" section, it can be disabled
5 G, n0 q! L4 M. Q( B9 p% z in a specific instance by prepending the "no" keyword before it.
2 ?" u9 f+ L5 |' S
- V3 t$ Q& a# D/ q# @ See also : "option splice-auto", "option splice-response", and global options
0 ]: A r1 o( X9 H% z "nosplice" and "maxpipes"
7 _9 S( a0 ], C7 d( N% ^9 C0 R4 M$ ]2 L- \$ j2 A% O! H
0 d( k3 N8 y, e* moption splice-response
* M, c& g8 q! ^4 X8 \* _$ Xno option splice-response. m1 Q( s; H u Y' p9 A! Z& y+ P; N
Enable or disable automatic kernel acceleration on sockets for responses
6 F( I7 G* ]9 e: U7 b; S May be used in sections : defaults | frontend | listen | backend5 O6 r3 @7 J8 e9 K2 A
yes | yes | yes | yes
' q& H- E/ l" B3 |2 T g3 l Arguments : none7 O9 Y( Y4 O; I5 ?
! F% B) f- a+ Y4 x4 f" Y When this option is enabled either on a frontend or on a backend, haproxy9 V# g) Z n5 v6 u0 t* u5 ~
will user kernel tcp splicing whenever possible to forward data going from
) E. g0 g7 j% u3 a the server to the client. It might still use the recv/send scheme if there
& X) e* A0 Q. x" f0 {) ^ are no spare pipes left. This option requires splicing to be enabled at4 B: u& a" Q7 l1 |7 `3 ~3 {
compile time, and may be globally disabled with the global option "nosplice".
! _$ `' f7 r8 p+ G: r+ E Since splice uses pipes, using it requires that there are enough spare pipes.- w" \) P; @4 e Q% Z) N2 g
3 l3 A: ]. [' `# j* w Important note: see "option splice-auto" for usage limitations./ a3 v7 y2 O# c6 B! R
/ m+ ~ m# d! k( V- k
Example :: j5 B0 D: b: D8 D2 a4 X$ d* y
option splice-response
" C8 C4 D* ?& f0 N2 I: Y5 o+ o+ p* R4 z
If this option has been enabled in a "defaults" section, it can be disabled
x9 P; w5 x2 Y6 ] in a specific instance by prepending the "no" keyword before it.
# |* [3 f% J8 O G. N
6 R) u: P( F& |: @ d See also : "option splice-auto", "option splice-request", and global options
, ^, y& E. I5 t# P "nosplice" and "maxpipes" B- O3 z2 S2 x# b! E6 _6 [. ]- I
$ A/ A" ~9 C& ~9 V4 } X6 F ?) t9 x
" a" I, i/ ] l/ F6 a7 noption srvtcpka
5 \4 R/ p% [4 ?. j. bno option srvtcpka$ j( ?+ A# s# B1 c1 y
Enable or disable the sending of TCP keepalive packets on the server side" t7 V X, ]9 ?) N6 L
May be used in sections : defaults | frontend | listen | backend- W- d$ C# o. f. x5 H! ~
yes | no | yes | yes
' g1 @+ D0 F# A }" g$ z4 U Arguments : none
7 N" n" p) a! r! Q8 v7 [- U
0 f }; m3 K: L1 e2 N$ r9 X When there is a firewall or any session-aware component between a client and3 g3 t: B/ A$ \9 l
a server, and when the protocol involves very long sessions with long idle7 P7 B A! `! @0 W( a% H2 ?# q
periods (eg: remote desktops), there is a risk that one of the intermediate
" _& c! q; G# I components decides to expire a session which has remained idle for too long.* n% U6 ?/ k; Z; }% i' o
8 T) F' V6 G) V0 v Enabling socket-level TCP keep-alives makes the system regularly send packets* I7 y: z4 x9 a4 {2 i! ~* P1 N) t
to the other end of the connection, leaving it active. The delay between
! _( l7 z: N" X' l. `* C keep-alive probes is controlled by the system only and depends both on the! x4 M) s: `5 u4 Z: A* H% Q2 V
operating system and its tuning parameters., I" X+ H$ d8 s7 F l; y+ I
" e- m K E( A) `2 F
It is important to understand that keep-alive packets are neither emitted nor4 z' ~! e6 U/ {" U. c$ N
received at the application level. It is only the network stacks which sees ^$ n" S. B; S; K1 H4 p4 k7 D
them. For this reason, even if one side of the proxy already uses keep-alives
2 T! r( y0 z. G( T4 K to maintain its connection alive, those keep-alive packets will not be
0 X0 N9 j& t- A* j# U5 ^: e forwarded to the other side of the proxy.) S. \. r4 E, n- s8 V; L) _& |
0 O9 B1 [0 i- q* r! z6 q Please note that this has nothing to do with HTTP keep-alive.
8 M ?& Y. x& S* a5 `/ g% W9 h0 U3 Q# m3 T/ B+ K1 g. f
Using option "srvtcpka" enables the emission of TCP keep-alive probes on the
- j! `, I6 `3 T. x3 A3 ? server side of a connection, which should help when session expirations are \# g. V2 U# q# v$ ~
noticed between HAProxy and a server.- Q- {5 H! p+ \: E, j
: u6 H+ u3 z3 o7 H7 i; i If this option has been enabled in a "defaults" section, it can be disabled8 v2 v) P. T6 f; T" c
in a specific instance by prepending the "no" keyword before it.1 D! z/ O, P5 f; R, u& X- l
4 ~4 H2 j9 z, |1 ^/ g See also : "option clitcpka", "option tcpka"
1 n) d# A# F2 v
0 Y7 g7 B% a2 R$ y3 }6 H) r/ I. r" A
option ssl-hello-chk, N9 i( g# n' ?; v6 W/ o% M
Use SSLv3 client hello health checks for server testing2 y7 ], I) ]2 F% ]" r J$ f- t
May be used in sections : defaults | frontend | listen | backend
& f, e2 L! Q$ z% s yes | no | yes | yes
' @2 ]6 M) Y7 u* x" ~- M3 s; r7 S5 ~& \ Arguments : none% a* a/ L& S3 K$ F
. _. m" B, z. l! o
When some SSL-based protocols are relayed in TCP mode through HAProxy, it is
# x7 S# D" h5 s1 I8 ? possible to test that the server correctly talks SSL instead of just testing# _* I4 L4 F/ e# X7 [' [
that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure; J4 g( Y2 `' Q# O
SSLv3 client hello messages are sent once the connection is established to0 x; l7 O: ^" j( ^ r
the server, and the response is analyzed to find an SSL server hello message.
5 A9 ]( T$ Z; n5 ? The server is considered valid only when the response contains this server( Y$ t9 n- M+ O5 g: W# F& ^$ q
hello message.
% L7 j0 ^9 z- z! @& X
. L1 w0 Z6 |: P8 E1 `& S All servers tested till there correctly reply to SSLv3 client hello messages,
8 o- T& Z) `5 H and most servers tested do not even log the requests containing only hello
- l" `3 E8 Y) { messages, which is appreciable.) e1 b& F/ I8 ~/ v7 s- ]# b' J$ H
/ q3 ]3 R: S/ l! ]" Z5 s. Q- b
See also: "option httpchk"
8 V5 H; @; P2 U" c8 T5 c8 D/ F& O# d! M9 j$ |% ~
+ j+ ?2 j& i5 r3 S& @option tcp-smart-accept
2 i) T+ `" H# D3 }6 w, Wno option tcp-smart-accept6 K( h% {4 K, u& k5 Q E2 h9 B& V
Enable or disable the saving of one ACK packet during the accept sequence
4 c1 I: d8 v) b! Q J/ U" b May be used in sections : defaults | frontend | listen | backend
/ T( o8 c, J& Q* y( \- h yes | yes | yes | no
2 u! y: y+ A# c9 D5 M1 f Arguments : none F5 o/ r6 e; q6 t/ V! w
+ i- \( t$ h8 [. P4 z1 y When an HTTP connection request comes in, the system acknowledges it on4 M: L5 c. y; K/ O3 y' v& h+ H
behalf of HAProxy, then the client immediately sends its request, and the: k& d/ Q$ |- g0 c
system acknowledges it too while it is notifying HAProxy about the new/ w0 `' z6 w3 O4 s7 Q' B( k
connection. HAProxy then reads the request and responds. This means that we
: `. w! L8 H9 V) y have one TCP ACK sent by the system for nothing, because the request could8 e6 Q3 G# i1 {: r8 J7 T& P
very well be acknowledged by HAProxy when it sends its response.
4 ^4 J# N/ E6 ?' s5 n2 Y7 [$ X, V3 F0 t$ u+ [" i, M. z
For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
L9 v, t( g% h sending this useless ACK on platforms which support it (currently at least
, g. z. M8 H% b Linux). It must not cause any problem, because the system will send it anyway
7 Q# b4 [( p( I after 40 ms if the response takes more time than expected to come.
: L% X8 E% q: [6 S e' H* z: e. P$ |+ j. e s% k$ X7 j, o" h8 z! O4 e" y
During complex network debugging sessions, it may be desirable to disable
& }# b- f, P4 d; l9 G' g this optimization because delayed ACKs can make troubleshooting more complex* v4 |) P* E; c7 J
when trying to identify where packets are delayed. It is then possible to
" f: u0 z2 A# A% M* f, K* N fall back to normal behaviour by specifying "no option tcp-smart-accept".' \4 V. @7 Z/ h5 ~! \" _
8 h; q3 X' _: D
It is also possible to force it for non-HTTP proxies by simply specifying
: T) M2 A8 A" S6 e, t$ E "option tcp-smart-accept". For instance, it can make sense with some services0 i: K- M6 p- k7 c; ?3 Q; ~
such as SMTP where the server speaks first.
" ?! {4 j/ W. }, I3 }' e5 o8 m- |- L6 u. j: i8 k3 l2 p
It is recommended to avoid forcing this option in a defaults section. In case3 I$ L: m1 f! Y- u9 G
of doubt, consider setting it back to automatic values by prepending the
3 Q/ r! ^2 @8 K0 J "default" keyword before it, or disabling it using the "no" keyword.' D% G4 Y7 Y: s1 C
/ d% ~0 ^& l; V" p/ Q3 o7 x' j See also : "option tcp-smart-connect"
- P* j* \" M) F* k$ o9 E! _7 \" ~5 z9 [( _$ r4 K# G' [
3 G; K* O9 X( O0 y6 o4 }
option tcp-smart-connect
0 z& q6 O: \5 P# I! Rno option tcp-smart-connect3 u- V& s% d n+ Q3 O
Enable or disable the saving of one ACK packet during the connect sequence- P1 a. `+ d: n8 ?) E
May be used in sections : defaults | frontend | listen | backend
% Z O6 g8 o6 I. K/ ^ yes | no | yes | yes
- e) J$ u# j8 L Arguments : none
* }3 \* O3 e) y1 @( w: @
- |& @3 a6 R: ? \3 O6 K On certain systems (at least Linux), HAProxy can ask the kernel not to
0 \; _0 a* c3 e5 ^; K immediately send an empty ACK upon a connection request, but to directly) O& M# k+ [% a# O, Q& E# |
send the buffer request instead. This saves one packet on the network and
) V3 F- {5 B H0 c- o: r ? thus boosts performance. It can also be useful for some servers, because they( b# j! o6 b1 P
immediately get the request along with the incoming connection.
5 U+ H- R; Z& R1 y" J, s3 t1 l4 G8 @+ E; J1 O# |$ i8 h/ q9 V8 |
This feature is enabled when "option tcp-smart-connect" is set in a backend.
* T* E: R: {: g6 `: Z+ K; O, ^ It is not enabled by default because it makes network troubleshooting more
! m6 X( z& H) t; _$ Y complex.- k( O$ N0 ], l0 _
$ {% }0 o* p9 y; B/ }$ t: ~
It only makes sense to enable it with protocols where the client speaks first
6 a, V& i, Q/ x I, f/ r such as HTTP. In other situations, if there is no data to send in place of
' V. ?) d8 Z3 |3 h ~4 F the ACK, a normal ACK is sent.
, g [) ]6 m Y4 U4 F; F5 r
; b8 F. Q+ H3 u3 C5 H; B7 q1 i' s, c0 d If this option has been enabled in a "defaults" section, it can be disabled
( v1 w" d* m2 E7 j K in a specific instance by prepending the "no" keyword before it.
' ^! L4 k) J L' g: h0 c# o
+ m9 |$ j8 @7 j& }" q+ o, C See also : "option tcp-smart-accept"
& B" T* v5 K. s: C* Z& |# Y" ]- e- a( s
+ F& W; F, p5 ?6 E' Woption tcpka8 b" S% \# W9 \% T, ~6 p
Enable or disable the sending of TCP keepalive packets on both sides
3 ~) a$ O' b( r! ~. [* ^# s May be used in sections : defaults | frontend | listen | backend* c9 c9 ?& A2 `9 H
yes | yes | yes | yes. P# [- Z2 v8 O) z+ B5 H, t
Arguments : none
5 o! s' O9 w5 B3 T) L9 h( v% K( K& x# J: ~/ a) O7 f6 S9 t' a* V$ T
When there is a firewall or any session-aware component between a client and
: S8 O7 a) N& W3 f- a* S a server, and when the protocol involves very long sessions with long idle
0 ]! y' {! s& d2 [4 n4 F periods (eg: remote desktops), there is a risk that one of the intermediate
8 e' D9 [$ b* M* y components decides to expire a session which has remained idle for too long.& o* C+ q. U* L$ p3 Y# n
/ |: E0 o, u* _8 B& y9 p Enabling socket-level TCP keep-alives makes the system regularly send packets
0 K! o2 z5 y$ Q# l3 ^. {# n3 W2 | to the other end of the connection, leaving it active. The delay between
7 R+ R/ u! ~3 ]" R( @ keep-alive probes is controlled by the system only and depends both on the# G( I/ @9 t& _# v7 @
operating system and its tuning parameters.
9 r+ b2 f# {% }. K; y; X1 `+ X- G' B' O/ V% f2 E, ^: \: \3 [
It is important to understand that keep-alive packets are neither emitted nor
0 N. o [/ n! R) J' [ received at the application level. It is only the network stacks which sees
. o% W1 ~5 W& n7 o4 [$ G3 p them. For this reason, even if one side of the proxy already uses keep-alives
% |* X7 P5 I. r P/ @9 n4 L f& n to maintain its connection alive, those keep-alive packets will not be
, V, S4 [; y: Q+ M! J forwarded to the other side of the proxy.
" O5 X2 p5 G, d1 c% f* [' z( s/ i: v2 R) R: S* p! H* F" |# @, L
Please note that this has nothing to do with HTTP keep-alive.
6 K8 n0 C4 Z7 ]/ E' r- _- \+ R0 x* z* t" z, w# @3 M8 p3 W0 P3 G) I! @, a
Using option "tcpka" enables the emission of TCP keep-alive probes on both, d8 N! q% h. c# I
the client and server sides of a connection. Note that this is meaningful
4 k0 L! S& i4 k" T) F2 |& c/ [ only in "defaults" or "listen" sections. If this option is used in a
6 t O4 w8 M5 D2 j$ v1 n" } frontend, only the client side will get keep-alives, and if this option is1 z( H) X5 N* K+ S
used in a backend, only the server side will get keep-alives. For this) a. m) [/ _( g' e+ @, Q
reason, it is strongly recommended to explicitly use "option clitcpka" and
7 _% M5 N# D. o0 m% B; P "option srvtcpka" when the configuration is split between frontends and
" |8 z* e( ~: D1 ~ backends.: n2 x$ n( l3 Z9 ]% |1 ~9 C
; A# A0 W0 x% M% s! N& t
See also : "option clitcpka", "option srvtcpka"% e% l, m1 R9 Z1 z) ?1 }1 _
* |, u$ B) j: }
1 n/ ?7 G* _' q/ Y3 ?: S7 `; c7 q# Toption tcplog3 @7 _7 d+ X" b
Enable advanced logging of TCP connections with session state and timers
@5 H$ Q1 \5 P May be used in sections : defaults | frontend | listen | backend% U8 @9 ~$ D* ?4 H. p! n
yes | yes | yes | yes
/ Y6 E3 j, I8 n Arguments : none
- h; a! f6 i; a9 g3 k7 `) H# _. m/ o. O' r& @. i! {# a
By default, the log output format is very poor, as it only contains the# \' u5 U. U3 ]6 ^
source and destination addresses, and the instance name. By specifying# r3 Y: M4 d1 p; c8 E2 W& a( j) X
"option tcplog", each log line turns into a much richer format including, but" d5 D; X' g1 u3 x
not limited to, the connection timers, the session status, the connections
# z4 p" g, m8 g5 ^, R0 B, R5 m numbers, the frontend, backend and server name, and of course the source
6 g j" B J8 f. E5 J address and ports. This option is useful for pure TCP proxies in order to
, }8 V2 r# ~* S7 V find which of the client or server disconnects or times out. For normal HTTP
( D d) }* |( I$ R) O9 a proxies, it's better to use "option httplog" which is even more complete.. e2 O3 Y8 N+ g% z, A3 {
5 t. Q/ Z: T: ^5 m8 s4 |& n, F
This option may be set either in the frontend or the backend.# W8 @% z* {. i+ Z4 |
s- F$ r0 a2 I See also : "option httplog", and section 8 about logging.
% ~& e! G7 W S5 O& M
. o% N/ b* v( r# Q. ]/ I9 l0 |0 z0 h. `* N6 c
option transparent
z- i) }& Z1 P! n( a0 Dno option transparent' @4 f/ X; w8 D6 O O1 P
Enable client-side transparent proxying
9 P" u7 f% o+ l" f May be used in sections : defaults | frontend | listen | backend
5 Z% N. q/ {' q yes | no | yes | yes. n, U8 s- @* u% p* C9 ]
Arguments : none
7 G5 N: p/ f' t+ a( y0 V, v# U
! @* T! V% a$ i; L This option was introduced in order to provide layer 7 persistence to layer 32 T* m+ f ~+ y9 [" Y1 p6 r9 b
load balancers. The idea is to use the OS's ability to redirect an incoming
/ j8 r w$ V/ a* k8 w! |0 S connection for a remote address to a local process (here HAProxy), and let
4 R$ m' }0 I5 y0 @. Y( R* ^. Q) T this process know what address was initially requested. When this option is4 w" r3 Z& l9 [3 I2 g( Y
used, sessions without cookies will be forwarded to the original destination3 k3 P- i) n; q7 Z: j
IP address of the incoming request (which should match that of another& ]# u V- t# N3 s( A
equipment), while requests with cookies will still be forwarded to the \) q" H3 _7 G- x# x. U
appropriate server.
- D( ~; m& H7 H( U+ _" ?! Q" L$ I+ j- v
Note that contrary to a common belief, this option does NOT make HAProxy4 U/ S; ^5 c# g% k, `+ p3 a
present the client's IP to the server when establishing the connection.
& [. l* Z" K1 G9 E' M) u, c5 X# [2 c% x" a
See also: the "usesrc" argument of the "source" keyword, and the J" F* i( J8 y. T3 S4 x, }
"transparent" option of the "bind" keyword.
d* n! d) o- z) p0 [: K% M* r, y5 }. D6 m3 P: e
0 n" N1 D1 ]% A- M9 u5 y; W
persist rdp-cookie4 K O J. N! b1 M0 _
persist rdp-cookie(name)
' N1 {* `7 s" R3 r Enable RDP cookie-based persistence
# x) Q* q! @# {/ y2 U: C- g May be used in sections : defaults | frontend | listen | backend
7 B% H6 P0 D+ p3 u" u yes | no | yes | yes
4 z2 m- l% ~0 t/ h% y- w Arguments :0 P4 |0 J" ?' V" G
<name> is the optional name of the RDP cookie to check. If omitted, the" q0 D8 q+ `0 W, `; ~/ r. e6 `
default cookie name "msts" will be used. There currently is no7 B1 ?3 l$ v4 C
valid reason to change this name.
# A% L7 F9 E6 x/ x+ }% W( a, V) M( R# Y9 R% \8 `. l
This statement enables persistence based on an RDP cookie. The RDP cookie
/ l, T) c- c6 m0 d( A U contains all information required to find the server in the list of known/ k/ ]! b& g, K1 ~4 Q9 w
servers. So when this option is set in the backend, the request is analysed
9 b. F c( x+ P. A! z and if an RDP cookie is found, it is decoded. If it matches a known server
" O' v, C& l2 D; X/ B( x& H which is still UP (or if "option persist" is set), then the connection is
, f: M7 p+ |! o0 N8 {0 @3 B forwarded to this server., X0 e+ E3 C7 O/ y
6 H9 N. K3 J- z5 N d* V* l5 ~* g. W Note that this only makes sense in a TCP backend, but for this to work, the5 k- t1 J" z, |
frontend must have waited long enough to ensure that an RDP cookie is present
# b# `1 b3 u' d5 D4 T0 g in the request buffer. This is the same requirement as with the "rdp-cookie"; @7 y1 O! b. V8 v6 R! }
load-balancing method. Thus it is highly recommended to put all statements in' @( v$ k ^' k1 n& Q& \) U g
a single "listen" section.
# w0 [, D( R; ?1 V: x+ Y5 Z; {
! B$ a0 F {. i. _# ~, B1 B Also, it is important to understand that the terminal server will emit this5 V* D! w8 b: `$ b/ p+ @4 w* q
RDP cookie only if it is configured for "token redirection mode", which means
6 f' K- Q6 H5 o# ? ?/ U that the "IP address redirection" option is disabled.
0 F, o0 U& z% l$ l! [9 e" ]5 w2 W& B& M0 L
Example :" n$ t. h- l+ L6 D( D& |% v' |
listen tse-farm
) k* Z) o: ?! s$ k+ i bind :3389
; c Y0 w( s- z8 I # wait up to 5s for an RDP cookie in the request% p: x8 s( g( @% i% w, p5 z
tcp-request inspect-delay 5s# Q- V& D3 ]# l {+ {' \
tcp-request content accept if RDP_COOKIE
' o1 ^; d% p, y$ v$ F # apply RDP cookie persistence( a$ p' C1 t# o# c9 s
persist rdp-cookie
) i+ m6 {( D; c8 c* d& V& ~7 i # if server is unknown, let's balance on the same cookie.
- S8 ?$ E3 b% T8 U # alternatively, "balance leastconn" may be useful too.
1 Y- q0 T) y0 t$ p balance rdp-cookie7 I$ i+ a6 {9 {# W
server srv1 1.1.1.1:3389
( x; s3 b' A! v server srv2 1.1.1.2:3389 ~2 d8 e# M# |
( X* r+ }, e; b9 p9 l
See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.
$ s; ?/ X/ K/ u! E6 P
: A- z# H" V; L& ~" [8 D8 b% g4 z
rate-limit sessions <rate>
+ U8 L. K6 R' }7 s" H# ^ Set a limit on the number of new sessions accepted per second on a frontend
- s$ n3 u* x4 l" N$ ^; { May be used in sections : defaults | frontend | listen | backend" ~3 Q+ H" d& C
yes | yes | yes | no) r/ ^) x* T1 }- k' l; M" n
Arguments :
i( e6 p1 |7 i* `5 X% L <rate> The <rate> parameter is an integer designating the maximum number
! {, |# S: J. u: O$ o! K of new sessions per second to accept on the frontend.
4 E$ \# Y( h" L& _2 B
2 j, K6 U" H* c When the frontend reaches the specified number of new sessions per second, it6 J8 ?! ^4 N/ y- E
stops accepting new connections until the rate drops below the limit again.3 U, B* j7 s; H9 `8 `# D
During this time, the pending sessions will be kept in the socket's backlog
" |: U2 G( w+ N+ W" W2 y (in system buffers) and haproxy will not even be aware that sessions are/ l4 W" s7 m4 w1 l/ Y
pending. When applying very low limit on a highly loaded service, it may make- k% S5 E' S0 R
sense to increase the socket's backlog using the "backlog" keyword.: C: c2 z1 ]& u8 n8 S
3 v* r) X9 r2 d5 G$ E* v- z
This feature is particularly efficient at blocking connection-based attacks
* \, d2 i7 }" W. j or service abuse on fragile servers. Since the session rate is measured every
, J9 ^ k3 f% I- b millisecond, it is extremely accurate. Also, the limit applies immediately,
) v& ]4 }. f2 ?' d no delay is needed at all to detect the threshold.4 W' x o) f- u/ ~5 j: D
. _* @ T& f0 S4 c' k) G; M3 n Example : limit the connection rate on SMTP to 10 per second max
7 C: S0 Y8 @- `7 a listen smtp6 q5 e9 }2 [; G% S& A" z3 }: Y
mode tcp7 a2 E4 ?1 j |$ W0 o% ]# {
bind :257 O. L: ^* C' u; y
rate-limit sessions 10
) O4 U. V$ J* n server smtp1 127.0.0.1:1025' r; H( M) t2 ]
9 |2 X5 \8 Z C: H Note : when the maximum rate is reached, the frontend's status appears as
% F$ L; s( D8 x2 m* o) N "FULL" in the statistics, exactly as when it is saturated.( F7 Z t+ R! m* h% \! k# A
1 Z4 G8 k$ P. k' K0 s, K: T See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion.0 \2 e/ Q. w3 f8 Z$ p
% z V. w2 e. y& Z7 J# j p
! s0 `5 {& E9 R& t' L* a7 lredirect location <loc> [code <code>] <option> [{if | unless} <condition>]/ g, @/ e* S6 p# P( H
redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]
/ g% Q% y6 z) U: Z8 predirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
6 x. P6 D& ^ K9 x Return an HTTP redirection if/unless a condition is matched- K" o/ u# g* B4 V7 n1 }' n* b
May be used in sections : defaults | frontend | listen | backend
" c4 R8 V' {2 s3 n' M no | yes | yes | yes; D& E A) @' E& K! g1 B
/ a, {- c1 V& G# K, r, H3 c) D. j+ R If/unless the condition is matched, the HTTP request will lead to a redirect
+ f4 M7 J1 |$ e9 c& M9 B) i response. If no condition is specified, the redirect applies unconditionally.
. L) [3 d1 @ O% ` W" ^ S1 {4 M$ }, Q a9 n+ x+ h
Arguments :4 V5 w2 J5 w y' l! n) [0 V
<loc> With "redirect location", the exact value in <loc> is placed into( U0 |% H# |; A {& z# e$ V( a
the HTTP "Location" header.$ g7 f5 R: G/ J4 _1 ~, M$ J( |! |+ c
$ g( e5 D7 Z3 n
<pfx> With "redirect prefix", the "Location" header is built from the
# z; K7 g3 B7 ^ concatenation of <pfx> and the complete URI path, including the: c K& n3 D5 {! }7 t9 L
query string, unless the "drop-query" option is specified (see B! R5 Z6 M! A; d( X# I2 g2 {
below). As a special case, if <pfx> equals exactly "/", then# ]* v. i/ p0 H) Z3 Q
nothing is inserted before the original URI. It allows one to
+ g/ p& f( J' D$ j redirect to the same URL (for instance, to insert a cookie). V7 L" E5 u- `: N
# O, v! P& P) f7 B0 a
<sch> With "redirect scheme", then the "Location" header is built by3 E8 A& o6 ~0 Q! P. v
concatenating <sch> with "://" then the first occurrence of the
' [' w- K( [4 R6 A. w' \* A "Host" header, and then the URI path, including the query string# x, r, D9 S1 z. v& s% Q- U: @% H
unless the "drop-query" option is specified (see below). If no
7 F- N: R. ?' s& i; k path is found or if the path is "*", then "/" is used instead. If
: g/ _; |4 |- O1 { no "Host" header is found, then an empty host component will be. ?0 G3 W$ N! K4 l- r, [7 C. n; n
returned, which most recent browsers interprete as redirecting to- [" {5 D' R( q
the same host. This directive is mostly used to redirect HTTP to
2 ?% J0 a. F+ q B HTTPS.4 h! r/ t+ v! ?% x4 X3 A+ }
% t* j! m2 x% e- K4 E, V; t' M
<code> The code is optional. It indicates which type of HTTP redirection
# P: O5 w3 J1 R1 ~5 F' s k is desired. Only codes 301, 302, 303, 307 and 308 are supported,0 d2 i, o5 }9 ^& Z: a n; `
with 302 used by default if no code is specified. 301 means; w5 F3 p3 y M- e3 g( |8 y K" i
"Moved permanently", and a browser may cache the Location. 302
0 V& a5 J& H) c means "Moved temporarily" and means that the browser should not3 I. j! e# ^5 I) ?- U. o) w2 l
cache the redirection. 303 is equivalent to 302 except that the
~. o% B+ `- J* ?" E1 A browser will fetch the location with a GET method. 307 is just% T+ E0 b$ y! h: L9 @' ?" s; _# S9 s
like 302 but makes it clear that the same method must be reused.
+ `- e: y& n. \2 g Likewise, 308 replaces 301 if the same method must be used.5 J. r( p1 n; G+ X
8 F, L" X+ O1 G$ J3 i <option> There are several options which can be specified to adjust the
9 r: t8 Z& Y& i: | expected behaviour of a redirection :$ [# ?- p; L& m2 h& P4 p! Z+ @( `
2 l/ g7 T3 t9 W5 a5 E4 @! ~4 k& w! V - "drop-query"' ]) i$ d# g: `( O8 Q. e% ]
When this keyword is used in a prefix-based redirection, then the- B" X+ C8 d2 Y3 E! K' y# O+ ^' F# f
location will be set without any possible query-string, which is useful' b, j- t! }* |0 [6 [6 {* W: a8 Y$ B
for directing users to a non-secure page for instance. It has no effect4 A( L; k1 O% S: \
with a location-type redirect.
/ ^% u: k: G0 F; M7 O. x% ^$ j- T0 g+ M" i9 }
- "append-slash"4 q& X" _1 |1 D, U& h( _' F. H W A
This keyword may be used in conjunction with "drop-query" to redirect
6 N- r: e& A! J( N# E- c2 H# Y4 ~: Z users who use a URL not ending with a '/' to the same one with the '/'.
) Q7 M# b; M9 x, g n7 O0 i6 C It can be useful to ensure that search engines will only see one URL.
' L0 J& N) E5 e/ d2 A# i For this, a return code 301 is preferred.
9 G8 o+ M+ B w! J( }% F( S6 ?; l0 k' x- G* j
- "set-cookie NAME[=value]"7 {1 G# T' B$ j. K
A "Set-Cookie" header will be added with NAME (and optionally "=value")
8 n% M I: m4 p3 v- b3 u4 h+ z to the response. This is sometimes used to indicate that a user has
5 T8 g B; T, Y h been seen, for instance to protect against some types of DoS. No other
5 Q4 }" ?% o" K% ]4 x o cookie option is added, so the cookie will be a session cookie. Note
9 Q8 l% w! m6 \# |+ T9 Q0 { that for a browser, a sole cookie name without an equal sign is
) | M5 r2 ?' W: q different from a cookie with an equal sign.
, R( o5 ^5 @. I5 B9 I9 B( ?* E* t
, J/ x* V# U' a! |0 h - "clear-cookie NAME[=]" ?; J( G" U6 ~
A "Set-Cookie" header will be added with NAME (and optionally "="), but
, D1 N) D2 O7 ^7 n- V( K# x with the "Max-Age" attribute set to zero. This will tell the browser to
2 G- u0 @" S, D delete this cookie. It is useful for instance on logout pages. It is
- g* q* l7 C7 }6 x important to note that clearing the cookie "NAME" will not remove a3 k" I4 o s, t+ k' v. k
cookie set with "NAME=value". You have to clear the cookie "NAME=" for
5 L" G3 J2 X8 y5 R that, because the browser makes the difference. v. |0 W5 N6 y
2 U% s7 N1 `. R& M2 F$ E
Example: move the login URL only to HTTPS.- O# ^+ f# X- u1 q1 ^7 Y
acl clear dst_port 807 ^# Y3 C+ _7 o) N' ]
acl secure dst_port 8080( }0 E* X/ H+ K9 f& K
acl login_page url_beg /login" z0 p9 e+ P' A- [5 x
acl logout url_beg /logout+ ]: P. K! h+ r% K8 Q4 M& ]
acl uid_given url_reg /login?userid=[^&]+/ v- s! s0 w# b4 m5 ?$ Q
acl cookie_set hdr_sub(cookie) SEEN=1
# W) e; G4 A" Y9 A
8 p2 h: V& q: \. N redirect prefix https://mysite.com set-cookie SEEN=1 if !cookie_set+ M! d; [4 w6 U6 }9 I4 I) {" j
redirect prefix https://mysite.com if login_page !secure
. X& n/ l" Z- A$ P redirect prefix http://mysite.com drop-query if login_page !uid_given/ G2 U4 z$ ]" K% C- w
redirect location http://mysite.com/ if !login_page secure( s0 \7 B+ |2 ^# @
redirect location / clear-cookie USERID= if logout, `$ N) o* r) t- v
: X. U" m! g: f% S- | Example: send redirects for request for articles without a '/'.
* u3 `4 G8 i. p, Q p acl missing_slash path_reg ^/article/[^/]*$
. I. }& m+ \; Q2 f( r) a% K redirect code 301 prefix / drop-query append-slash if missing_slash" E. e% S- K+ i' z# x6 O
8 g0 `2 K+ N0 [" \
Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.& o: M V/ m; @8 A7 w5 u
redirect scheme https if !{ is_ssl }# f, w) W3 m5 ], q+ x2 p5 G
0 y {1 L" U2 D& T
See section 7 about ACL usage.
! F! f# Y( _& r" c7 U
! U0 R/ n+ x4 K+ S2 q, w# N, {. C6 f
redisp (deprecated)' W3 s& P# S# J) i5 i
redispatch (deprecated)$ s: w- }. ^: Y" {& B* Z
Enable or disable session redistribution in case of connection failure
" \1 r6 w0 Z5 X% W0 ` May be used in sections: defaults | frontend | listen | backend% T; w s/ v2 [7 Q; D
yes | no | yes | yes
2 x8 w H' D- H8 J+ u! ` Arguments : none$ b# u0 k: r7 f- _% l
9 M% c" y) ~# \0 w
In HTTP mode, if a server designated by a cookie is down, clients may" I! c2 g$ l. a8 E: o0 o7 X
definitely stick to it because they cannot flush the cookie, so they will not1 B5 A; N* a- \3 r3 J
be able to access the service anymore.
2 w4 L% x0 N) {) G" H W2 e7 }+ C/ Y5 C$ S' h
Specifying "redispatch" will allow the proxy to break their persistence and, \& G# j% w2 L+ B7 D7 ?' `
redistribute them to a working server.
; v7 _$ J/ X3 F* |6 L/ n4 e9 J3 s/ t/ o
It also allows to retry last connection to another server in case of multiple+ ]+ J9 Q! ]9 a: R
connection failures. Of course, it requires having "retries" set to a nonzero+ m' `3 K9 P# b; o) R* v2 w
value.
' v! ?* C- g8 t$ j
$ E) R$ _8 X! G* ?& B This form is deprecated, do not use it in any new configuration, use the new+ p& [# e L" B* j! z7 i% x
"option redispatch" instead. d/ z8 |. S" s+ D4 n- R, c6 E9 B
7 }! }8 C# ?; j$ V4 j See also : "option redispatch"0 a/ `) d: B6 X0 X' l
- h8 x. } Q0 l' Z
' k6 x* m0 T9 Preqadd <string> [{if | unless} <cond>]3 u) E% t6 h9 @& {' m
Add a header at the end of the HTTP request
) }6 Q# e' a6 u9 y) b5 K. c# F May be used in sections : defaults | frontend | listen | backend
9 l1 C4 V. ]+ r no | yes | yes | yes
* x L4 A7 Y* g Arguments :
- U K6 u! K6 h. C5 w <string> is the complete line to be added. Any space or known delimiter, w0 |; q1 B) x* F' [, X
must be escaped using a backslash ('\'). Please refer to section
3 [* \) U4 _' b/ I 6 about HTTP header manipulation for more information.
4 ~# B4 O) A Q6 `
" B. h* s- Y4 O8 { <cond> is an optional matching condition built from ACLs. It makes it9 S% F9 z* }! {% B: v
possible to ignore this rule when other conditions are not met.
. h( I/ U6 B( ], k& O$ h, w! W# v0 z/ _/ J' l
A new line consisting in <string> followed by a line feed will be added after2 B$ l$ M/ @% Y" E1 A: V; A/ `
the last header of an HTTP request.- K, Q3 A* ]& U8 d
9 u1 `$ l# x. _6 o( ]5 H Header transformations only apply to traffic which passes through HAProxy,
* @+ {- v* P/ z' c% f7 y and not to traffic generated by HAProxy, such as health-checks or error
$ C0 x+ F* M( X responses.
7 ~6 O# E" k' S8 H. [+ s. m7 {) r) L
Example : add "X-Proto: SSL" to requests coming via port 81
' d% c( [* [1 Y2 i acl is-ssl dst_port 81) \5 [7 q; Y9 M% q/ Y0 M1 Q
reqadd X-Proto:\ SSL if is-ssl+ Y) c+ S8 M8 H* Y3 e- @
8 @+ w! j- f0 J, P
See also: "rspadd", section 6 about HTTP header manipulation, and section 7
) q: E) v0 I0 X8 ^ about ACLs." b( B; d: U8 l% S
Q, D; n$ {* B6 g1 K% X* I: D8 F0 K/ \( z
reqallow <search> [{if | unless} <cond>]' |/ u N% d' Z; ?) E
reqiallow <search> [{if | unless} <cond>] (ignore case)( v- o. L' ?1 l% f! r k
Definitely allow an HTTP request if a line matches a regular expression
3 z5 v7 C+ E" ?2 @5 v/ e May be used in sections : defaults | frontend | listen | backend4 D. {, V& {- o f% Y. s
no | yes | yes | yes2 E* O W. X E* v: T7 ^
Arguments :
6 C" m7 Q7 M% C4 L$ S4 W/ R9 ? <search> is the regular expression applied to HTTP headers and to the9 {8 t9 m& i! Y; @: h3 y; k
request line. This is an extended regular expression. Parenthesis( X1 q; a6 n3 k
grouping is supported and no preliminary backslash is required." }% ?, [* E0 X& O/ M$ A
Any space or known delimiter must be escaped using a backslash
/ ^) ^. d1 a: l* { ('\'). The pattern applies to a full line at a time. The
0 Y7 [ w% t8 w/ n0 u( [ "reqallow" keyword strictly matches case while "reqiallow"/ I! `) k% ~) U& E* e
ignores case.
" z' c+ Y/ {3 n: `7 d( f4 h* c/ G5 W2 M! c, j3 n x
<cond> is an optional matching condition built from ACLs. It makes it
( A& Y* P9 m% C2 n0 i& t possible to ignore this rule when other conditions are not met./ c! p/ U; i7 Q) p: J/ i3 K
: G! o4 `7 n( d9 D2 M! n% p1 o A request containing any line which matches extended regular expression, i% Q/ D$ r! d4 t7 \0 k
<search> will mark the request as allowed, even if any later test would
, {' f% x. g7 F1 q0 g) H& W2 E3 } result in a deny. The test applies both to the request line and to request
+ r% h& t; p/ F- K headers. Keep in mind that URLs in request line are case-sensitive while9 s- S# g+ s8 A* `7 U, \, |/ k
header names are not.9 P2 }3 M# V% z# g$ t
0 N; m0 P% h$ y7 S7 r, ~0 w$ k
It is easier, faster and more powerful to use ACLs to write access policies.3 Q# y( q% W B1 }8 M( e
Reqdeny, reqallow and reqpass should be avoided in new designs.
' V; @3 a) j) j0 B
* _9 T! U7 j2 ~7 p Example :
+ L; I c% I; L4 A" n, ?# Q9 w # allow www.* but refuse *.local
1 T. M& u F' j3 j reqiallow ^Host:\ www\.: r) |4 [7 e) E6 e
reqideny ^Host:\ .*\.local# n- H- M9 S1 D, P L
& h3 E) k; z( N- c7 S' k
See also: "reqdeny", "block", section 6 about HTTP header manipulation, and" ]9 r8 E0 @" R' [
section 7 about ACLs.9 s1 i- ]% e* H* i1 G! c: c) O3 G
- x. Q; R% K1 G4 m# _; d/ K }
. c0 B" C; k! ?reqdel <search> [{if | unless} <cond>]
# b' E5 x( p3 lreqidel <search> [{if | unless} <cond>] (ignore case)
/ `- N4 V* j" K$ ^0 N$ N- m* n% L Delete all headers matching a regular expression in an HTTP request
! K5 z% G) ?2 ?% F8 H May be used in sections : defaults | frontend | listen | backend
3 G) g2 O' g, b7 c' N4 S no | yes | yes | yes- p0 d& V" n# |- F2 x. |
Arguments :
* c! p; M5 C4 C v* x <search> is the regular expression applied to HTTP headers and to the
" Z# _0 J. a+ }5 O5 ] request line. This is an extended regular expression. Parenthesis
. u& Q8 q: X4 r( i9 k grouping is supported and no preliminary backslash is required.( R, Y% X" [0 t- u
Any space or known delimiter must be escaped using a backslash
: }7 S) I' i: P8 |2 D ('\'). The pattern applies to a full line at a time. The "reqdel"" {* b- Y; p: N( n
keyword strictly matches case while "reqidel" ignores case.( O; g B @) b8 ^
1 d5 `& G3 M. M4 j+ S' v
<cond> is an optional matching condition built from ACLs. It makes it; W3 k- e+ [: B8 b. @7 S
possible to ignore this rule when other conditions are not met.
( R& x( L1 N2 q. M5 f* j$ h$ `& U: N Q0 {3 i5 ^7 u
Any header line matching extended regular expression <search> in the request: c" I' z: z6 L7 U5 m: N; ]
will be completely deleted. Most common use of this is to remove unwanted
* L8 v1 p0 ~# p and/or dangerous headers or cookies from a request before passing it to the
( c' c' m! X& x) H. R* P9 C next servers.
% s9 C; U5 {9 d1 \4 Y4 ^# d7 i1 P2 k9 x7 Z [# B1 [, j
Header transformations only apply to traffic which passes through HAProxy,
M6 v+ D0 |" J- z and not to traffic generated by HAProxy, such as health-checks or error
' \" l# d. M7 Y' {: L: E# ? responses. Keep in mind that header names are not case-sensitive.9 l7 I% E" \4 f: k( X9 G3 _
- `* v, C8 ^5 O Example :2 U4 }! c% c& v* X( A
# remove X-Forwarded-For header and SERVER cookie. [- n; t1 N# c. K) ` C
reqidel ^X-Forwarded-For:.*
5 X# Y1 Q" x2 k6 n! L( Q reqidel ^Cookie:.*SERVER=8 J; l$ ^+ R# z+ m! m# R0 S
$ J. V6 v4 P; M1 h
See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header- p8 h& t- _( `* |; Z: C$ @
manipulation, and section 7 about ACLs./ k' }3 C F( _
$ l1 [ r$ e1 u8 L# l+ _
7 W% H6 T" u( d) `0 dreqdeny <search> [{if | unless} <cond>]
' [5 m- L- E7 Z0 O% Breqideny <search> [{if | unless} <cond>] (ignore case)) `+ A1 _4 j; C' E1 w
Deny an HTTP request if a line matches a regular expression& p4 p# X. b, a2 G( a/ I: w" ` |
May be used in sections : defaults | frontend | listen | backend8 \9 k% [( K/ D4 c
no | yes | yes | yes
0 w# @# _ `; { Arguments :
, i; d+ X# N) S3 z- R, V <search> is the regular expression applied to HTTP headers and to the
- L- c7 J4 Q& ~' X0 a7 q request line. This is an extended regular expression. Parenthesis
- Z7 U. K b8 g# z6 Y- m: n grouping is supported and no preliminary backslash is required.+ U5 m+ i7 O. x" {3 w- P/ d5 g
Any space or known delimiter must be escaped using a backslash
% J0 `# p& Y! S# ` ('\'). The pattern applies to a full line at a time. The9 ?2 y3 O& n* g! L Y) Q0 p
"reqdeny" keyword strictly matches case while "reqideny" ignores
+ ]$ p" |6 z. b& @; i0 ? case.
' j+ ~ x9 D0 q) E1 ? u$ g; v* I
/ n' l: J: x- `7 d& |! ] <cond> is an optional matching condition built from ACLs. It makes it
; D8 y5 ]3 g1 @9 d5 @% S possible to ignore this rule when other conditions are not met.& p4 P: h% L) z! |5 X8 L0 z- T
$ G+ ~5 P5 I: S; K
A request containing any line which matches extended regular expression
( A5 G5 i, \; x; b9 J" n o <search> will mark the request as denied, even if any later test would
6 E) k- m V- l$ a# d7 V result in an allow. The test applies both to the request line and to request
1 p' v$ i- q' z3 g6 r/ } headers. Keep in mind that URLs in request line are case-sensitive while! f& t" T- B* r$ f* B
header names are not., Y. u0 C0 L4 z* s1 [" h
c' f4 @ y' k# f( q* N A denied request will generate an "HTTP 403 forbidden" response once the) [, r/ Y" `5 Q' V; V2 `
complete request has been parsed. This is consistent with what is practiced
0 V# ]1 o( c. F using ACLs.
$ T2 ]' _ N2 Q% m) c$ N
3 l. ^" \# m& h: X: X0 i It is easier, faster and more powerful to use ACLs to write access policies.
" K1 [( u8 u4 B; V' O) u Reqdeny, reqallow and reqpass should be avoided in new designs.6 | W& J/ {' `* e6 Z ^& D$ W% }; i
+ X' d. ~' k8 A
Example :7 ]! H" E% ]* y
# refuse *.local, then allow www.*
( @6 {5 x2 ^5 Q/ y# n; ] reqideny ^Host:\ .*\.local( k" _+ t7 w! R {4 I. D- F% d$ O
reqiallow ^Host:\ www\.
8 @! s/ b8 j) Q% s( X# z$ B8 K( x Q: N, _9 O ?1 Y* ~
See also: "reqallow", "rspdeny", "block", section 6 about HTTP header
1 _, _& ^6 a% E& l8 x t& i. G) M manipulation, and section 7 about ACLs.9 E" Y' Z0 \3 c7 s: g
r) z9 W2 y' e" f6 O" o' [
' X2 r. @5 s& Preqpass <search> [{if | unless} <cond>]
* D. l9 S4 v) i% |2 U$ g2 Jreqipass <search> [{if | unless} <cond>] (ignore case)2 T3 S8 d% A. ]: t' x2 `! q" }
Ignore any HTTP request line matching a regular expression in next rules
4 V, r$ X- }0 O0 f6 O May be used in sections : defaults | frontend | listen | backend0 I1 X3 C3 o. |
no | yes | yes | yes; F% U! V1 H% w$ x ~$ i
Arguments :
Q& f3 z1 n" b" ]; e <search> is the regular expression applied to HTTP headers and to the
2 _1 h; }# n4 ]9 q( X( i request line. This is an extended regular expression. Parenthesis
9 O" p x7 P! S# G& V8 B grouping is supported and no preliminary backslash is required., @, u( y7 Y, F5 F) l) N
Any space or known delimiter must be escaped using a backslash
& B% w2 b' ?# O/ O9 ~! z ('\'). The pattern applies to a full line at a time. The
, U+ ?6 ^; e1 e+ b "reqpass" keyword strictly matches case while "reqipass" ignores7 t( g1 X. e& r
case.
6 T/ [/ I" y% {8 x" ~0 d5 Z' R# g2 w* g
<cond> is an optional matching condition built from ACLs. It makes it
* T9 ?' ^- ^5 ~+ n* f. R+ p. i possible to ignore this rule when other conditions are not met.
& \. F/ o' H7 G# y ~6 V3 `0 U0 }! D9 x
. e4 o2 R) w2 v/ d& `) y& E& U7 B A request containing any line which matches extended regular expression9 \1 z5 V7 k% Q2 h$ O* ~/ l+ O
<search> will skip next rules, without assigning any deny or allow verdict.
+ X( ^& J, }/ c# k" ]/ N/ d The test applies both to the request line and to request headers. Keep in
8 o: A' C1 U, \7 I7 P& @/ i2 Z0 H6 w mind that URLs in request line are case-sensitive while header names are not.+ y0 U4 ]& ~9 [" K
- A# \, p6 [& R It is easier, faster and more powerful to use ACLs to write access policies.! u$ i o& C# X& ~
Reqdeny, reqallow and reqpass should be avoided in new designs.
5 Z* D0 Q2 q) t6 [ F) [9 F A3 N) \5 u+ C/ i! W+ I9 f! f
Example :
" ~; O3 @& Q0 m1 c$ D # refuse *.local, then allow www.*, but ignore "www.private.local" U/ _. l/ i$ A. ^8 k. E" ~
reqipass ^Host:\ www.private\.local4 q8 N% }# X( I1 B& Y
reqideny ^Host:\ .*\.local
4 t1 a+ n- a6 ?2 G5 g, h9 t9 S reqiallow ^Host:\ www\.# L( `1 o- H. u* ?
6 I" L x. _9 G4 R; x
See also: "reqallow", "reqdeny", "block", section 6 about HTTP header- F7 B/ u" R9 P
manipulation, and section 7 about ACLs.
5 l: B9 q' x+ y1 [- I; C T" @: T3 r( y5 f# {& m. u' {6 `; z b/ ^
! S; A6 b0 Y+ H( ~5 @) V3 S
reqrep <search> <string> [{if | unless} <cond>]
4 E* C! U% B7 ]2 v1 i; greqirep <search> <string> [{if | unless} <cond>] (ignore case)8 C+ Y1 q; Y" t+ f
Replace a regular expression with a string in an HTTP request line
9 ?9 g- M# P; k# J: w9 B% ?+ N May be used in sections : defaults | frontend | listen | backend+ D9 h: k* d2 P
no | yes | yes | yes8 f$ ?3 i0 f" | p% t* K. }
Arguments :
* Q# L* @5 u* i K% q% f <search> is the regular expression applied to HTTP headers and to the
3 B: ?0 t8 X* N, A9 X1 n% d3 N request line. This is an extended regular expression. Parenthesis! M; h2 _* _4 ^
grouping is supported and no preliminary backslash is required.
C% A2 j, T1 i; h4 A Any space or known delimiter must be escaped using a backslash4 a8 ?- ^+ h+ ^) S
('\'). The pattern applies to a full line at a time. The "reqrep"
6 @& D$ g) U2 o" K) _ keyword strictly matches case while "reqirep" ignores case.
, ~# O. _, @, c6 a! N% f, c% Y
7 T7 v+ `# n$ I& Q, t <string> is the complete line to be added. Any space or known delimiter+ v+ C& r/ W( _3 {" r4 V5 c
must be escaped using a backslash ('\'). References to matched% ^8 {, F+ s$ ?: u
pattern groups are possible using the common \N form, with N
7 Y. c) F. @' R# o being a single digit between 0 and 9. Please refer to section2 K6 w9 W" b. @) Z5 X
6 about HTTP header manipulation for more information.. h* ^. @% q" N9 D
8 L1 [+ I" t7 ~* x7 Y& J2 h4 j
<cond> is an optional matching condition built from ACLs. It makes it, |/ Q% ^( s9 }/ s" E3 c( X% D
possible to ignore this rule when other conditions are not met.
* e& {! R$ `6 F) o' `" R& S; n' ]: G7 J8 o/ [
Any line matching extended regular expression <search> in the request (both( |9 K' x( y: f+ _
the request line and header lines) will be completely replaced with <string>.
) ]! t3 r$ I/ { } Most common use of this is to rewrite URLs or domain names in "Host" headers.
2 v+ [* u: v/ f7 M5 n) p: @
0 Q2 Y4 u6 ^+ H2 W: D: u' b Header transformations only apply to traffic which passes through HAProxy,6 T0 t' h3 W9 |1 g8 o! K# r
and not to traffic generated by HAProxy, such as health-checks or error- A# V4 q' o7 L8 _
responses. Note that for increased readability, it is suggested to add enough$ Y, G% ~9 c" M( S0 P
spaces between the request and the response. Keep in mind that URLs in
; g4 T( v- k" w0 _ request line are case-sensitive while header names are not.
0 S; A, u$ A+ C- M k2 b1 Z& k' T; ~, N/ n
Example :: K, a4 h7 j8 k' @
# replace "/static/" with "/" at the beginning of any request path.6 N% F9 a: U3 [9 s* X
reqrep ^([^\ :]*)\ /static/(.*) \1\ /\2
6 W h: [. U, }3 D # replace "www.mydomain.com" with "www" in the host name.4 e5 ^1 }6 k2 K' ^1 m- X% {6 [6 U
reqirep ^Host:\ www.mydomain.com Host:\ www1 I1 w( w7 V: |0 P
- n! N, \; l3 d {; U; _% U% C3 p8 G5 q See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header! ~8 y, l2 I' H3 F0 _- @7 U
manipulation, and section 7 about ACLs.
, j+ ?+ O) r6 W4 F0 w# Z9 Q1 m
2 D, ?: |9 w H6 m: F# } L- }3 o3 m" G. V5 r6 M5 {" ~0 h
reqtarpit <search> [{if | unless} <cond>]
9 E6 U' z) B M; T4 creqitarpit <search> [{if | unless} <cond>] (ignore case)
: Q' d! H' K* h- } Tarpit an HTTP request containing a line matching a regular expression
7 H" h$ b: H0 O& Z) T" n8 `" l May be used in sections : defaults | frontend | listen | backend
! D) o( [7 @0 @6 g no | yes | yes | yes, R) n! O; ~7 K3 I
Arguments :
. W) D/ q3 i l$ d <search> is the regular expression applied to HTTP headers and to the. c# ]" m9 i, W2 z$ T% G
request line. This is an extended regular expression. Parenthesis( O" K3 U# l8 A& D4 |
grouping is supported and no preliminary backslash is required.) g7 g& e& k( m! d+ _8 o
Any space or known delimiter must be escaped using a backslash
* Y! A; F& r D ('\'). The pattern applies to a full line at a time. The, @. I: @% d. o$ d- D
"reqtarpit" keyword strictly matches case while "reqitarpit"
. I" x1 @: A' a8 R, ^0 D ignores case.
& W5 ]9 y: c& y8 ^& _ y+ o! {
' q9 R$ @* b+ P* K: ` <cond> is an optional matching condition built from ACLs. It makes it) t! T6 {7 Y" u. ^
possible to ignore this rule when other conditions are not met.0 F4 i3 M% O6 v' y7 w9 U7 _
/ A% I9 x% G% P& N! H2 T# F
A request containing any line which matches extended regular expression
0 L1 r: z% b! u# i <search> will be tarpitted, which means that it will connect to nowhere, will
" s9 H# a& E7 S& {+ q' [. Y be kept open for a pre-defined time, then will return an HTTP error 500 so1 e# v# t1 @" y$ _. U! I
that the attacker does not suspect it has been tarpitted. The status 500 will# g0 _) A. P' m: p
be reported in the logs, but the completion flags will indicate "PT". The
$ O% _7 V! }; M$ j6 f. n delay is defined by "timeout tarpit", or "timeout connect" if the former is8 k* q3 |( }- W7 P
not set.
: W) b0 ~" y& B: C6 A, V
5 r" U$ I+ _! n3 J E The goal of the tarpit is to slow down robots attacking servers with
% \, C4 |4 d8 n$ E) h+ y l' j identifiable requests. Many robots limit their outgoing number of connections
3 N# j. J1 q! k" Q" a and stay connected waiting for a reply which can take several minutes to
2 [# M4 R5 K# Z+ F- m come. Depending on the environment and attack, it may be particularly- q) s% D p! P W
efficient at reducing the load on the network and firewalls.
. \4 s% W0 d; D$ B( r) [ E8 X+ x
Examples :) N2 E- @, `5 ] g9 G
# ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but, m" M* F1 @4 x) f' Y
# block all others.( N8 f9 E) E1 r, f. ?7 r/ t
reqipass ^User-Agent:\.*(Mozilla|MSIE)! _ \ b0 e& l, P5 B
reqitarpit ^User-Agent:' i' y) W( m& _! g9 N- u
1 |2 k1 G* }( u
# block bad guys
# }( \" P/ C4 ]" x acl badguys src 10.1.0.3 172.16.13.20/28. F: ~' V/ w4 S! Y& S& Q3 u
reqitarpit . if badguys
. F* T9 _6 U; S
* T, W/ Q* m4 b' O See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header- C. h9 q7 ~3 k9 x8 Z
manipulation, and section 7 about ACLs.
1 S$ g/ V$ k; |
, h% m9 c( V- A7 [9 W* \0 E# m% `
7 o9 f1 `: P- @/ L8 b) fretries <value>$ ]+ O" [, F. P5 L5 y8 _
Set the number of retries to perform on a server after a connection failure7 E6 e/ d7 i- V2 R) {" w
May be used in sections: defaults | frontend | listen | backend
; q7 t w7 S& X+ g$ L yes | no | yes | yes
) m, Z7 S/ O' d/ B; S% r* q0 K Arguments :
2 m) K" {8 f N" |* F <value> is the number of times a connection attempt should be retried on
' I7 Z: U! Z8 g( p- V/ C4 v a server when a connection either is refused or times out. The" u' P0 J7 { J% ^& x% t! |
default value is 3.
4 q: t* R* |$ P T+ u D2 t: l
! \6 z9 W! P9 {8 f( w7 _+ }4 g It is important to understand that this value applies to the number of2 T4 {/ y3 e1 ~8 T3 ]) r
connection attempts, not full requests. When a connection has effectively
! F1 c* Z- J: P$ E4 E been established to a server, there will be no more retry.
1 p5 P. a# I' F8 G1 X y+ S S+ S
In order to avoid immediate reconnections to a server which is restarting,
6 X) S/ Y Y2 P5 S) S8 y8 ` a turn-around timer of 1 second is applied before a retry occurs.
3 J$ }. M( k9 j: ~' c5 @- S; G# P: [( Y% F% Y- Y; j, [) p
When "option redispatch" is set, the last retry may be performed on another$ q9 H* {! T9 ~% i- x+ _- X
server even if a cookie references a different server.
: Q! \ r! T1 Z+ @3 x" g6 Q/ T, o M* C; d+ J
See also : "option redispatch"/ A7 f2 A/ x( r" ~* L
- u+ h8 \# O% H; x5 b, J! Q. }: r3 k
' q+ a( O3 V5 e" Qrspadd <string> [{if | unless} <cond>] Y& O+ ]8 Y! z7 r
Add a header at the end of the HTTP response
' N! ^) k; L" R% I May be used in sections : defaults | frontend | listen | backend
$ f# K9 N* i; l. D C7 e# i no | yes | yes | yes
4 y. M; u0 F# b* K1 \: R: ] Arguments :+ Z3 k# y: Y s9 i
<string> is the complete line to be added. Any space or known delimiter! N) {- Q$ A6 B* b
must be escaped using a backslash ('\'). Please refer to section0 O* c( h" k0 ~, \
6 about HTTP header manipulation for more information.4 H9 w# g" C2 v% M: o( W4 @
5 V4 ?3 l' Q$ |
<cond> is an optional matching condition built from ACLs. It makes it
; R' g# s6 o' E3 ?% \5 p possible to ignore this rule when other conditions are not met.
0 f7 ~/ P; ^8 T- E2 t$ M- Q! O( ?% q N) D/ }: w
A new line consisting in <string> followed by a line feed will be added after
) b' R+ `0 ?7 R! k- U7 M8 y the last header of an HTTP response.4 G; F6 h M; q+ n C/ t5 l1 {
3 z$ j) g6 |& j/ m# P Header transformations only apply to traffic which passes through HAProxy,1 r/ o5 C v6 N5 q2 u" C
and not to traffic generated by HAProxy, such as health-checks or error
) ?5 M& G9 Y3 k t3 a5 x0 C$ ~$ K responses.: S- P: X2 U5 ?; \, e' `
& g3 [8 g* [: A0 y! U
See also: "reqadd", section 6 about HTTP header manipulation, and section 7
/ E$ F' K7 T2 m) u/ Q% c8 Y about ACLs.) R q$ O/ u* T2 O* c* A) i9 }
. }1 G$ K$ M" x# X$ C; m
3 U; u( U; ?( Y" a8 D5 x: M$ R: srspdel <search> [{if | unless} <cond>]
* N3 e; ~: b) D. e% _rspidel <search> [{if | unless} <cond>] (ignore case)
% ~9 K2 {. s5 x% M+ u V" M Delete all headers matching a regular expression in an HTTP response$ ^8 {: c7 W. h/ Z/ K$ L
May be used in sections : defaults | frontend | listen | backend. v3 O5 c& B8 O# R9 u y
no | yes | yes | yes% q9 @# p8 y+ ? M) H
Arguments :
/ Y6 j3 d0 I: L, T5 @' b <search> is the regular expression applied to HTTP headers and to the3 v: q! a. M. b% R
response line. This is an extended regular expression, so
- B! K5 {- y+ a7 o5 p; T parenthesis grouping is supported and no preliminary backslash
7 L( g! f; f" u, ]" ~2 L is required. Any space or known delimiter must be escaped using
n7 A( l3 {6 y, e* p3 U a backslash ('\'). The pattern applies to a full line at a time." y8 F, W1 d' n8 _4 Q, i0 f
The "rspdel" keyword strictly matches case while "rspidel"" P& k8 p4 U/ ~5 [( c3 Z
ignores case.
6 ]+ B* ^8 G5 D ]* _# A9 A) R
6 I: L* r. |2 T0 U, F7 W! l <cond> is an optional matching condition built from ACLs. It makes it
% S) ?3 [: f% N/ \: b5 \ y possible to ignore this rule when other conditions are not met.+ N+ ~0 a& W( o6 B* J* y6 y
" Z$ A9 ~3 F3 w0 F" h
Any header line matching extended regular expression <search> in the response6 M9 X }( O# @2 K
will be completely deleted. Most common use of this is to remove unwanted
% g- c8 R3 y( h) q/ ]/ R2 ~3 Y- A and/or sensitive headers or cookies from a response before passing it to the- T5 Q6 y2 `# y, C8 q
client.
; {. \3 u# R7 M! p( H# K; v% D h; @; \3 W
Header transformations only apply to traffic which passes through HAProxy,
# T( U& h) c( D6 T! k/ W% A' W9 Z9 ? and not to traffic generated by HAProxy, such as health-checks or error
& a2 i& o: G6 d3 a5 h responses. Keep in mind that header names are not case-sensitive.
/ [" ]$ n9 v4 P8 ]1 H) H
8 t1 E4 L, W2 Z+ Z7 L: A: [5 W8 O9 } Example :
* [$ o5 U3 r( @& G$ N. p1 | # remove the Server header from responses
+ i) g) W5 _6 \2 c5 `6 a reqidel ^Server:.*
; J! P4 E# n$ }/ j! m# E1 ^8 ` Q, N5 g) Y* P3 x1 t5 V
See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header5 ?1 j T$ ~" e) O6 s$ F Y
manipulation, and section 7 about ACLs.
/ Y* G' r& l/ l& v
7 l/ l2 z' `, ~ n/ ?1 T
: X" h. F( [$ N8 R( }rspdeny <search> [{if | unless} <cond>]
" D8 Y* `1 m* y8 J, Arspideny <search> [{if | unless} <cond>] (ignore case)
, A. Z6 A9 g6 H4 r5 I Block an HTTP response if a line matches a regular expression r4 }: s4 ?* @9 S D3 I+ ?' p
May be used in sections : defaults | frontend | listen | backend3 a1 i6 P5 K2 G w
no | yes | yes | yes7 F# t+ [) ]* V, i M' p7 p' v7 R
Arguments :& S; q6 _; [7 C8 W
<search> is the regular expression applied to HTTP headers and to the- D# ~& O7 E3 |0 q6 J
response line. This is an extended regular expression, so1 q Q' x. R3 ~' ^5 z
parenthesis grouping is supported and no preliminary backslash2 B' h& r# l/ B; p; C G
is required. Any space or known delimiter must be escaped using
; H1 w) I" `' `; m: v% u+ v' N a backslash ('\'). The pattern applies to a full line at a time.
* i% x# [7 P9 y( ~ The "rspdeny" keyword strictly matches case while "rspideny"
4 U7 F7 g4 x5 M1 P ignores case.
6 r7 |3 t/ W1 U- |. \) ~* w5 K4 F, s o4 X+ t
<cond> is an optional matching condition built from ACLs. It makes it
# F6 C, b3 G' Q9 U$ t possible to ignore this rule when other conditions are not met.
9 S$ C: j; V2 h9 v: s% O/ U& b! _
& D- j. O! p. p" |! S& O A response containing any line which matches extended regular expression
! Y/ N: f( E, A N C; W1 ~4 h7 |. t; ^ <search> will mark the request as denied. The test applies both to the* z, c( C) s5 i
response line and to response headers. Keep in mind that header names are not* X, T4 K' h" k
case-sensitive.
! D! F8 X3 {+ {; a: F* Y) r# i8 L1 [/ w
Main use of this keyword is to prevent sensitive information leak and to4 U9 `' [% q0 C. [
block the response before it reaches the client. If a response is denied, it
8 z4 I' ]1 x+ `& H, M5 S2 I5 M" M0 l& [ will be replaced with an HTTP 502 error so that the client never retrieves
% ]* t6 Q- o6 p k any sensitive data.0 L& Z. Q" U7 S' N& G* Q& {
1 T. H7 M# n' b- w+ q; {
It is easier, faster and more powerful to use ACLs to write access policies.
8 \9 i5 E% \ [7 t' U0 ^+ W Rspdeny should be avoided in new designs.
! ]' _9 s. r) A' ]1 W" n" Q K8 a5 i5 t1 S8 m
Example :( k' B/ H7 Q( a/ j, H
# Ensure that no content type matching ms-word will leak
2 R7 ?* ]- d" g- F+ c' }/ ] rspideny ^Content-type:\.*/ms-word0 O/ `3 W$ w, B+ L; h$ J
+ f4 S9 ~" n& K
See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation
/ U8 Y2 v2 T6 D& j and section 7 about ACLs.
. [( l" u4 @$ X ^* V9 z! a2 o1 S7 e& T; d6 U" D A
4 z5 j! R: ]! O+ v6 I7 T
rsprep <search> <string> [{if | unless} <cond>]
2 J+ O$ @9 |1 ]8 w5 H# ?; brspirep <search> <string> [{if | unless} <cond>] (ignore case)
; ]0 G g& f# D5 D- W Replace a regular expression with a string in an HTTP response line
_& V# S8 N0 Q& P! |; ~ May be used in sections : defaults | frontend | listen | backend
Z/ ?9 g1 K3 {: z no | yes | yes | yes
8 g: Q/ B# Q5 W Arguments :1 B5 F% ?# V' n. x; P, X/ j
<search> is the regular expression applied to HTTP headers and to the
! o8 w. t' l2 k response line. This is an extended regular expression, so
1 w( j2 W3 a% h# Z3 k% ?7 N parenthesis grouping is supported and no preliminary backslash
8 w3 f7 E8 a* ] is required. Any space or known delimiter must be escaped using& _+ k8 s! Z+ B0 h
a backslash ('\'). The pattern applies to a full line at a time.: u& R0 [" b* n1 V
The "rsprep" keyword strictly matches case while "rspirep"
- a- {5 D$ [' Z6 ^ ignores case.8 l% q: X- I C) t7 [$ x1 a
* n/ w# k+ B D* u- ?# e
<string> is the complete line to be added. Any space or known delimiter: Y, t0 i6 u9 l" V" _9 b2 Q4 M
must be escaped using a backslash ('\'). References to matched
' F0 e* S, c1 b) J2 n6 v pattern groups are possible using the common \N form, with N
4 ?+ ~9 x4 V! W& g- i" T3 | being a single digit between 0 and 9. Please refer to section( w: v! Y8 F9 _0 {9 W
6 about HTTP header manipulation for more information.
% A4 U; z# Z: }3 X; I4 U O: B
3 o% n4 Y n6 W5 Q3 _: `( \2 l <cond> is an optional matching condition built from ACLs. It makes it) L# D. `; L+ C1 I
possible to ignore this rule when other conditions are not met.. V9 U$ m& i8 O( l. S+ l; J
! g: q+ L; u% ?# n' x Any line matching extended regular expression <search> in the response (both
$ Z# f6 q. D5 p6 I the response line and header lines) will be completely replaced with
3 P) B' O. I% [ v @. Q7 M <string>. Most common use of this is to rewrite Location headers./ d& |7 z+ E' B
2 R2 z* F3 q% K7 H- _& \, [( i0 O Header transformations only apply to traffic which passes through HAProxy,
1 I k7 X4 V+ z( G9 t and not to traffic generated by HAProxy, such as health-checks or error
% l2 d# I( [' | responses. Note that for increased readability, it is suggested to add enough2 P2 x; |) G0 i+ ?( Y
spaces between the request and the response. Keep in mind that header names
) `0 I, I5 K0 U are not case-sensitive.7 P$ _1 @' F% Z$ }
. h& R* G8 l4 i* e" }3 C
Example :
7 E' d- b7 D$ y$ W# @. L/ L. j, k& \ # replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"
$ O3 b0 L2 R* i8 s: I rspirep ^Location:\ 127.0.0.1:8080 Location:\ www.mydomain.com
( ?7 Z# J$ F+ x3 M3 m. S1 m' X! _ `- v0 d
See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header% D% R7 ~& l% U8 H
manipulation, and section 7 about ACLs.3 s C! g; n3 _( [4 v+ D8 L- c
- x0 m- N4 u8 E9 p' a# d) i. a
server <name> <address>[:port] [param*]
+ t4 J/ i. ?# o# { B Declare a server in a backend
3 D& o4 g5 r6 Q2 `' d! `; c8 m May be used in sections : defaults | frontend | listen | backend
' J8 ^% S0 A6 P; F& {( m- E1 ` no | no | yes | yes
. y3 c! _4 r$ J9 _ Arguments :4 t8 z& V& g& ~# J
<name> is the internal name assigned to this server. This name will
( _) P2 ~: `0 v) B2 Q7 s( X appear in logs and alerts. If "http-send-server-name" is. X& K* L; \% h5 X
set, it will be added to the request header sent to the server.' o# ]2 W; V( T" R. J
3 y# e+ B4 P8 U0 y6 a# K& t <address> is the IPv4 address of the server. Alternatively, a resolvable" ]" J; z' g; R: w7 W
hostname is supported, but this name will be resolved during
3 n0 K ^6 v6 z2 _" z' |& M start-up. If no address is specified in front of the port, or if- c6 A* s, @1 X, y) F
address "0.0.0.0" is specified, then the address used will be the, Q0 D( e" l8 W. P x+ z
same as the one used by the incoming connection. This makes it
* z& p2 w! L0 Y1 N: ] possible to relay connections for many IPs on a different port or
3 @* {! w6 B. Q. K; E to perform transparent forwarding with connection limitation.3 }7 O9 W/ f6 q0 z/ b. o% O
5 X1 G2 X( J' f! b <ports> is an optional port specification. If set, all connections will
! u* J! R) |( ^& N3 B3 D' k be sent to this port. If unset, the same port the client
( i# L% ]7 h) l9 Z, f' T: b connected to will be used. The port may also be prefixed by a "+"
$ N- d, p" p; d% Q or a "-". In this case, the server's port will be determined by
, o, C0 X) A7 U8 {" X adding this value to the client's port.; B7 Z3 G( b- Y+ O- ?
' C0 U: U3 S, L0 Y9 o/ }+ E
<param*> is a list of parameters for this server. The "server" keywords: Y4 {" w7 f) g A( S! v, ?- L( A
accepts an important number of options and has a complete section( m: o: B' x1 U% [1 V6 G2 c4 e; v
dedicated to it. Please refer to section 5 for more details." B" R3 S2 q1 L3 i2 w& d M" P
* H& @) \3 w) E' T. S
Examples :
- X! j1 y; H: ~0 \! u2 w/ B server first 10.1.1.1:1080 cookie first check inter 1000& y# K8 }7 I; [5 p
server second 10.1.1.2:1080 cookie second check inter 1000* Z3 Z( G. M( H! `1 H
9 D; L) Z6 E( U
See also: "default-server", "http-send-name-header" and section 5 about
6 C/ R2 D @" h Z server options0 o! D& X; ]7 Z9 v
2 C2 b& l1 n1 O+ o) Q3 M: b
3 `" E* Q! z8 c7 Esource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
( K: q; y( g$ N# T4 L# C* tsource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
& a1 X( I( Z6 k- z6 ]/ u% b5 bsource <addr>[:<port>] [interface <name>]
7 ^! c9 t Y4 P Set the source address for outgoing connections
' d- ^ |+ T2 ?1 a May be used in sections : defaults | frontend | listen | backend
# S6 S- T3 B4 n3 e yes | no | yes | yes, W# v9 @' u5 E9 }
Arguments :. m& [* l! k% U( }: Y
<addr> is the IPv4 address HAProxy will bind to before connecting to a, f2 G x* L, Y' w1 @. G
server. This address is also used as a source for health checks./ B. ^# E; j/ h% p! S
The default value of 0.0.0.0 means that the system will select
! Q. o/ W K. A the most appropriate address to reach its destination.$ Q7 b" k, J: p* I" @ \& Q( D: Y6 D0 q2 Q
+ X6 L9 g5 `, t+ k! T# T% q <port> is an optional port. It is normally not needed but may be useful1 F% t2 R5 D$ ]
in some very specific contexts. The default value of zero means
( f( T) U8 p c9 k8 ? the system will select a free port. Note that port ranges are not, ^; j( J9 Q9 m. Z( H- @6 R
supported in the backend. If you want to force port ranges, you4 |% Y7 o! s# l2 ^& u
have to specify them on each "server" line.
5 Q6 g5 O. h( z; Q
8 U W1 h0 f" t' u7 L1 j+ D& M <addr2> is the IP address to present to the server when connections are
2 }0 f' A2 c2 D. j! [ forwarded in full transparent proxy mode. This is currently only; L9 Z2 `# k+ I: D0 e* M
supported on some patched Linux kernels. When this address is$ ?6 c$ _4 O/ i: q8 G$ ^
specified, clients connecting to the server will be presented8 X7 M9 ?; R% H
with this address, while health checks will still use the address( }1 D" o* k: ^1 D) N8 R) }
<addr>.
# p% M5 q( h5 c5 y: C" {3 L3 U: l- w4 h9 G) D5 U
<port2> is the optional port to present to the server when connections1 m* O, ^, p9 U) o) L( H
are forwarded in full transparent proxy mode (see <addr2> above).
) ~7 n- @5 h- _& v5 i The default value of zero means the system will select a free7 o: ^% M6 j4 H, x0 A
port.1 d/ x1 `* s; }- r/ y
9 j/ _3 t1 E: x4 R N" x9 C
<hdr> is the name of a HTTP header in which to fetch the IP to bind to.* v& Q8 V2 `/ z/ f( ?9 f
This is the name of a comma-separated header list which can+ j6 e% F( T( o
contain multiple IP addresses. By default, the last occurrence is' s0 E+ D$ i& O! A1 @9 Z
used. This is designed to work with the X-Forwarded-For header; b2 ~7 x, \2 j# z
and to automatically bind to the the client's IP address as seen
9 v0 F. \' Y+ x% M( y by previous proxy, typically Stunnel. In order to use another8 |* L( F9 r p% B2 F' y
occurrence from the last one, please see the <occ> parameter2 i- l2 S% K4 A" N$ @; ~
below. When the header (or occurrence) is not found, no binding
1 v# c2 y7 M1 v8 b' { is performed so that the proxy's default IP address is used. Also
( b4 h4 h. Q6 r; m$ y$ g: b0 R keep in mind that the header name is case insensitive, as for any
+ o4 t: H# Y$ {8 g7 B HTTP header.
, \( E- R, i6 ` Y: r/ T( D
( t8 R7 s, |! P) a R8 C2 H6 } <occ> is the occurrence number of a value to be used in a multi-value9 I. @! s, ^! n( r+ ^
header. This is to be used in conjunction with "hdr_ip(<hdr>)",
% e" H/ C M4 h in order to specificy which occurrence to use for the source IP
* Z! X" s9 M% P address. Positive values indicate a position from the first
6 H# s) ~7 q4 p# @0 a% ?! D2 i occurrence, 1 being the first one. Negative values indicate
8 C& U1 Z" z* r i1 B+ R positions relative to the last one, -1 being the last one. This7 {# z, W A" Y5 N8 T% d9 `6 `- ]8 h
is helpful for situations where an X-Forwarded-For header is set
: X6 s4 R" [5 _0 j! H. Z at the entry point of an infrastructure and must be used several
5 L7 W9 L: |: H proxy layers away. When this value is not specified, -1 is
' ]/ i* y2 U9 P" v* o6 V assumed. Passing a zero here disables the feature.
# h: L) h5 B2 n$ B t; K4 y8 a$ i( t, D& b1 s8 T/ r) l* B$ y
<name> is an optional interface name to which to bind to for outgoing
- A7 Y: w) A8 v; i4 \ traffic. On systems supporting this features (currently, only8 {$ G8 Y8 A4 g, O
Linux), this allows one to bind all traffic to the server to: r% ^" A( G# p) m/ }
this interface even if it is not the one the system would select
i9 A% O* f4 [# E# W( g based on routing tables. This should be used with extreme care.
. G: Y; C- R2 H* N! q7 k* [: y, ] Note that using this option requires root privileges.
' ~$ M3 C: t5 d( E W3 l, k: A6 R9 ] t/ H
The "source" keyword is useful in complex environments where a specific
I/ D- L' m. C% }9 p: r. E" l address only is allowed to connect to the servers. It may be needed when a0 G( Q- \% Z5 Q/ a& t/ l) Y( ?
private address must be used through a public gateway for instance, and it is
" n' @& e- p, ~# d% | known that the system cannot determine the adequate source address by itself.
- J0 n4 Z1 n, Y' Z
8 ^$ f, j# K2 g, B. g An extension which is available on certain patched Linux kernels may be used1 V$ S' V0 S0 T( t! C9 Z
through the "usesrc" optional keyword. It makes it possible to connect to the
- c+ p0 g; b* \7 m G8 } servers with an IP address which does not belong to the system itself. This% U2 ]4 S4 b' m$ o$ ]+ i
is called "full transparent proxy mode". For this to work, the destination/ a, @% w7 u; c1 P& P
servers have to route their traffic back to this address through the machine
1 f# s7 R) m1 b* [! F% M, y running HAProxy, and IP forwarding must generally be enabled on this machine.
8 H3 p5 V6 j! A# Z( }% }. D9 w. X* R% x& x
In this "full transparent proxy" mode, it is possible to force a specific IP6 H8 C2 Q5 O) \% g2 c' P/ F
address to be presented to the servers. This is not much used in fact. A more
; s' A; ], _" ]: s common use is to tell HAProxy to present the client's IP address. For this,
$ r E: Y, {+ G3 Q9 ] there are two methods :
9 k3 N4 V3 \7 z' S+ h; a$ |/ k' k7 h, D5 b" o. F' i
- present the client's IP and port addresses. This is the most transparent
( N8 o, }, J; G mode, but it can cause problems when IP connection tracking is enabled on
5 E( K% `! _' A+ L the machine, because a same connection may be seen twice with different8 s5 v9 X! X8 x0 B4 U4 P! P I' R
states. However, this solution presents the huge advantage of not. a2 n5 a& s2 y6 j' B# |4 l+ p4 H6 v
limiting the system to the 64k outgoing address+port couples, because all# _" m) k4 Q9 i! n$ r$ e
of the client ranges may be used.
5 u6 L2 N* u; F) p$ C
# C' y8 @- q( K* t6 ]: m- u! I% l2 ~ - present only the client's IP address and select a spare port. This
. ~, n5 i4 ^ ? solution is still quite elegant but slightly less transparent (downstream
* D# q! J$ o6 x1 ?0 X firewalls logs will not match upstream's). It also presents the downside* {/ c& o+ D% H E9 k- B
of limiting the number of concurrent connections to the usual 64k ports.
2 W! Z Y( `" T! U, O1 h" L However, since the upstream and downstream ports are different, local IP8 W5 Y0 g$ d/ k; K9 t) r) w
connection tracking on the machine will not be upset by the reuse of the+ G4 h& c# y* z
same session.
H% m1 B0 x( C% S, b4 D7 Q- R; [, n, I- P6 F# b0 x, d0 B- C( X
Note that depending on the transparent proxy technology used, it may be$ W( K; X( b: R! x3 ?# v
required to force the source address. In fact, cttproxy version 2 requires an1 M9 y+ A8 y9 [; p: f) Q l7 b
IP address in <addr> above, and does not support setting of "0.0.0.0" as the
5 t- u1 P$ ~5 c' r1 P7 Z4 v b IP address because it creates NAT entries which much match the exact outgoing" B( V' O; |$ u7 o% U
address. Tproxy version 4 and some other kernel patches which work in pure
# e- H1 U, N1 B% y3 k) V forwarding mode generally will not have this limitation.
& B- ^, F$ ~! w& R
. g0 a: P; m, c9 I. O5 ] This option sets the default source for all servers in the backend. It may
) E* H9 G1 S3 a6 i9 f also be specified in a "defaults" section. Finer source address specification$ E4 p3 l8 W5 l5 P3 b
is possible at the server level using the "source" server option. Refer to
0 w: V7 s! F' H/ R8 o# `. d section 5 for more information.
/ f/ @9 p7 R1 ]; o9 }+ P* C4 _% }9 r; J+ @0 d
In order to work, "usesrc" requires root privileges.3 u- l) `" e: {; p# m3 Q. ?
9 x8 l5 U. o7 w: |; u5 t$ M& } Examples :5 Y+ D4 K# W8 D$ V( n
backend private' [. g, `2 T. @
# Connect to the servers using our 192.168.1.200 source address
: M2 w" s5 S: H, L source 192.168.1.2005 ?) ~- _: r' W! f0 y) y' |
# ^# ^! }2 n x6 {) A, n% T6 @5 g
backend transparent_ssl1
) }# Q2 E' O! ?$ h' h. [ # Connect to the SSL farm from the client's source address9 A2 o/ e- n; s* I+ V" \
source 192.168.1.200 usesrc clientip3 r( x8 q3 B: G& N: C
: H( K! C3 U5 j) P+ P+ T
backend transparent_ssl2( s$ T( [7 \( O. U. v0 [3 Q/ q
# Connect to the SSL farm from the client's source address and port# E& k) s) @$ a0 u& Z
# not recommended if IP conntrack is present on the local machine.
( l7 @7 z7 d, K' i) Y" u& v( A5 Q source 192.168.1.200 usesrc client* w7 ^1 E! |/ V" Q9 I7 c+ k# d( j
- u& j8 c! T L% t
backend transparent_ssl3
, N" H. ]5 t# ^: G+ Z9 k0 v; d # Connect to the SSL farm from the client's source address. It
: |2 F. {% F% n8 ^7 n # is more conntrack-friendly.! I: b! [6 e. e; O3 ^7 M- L; r
source 192.168.1.200 usesrc clientip, J" C/ w8 b4 r/ ^" {# V
5 ]$ x# z3 O& }( i7 k backend transparent_smtp! K; O/ V3 ]! \) f7 e% Q w
# Connect to the SMTP farm from the client's source address/port' w5 Q- y. f& S9 o
# with Tproxy version 4.( Q( W/ m; j4 A5 z/ K+ e
source 0.0.0.0 usesrc clientip
3 ~, V! m7 a# ^7 q0 Y
3 C6 t$ }% l% e0 Q4 S, b' Z backend transparent_http& o. C1 a5 g% q2 B
# Connect to the servers using the client's IP as seen by previous; O, e3 i. S _3 m- Z
# proxy. l' _! T# [% R1 \
source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
2 y" z" J* T9 n. A0 p; u* l. s) \5 E: y# c6 w% N8 |& I
See also : the "source" server option in section 5, the Tproxy patches for+ v, l+ R$ H, l7 j g' L4 k
the Linux kernel on www.balabit.com, the "bind" keyword.
+ @# S# _' h6 }7 B) s/ g* @6 r
% h% i/ t% z/ B' ~8 `* o D& V: B/ n4 O
srvtimeout <timeout> (deprecated)
/ e- X. Z$ ]( W" H9 c, r Set the maximum inactivity time on the server side." e3 l( P$ I Q
May be used in sections : defaults | frontend | listen | backend
0 M2 o ?8 H% c( b yes | no | yes | yes+ S* T4 x) B& S/ j4 j5 I0 o
Arguments :
9 S! D& f" W. }$ R, ^( x <timeout> is the timeout value specified in milliseconds by default, but3 F' v/ f6 v l3 f
can be in any other unit if the number is suffixed by the unit," c/ E, S# o4 M8 V9 o0 h# A9 H
as explained at the top of this document.( P; V/ Y+ J) S' T# h h4 y+ J7 o# x9 U
) }5 z- d3 J Q3 J) y: }9 }! A
The inactivity timeout applies when the server is expected to acknowledge or2 [! [# W3 o |& s7 T, M4 B
send data. In HTTP mode, this timeout is particularly important to consider
, l+ g9 k- A8 D5 j2 M) z. T j% [( m during the first phase of the server's response, when it has to send the
4 h" Q" `1 u3 n! O6 F5 v. ] headers, as it directly represents the server's processing time for the
. {* {, t$ s u request. To find out what value to put there, it's often good to start with7 @( o v$ c* }5 `8 J+ p
what would be considered as unacceptable response times, then check the logs, d( W9 ~4 ~0 O6 i/ B( i+ ]
to observe the response time distribution, and adjust the value accordingly.
$ G3 `9 P& V$ Q; o3 `5 O* D( T
, B" ?# {! G x The value is specified in milliseconds by default, but can be in any other& Y; _+ R: h6 y: w& d6 k9 U
unit if the number is suffixed by the unit, as specified at the top of this
( y6 r5 I1 i$ s4 I2 N document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly- g$ u; }! C/ R
recommended that the client timeout remains equal to the server timeout in
6 v+ Y! l8 a+ j2 z$ p order to avoid complex situations to debug. Whatever the expected server% u% w6 _& k P8 D* W
response times, it is a good practice to cover at least one or several TCP( p& a& M8 J3 L+ O
packet losses by specifying timeouts that are slightly above multiples of 34 m- {4 S+ ^, G3 `
seconds (eg: 4 or 5 seconds minimum).
. R1 a, c' P' o4 Q' v
$ A3 m/ Z0 v7 G0 O' `- }5 G This parameter is specific to backends, but can be specified once for all in2 H6 O2 v7 A# @; d2 `
"defaults" sections. This is in fact one of the easiest solutions not to
; G4 _1 K4 E7 t$ T; i forget about it. An unspecified timeout results in an infinite timeout, which
: @* m: N" ^/ a* T is not recommended. Such a usage is accepted and works but reports a warning4 l+ p1 F) |2 y
during startup because it may results in accumulation of expired sessions in% e2 X* @! M/ \; h# z( w! a
the system if the system's timeouts are not configured either.
. z$ ^& N. G3 f
B' o: y: }9 r This parameter is provided for compatibility but is currently deprecated.
0 ~) g+ L0 {* B$ A8 @( | Please use "timeout server" instead.: o. F3 W' E+ ]& }7 x% T
" G( ]6 I W4 I! d2 \! e# ]
See also : "timeout server", "timeout client" and "clitimeout".* f/ A+ R+ m: }" S3 H! I; ?
! l* P2 m5 A( L! b" r9 W, Q
3 U5 j5 C1 v# o' z" A
stats admin { if | unless } <cond>
, J) k3 r1 Z& h( d/ O7 z4 f Enable statistics admin level if/unless a condition is matched7 X ]) o) ?8 a d) n0 d! n
May be used in sections : defaults | frontend | listen | backend! x. W F/ l' |! y8 Y N6 p3 v
no | no | yes | yes, c! j7 A! u" v$ m
6 m' d) u: q8 _. w This statement enables the statistics admin level if/unless a condition is
$ H5 [7 o+ ?" \# V matched.5 ?3 x% v% i# c {
; ?: s5 k, |+ t% r
The admin level allows to enable/disable servers from the web interface. By. j( t% ]( i* Q1 X& C0 o/ X
default, statistics page is read-only for security reasons.
( L8 [4 z9 t5 j9 V4 t: H2 J: h3 Q7 [3 _( A6 p+ c( |
Note : Consider not using this feature in multi-process mode (nbproc > 1)
! z1 J+ X, o4 C# f+ P: v3 z& O9 p unless you know what you do : memory is not shared between the
6 b& e1 {8 \: K processes, which can result in random behaviours.* Y7 g7 S& T& G0 X
2 A4 {! A7 Z+ k1 i* A4 u
Currently, the POST request is limited to the buffer size minus the reserved
9 Y7 r" ^; e7 i0 _ buffer space, which means that if the list of servers is too long, the; G4 m% H7 X' [% y# y9 r7 ~3 z
request won't be processed. It is recommended to alter few servers at a
/ ]/ Q* Z5 |; I, { time.
+ F8 b3 ]- C- R( h! @0 i: l: E- w: i2 d% P* L3 J
Example :
; N- [' W5 ]6 }' P8 L3 \ # statistics admin level only for localhost, W* g; g6 J. D- e4 S
backend stats_localhost/ J* m. b/ J2 {5 ^
stats enable1 |8 f n9 b* c( q" ` o* Y6 s# ?
stats admin if LOCALHOST
3 H- S1 o9 J9 H1 z% N8 g$ |& r. a8 P6 M: x/ F: A2 s( r
Example :; Y2 [) k! l7 i& G, h0 z
# statistics admin level always enabled because of the authentication; W8 T' ^; E7 x v
backend stats_auth
# w5 m1 j: `5 _/ Y2 z8 {3 U stats enable: y/ P5 ? M) Q- G4 ]
stats auth admin:AdMiN123
" ?' k" ^6 m/ |. q5 c6 A2 D stats admin if TRUE
* j( j2 e5 v9 \- y
! [6 N3 B+ B: V Example :
: Q3 `% \, z" J7 W2 p* n0 A* p # statistics admin level depends on the authenticated user
. e1 u# J" n6 Q+ c userlist stats-auth
; H2 m" q% [- J0 T group admin users admin
! i7 |# o' M, v4 Q; ^ user admin insecure-password AdMiN123) R- I S, W9 N6 N& A
group readonly users haproxy
) e3 G. @9 z6 s) E& @& o0 ]5 v/ q user haproxy insecure-password haproxy
. _% i% l& b, G, `4 a* T+ ?
6 b, h u) e: A- [8 Y backend stats_auth
0 {/ X' l$ r: f; F/ j stats enable9 i6 X9 W8 \% C/ |
acl AUTH http_auth(stats-auth)
# j4 ^8 Y4 ]6 o) T; k: V# _* W acl AUTH_ADMIN http_auth_group(stats-auth) admin
2 D# X* `$ B' i! E! k7 u$ u$ d stats http-request auth unless AUTH3 x9 m; ~& b$ A' s
stats admin if AUTH_ADMIN7 T. r% Y K! n1 J# j
& ?: _4 s; A f" v2 ^0 i/ U* W: t See also : "stats enable", "stats auth", "stats http-request", "nbproc",
8 E$ o4 k* e& u( f. l y "bind-process", section 3.4 about userlists and section 7 about, r" e9 j8 r# C
ACL usage." d4 j6 J" p, k5 b' ?, q9 c
9 A; u! Y. c' c7 X* w! C2 g
2 q7 L' r; k/ g! K4 Sstats auth <user>:<passwd>
; K q: W3 P. T e Enable statistics with authentication and grant access to an account1 B" Y& V5 `4 Z1 e6 K
May be used in sections : defaults | frontend | listen | backend
9 w# _, P) v( s2 M6 g3 o2 P yes | no | yes | yes
; h! x7 ]% K& N* r6 L8 w Arguments :
! Y6 l6 T4 G' R T& o% e <user> is a user name to grant access to) D4 t- J8 }$ R% H
& U1 H7 A( r8 n5 d. Z# Y <passwd> is the cleartext password associated to this user: b7 ]1 L g/ z& g1 F+ [( [# s
0 X5 W n0 S* X
This statement enables statistics with default settings, and restricts access( O* c' a8 v' v" c
to declared users only. It may be repeated as many times as necessary to
H* g o0 L$ s0 Z# m: Z5 M allow as many users as desired. When a user tries to access the statistics
9 i6 T3 L4 J2 K without a valid account, a "401 Forbidden" response will be returned so that
: U* _0 g# ]+ h, {; k the browser asks the user to provide a valid user and password. The real
" w+ ?0 E; q7 v1 }' V' m& ]; W( e which will be returned to the browser is configurable using "stats realm".
3 m9 \* q, B: |
$ o: ~6 y [+ t# w4 s' n Since the authentication method is HTTP Basic Authentication, the passwords
; {% D4 N+ b {7 t; G ` circulate in cleartext on the network. Thus, it was decided that the
3 Q9 d0 S9 T9 U' n8 i configuration file would also use cleartext passwords to remind the users
& e5 X2 w1 M& N/ y* w that those ones should not be sensitive and not shared with any other account.7 }' b! p8 f5 z
: F% T4 \, d* i9 s; W& z& S. @' a It is also possible to reduce the scope of the proxies which appear in the
* U5 }1 e5 U/ j0 G2 g report using "stats scope".
. \; |# F6 n K) m. q, J- T# W) v1 A$ b( ^0 v9 }0 F1 d$ u, |
Though this statement alone is enough to enable statistics reporting, it is
6 E- x' H" ]' f/ S4 @3 t V! c recommended to set all other settings in order to avoid relying on default B5 u0 p* d3 }* E1 V& k8 K
unobvious parameters.8 C8 M. P+ l0 x7 k/ E/ e
/ u: q8 I2 Y/ A: E6 g9 e Example :
5 L( K, f+ @) L' u2 b7 \ # public access (limited to this backend only)
, b ^& K" u" ?7 R' U- c: N backend public_www
. ?' e" n7 h/ j- E1 B server srv1 192.168.0.1:80
5 y' n7 H. ]5 F; n stats enable
$ J9 J- O; T- o [% h* A) u% S stats hide-version2 H; \5 P. n. w D
stats scope .$ L( s- ]8 f4 ^
stats uri /admin?stats
! z( b+ C4 x& N, e+ b* R! Y stats realm Haproxy\ Statistics
; v; S4 T: o2 k5 t) _) j) y3 E stats auth admin1:AdMiN1239 K+ A3 R) A! w1 z6 s1 X9 y
stats auth admin2:AdMiN321
. m# z5 ~$ d2 C4 A& o' U3 N) q( x7 p" x5 @" d
# internal monitoring access (unlimited)
! ]+ Y1 T7 F" k. ?( Q" B$ u- o0 T backend private_monitoring, D5 M1 J# R3 H, l# c5 m
stats enable! Y$ p3 b3 S* i& C
stats uri /admin?stats H9 D3 k, N3 w3 s: N
stats refresh 5s n' ^3 u, n8 M, b
$ U/ D9 w0 ] L" E/ h! Y" J
See also : "stats enable", "stats realm", "stats scope", "stats uri"
4 \. q' W% K% W& X- k+ r
- _$ a5 g7 _2 o2 F/ d6 q7 B1 l$ B; T3 K$ H- }
stats enable
! G, m6 y" E" A) d Enable statistics reporting with default settings
^$ @( n, @1 P$ K4 F May be used in sections : defaults | frontend | listen | backend
3 q1 R, f, |0 X- \; y5 N yes | no | yes | yes
! J3 u& @& e& q) C Y. g8 q Arguments : none
9 Q: p' g; k) j
/ P6 B6 p! d. a5 ]4 u* l. N5 x% M This statement enables statistics reporting with default settings defined
$ x% X4 A8 f* {) F at build time. Unless stated otherwise, these settings are used :
; S1 J: p# w1 O+ F7 \ - stats uri : /haproxy?stats7 N/ x5 Z2 ?8 O2 _3 W
- stats realm : "HAProxy Statistics"% Q1 f, e, x7 O# A+ j7 c
- stats auth : no authentication4 M* ?; @# U! V
- stats scope : no restriction3 f0 w. p* E1 l# X& C! Q
* } S9 ^2 [ O# z) m7 | Though this statement alone is enough to enable statistics reporting, it is
8 m2 @9 p# `) r9 C' M1 p# P recommended to set all other settings in order to avoid relying on default& D* _. s& l; V. a! J
unobvious parameters.1 S3 X, z0 Y9 m
" ]( _ r0 i/ t+ P- T: `- `
Example :
! N [+ U: g& J; [ # public access (limited to this backend only) n. L4 |- Y3 P4 r# g
backend public_www: B& Y: m! r3 G$ F
server srv1 192.168.0.1:804 F" G6 A* K$ A( x* S9 M: G9 `- N4 Z0 k4 W
stats enable
1 V; H( |- H& n stats hide-version
0 O. F4 s! B0 u stats scope .1 r5 z1 _1 F+ Q& l/ D1 Y
stats uri /admin?stats
. \) r5 ]$ x% @- [ stats realm Haproxy\ Statistics
& c# F- i9 G8 c) m" d stats auth admin1:AdMiN123( ?& b% ^9 N+ m: z4 C! y' T# O
stats auth admin2:AdMiN321
6 b2 K' C5 _: n% d7 y
8 w2 Y& d$ h N5 J% f( \- x# p; l # internal monitoring access (unlimited)- l2 Y/ K2 a7 x( W
backend private_monitoring
: A& y1 E2 F. R6 L9 E2 I- | stats enable. R# S2 p5 o6 V( l
stats uri /admin?stats% Y( \" F# u* P
stats refresh 5s
6 w8 T. G# U& d* b
7 W9 ^' w5 y7 f3 v See also : "stats auth", "stats realm", "stats uri" g1 u' d ?+ u9 `, `! L8 j& x
' s9 s4 K. D8 u
( V1 w( J( k, \1 v) j2 e& d& O9 W) e% Ustats hide-version
0 i+ z3 L* d" q& _5 r; I# N Enable statistics and hide HAProxy version reporting6 } s+ t: {2 W
May be used in sections : defaults | frontend | listen | backend
$ r/ Y) B$ f3 h4 c yes | no | yes | yes6 p* e+ l, h6 T0 Z
Arguments : none4 W* L) s' v% k, o$ y( h/ W
: O) j2 x6 f3 G. ?# W- L _; _
By default, the stats page reports some useful status information along with
8 \! \5 O* G. E the statistics. Among them is HAProxy's version. However, it is generally
$ J- B* T- ?+ ^2 X7 n7 ^. c5 \ considered dangerous to report precise version to anyone, as it can help them
@9 G i! J# H0 v target known weaknesses with specific attacks. The "stats hide-version"
% ^1 |3 m2 C- c2 M: Y+ ^6 }/ G) o6 R statement removes the version from the statistics report. This is recommended
0 J( y5 l" @# e for public sites or any site with a weak login/password.
( A8 C" }6 l; F! j4 ?& ~0 h7 ]2 F# k3 F, i7 L" e
Though this statement alone is enough to enable statistics reporting, it is
; v8 O6 H( y1 g; I2 E6 K recommended to set all other settings in order to avoid relying on default
. V- a t) b ^3 h$ y" C) o, N8 E unobvious parameters.
3 P" S3 ~; o$ x. v: K$ h& l: x& z& T5 J2 P* B L8 P
Example :# |( L, L: I/ c( I, f* a& \
# public access (limited to this backend only)
0 B! B/ J) J6 Q* |. T. f+ T8 G backend public_www
! Y8 l' U8 ^! g5 y9 |( C" }7 ~! F server srv1 192.168.0.1:80" M8 O0 z" h3 W S* y& E
stats enable+ k5 f" _8 f- S8 E
stats hide-version
! j% h) _' I7 Y0 K* I stats scope .. z, y6 a5 x' E5 G
stats uri /admin?stats. A5 o# J- ^, l5 i( n
stats realm Haproxy\ Statistics/ H& \ q* J9 \3 w y. b
stats auth admin1:AdMiN123
0 D: l$ ]( y( F- ?. [: ` stats auth admin2:AdMiN321
8 }8 m% W3 `. v ~
2 L+ d7 Q# P; ?) N # internal monitoring access (unlimited)5 N$ M& H: P7 Y5 D7 \- _8 y
backend private_monitoring- b- I" p; m+ Q9 D5 y
stats enable, L0 R1 S7 }) g
stats uri /admin?stats) e1 f% l* X# i8 ]/ L3 q
stats refresh 5s
' @2 J- l" V" B+ X! v" Q' ~6 g# j: ^8 D, y
See also : "stats auth", "stats enable", "stats realm", "stats uri"
' n) O V3 ?, q p
0 s: K% ^, N# X! Q" Y' G1 Y0 u& Y: [; p3 A+ q
stats http-request { allow | deny | auth [realm <realm>] }
, Y6 X/ d" [ X [ { if | unless } <condition> ]
5 f' d. {/ t" I: S- y$ h Access control for statistics. p; ]0 t9 k: I1 L
# W& f& R# t' g
May be used in sections: defaults | frontend | listen | backend9 f! q' S( i- c* g
no | no | yes | yes
) i5 B6 p$ {* o. v4 D7 u5 ?
6 V2 W! Y. ^3 B& P, s( f" \8 O As "http-request", these set of options allow to fine control access to, _3 H# s' |( o; e/ z
statistics. Each option may be followed by if/unless and acl.' G+ \5 l$ m- t% t }: ?; P
First option with matched condition (or option without condition) is final.
7 |; r& j9 M% C' A) O: ^ For "deny" a 403 error will be returned, for "allow" normal processing is
/ T# t9 i! Z9 U; J7 ~! D performed, for "auth" a 401/407 error code is returned so the client
4 E _2 O; y1 O5 |5 B4 [5 h" x should be asked to enter a username and password.
/ R5 j; ~' } H. Z. W0 V+ w E5 H
; @% e1 b( A( o( O$ i There is no fixed limit to the number of http-request statements per
( M! C* r6 U; ?. E' I* }0 Z instance.
9 O. N" `/ P7 f2 u1 ~! F
' Z5 [6 P3 @' ? See also : "http-request", section 3.4 about userlists and section 7
8 g- C8 R6 S. }7 a& c" A about ACL usage.& c* S( u! c m" s' p5 i
5 S% k7 i2 v" L& J7 p% ~
( `' T5 Y, q9 gstats realm <realm> a" B. Q* c) ?# A8 u; H
Enable statistics and set authentication realm
* F/ L* h+ V$ Y+ g May be used in sections : defaults | frontend | listen | backend
W+ V" N. O: Y9 t0 r. J yes | no | yes | yes) k: V1 r1 [( f0 r% W+ g
Arguments :
' E$ y( E- q* D. ]1 u <realm> is the name of the HTTP Basic Authentication realm reported to Z+ O% y, T. G& O$ [* \. f& E
the browser. The browser uses it to display it in the pop-up
3 g* Y) U& {2 i% X% p* K. r. R inviting the user to enter a valid username and password.
) w' A! H; B5 `' E, o. M6 m7 C
The realm is read as a single word, so any spaces in it should be escaped6 f4 m! ?$ L1 u4 {6 h& Y' _( c
using a backslash ('\')., Y1 C. g1 R1 a+ Y. x9 Y' p- c9 x
3 z& m7 D6 \6 u5 W This statement is useful only in conjunction with "stats auth" since it is4 f) M+ x0 B& {& Q. N
only related to authentication.2 _2 O6 l- ~6 {( B& A( g- X
* i9 J' [5 l1 i& _$ }9 G" ^
Though this statement alone is enough to enable statistics reporting, it is: s9 \3 A6 M9 _! |; h6 T& }: }' ^
recommended to set all other settings in order to avoid relying on default; e6 V; \: c' F- N
unobvious parameters.9 a! x: V( E! Q0 C6 p
M0 ], P4 _' m% U1 S. @
Example :
7 b6 a% t6 S, w, I # public access (limited to this backend only)' t; c1 R1 V+ J- Z- f, h( z, w
backend public_www
! Z0 F% z5 }9 D2 I server srv1 192.168.0.1:80
& s! N% N1 @4 \+ b, l$ q stats enable
" O% d5 B: A$ f0 z8 {4 Y4 t stats hide-version
: h& R4 ?# U9 o' E! n5 a* c stats scope .
v& p# k M- x stats uri /admin?stats: l$ H; S" z j! T6 N" y& a
stats realm Haproxy\ Statistics
5 Q" c# y. G+ W stats auth admin1:AdMiN123
& y# X8 E; p! P stats auth admin2:AdMiN321
" O* Y4 t% Y" ]2 B8 l4 C9 ~' q- H1 \2 @8 T) t6 X1 p
# internal monitoring access (unlimited)
, ?# q3 C. ^5 }, K2 O backend private_monitoring' s" e- H- w) U* ~$ b. e. ]/ _# N
stats enable
! A& n. B! F0 |* A stats uri /admin?stats
4 y' g! \+ e Y+ M, z stats refresh 5s
l: J5 f: q7 S; O# }) L5 V+ W/ j' r8 h. K6 i s p, `+ V
See also : "stats auth", "stats enable", "stats uri"0 Y+ S& ~6 d- O, H2 Q) G2 e
" q% X- s/ ^0 e7 m& t2 g
9 e' w; r0 l! x* Hstats refresh <delay>/ W: J e) H, R. s$ B B
Enable statistics with automatic refresh
8 Q( ~0 l) @( O2 ?! n+ ]; M0 B May be used in sections : defaults | frontend | listen | backend/ s' l% b# j/ Y# }" M E: M
yes | no | yes | yes
7 X3 E( \, m0 k2 Q8 v: _3 J4 N6 n Arguments :
% E7 ^; y6 T: n+ j( a* f <delay> is the suggested refresh delay, specified in seconds, which will
8 r$ n: {) T0 E4 T! y: y be returned to the browser consulting the report page. While the( B0 `9 T$ { o1 y
browser is free to apply any delay, it will generally respect it
2 A8 |1 [# r" @: V% G! S and refresh the page this every seconds. The refresh interval may
( @- m W0 Z1 x8 L; p( D be specified in any other non-default time unit, by suffixing the
! V7 L* B# N: W( {, I unit after the value, as explained at the top of this document.: M8 q2 g0 o/ g+ N r- M& f
% m" O. [! }6 J
This statement is useful on monitoring displays with a permanent page
. N z$ V3 A$ T; V( O reporting the load balancer's activity. When set, the HTML report page will
( |# ~2 R' n5 M include a link "refresh"/"stop refresh" so that the user can select whether
P1 L. C; ^9 e; F he wants automatic refresh of the page or not.( J8 ?* C2 j, m4 [
4 J. E# E+ p' ?/ P3 H7 f Though this statement alone is enough to enable statistics reporting, it is/ f, @6 V, {4 d: o) j: Y ^' f$ T0 h
recommended to set all other settings in order to avoid relying on default
) ]: d$ g6 m1 [4 a unobvious parameters.1 E2 g- b! S$ Z8 r* b8 L, r5 f
5 b q5 a% s$ ~+ _& }! Z; d) t
Example :
/ ] k- L4 W) m3 @6 N, \/ Q5 |) B d, m # public access (limited to this backend only)# }, [: J; Z1 e V
backend public_www
% S: O- W4 a, R( v5 Y& S server srv1 192.168.0.1:80
2 _. j/ g9 Z! o# Y4 Y6 t% ^ stats enable% M6 l0 o) v7 ?4 L* r' V; X
stats hide-version
: k! H6 i) g" d stats scope .
3 l7 g/ d$ L# Q# h2 p stats uri /admin?stats W% ?) c* G7 t& J$ j" l; R. I( v
stats realm Haproxy\ Statistics- A: o- z) \; _$ }
stats auth admin1:AdMiN1233 R$ Q$ o2 l: B; O- I6 M. B
stats auth admin2:AdMiN321
* Z+ g! W% c6 o7 E& O) O2 A$ H* _+ Q. X
# internal monitoring access (unlimited)
6 S7 r; W6 e1 N3 v backend private_monitoring
+ ^) y+ Y1 o- B) Y6 o/ W stats enable' |1 N A1 G4 O7 x; q; ^
stats uri /admin?stats/ q* T) e5 J7 h! O) l
stats refresh 5s
+ {+ D& c# b' S" Y- U- Y; t
5 w- i7 E& g$ H' I See also : "stats auth", "stats enable", "stats realm", "stats uri", p' x) S+ O( C' r6 R+ i% g
' U3 O- ^# z" t2 X0 D+ q i
. o4 d. r1 }0 y) k, \stats scope { <name> | "." }: P1 z$ O5 d/ A2 h9 P7 a% K( v
Enable statistics and limit access scope+ F! N# N* {3 p b; [- X2 |* j
May be used in sections : defaults | frontend | listen | backend* }6 i6 z& E. q# V3 b6 S8 @4 C, a
yes | no | yes | yes# G8 p) r" R! x" G2 m% P; T* }/ i
Arguments :
n/ ?2 Q* m3 i. B* _) C4 ^ <name> is the name of a listen, frontend or backend section to be: O1 v! {: _5 Y2 @
reported. The special name "." (a single dot) designates the7 x# k# R; m$ }
section in which the statement appears.* N0 g8 [: p8 s, `$ u% `3 h
" l5 W4 T* V; F When this statement is specified, only the sections enumerated with this
c2 c* J( S( O9 f- ]1 J8 Y statement will appear in the report. All other ones will be hidden. This' E9 D4 T" N8 c+ e+ Y
statement may appear as many times as needed if multiple sections need to be
' I( r, a! G5 S& S7 Q& i reported. Please note that the name checking is performed as simple string. t C4 c8 ?1 {; I2 g% }
comparisons, and that it is never checked that a give section name really
) B* J% ^$ j8 n$ ? exists.& n/ i7 s; J. z- K- g, X5 V- H
9 H% ^+ P0 [1 v1 e7 B) F Though this statement alone is enough to enable statistics reporting, it is0 u7 I$ C% g7 A" R/ L3 W
recommended to set all other settings in order to avoid relying on default' q0 [, k+ w; }. c" h
unobvious parameters.
4 A+ i. o) h- n8 G" V+ |2 M0 I- s x* i; T5 J3 v
Example :
8 v- e" ^' |( C' [ # public access (limited to this backend only)5 f; }& T$ N7 Q! [) r) J5 s- h0 p
backend public_www
4 {6 B( r& R/ z8 s& g7 y4 D server srv1 192.168.0.1:80
: n6 G7 l& @8 L9 A) F$ g' v7 ^* W- f stats enable
) d- v( p4 \# C stats hide-version
( ?3 Y2 b! `; O( w. j stats scope .
8 G5 T. R6 K4 R stats uri /admin?stats u% o O# b7 g8 Q5 ~6 o- K
stats realm Haproxy\ Statistics
6 Y1 B% W5 g( R! b stats auth admin1:AdMiN123
/ _9 c% `& S2 ]% y3 W stats auth admin2:AdMiN321" {) p% i; ~, k" H* Q- A q
5 D- ^, i# w2 H3 D # internal monitoring access (unlimited)
8 F8 H4 P1 n+ A" f* n7 z backend private_monitoring& f7 S2 s8 _' d
stats enable
; {. f5 K) _: Q( T; `- ] stats uri /admin?stats, l+ k. K8 M2 z' }
stats refresh 5s
I* f4 `5 E& P
, {# t8 } a+ w; ~2 J) O! Z/ r0 y See also : "stats auth", "stats enable", "stats realm", "stats uri"/ H3 o) E. l- M' L( ^$ r7 N7 r
1 w" q, H7 k- b" I) ^ T- X
( J/ W' z4 a) w* v$ h
stats show-desc [ <description> ]& ~, q2 N3 w/ c/ n: f5 I
Enable reporting of a description on the statistics page.0 F' t a0 D* x# D" U
May be used in sections : defaults | frontend | listen | backend0 P5 O" L& R' m
yes | no | yes | yes. _/ K& V$ t$ m/ H& Y( q( i7 n
J3 I; \6 a5 G4 s& n <name> is an optional description to be reported. If unspecified, the
& g2 \' U" R. Y( Z. Q/ j" f description from global section is automatically used instead.# S( ]5 M q/ G7 h$ S4 e
7 D/ W" J @( Q/ l; F
This statement is useful for users that offer shared services to their
- ?; \- k/ G0 P7 ^) E( p customers, where node or description should be different for each customer.
+ \+ L C! @3 s; Z' a) x, w% A- t6 k' S8 ?( t
Though this statement alone is enough to enable statistics reporting, it is
" Z8 |+ m: W9 h recommended to set all other settings in order to avoid relying on default
1 P2 Y% i! i1 i, G unobvious parameters. By default description is not shown.
! U1 F, Y. l# d" ?( n( |! f( D3 q3 ? }% d4 D
Example :
2 E, p8 e: o* o" I # internal monitoring access (unlimited): C8 t. Y* ~1 I* N' d8 D. h
backend private_monitoring' D( S/ x) h7 C* i( {3 ]. H
stats enable! c# l7 ^. ~* Z( w9 b
stats show-desc Master node for Europe, Asia, Africa
H f+ E8 l! g* L9 p stats uri /admin?stats) [. Y8 j3 Z$ m4 G; K7 L
stats refresh 5s
( e1 K# M& D& f6 N c2 v1 {# y, j1 y9 N$ T$ l0 R* f
See also: "show-node", "stats enable", "stats uri" and "description" in( ?, n1 Z* Q1 w2 w, \
global section.! ^# Y7 ^( a% T
' f9 w) _) q. V$ S" y$ l+ P
7 v1 j) T Q* n& s A( R
stats show-legends1 b9 l) z, F5 O: U- D
Enable reporting additional informations on the statistics page :! O% V1 X/ h) a. O ?
- cap: capabilities (proxy)
/ _6 I ^8 U- `2 p( }1 f3 w7 y) ]1 @ - mode: one of tcp, http or health (proxy)4 s- d" E* B' Q- \- y' q
- id: SNMP ID (proxy, socket, server)
( K+ y9 \+ p9 V7 K# B - IP (socket, server)8 W; ]" L9 Z# Z0 e8 ~0 G$ m3 _
- cookie (backend, server)
$ z* |! [- x, c, o0 H! `
8 L; c9 m O1 G: a Though this statement alone is enough to enable statistics reporting, it is. K/ L2 D) T6 `5 u' _
recommended to set all other settings in order to avoid relying on default
' t2 u+ G y2 [1 h# G4 g& B3 ^ unobvious parameters. Default behaviour is not to show this information.& O+ Z1 u/ o( p
$ J h: C" V: w3 K: F j# s
See also: "stats enable", "stats uri".4 H# a! T' o( \! u) _( O/ K5 p
; M! @7 V' D- s6 u
4 M A9 }% F, p9 M+ k# M
stats show-node [ <name> ]! u9 o/ y1 O5 X2 ]
Enable reporting of a host name on the statistics page.1 e2 |2 y$ S% v- b
May be used in sections : defaults | frontend | listen | backend$ \# b# W4 s: D4 W2 M9 g
yes | no | yes | yes4 K4 ?) x' p U) U/ B5 U8 Q
Arguments:( D/ i0 V5 Q& @( |+ M
<name> is an optional name to be reported. If unspecified, the+ {, ]* w1 p1 h3 E6 J
node name from global section is automatically used instead.
+ O O, I9 ?; H2 L# G$ L4 O w- H( y4 Z+ ~" ]' a, N$ `
This statement is useful for users that offer shared services to their4 O9 T/ r. Y' w. Z( H. @9 J
customers, where node or description might be different on a stats page
4 a, h3 S4 ]: T: B0 ?; O( i" k3 e provided for each customer. Default behaviour is not to show host name.
, h7 ?) f8 z3 T% s) Q- z! p. u- _- j. A2 s& I4 s6 E
Though this statement alone is enough to enable statistics reporting, it is
4 [6 V/ W: h; v: z. D recommended to set all other settings in order to avoid relying on default
8 J" _) o. r4 \1 L) x1 D unobvious parameters.3 P7 k S) E* ?4 u5 _, {# h
. k' D$ j! ^$ Q
Example:6 Y3 P$ C$ D( s N7 s) U M
# internal monitoring access (unlimited). E' d! ?6 m3 i! J$ j- q
backend private_monitoring" A1 T' l* s( S6 E* T+ H# F) N# V
stats enable$ A9 N; n {2 g3 k8 P; ]
stats show-node Europe-1
+ M, ]+ e/ Z# ?9 h stats uri /admin?stats
# t" O5 Q. j l8 W7 i0 D5 w0 @& Q stats refresh 5s
z' V) X; n5 h1 o [% M8 q C# B1 [: R" N' x6 S1 H0 o
See also: "show-desc", "stats enable", "stats uri", and "node" in global
: m1 {8 W2 J* _1 C9 C0 h4 Z$ M8 O section.
\( c2 @. p9 E4 S& W* R& ?* R8 o# I2 t: Y
; b: M5 O: X9 fstats uri <prefix>, ^6 n! b$ S. P7 U+ l& X
Enable statistics and define the URI prefix to access them
5 i$ q+ }+ n* q3 o9 L9 J May be used in sections : defaults | frontend | listen | backend
0 i d- V* ]/ Z5 _* a yes | no | yes | yes
" ?3 `, {5 h( f3 M Arguments :
7 a% k! ]5 _0 c& v <prefix> is the prefix of any URI which will be redirected to stats. This
1 a# b; ]$ l/ H7 X! y C prefix may contain a question mark ('?') to indicate part of a
* t6 J# `- b7 s4 f9 r# B2 A+ e( A query string.
( F, q, x2 {# |
. Z% Q; x. a4 y# e V9 j% h9 [2 k The statistics URI is intercepted on the relayed traffic, so it appears as a
8 g; W/ R4 t0 _3 J, u( f8 x page within the normal application. It is strongly advised to ensure that the
8 K+ k! o7 G4 H- g4 ?9 \" E selected URI will never appear in the application, otherwise it will never be/ e* `0 N1 [* @2 B
possible to reach it in the application.
+ x3 j% H. m* s+ `" p8 c
6 R) c+ y% J$ X g& k ?# M/ v The default URI compiled in haproxy is "/haproxy?stats", but this may be+ a ^! w! } t) x
changed at build time, so it's better to always explicitly specify it here.
2 t1 m( I- v, J) i6 Q It is generally a good idea to include a question mark in the URI so that
, H, G" x& l& S. N' } intermediate proxies refrain from caching the results. Also, since any string) n% V6 o. ?* \# A
beginning with the prefix will be accepted as a stats request, the question
1 x' j0 r% Q+ p K( Q mark helps ensuring that no valid URI will begin with the same words.
- f5 I6 K0 z7 @3 N k
6 O: S" Q! |* ?$ u" \0 F5 B& d; I It is sometimes very convenient to use "/" as the URI prefix, and put that
u( M5 J: K4 r8 P5 {9 a( b statement in a "listen" instance of its own. That makes it easy to dedicate
1 F2 a" Z6 @8 C7 ?) D an address or a port to statistics only., f0 u! J- |* i, @
" `, G+ m: l% s& K- ~
Though this statement alone is enough to enable statistics reporting, it is
7 ]( E5 F$ u% ?1 E# O: r: J# k recommended to set all other settings in order to avoid relying on default T6 h& l" a( ]1 t. l( _1 u) m
unobvious parameters., N4 j G) F2 t2 M1 v2 m6 r
+ K. y3 ^# y2 A2 A; S) u+ o5 d
Example :
* y4 G. A; u5 _; r4 M. n # public access (limited to this backend only)
5 g: O6 h3 R- Z, s- A backend public_www
' @, v3 J o$ T" j6 {! R server srv1 192.168.0.1:80% U* [* K% Y3 r
stats enable
/ Q; v' B8 T0 d9 M% |9 U$ E2 e0 h6 ` stats hide-version [& D+ F. c/ h; j6 U, B
stats scope .
0 E# V* M8 z8 U6 z' Y stats uri /admin?stats
& M5 k" ]: ^4 O4 y- X% f stats realm Haproxy\ Statistics
* e. l( n. i6 x/ L8 A# \ c1 H stats auth admin1:AdMiN123
0 B0 i/ O, b! t stats auth admin2:AdMiN321
9 O0 _4 F( K6 o: l S: A) d5 d2 n( _' w) p) U
# internal monitoring access (unlimited)) b3 w/ W7 V) }% A) |
backend private_monitoring/ j; I. n; ^* r8 p! A! c
stats enable
+ ~6 a& r2 _: o, p stats uri /admin?stats
2 ~$ q6 b: V5 a7 J9 M stats refresh 5s9 V( }3 c+ C/ u6 a9 T
3 `1 l0 Y2 M8 B, g* b1 j See also : "stats auth", "stats enable", "stats realm"- Q v" m; \3 P) O" j1 f
! n3 a- f) Z: O8 u) Y( c9 |' o- S: j* ^
stick match <pattern> [table <table>] [{if | unless} <cond>]
! v, H1 h7 E0 z Define a request pattern matching condition to stick a user to a server
7 C( a9 ~. j9 F) b: k8 D0 ?6 Y8 t0 B5 C May be used in sections : defaults | frontend | listen | backend3 m3 O2 }1 X& q: D' J0 j
no | no | yes | yes
! d! D& d9 E% p2 {8 [& B! f9 G5 c. u$ v4 R+ q- ~2 y6 a
Arguments :3 |7 y: ?3 a' f/ ~
<pattern> is a pattern extraction rule as described in section 7.8. It
+ K8 |. Y$ |- q0 U7 E9 v% L5 C: W describes what elements of the incoming request or connection; H! n& v: g1 C/ b: t( s h
will be analysed in the hope to find a matching entry in a; D i6 F) @7 ^+ C
stickiness table. This rule is mandatory.
3 R' ]9 F9 L$ {# x+ Y, l7 i6 i
<table> is an optional stickiness table name. If unspecified, the same
' h3 m8 e( `& f i2 [6 q1 m backend's table is used. A stickiness table is declared using
& T3 e1 e/ U( e+ i; w the "stick-table" statement.
+ Z) A; p7 m: H! R" R9 @: Z A; {- O& x0 \+ P2 h
<cond> is an optional matching condition. It makes it possible to match
. e# e* x a$ S; j/ I, S# |2 i on a certain criterion only when other conditions are met (or7 G* g5 ^/ k8 }% @3 Y2 ]# `$ H
not met). For instance, it could be used to match on a source IP2 r& R3 h( ?" p/ d" R+ Y
address except when a request passes through a known proxy, in' y2 y, k7 m* j& h% p
which case we'd match on a header containing that IP address.' }' _4 Z# I, F- V# Q. Y3 s
; C/ R* B$ I# |& Q$ T
Some protocols or applications require complex stickiness rules and cannot* c$ t2 b8 k9 j) `. H: Y2 |* a* z
always simply rely on cookies nor hashing. The "stick match" statement
8 S' X: c) r7 l# C$ b- r describes a rule to extract the stickiness criterion from an incoming request
- b+ h2 s, R" J9 n# C( N p: x$ U5 d or connection. See section 7 for a complete list of possible patterns and
) a1 ]. N% x* [. Z/ E transformation rules.) }( y( t* l: Q* B
! ~" ?0 T, x+ p7 K* T
The table has to be declared using the "stick-table" statement. It must be of
4 \6 N% Q# `' G8 x a type compatible with the pattern. By default it is the one which is present
# ]9 h* x2 |; z* P- q in the same backend. It is possible to share a table with other backends by
0 f' K6 o5 \ v. }9 O referencing it using the "table" keyword. If another table is referenced,
+ i5 E, y6 ^+ n. w$ \. V: P5 d the server's ID inside the backends are used. By default, all server IDs
9 _# ?/ S* [$ m* P8 m! L5 n* ]+ g start at 1 in each backend, so the server ordering is enough. But in case of: p, y; r0 F+ I4 v& b# y) G
doubt, it is highly recommended to force server IDs using their "id" setting.
7 l6 V+ K2 I) Q6 T" ?6 z8 |( |! A# I" z' G/ n
It is possible to restrict the conditions where a "stick match" statement
5 Z V# N5 U$ {' O will apply, using "if" or "unless" followed by a condition. See section 7 for
% T7 I- \- K k ACL based conditions.9 m; g* A3 m3 S; K+ N$ s l0 c
$ ~! H$ h- E. H4 C8 w: H7 i
There is no limit on the number of "stick match" statements. The first that! h& B7 T$ M2 F1 J& t/ h
applies and matches will cause the request to be directed to the same server
4 _! z: `' O' |2 b) U# B, k3 S as was used for the request which created the entry. That way, multiple
* L N) G4 ]# E matches can be used as fallbacks.3 J1 `( q1 A G5 D7 ^
' p; ]6 w7 l! m# \* D' w
The stick rules are checked after the persistence cookies, so they will not# s; b: J6 O( P& _$ [; \5 U
affect stickiness if a cookie has already been used to select a server. That' p- J& u- v) X9 ]! B; W
way, it becomes very easy to insert cookies and match on IP addresses in
0 Z0 p( ?( ] B/ b3 d order to maintain stickiness between HTTP and HTTPS.
# U5 g/ b. Z# T
3 e$ p3 p+ C) u$ [$ C Note : Consider not using this feature in multi-process mode (nbproc > 1)- o1 m$ K$ V2 I" l. Z4 m: e
unless you know what you do : memory is not shared between the
4 B ]/ R6 \; ]7 E: C processes, which can result in random behaviours.$ R# b) n0 D. O( |0 g$ ~1 k
4 x! B: b- R% u9 R, \; E, u4 A$ q Example :
6 }& l: r- U, C# R+ p$ A9 U' j # forward SMTP users to the same server they just used for POP in the2 S+ a6 R9 S1 t v' _
# last 30 minutes8 Z. I" i& E9 L) U% m
backend pop
; G: h- F# r! R mode tcp3 Z% {0 j1 C/ {/ E* f% `
balance roundrobin- h5 q* a% |/ J* b7 ]8 |
stick store-request src
5 I4 }4 [2 Q. Q6 ~ stick-table type ip size 200k expire 30m5 l$ l+ F% U' ?, L/ Z9 c% L
server s1 192.168.1.1:110
; }* m {* Z, v- w2 \8 t" a5 ] server s2 192.168.1.1:110 `7 |- x" }: W0 r( t# C! W
4 A* t; U/ R6 ~- M7 F; s7 g backend smtp0 p$ ~' P# D8 X$ Y; K+ O* G+ C3 j2 g
mode tcp K' z2 V8 V J+ S# h
balance roundrobin
' z$ P) b7 y4 J/ I, s2 z) z( p& Q9 `3 E. g stick match src table pop
, q2 l& P H5 {0 v9 r server s1 192.168.1.1:25
, M$ U( B4 Y9 \- @- j4 R server s2 192.168.1.1:25
) A! [6 \6 K. A
( \3 X1 G3 @. | See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7+ P7 c3 |7 ]- y* I
about ACLs and pattern extraction.: |( h& Z& z- r5 f' A1 z" I
9 q% ]9 i2 [% d4 G7 U3 |; j+ ^. I8 t! ^" C& O& X% I
stick on <pattern> [table <table>] [{if | unless} <condition>]5 ^! u+ Z: s3 U( w
Define a request pattern to associate a user to a server
2 O7 L ^1 S; [' F! a, s9 s May be used in sections : defaults | frontend | listen | backend
4 R8 i( U, b. ]$ U: Z t no | no | yes | yes/ f; l1 i' |$ M5 L
. q9 Q5 B3 t+ Q* x* ~& a
Note : This form is exactly equivalent to "stick match" followed by5 b7 K" S$ @( x& T
"stick store-request", all with the same arguments. Please refer
* V2 n: o; z {) N6 V7 z* v$ Z6 R4 i to both keywords for details. It is only provided as a convenience$ l2 }- x3 M( k
for writing more maintainable configurations.* u5 q: c {/ e, F/ f% @) M: t1 ^
5 t/ }6 H/ O, z5 \) ~/ q8 D Note : Consider not using this feature in multi-process mode (nbproc > 1)
. p3 C# e+ W4 u! { unless you know what you do : memory is not shared between the" w! ` y. f$ ~% E
processes, which can result in random behaviours.
8 i+ W* C% H4 M+ T1 D2 L" t# G$ m% B% g, g
Examples :+ E$ z+ E2 T% N
# The following form ...+ c$ g6 A5 X& o# ]% B
stick on src table pop if !localhost4 q, B& R- M& t e, y! y. Y/ S' e
! \& C( a1 }+ o
# ...is strictly equivalent to this one :* ]: v" `, S% t+ U6 g {$ v5 J1 L
stick match src table pop if !localhost
% Y( r" F* I, w8 o( q2 ? stick store-request src table pop if !localhost
* X* l6 P& V3 J9 f8 J7 F+ E* n8 x5 }6 `% A$ V$ W
) m6 U* N+ T( }* C # Use cookie persistence for HTTP, and stick on source address for HTTPS as
7 Y( E* F0 I/ G _& r # well as HTTP without cookie. Share the same table between both accesses.1 a1 I- ^5 @0 t( t5 f
backend http! X' |+ n) F3 c( p, {$ _
mode http
) o- m& E7 f& ], H6 u5 n" A balance roundrobin
! M$ P" V- Q d2 K stick on src table https* {* G+ `5 w# r/ T' c9 p1 q
cookie SRV insert indirect nocache
8 z! R: x! \# h- } server s1 192.168.1.1:80 cookie s1
1 X& g. @# u% }# G4 V6 _8 g server s2 192.168.1.1:80 cookie s2. M1 [" V0 c+ Q( |# J, |2 t- H
1 A" b; d5 g# T; p5 c! \
backend https# n5 B, I( K5 M8 J" i! F$ r
mode tcp
! G0 _; G( C( L$ G balance roundrobin
: z; j# Q4 o7 K5 K- L$ p stick-table type ip size 200k expire 30m& ?, A9 s0 J6 O" j# t8 [5 Z' ?) t: k
stick on src+ O) T1 R9 y% c' _
server s1 192.168.1.1:443
1 F5 u; R" d( V server s2 192.168.1.1:443
" Q5 I' I# H! K3 M7 m+ T+ k+ X9 O4 O$ k3 m1 p1 v1 `4 c
See also : "stick match", "stick store-request", "nbproc" and "bind-process".$ L z, n' n2 u# g
; B, B! [ R" l, t8 v* w
$ c" k" Y5 A% E1 F z
stick store-request <pattern> [table <table>] [{if | unless} <condition>]; j" c$ q& I3 _, E. O- z% c' A
Define a request pattern used to create an entry in a stickiness table
, P3 ~5 y! s$ h: Z4 s* Q May be used in sections : defaults | frontend | listen | backend
; V3 }# ]- D' ~/ g( U+ V0 V% N no | no | yes | yes" @) e D. ]8 _# l4 G; ^- Y$ h
7 l* j" L, w" H' j* g9 E Arguments :: }3 r9 G. P1 U, L7 j9 C2 V
<pattern> is a pattern extraction rule as described in section 7.8. It2 s) Z [- ^2 C5 [# R7 s
describes what elements of the incoming request or connection
4 D5 V: M7 g* y/ j1 u: k; |9 S will be analysed, extracted and stored in the table once a
: }$ _: D: l( J2 ^ server is selected.# X: i, X" K6 a" I& u
/ X8 @) E' N) a; n$ \/ [ <table> is an optional stickiness table name. If unspecified, the same* t& o, {# V, f( d
backend's table is used. A stickiness table is declared using
* y$ `4 o' h8 R! T# V the "stick-table" statement.
z2 R4 M, B8 L& g( m
5 |7 H4 \8 X1 ]1 S/ S L2 p0 t" a* n <cond> is an optional storage condition. It makes it possible to store
% j9 ]8 x% ]3 k" Z certain criteria only when some conditions are met (or not met).
* I4 @! R! E6 x For instance, it could be used to store the source IP address
/ V5 n/ g8 [1 z, @- D9 z$ i except when the request passes through a known proxy, in which) M/ M( P* d! e6 z7 Y
case we'd store a converted form of a header containing that IP
. E+ _/ j6 r: V address.5 E9 l* ^ ?3 D5 O$ S
( y( M( i" ^" m+ k
Some protocols or applications require complex stickiness rules and cannot
5 |/ P; o0 U9 b9 ]+ a- E& {' c/ b& \ always simply rely on cookies nor hashing. The "stick store-request" statement- C1 d' ]* J2 q. C4 y: }# _
describes a rule to decide what to extract from the request and when to do) [; t( M w" C$ p# b
it, in order to store it into a stickiness table for further requests to
0 {$ C7 j0 h) ]3 m/ ] match it using the "stick match" statement. Obviously the extracted part must. m: W$ h! j4 G! {9 q H6 V; m9 k
make sense and have a chance to be matched in a further request. Storing a
3 j7 ^& W! e7 ]: M+ ?* s client's IP address for instance often makes sense. Storing an ID found in a% e- q+ D% b* k$ T) s1 d
URL parameter also makes sense. Storing a source port will almost never make
3 B) n3 q1 Z" F U any sense because it will be randomly matched. See section 7 for a complete) p2 u8 o3 q) g
list of possible patterns and transformation rules.
; ?$ y" T, {: I' F$ g) Y( W
$ M8 ]4 S f- P8 B6 E The table has to be declared using the "stick-table" statement. It must be of# K: c$ T& G( B1 u& l
a type compatible with the pattern. By default it is the one which is present. u+ D0 M- a' k: m% n/ @2 r( R* n* V' V
in the same backend. It is possible to share a table with other backends by
! a4 H7 j# N: _/ D6 d @5 P* Q& O$ g referencing it using the "table" keyword. If another table is referenced,) d' N7 i# m& ]3 t+ g' B% c
the server's ID inside the backends are used. By default, all server IDs
/ Z) f9 _! ~# p9 O. Z start at 1 in each backend, so the server ordering is enough. But in case of
& w' U! g! n7 D! v doubt, it is highly recommended to force server IDs using their "id" setting.( n/ d/ I1 z% z$ Y7 Y5 J
2 W( `' E( E' T. D. V! @% g It is possible to restrict the conditions where a "stick store-request"0 `) F6 @: R2 I; Q
statement will apply, using "if" or "unless" followed by a condition. This' h+ I4 Q9 Q. U5 Q
condition will be evaluated while parsing the request, so any criteria can be3 n) k& O, G, G; l3 v9 l% ^
used. See section 7 for ACL based conditions.. I0 v: ~' g; o
8 U; H2 K& _; B/ X# ^5 r6 }: R
There is no limit on the number of "stick store-request" statements, but" d8 |$ c% Z% f: [
there is a limit of 8 simultaneous stores per request or response. This% i- w( T% [9 b+ Z
makes it possible to store up to 8 criteria, all extracted from either the
; H$ t# k& G* J, w request or the response, regardless of the number of rules. Only the 8 first
, t4 w8 r( q$ Y5 y) M ones which match will be kept. Using this, it is possible to feed multiple* o' i% L4 s( U5 J
tables at once in the hope to increase the chance to recognize a user on
" X4 Z+ E& l9 d1 V another protocol or access method. Using multiple store-request rules with
; G2 G' `0 R1 M' |4 B the same table is possible and may be used to find the best criterion to rely
& f8 e f# U$ w7 D/ [) d! p+ n on, by arranging the rules by decreasing preference order. Only the first9 T9 O4 p- F% F) J
extracted criterion for a given table will be stored. All subsequent store-$ ]; U% z! w L# ^: j9 t
request rules referencing the same table will be skipped and their ACLs will: y* ?7 ?4 w. |! w6 C
not be evaluated.+ d9 s4 z1 ~0 s! ]: } s6 X
* ^6 [! [# T+ F% H# i& N. E" k0 @( V
The "store-request" rules are evaluated once the server connection has been
9 G- I- F( W/ ]$ b8 s established, so that the table will contain the real server that processed
; |* K2 ]0 Z- M/ H& I the request.
+ S0 r( h! @5 T' }$ h; d
5 s8 z* [% n8 D6 z Note : Consider not using this feature in multi-process mode (nbproc > 1)
4 x1 {) M9 d0 M* V' f6 U* t6 C unless you know what you do : memory is not shared between the
$ q* S& j. Y- W, V9 Q* L processes, which can result in random behaviours.
2 ^7 R( C) D+ L! M& ?
3 l+ h. K! a. W: i7 Q/ r H9 j Example :3 K! i4 d) e% j6 P% @4 p
# forward SMTP users to the same server they just used for POP in the
, u8 a; ~: x6 w W: U+ Y' W4 n) [+ l # last 30 minutes
" a: O- k( o( ?9 n backend pop
4 f# K. j) z1 E3 W mode tcp+ H5 G) x! s) @
balance roundrobin: `, h# t. S6 i. Q9 e, Z3 _
stick store-request src
6 p5 O$ X' ]8 K0 o8 W. N( {2 k stick-table type ip size 200k expire 30m
7 K! o% p: ^4 e" ? server s1 192.168.1.1:110/ z6 T. ]% [: Q: u8 U
server s2 192.168.1.1:110" J( O( I! k( {3 N; e
( ` ?6 U# w1 [5 }# }
backend smtp- J1 x& J( z6 D$ F
mode tcp
" G) L* s; L% S5 H balance roundrobin# H8 \4 W4 f, V7 K
stick match src table pop6 T4 A' \( D# ^* }& }0 o" e+ O
server s1 192.168.1.1:25
* _7 {, J& `0 s% T server s2 192.168.1.1:25
- W7 \0 Z4 h* z" q% I: e# I! [$ ?1 \- v0 w
See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
9 u0 \/ n# ~+ T' M$ v! n7 h about ACLs and pattern extraction.2 J6 `) ^+ l& b T: d; r$ Q6 h
1 o3 R3 d- G% @
1 n, {: b0 J" c! O" p
stick-table type {ip | integer | string [len <length>] } size <size>
% n3 x7 B# m' Q: ~9 r3 x, c* H [expire <expire>] [nopurge]* _5 \' V0 ]" A* ?# |- S1 m5 n& ]
Configure the stickiness table for the current backend4 \, p* v) |+ Q
May be used in sections : defaults | frontend | listen | backend
% n! D. u, L4 I" s( M no | no | yes | yes) [! o! P2 d# f3 x h* c& m3 j
- c, {7 k$ Z$ Y+ z- [6 P Arguments :
& h. k+ n3 F1 h5 q ip a table declared with "type ip" will only store IPv4 addresses.
+ m/ j8 V8 Y5 o' v/ f5 V' ` This form is very compact (about 50 bytes per entry) and allows* Z8 n, q& S5 ~4 Z* [
very fast entry lookup and stores with almost no overhead. This
, q: S" r8 Z! l. l is mainly used to store client source IP addresses.
1 N( p' f/ o1 B" m& b
7 K, Z, [4 B4 w6 a9 D4 ]3 [ integer a table declared with "type integer" will store 32bit integers
/ m5 j+ O5 v. y6 A which can represent a client identifier found in a request for
6 W' o% J3 q- }9 j4 ~ Z$ F instance.1 B1 B( p8 _9 B$ w
6 x' @& y/ d! }% h0 T$ \0 o9 k
string a table declared with "type string" will store substrings of up
, @: q+ f5 K+ ~: G9 C to <len> characters. If the string provided by the pattern8 e0 v. A9 Z" j. X" J
extractor is larger than <len>, it will be truncated before
# t5 J4 v4 Y S being stored. During matching, at most <len> characters will be
3 D" J% L8 c5 o% z0 v) `0 O compared between the string in the table and the extracted
9 _! Y" e4 T4 M- T4 i2 a R( z pattern. When not specified, the string is automatically limited
6 A5 r7 X7 E5 ?% A( | to 31 characters.
. e" d/ _7 P+ g- B5 d- ~9 i9 C$ E R) Z, L3 L/ `$ w0 d
<length> is the maximum number of characters that will be stored in a
# I" d: {7 r. u; U* O% a) q "string" type table. See type "string" above. Be careful when* W5 o1 K$ A: l% ~3 O& }/ b
changing this parameter as memory usage will proportionally
! p+ P8 P1 J. Z6 J* I+ m increase.* t k# k6 ], w E" c* @/ z
; V, }9 [% q* Z' d- P: R/ y* H
<size> is the maximum number of entries that can fit in the table. This
$ l+ f5 m* G% N; Z+ U7 I2 r value directly impacts memory usage. Count approximately- C( y5 z. R: P' X" X. z
50 bytes per entry, plus the size of a string if any. The size4 C+ m/ c" e+ u& o4 ^
supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
; j0 W9 `' \" o/ X3 a( X2 k* ? P3 G
[nopurge] indicates that we refuse to purge older entries when the table, j* n7 u7 M6 c7 ?+ ]
is full. When not specified and the table is full when haproxy0 u- V* w2 z" I0 U) o8 Q, x
wants to store an entry in it, it will flush a few of the oldest
, {3 W) B/ p8 ]* p$ ?& r entries in order to release some space for the new ones. This is3 Q9 ?6 G) d/ [; {
most often the desired behaviour. In some specific cases, it
1 @2 W# ~9 J; j, q, D' _ be desirable to refuse new entries instead of purging the older
7 S0 m8 ^/ U) T" l0 @ ones. That may be the case when the amount of data to store is
7 b3 B# x2 c! O3 d" T1 F% e far above the hardware limits and we prefer not to offer access
- e0 c0 h3 S: }4 R$ R/ G5 ` to new clients than to reject the ones already connected. When) @- H, s2 y$ ~. g/ I/ a8 U: P4 u
using this parameter, be sure to properly set the "expire"1 Y2 L w0 K/ s# ]
parameter (see below).2 Y5 ~7 C6 ^3 J& ~
( M1 p$ v2 r5 g: D/ I7 V& ?
<expire> defines the maximum duration of an entry in the table since it ^3 J. F1 h7 e$ \
was last created, refreshed or matched. The expiration delay is* a# l* C% x2 o
defined using the standard time format, similarly as the various7 R, S- Y, ~- }- `1 ?
timeouts. The maximum duration is slightly above 24 days. See
5 M3 A; H& u+ O | section 2.2 for more information. If this delay is not specified,* M+ r1 p( A- M6 t x
the session won't automatically expire, but older entries will
" I( ?+ c" S* z5 w& } be removed once full. Be sure not to use the "nopurge" parameter) a# k6 Z' U3 Y. M& L$ l
if not expiration delay is specified.2 F! [& o/ h$ O/ D2 ]6 R
) \% t1 s) U2 U9 T9 a2 o1 O* n The is only one stick-table per backend. At the moment of writing this doc,
& g9 r1 `; V. z) Q it does not seem useful to have multiple tables per backend. If this happens$ v* J4 Z: E% I y+ d
to be required, simply create a dummy backend with a stick-table in it and3 t# U( }& p' {( i r* t& b6 }# Q( Z
reference it.* d( C. C& Y4 h) |+ \
, p+ {) ?( L z/ B It is important to understand that stickiness based on learning information" d5 K+ n! L+ B# p' r
has some limitations, including the fact that all learned associations are
7 @ a/ p* f" u- C lost upon restart. In general it can be good as a complement but not always& m, Y" h( j! D7 h7 b4 f5 K
as an exclusive stickiness.! Z6 W6 V% Q& @9 W$ n5 ?
h% r( y0 K* K) e3 L9 c See also : "stick match", "stick on", "stick store-request", and section 2.2
( E6 |( O: p! n$ X1 O. \$ } about time format.) L- y+ A* K5 n G& Z: _
2 V' ^5 ?* X7 b9 [4 |) Q
5 O. J5 E2 W( }# u$ T9 `3 Ytcp-request content accept [{if | unless} <condition>]( y- }, l' i& ]/ E/ Z
Accept a connection if/unless a content inspection condition is matched
$ x! C) L, @, s May be used in sections : defaults | frontend | listen | backend
+ R- Z5 q. X" V$ R no | yes | yes | no
5 t2 f- d+ w6 A$ K/ L7 F
- M$ s3 E$ M' ~0 B During TCP content inspection, the connection is immediately validated if the
4 p; z, f x& h4 {5 l condition is true (when used with "if") or false (when used with "unless").; n5 H) X+ f" N2 \: d/ q
Most of the time during content inspection, a condition will be in an8 \( C$ `* k$ e; e( w+ A
uncertain state which is neither true nor false. The evaluation immediately
5 l5 @& z3 C& @" c2 O5 W, ]! H stops when such a condition is encountered. It is important to understand2 U6 l4 _( h& K9 X/ f8 H5 q, @& w( |
that "accept" and "reject" rules are evaluated in their exact declaration7 j, ^1 `. t z) d$ Y
order, so that it is possible to build complex rules from them. There is no0 t4 b7 I% }2 B* w( J$ K0 K
specific limit to the number of rules which may be inserted.
2 E) l9 C h7 X
. u5 T$ Z; a0 {! ]* | Note that the "if/unless" condition is optional. If no condition is set on$ ~3 P" U* o$ d5 U
the action, it is simply performed unconditionally.* Q0 X& O5 K: q- I0 @% J
/ L6 d5 W+ D& s: w2 ], Z
If no "tcp-request content" rules are matched, the default action already is
1 l* z3 m! Q* `4 s) k, O; r "accept". Thus, this statement alone does not bring anything without another0 t! Z9 ?' V1 a- M2 B
"reject" statement.
% e4 w0 j& f" h/ Z
) b1 C0 a# Y# p See section 7 about ACL usage.
! v7 P& V# W8 w- c2 ?$ r# S$ P3 h
1 u3 N* M7 r8 |7 ]# H) u' d See also : "tcp-request content reject", "tcp-request inspect-delay", J2 ]. j4 V8 |8 P
9 X2 W# E( A: B/ t" d$ h* a. ?1 l$ O7 E9 z# M
tcp-request content reject [{if | unless} <condition>]3 U, \9 H# e+ C3 O0 T# p# D
Reject a connection if/unless a content inspection condition is matched+ O9 k1 ~: Q. e' P7 c. Z2 Q
May be used in sections : defaults | frontend | listen | backend
$ w6 [. f' j! q- A+ }7 s no | yes | yes | no
$ S6 b2 O. G( S2 @
: O% l7 A& _- H During TCP content inspection, the connection is immediately rejected if the
3 h [) | [: M3 m* _ condition is true (when used with "if") or false (when used with "unless")." _ R4 H, g- J2 ^
Most of the time during content inspection, a condition will be in an
$ |7 f+ W6 f t2 F uncertain state which is neither true nor false. The evaluation immediately
z' ]% B, |4 ~! D stops when such a condition is encountered. It is important to understand
+ B; A- X$ M f; v that "accept" and "reject" rules are evaluated in their exact declaration
0 ]& H4 e0 r, @: P, ~ order, so that it is possible to build complex rules from them. There is no' {( b( ?! [5 s0 e8 b( o( Z% h
specific limit to the number of rules which may be inserted.
: D3 t1 P$ O* R, }5 q+ ^7 y% e5 E2 o7 Z( j& Z3 a
Note that the "if/unless" condition is optional. If no condition is set on7 Y% C5 J& q$ F% \! `; o" e
the action, it is simply performed unconditionally., G* J4 @( d% O4 I; N' Y$ D1 t; S+ G
% x, F/ b8 t' J/ K
If no "tcp-request content" rules are matched, the default action is set to
/ J$ c2 {6 b& o# d/ r5 ?# ] "accept".9 e) [8 h7 j3 B+ A
( o2 B. i0 \, }- p! Y! j: F* T Example:( Q. j- R. Y4 c2 J# \( ]7 k
# reject SMTP connection if client speaks first% e6 ^! V# m- N- ?/ A7 F% n
tcp-request inspect-delay 30s
3 @" ^/ s2 y$ F7 O; [! s) v acl content_present req_len gt 0
% Y9 F O3 _6 V# H7 ? tcp-request reject if content_present
1 J! Q2 k' u& t+ Z2 H9 `5 d
$ O7 J" `% f* z7 b# k) t # Forward HTTPS connection only if client speaks3 I5 {1 u5 Q, m" D9 F7 c' G) G: o# Z
tcp-request inspect-delay 30s3 z! }! v7 u, Z" P2 K" `1 t) C& ]
acl content_present req_len gt 01 K) S/ J6 Y D/ U0 \3 {
tcp-request accept if content_present* z( ~ V: W6 Y/ K: H7 z' T& p
tcp-request reject
- [: {! i" V" X* a6 m9 S/ F6 b0 C# s; B! v1 ?
See section 7 about ACL usage., t! N% H0 m7 H$ P# `, ^, N
. W& A, M% W1 @7 T7 E2 D
See also : "tcp-request content accept", "tcp-request inspect-delay"
' S6 j/ \1 |0 J
$ {# I+ l/ e: L& r, e
5 k8 X$ u; {2 y2 E9 e. ^9 X; t& z8 Ntcp-request inspect-delay <timeout>
5 n) A# I' i7 y( q5 g Set the maximum allowed time to wait for data during content inspection9 Z# ? s5 D/ D. T
May be used in sections : defaults | frontend | listen | backend
/ C1 o, J( O; O% M* j; G5 e& l no | yes | yes | no$ |) b: A G% t
Arguments :
$ Y0 Q- p4 x/ H0 V+ v. B <timeout> is the timeout value specified in milliseconds by default, but
/ T. C- P$ l: l8 m: q: X0 Z can be in any other unit if the number is suffixed by the unit,
! z* N3 c S: A' T4 w# y7 j as explained at the top of this document.
! N/ ~8 o( T" `2 `4 P; }: }: E! w7 U3 Y
' W& W" _/ H! `0 V: a c5 I People using haproxy primarily as a TCP relay are often worried about the
' Q, C9 C9 U2 W! Q& H; i risk of passing any type of protocol to a server without any analysis. In
8 H/ C9 s) C/ x5 c8 i0 G order to be able to analyze the request contents, we must first withhold% F/ ^! g' Y' }" ^- ]( l2 J
the data then analyze them. This statement simply enables withholding of2 Z5 t7 J% _2 _1 h" N0 c/ Z
data for at most the specified amount of time., s2 o; N. ?: `7 T7 \1 ]
+ N! @% z: {. u G7 G% T- s4 c1 W% z Note that when performing content inspection, haproxy will evaluate the whole& O. `9 x, R& m, ]" V
rules for every new chunk which gets in, taking into account the fact that
9 V+ U7 S4 r/ g1 Y! g: ?+ Y those data are partial. If no rule matches before the aforementioned delay,
4 ~# x, r1 X: B1 v4 ]* C0 w a last check is performed upon expiration, this time considering that the
/ e9 d l2 c5 q$ D- U contents are definitive. If no delay is set, haproxy will not wait at all
1 A: G- B# Q) d+ t4 S8 B" \ and will immediately apply a verdict based on the available information.
* t0 w) F5 Q u; g, s. q Obviously this is unlikely to be very useful and might even be racy, so such& @, d& O7 H( u4 ~
setups are not recommended.! @( d! F' U0 o' ]& i# }# Y* K
( Y; n: M% C% E% u% ^+ P6 } As soon as a rule matches, the request is released and continues as usual. If! N$ I: ~5 F1 F' y- w, J
the timeout is reached and no rule matches, the default policy will be to let
" F i' K' o! x( S7 ]$ D9 @ it pass through unaffected.# F. e5 k [2 \2 N; j* i/ ]
- t* h5 Z: z9 b) Y. p) V, N3 T! q
For most protocols, it is enough to set it to a few seconds, as most clients
) l1 d! V9 F5 z Z# V+ r" s0 k6 e$ a send the full request immediately upon connection. Add 3 or more seconds to
3 Q8 c' w" U4 r8 D; P) d% D% A2 i8 I cover TCP retransmits but that's all. For some protocols, it may make sense
?8 h" o, k% b* H3 C" f8 q to use large values, for instance to ensure that the client never talks: ^$ v2 X& E* W9 t! _
before the server (eg: SMTP), or to wait for a client to talk before passing c6 G6 B: t- G r% a
data to the server (eg: SSL). Note that the client timeout must cover at& q! g0 w8 @0 p5 @
least the inspection delay, otherwise it will expire first. If the client. I4 ^9 x7 d5 G
closes the connection or if the buffer is full, the delay immediately expires
2 }5 k8 B U; ? X6 ~5 Y! v since the contents will not be able to change anymore.
0 B; t" e5 d( G3 t; P8 ` R f& r X6 H4 F% f1 I
See also : "tcp-request content accept", "tcp-request content reject",
$ D1 ?5 ~8 h& n1 p5 g7 F "timeout client".' x! x, u4 ?6 H- c
( @" n& P& O0 q, K( k7 d2 u. y K% X" u7 r0 h0 @: q
timeout check <timeout>
& d, b1 U( `: ]$ {( b% N Set additional check timeout, but only after a connection has been already
9 x% e0 C n. c5 P( ^4 p established.' H, B3 ~$ ^0 W/ q( s' J1 H
' F4 [- |. G( n0 p May be used in sections: defaults | frontend | listen | backend/ L ~4 t1 f9 S0 ~/ {- m M
yes | no | yes | yes
; C7 i. o- o0 t/ ~) ^1 d( ]0 p Arguments:! T8 U3 `4 X' g
<timeout> is the timeout value specified in milliseconds by default, but
- d& e+ Y% n8 ?: @( `( n6 G can be in any other unit if the number is suffixed by the unit,0 F4 T& H3 `) N% L7 }# E( {
as explained at the top of this document., a; E7 T; M! _$ O/ Z. P2 i! \
8 B' @0 q8 }8 y5 J2 G+ @ If set, haproxy uses min("timeout connect", "inter") as a connect timeout& u' i3 w0 D; U/ `2 V$ [6 x$ |
for check and "timeout check" as an additional read timeout. The "min" is
/ F, q( S- Y* P8 U7 |9 c" G used so that people running with *very* long "timeout connect" (eg. those, m: F4 S+ X) ]3 e/ Q& b5 a
who needed this due to the queue or tarpit) do not slow down their checks.+ u' _/ D9 R3 s0 [+ {5 z6 l3 r
(Please also note that there is no valid reason to have such long connect- ^) w0 t* V; `
timeouts, because "timeout queue" and "timeout tarpit" can always be used to
$ I. N5 L1 N# k avoid that).
, m; Z! Z( [/ c2 |0 v* g
" w+ F4 v7 l# a) q7 n4 n$ S If "timeout check" is not set haproxy uses "inter" for complete check
) G7 Y; `% @' n timeout (connect + read) exactly like all <1.3.15 version.& T* o( ^' [- Y9 E$ {+ [4 _
7 i# K$ P, X# K' [ @
In most cases check request is much simpler and faster to handle than normal/ Y( Q$ E$ M1 s8 O
requests and people may want to kick out laggy servers so this timeout should) I8 ]) w9 g" S! z7 R. Y
be smaller than "timeout server".
% ]& O) K: S# ^. P+ y+ o3 V) V! J9 i3 `- v( d' }& C7 n
This parameter is specific to backends, but can be specified once for all in0 [; L) G3 a9 e8 u8 d% o. s+ J8 R
"defaults" sections. This is in fact one of the easiest solutions not to
; \. u6 X( u# }# R# | forget about it.
8 l6 x. v/ F9 H
1 \* G- k7 s" l; { See also: "timeout connect", "timeout queue", "timeout server",
3 \ d6 ]9 E# l9 ^ "timeout tarpit".% P9 U& O A, V* q* H
% X0 `0 ?0 Z2 b- F b5 P( m9 j
4 x# Q0 ^+ c$ O! E! j
timeout client <timeout>
9 _" l+ O. `% \3 C. g- C& Ttimeout clitimeout <timeout> (deprecated)+ f0 R9 W6 i4 [3 W3 ^) k: y5 t4 I
Set the maximum inactivity time on the client side.3 i; k$ ^8 c0 j7 e
May be used in sections : defaults | frontend | listen | backend
8 Y9 y% D( @" b7 r# O& D! U yes | yes | yes | no
0 p# y! \% }) @ Arguments :$ o" p( L& f. ] Z1 I
<timeout> is the timeout value specified in milliseconds by default, but
! T' J. Q1 Y( x( e* u) w4 X6 I/ S can be in any other unit if the number is suffixed by the unit,
; @, ]; r! e& h2 s as explained at the top of this document.6 ~" A0 k! ]* q/ {- T7 R7 I
% P9 j( t' d* l The inactivity timeout applies when the client is expected to acknowledge or w. U* b( C' B3 A
send data. In HTTP mode, this timeout is particularly important to consider
' W/ R# |$ d# c during the first phase, when the client sends the request, and during the' l/ e; G( X9 m) B2 ^/ R
response while it is reading data sent by the server. The value is specified
# F2 E$ K* R- d" b. q in milliseconds by default, but can be in any other unit if the number is
8 y0 F& F$ k# [4 h0 r suffixed by the unit, as specified at the top of this document. In TCP mode. P% p3 F8 G0 ~- w, Y. G
(and to a lesser extent, in HTTP mode), it is highly recommended that the
- ?) c9 V: I3 I- p3 x# [* E client timeout remains equal to the server timeout in order to avoid complex
) a0 E9 F; z$ X; ]( a situations to debug. It is a good practice to cover one or several TCP packet
" N7 f# X( Q* j5 P& C( e: {7 | losses by specifying timeouts that are slightly above multiples of 3 seconds6 }4 [4 x k6 d) x
(eg: 4 or 5 seconds).5 U# D% n; b0 C" j( O+ \4 k, \
4 m1 @3 n- q( F- S0 k9 J# A s9 B c0 x This parameter is specific to frontends, but can be specified once for all in1 m9 X$ V+ P% N' `# {
"defaults" sections. This is in fact one of the easiest solutions not to
~) K/ d7 A H( o: p. @ forget about it. An unspecified timeout results in an infinite timeout, which: F( C/ N+ c& R- P2 n' z; O
is not recommended. Such a usage is accepted and works but reports a warning7 w j: [6 O+ p4 k. q9 l: B
during startup because it may results in accumulation of expired sessions in' t5 k7 D! d1 K% `# X' d
the system if the system's timeouts are not configured either.
3 j1 L3 f" _/ p, c& ?6 U
7 ?- V7 U# {0 u5 k" D+ j* E) r This parameter replaces the old, deprecated "clitimeout". It is recommended, c! ?& p }7 H W. }
to use it to write new configurations. The form "timeout clitimeout" is
; L0 I- d; T$ M8 K$ M5 ~4 T- ~ provided only by backwards compatibility but its use is strongly discouraged.
1 J: R* J0 [9 N4 W8 _# N1 C
- |4 k& z/ X M; @4 c7 P/ j See also : "clitimeout", "timeout server".$ p. N# A; u* V4 ^. m" e% n
, A+ o, S# g; _2 Q# p
: g# a+ r2 `& S) |& ^$ E8 `# gtimeout connect <timeout>
( L1 i* a5 R' w" J4 q1 mtimeout contimeout <timeout> (deprecated)7 s" ~) _* _0 z- {
Set the maximum time to wait for a connection attempt to a server to succeed./ s/ c6 V! T5 s" k
May be used in sections : defaults | frontend | listen | backend
1 K& C: D! P0 F0 c2 |0 P# `- o yes | no | yes | yes
- y A0 F) p5 I! A Arguments :' g8 L- i- ]1 {
<timeout> is the timeout value specified in milliseconds by default, but
; ~7 x4 E, ]0 E can be in any other unit if the number is suffixed by the unit,! E5 I/ m8 I' d" R) z
as explained at the top of this document.
' I% e# e0 v+ W: @7 L& o# c& v# D" P2 Y8 S- H7 z
If the server is located on the same LAN as haproxy, the connection should be3 B, j' [* ]% I0 Z
immediate (less than a few milliseconds). Anyway, it is a good practice to
; D0 P& Y) \: w2 _ cover one or several TCP packet losses by specifying timeouts that are
8 a: j9 h9 x( W& W- }( ?/ s slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
, W( z* o" T# Q connect timeout also presets both queue and tarpit timeouts to the same value
" x& ?. P6 b4 Q; c4 W4 S# a if these have not been specified.
' R; |" _9 I* L2 X
' u- w w9 p1 |9 J) a This parameter is specific to backends, but can be specified once for all in
2 _7 T' M4 i; L: Z7 A "defaults" sections. This is in fact one of the easiest solutions not to, o$ A6 h3 }: Z8 x' B
forget about it. An unspecified timeout results in an infinite timeout, which4 ^" B& X; t- f0 o7 ^5 z
is not recommended. Such a usage is accepted and works but reports a warning W: ?/ b3 U- o8 M
during startup because it may results in accumulation of failed sessions in) b: h! {+ C+ j1 \. {/ k' p
the system if the system's timeouts are not configured either.- ^7 ]& X% H% \& |8 o! P0 L% l
; r/ B. a8 W" C$ x* P, M2 [) w
This parameter replaces the old, deprecated "contimeout". It is recommended
) ]* ~% A" X/ @ to use it to write new configurations. The form "timeout contimeout" is3 o! Z1 i7 N' A
provided only by backwards compatibility but its use is strongly discouraged.
- ]( t: E k) n) x! ?, m* Z
2 A2 m- U& N" h' Y( W. V3 _ See also: "timeout check", "timeout queue", "timeout server", "contimeout",4 i1 C2 c. v( H; E
"timeout tarpit".
7 l6 D! [! f5 M! D& b
* V/ D( X$ I% {& {4 y( p! v$ ~+ Q
timeout http-keep-alive <timeout>8 o# \* E" H! }! H: @8 |
Set the maximum allowed time to wait for a new HTTP request to appear8 P- J1 `+ `; b7 J; p/ O1 |1 R
May be used in sections : defaults | frontend | listen | backend
( _9 U2 l5 A9 L. j+ k F8 v8 h0 b yes | yes | yes | yes
9 l/ P2 r. \ G0 b. `, E Arguments :3 x( y6 `3 p; d; q0 _% G
<timeout> is the timeout value specified in milliseconds by default, but3 b9 b; }) F. r2 F
can be in any other unit if the number is suffixed by the unit,
: [6 y9 C. m7 q$ o$ c as explained at the top of this document.! w8 D9 o6 z* v& n9 F
9 O6 b! g- i, Z. L By default, the time to wait for a new request in case of keep-alive is set# ~) n9 O9 [/ [( L
by "timeout http-request". However this is not always convenient because some
4 O! I# o2 o+ K+ m5 ~7 ]' k5 _- z2 _ people want very short keep-alive timeouts in order to release connections0 T6 e& a# A1 [1 q d
faster, and others prefer to have larger ones but still have short timeouts0 S% e% M7 m- {, k1 _+ Y% |
once the request has started to present itself." Q7 C* e# G |% }* B: T# H
! @5 V& ~- R, Y* c; i. M0 Q7 D
The "http-keep-alive" timeout covers these needs. It will define how long to4 Y+ `: t- H$ C! V; ^4 d
wait for a new HTTP request to start coming after a response was sent. Once
7 u8 K X0 q7 T! J- S6 ] the first byte of request has been seen, the "http-request" timeout is used
Y4 p3 V- f6 F; }: @( R to wait for the complete request to come. Note that empty lines prior to a2 u6 E: `: ~& G' |
new request do not refresh the timeout and are not counted as a new request. r0 T( c6 q* G
- b& I+ {) X3 v# q There is also another difference between the two timeouts : when a connection
$ E, w# z, Q' }& Q! a) O7 _9 v( z expires during timeout http-keep-alive, no error is returned, the connection1 O. l4 u7 s4 h- g2 {; |
just closes. If the connection expires in "http-request" while waiting for a6 K' P5 L7 V8 C) C4 s
connection to complete, a HTTP 408 error is returned.
$ D0 P9 {1 @2 ~9 @: a) ?" u# {6 \ I
In general it is optimal to set this value to a few tens to hundreds of
# o& Q8 ?- I/ |! a! z' W- @6 K milliseconds, to allow users to fetch all objects of a page at once but
) e9 ^; W9 |! W! z3 y) ` without waiting for further clicks. Also, if set to a very small value (eg:6 V' Z: t1 c9 C. O& e. T
1 millisecond) it will probably only accept pipelined requests but not the0 f% l" E1 X G+ r5 K
non-pipelined ones. It may be a nice trade-off for very large sites running
# j5 G' j0 J# z- i0 _# d with tens to hundreds of thousands of clients.
8 ^3 _+ O* | M- b- v' [, O! `! q( _& q- v. P. q# Z6 t
If this parameter is not set, the "http-request" timeout applies, and if both
9 O7 u) x4 }3 k# `" y* h are not set, "timeout client" still applies at the lower level. It should be ?. \# ]0 \! u" @2 E) e
set in the frontend to take effect, unless the frontend is in TCP mode, in
( J- u9 A/ r# _3 l which case the HTTP backend's timeout will be used.
; r0 ], D& G4 O; `4 O% H8 f1 ]& ~$ `. S
See also : "timeout http-request", "timeout client".: H( _4 i3 V$ Z2 _
% k) b, @6 ^0 l% a' S: |4 `4 K1 o; f" K. p* }0 q
timeout http-request <timeout>
. p, [. K, C( B y' g3 k Set the maximum allowed time to wait for a complete HTTP request
+ {8 e# C9 }+ q+ i: n3 E; j May be used in sections : defaults | frontend | listen | backend
! R: r& B9 m* u) c4 X5 g yes | yes | yes | yes
2 y c2 D% J% w Arguments :
) q+ b1 T+ n/ J2 W7 }" k <timeout> is the timeout value specified in milliseconds by default, but$ ?0 T$ ]0 C! `4 S# y- C
can be in any other unit if the number is suffixed by the unit,
7 l% O+ H; l. c% V as explained at the top of this document.
9 {* I% `! K2 f1 z2 y) \
( u: [- S, d: l ?" b% D* S3 V- } In order to offer DoS protection, it may be required to lower the maximum
# X3 H" y" G" d, s9 x2 h accepted time to receive a complete HTTP request without affecting the client
% u9 x7 i, W; K: I timeout. This helps protecting against established connections on which5 f' }+ A7 {; o
nothing is sent. The client timeout cannot offer a good protection against
8 L1 Q& B& ^2 A1 Q+ E& J: ]- \5 y this abuse because it is an inactivity timeout, which means that if the
( Q9 C, Y% C! P/ M$ d$ _% ]6 } attacker sends one character every now and then, the timeout will not- M6 s# z' A; {5 P! C5 H
trigger. With the HTTP request timeout, no matter what speed the client
& k+ ?; q5 `2 c, W: H( ?% D+ v types, the request will be aborted if it does not complete in time.( h& i3 } j2 j4 R! Z6 c3 y2 f# i% J
8 u; K. x. W7 m* m! B+ {6 { Note that this timeout only applies to the header part of the request, and
# D" ^/ c+ B4 R M not to any data. As soon as the empty line is received, this timeout is not- D- \; [+ K. |
used anymore. It is used again on keep-alive connections to wait for a second7 }) r9 F+ I; T4 F8 T% j" j
request if "timeout http-keep-alive" is not set.$ m+ X `- ?) D1 g) V2 ]
G2 q2 O4 d; h$ t) A; L6 m Generally it is enough to set it to a few seconds, as most clients send the
% j/ U! q% V1 ^4 s* y full request immediately upon connection. Add 3 or more seconds to cover TCP% o r4 L$ L8 A( a
retransmits but that's all. Setting it to very low values (eg: 50 ms) will
) @! V8 r* l4 H4 b, ~% Z. _ generally work on local networks as long as there are no packet losses. This
5 U$ f/ @, D/ u) G. K will prevent people from sending bare HTTP requests using telnet.
0 }7 _/ J' S. Y. K( h" c$ \5 K2 g* F" X: D* d' }3 f
If this parameter is not set, the client timeout still applies between each7 A' L2 E1 b) ^* T3 f
chunk of the incoming request. It should be set in the frontend to take
2 l8 B. l2 F# J& g- U effect, unless the frontend is in TCP mode, in which case the HTTP backend's
. ~$ H5 w7 |$ S; G timeout will be used.: q7 d; y$ r: R/ b2 G. Z
* e. m' n" e w$ m/ C0 ` See also : "timeout http-keep-alive", "timeout client".# A" _1 I7 P$ R& \
: v3 i, g" K' D, [& a' I
5 k: `0 q3 ]0 W4 O- S2 c' r i8 k* {timeout queue <timeout>
6 l b( h3 V( j) A2 C Set the maximum time to wait in the queue for a connection slot to be free
* p, J* R7 L- t' ^, y4 w4 } May be used in sections : defaults | frontend | listen | backend! E" j, {0 d4 H) q- A( E7 S
yes | no | yes | yes
' U( _3 U3 b0 _7 P Arguments :
6 r: |8 m/ W- z# t/ k <timeout> is the timeout value specified in milliseconds by default, but. f; Y$ `, F2 X+ ^! R, J8 q
can be in any other unit if the number is suffixed by the unit,- J9 [+ b" c& Z: S) @
as explained at the top of this document.
{: j( S0 |; v$ ?
- t# g' U" F! g When a server's maxconn is reached, connections are left pending in a queue+ g' O5 I) K% q# v5 S# }6 z
which may be server-specific or global to the backend. In order not to wait
" D7 e j! q1 H7 r. z1 _ indefinitely, a timeout is applied to requests pending in the queue. If the& d& V% r5 Z. g( d( z- [" {
timeout is reached, it is considered that the request will almost never be
' \, ]7 V4 X( V8 z/ `% y+ B served, so it is dropped and a 503 error is returned to the client.
6 f+ Q8 U8 Q( |
3 R0 e) a- `: K, y+ i( @ The "timeout queue" statement allows to fix the maximum time for a request to( s w$ Y0 i) _* ~
be left pending in a queue. If unspecified, the same value as the backend's
/ l: K& c( L5 P4 U connection timeout ("timeout connect") is used, for backwards compatibility
8 A9 h4 {4 \- J6 p2 ] with older versions with no "timeout queue" parameter.3 X) t% J6 d+ B& s K. Y
( i/ n8 f& ~8 J; Y
See also : "timeout connect", "contimeout".( M9 @% P! W7 U: R1 N, \; l
! i, O5 I. g- b% q# j4 Z1 X+ M! G( z4 S& [; @
timeout server <timeout>3 x3 |* S$ W) }3 ^
timeout srvtimeout <timeout> (deprecated)" K1 G. Q, x1 m) b& \
Set the maximum inactivity time on the server side.
% R0 E# t6 y. t; F7 M9 L May be used in sections : defaults | frontend | listen | backend$ L$ G3 e5 w3 q9 S9 N8 \, q. f
yes | no | yes | yes ?) ~/ ]% q" {. B- z
Arguments :
% e5 s9 V/ C4 {% b7 @ <timeout> is the timeout value specified in milliseconds by default, but
4 B( c9 r9 b6 W+ R can be in any other unit if the number is suffixed by the unit,6 A& ? ^( @9 m3 N1 c
as explained at the top of this document.
, U |3 f( X3 M1 ~) T% e* [! }4 e- F' H7 o; C3 j+ `. D' W
The inactivity timeout applies when the server is expected to acknowledge or0 ]" `4 h0 w5 t
send data. In HTTP mode, this timeout is particularly important to consider1 w ?7 P6 ]+ I; A! v
during the first phase of the server's response, when it has to send the
1 k( J. y2 @# W' }$ i( i- \ headers, as it directly represents the server's processing time for the4 j6 d, o w3 v F3 B2 b
request. To find out what value to put there, it's often good to start with
. N7 @3 D# t8 ^3 Z what would be considered as unacceptable response times, then check the logs
! x- Z. @, |. I+ k$ a to observe the response time distribution, and adjust the value accordingly.3 A; E [2 _: @: F
G4 z, V5 [6 h- x
The value is specified in milliseconds by default, but can be in any other4 Z |, q7 N" v9 f3 @! v4 y( ]) {
unit if the number is suffixed by the unit, as specified at the top of this
M- B/ A/ D x3 u/ a document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly5 W1 g% X3 h# x+ J6 y
recommended that the client timeout remains equal to the server timeout in* s' x p/ b1 `: a
order to avoid complex situations to debug. Whatever the expected server8 A. `3 R. A% r
response times, it is a good practice to cover at least one or several TCP5 W! r$ C7 y% M
packet losses by specifying timeouts that are slightly above multiples of 3
) N4 V+ g$ {: `4 _$ G seconds (eg: 4 or 5 seconds minimum)." C" j' K8 E2 U0 e1 v/ I4 {
; U# |9 i: _0 F* c, @+ t) e
This parameter is specific to backends, but can be specified once for all in
7 L1 }1 q5 k) i3 g) d9 A "defaults" sections. This is in fact one of the easiest solutions not to
$ B9 o }$ Y& ] forget about it. An unspecified timeout results in an infinite timeout, which, V0 H8 O; s: h9 E
is not recommended. Such a usage is accepted and works but reports a warning
@5 s. G4 n( b2 D, { during startup because it may results in accumulation of expired sessions in
3 ` `4 d" J8 t- h, c the system if the system's timeouts are not configured either.4 u" ~' d& O! f9 f* A4 z' h' z
9 O* n# L9 p* |7 a% S+ T9 G# m This parameter replaces the old, deprecated "srvtimeout". It is recommended
3 X5 F4 L; W" f. `6 m) _& E to use it to write new configurations. The form "timeout srvtimeout" is
1 T9 \ G) G0 x3 a provided only by backwards compatibility but its use is strongly discouraged.6 w% _ w0 R; j+ r- l7 D
% g, S! ], }" K/ x+ r See also : "srvtimeout", "timeout client".
/ Q5 g9 D& n G+ g( V5 u+ i( ~8 y1 ?. V7 J/ W% Z) ]4 \5 p |& d
+ N. n. q* t& ]: ~8 J1 @( X9 t8 q
timeout tarpit <timeout>
4 a* W$ R5 K& K8 D( n G y Set the duration for which tarpitted connections will be maintained w0 g% n7 |# x
May be used in sections : defaults | frontend | listen | backend
) L \, K0 K- U( @2 ] yes | yes | yes | yes j% S0 \* o9 b9 ^# l
Arguments :8 K) ?2 d% G! b
<timeout> is the tarpit duration specified in milliseconds by default, but2 y+ }5 h( E |/ t3 ^
can be in any other unit if the number is suffixed by the unit,. N/ @/ h, p3 v. Z
as explained at the top of this document.
u- c- W. a; ]) G
, @: g9 c# z- u$ R& ]8 P: k4 S$ G When a connection is tarpitted using "reqtarpit", it is maintained open with
- m; X+ v4 a6 m9 M, y# n no activity for a certain amount of time, then closed. "timeout tarpit"
! M' `' c8 {( {% V A. g defines how long it will be maintained open.
) u: h$ \0 w7 ?# l! N8 [5 Y7 a/ e" {" O: { T# b
The value is specified in milliseconds by default, but can be in any other. G5 s4 u" d/ P: f, a. }
unit if the number is suffixed by the unit, as specified at the top of this9 c* A2 r4 Q& E& ?( K( p1 [
document. If unspecified, the same value as the backend's connection timeout' x/ e! q* D! O3 K4 w: n2 j; _/ z$ X
("timeout connect") is used, for backwards compatibility with older versions
! y) T. g+ X4 G T with no "timeout tarpit" parameter.' ^& ]/ [. _- X/ Y
0 P' N" {' l1 j/ R See also : "timeout connect", "contimeout".
9 l7 x/ ]: x6 I' v# P6 c9 b5 `/ ^* C) U0 A6 A* W" H
# y' X! F; o. O0 R6 e, Z1 |/ u- E
transparent (deprecated)5 l$ a; C% U# k
Enable client-side transparent proxying
3 @* R) h8 ]' ` @/ a( G: @ May be used in sections : defaults | frontend | listen | backend. e# ]! E* B6 @( k+ f8 e- v
yes | no | yes | yes
6 L4 O; L$ T( \2 F0 i) N/ c Arguments : none; t9 m, y& j: l9 b
7 R7 Q0 d3 n2 H/ p This keyword was introduced in order to provide layer 7 persistence to layer
2 R% v m- Z U* { }% r c 3 load balancers. The idea is to use the OS's ability to redirect an incoming# Z, V8 ]) z: z
connection for a remote address to a local process (here HAProxy), and let
! p5 a* z7 \4 h4 o. x& c this process know what address was initially requested. When this option is
, D V: g0 [: E. r6 I used, sessions without cookies will be forwarded to the original destination
) ]& g) w) A4 m( y IP address of the incoming request (which should match that of another
1 u* z4 y* d) b2 G7 K6 `; a equipment), while requests with cookies will still be forwarded to the/ I/ P4 D, O: G' n& W. i# s
appropriate server.# O- O1 R5 J. V9 E- [8 i; D* \
# J. V# I9 l1 o# {" I; U4 {' c- B
The "transparent" keyword is deprecated, use "option transparent" instead.
% S0 z5 Y/ f* ^
! {$ [ X2 S3 `5 k: m D7 e Note that contrary to a common belief, this option does NOT make HAProxy
' c7 r+ S& {0 a6 }( h. F present the client's IP to the server when establishing the connection." Y9 {1 Z5 A5 c
5 W( H! G" p$ E$ D" n See also: "option transparent"' a* [. M J" D3 p# X/ b2 v
3 B5 k; ]) P/ s8 b: L
2 k4 K6 ?4 Q3 E% D' Cuse_backend <backend> if <condition>3 Q6 ^7 J! L- F( Y% l Z
use_backend <backend> unless <condition>
$ Z" w) z! a+ b& k i% p Switch to a specific backend if/unless an ACL-based condition is matched.- m2 Q) d. y( T8 B8 [
May be used in sections : defaults | frontend | listen | backend
7 [1 R# d5 ]! J; h3 l' { no | yes | yes | no5 N' R+ n$ g- o0 b
Arguments :( b+ @, s* r1 O5 {# E2 ~
<backend> is the name of a valid backend or "listen" section.! V5 a1 C# m, d8 v0 F% i q
/ z- U5 c: E+ ]: h" j2 w' I0 D <condition> is a condition composed of ACLs, as described in section 7.
4 m. ~3 K5 k* H; p; ?1 {; }9 L, F2 x
When doing content-switching, connections arrive on a frontend and are then
1 U1 W- w1 Z7 k8 \+ x0 f" M dispatched to various backends depending on a number of conditions. The6 n3 V+ c; u' P# q
relation between the conditions and the backends is described with the: W' S( B& N( I6 p- b; G0 `$ A+ E9 A6 [
"use_backend" keyword. While it is normally used with HTTP processing, it can
0 x/ q9 ^" g5 x" h) l7 i also be used in pure TCP, either without content using stateless ACLs (eg:, k* A6 f5 w9 Z1 J; ~# ^: w
source address validation) or combined with a "tcp-request" rule to wait for
6 w& E+ ]$ G; J% A+ U" w7 o, O some payload.: ^" W8 ~/ r* u, z) p
7 E3 m) \% b$ x$ s$ Y# f* @
There may be as many "use_backend" rules as desired. All of these rules are# w3 g# _/ `: k& n
evaluated in their declaration order, and the first one which matches will& W' L7 m0 _* u' O
assign the backend.+ h8 q. a: G7 y9 G$ I, u
, r$ \7 Y( S* G$ } In the first form, the backend will be used if the condition is met. In the9 D( R Y; Y$ G3 Q0 u8 m
second form, the backend will be used if the condition is not met. If no! y5 x& J2 y3 n) K) }4 Q& Q
condition is valid, the backend defined with "default_backend" will be used.
s; C' K( J& w If no default backend is defined, either the servers in the same section are9 M, y0 d. c; p O V) P- H
used (in case of a "listen" section) or, in case of a frontend, no server is
5 h/ Z$ h: P- l used and a 503 service unavailable response is returned.$ w2 H0 V1 n m9 \: C K. E
1 W. b7 l& M& X; ~
Note that it is possible to switch from a TCP frontend to an HTTP backend. In9 F. c" V9 i9 b2 ]5 D% E
this case, either the frontend has already checked that the protocol is HTTP,
- C R+ u0 F' k3 b and backend processing will immediately follow, or the backend will wait for6 @. m6 p& O$ l0 g5 K0 Y) j
a complete HTTP request to get in. This feature is useful when a frontend
9 a1 ]% v, [1 v1 Y$ w$ E must decode several protocols on a unique port, one of them being HTTP.
9 n7 ? T1 D" C0 |
/ d9 i4 Y3 Y W2 A& [ See also: "default_backend", "tcp-request", and section 7 about ACLs.
( U# m" a( k7 i, ]8 E; F) H+ z" ~8 B, X( \. D* q# o8 Z7 ]
9 S1 Q4 G0 f5 B. T8 |; q
5. Server and default-server options
l: S* H9 S! ^/ N; N------------------------------------& s7 A% w0 R! |. X( n
7 S# k& n3 }+ B' [2 L8 NThe "server" and "default-server" keywords support a certain number of settings) j4 W8 [3 R5 Z5 ?8 k9 w! u
which are all passed as arguments on the server line. The order in which those4 Z% Y* z* f- s7 o2 ?+ v/ I: y
arguments appear does not count, and they are all optional. Some of those
2 J/ o) s! {7 R4 \. \ X4 ]4 Msettings are single words (booleans) while others expect one or several values
7 a: i& I5 n- W% G7 P$ i/ Jafter them. In this case, the values must immediately follow the setting name.
I4 }" j) j% V! D3 k) H& s. gExcept default-server, all those settings must be specified after the server's0 I2 E& r1 G1 E% p1 v
address if they are used:
& j, s/ e- c( N: A9 |/ n! i( E: s" {! Q7 l! q7 A* ?
server <name> <address>[:port] [settings ...]
0 c- @% A" ]7 z% W: m: } default-server [settings ...]5 _* Z$ k- _) Q6 h
' M+ J: i1 W: X
The currently supported settings are the following ones.
- E+ R( n* u( Z; A4 f' D5 i0 C3 ^
& ~$ u$ G8 Q" E' ]; Gaddr <ipv4>: ?# K6 k9 J+ ?( x
Using the "addr" parameter, it becomes possible to use a different IP address
% d, z) |/ u; K+ v* w1 s to send health-checks. On some servers, it may be desirable to dedicate an IP
* ^- A( p: H1 C) g: |2 u8 p address to specific component able to perform complex tests which are more
& P$ `, R9 v$ q/ \: @8 O suitable to health-checks than the application. This parameter is ignored if
4 S; s9 z. W0 z# T the "check" parameter is not set. See also the "port" parameter.9 W% c8 P; c% u+ R0 G: N' }
6 \6 c* g8 c$ K r: b
Supported in default-server: No
8 l" I) ^0 p3 y7 o8 M/ S, U
3 L; e, h/ _4 }7 X9 H0 Qbackup; q) W# w) h( d( v" L) [
When "backup" is present on a server line, the server is only used in load
, n6 b3 p) b" Q- p& h# @5 A balancing when all other non-backup servers are unavailable. Requests coming
& L4 Y# \, U9 d6 r' i$ T with a persistence cookie referencing the server will always be served
$ F) h. j8 _$ L/ D$ `" i though. By default, only the first operational backup server is used, unless0 Z! z- I- [! f8 D: |
the "allbackups" option is set in the backend. See also the "allbackups"
" u' u4 i# p; Q3 T option.+ C* h4 x) x# d7 a0 Q
( \ _+ M0 m. |# c Supported in default-server: No
' m9 ^1 s& E( r# g% U5 F
* ?/ l% w8 \% a; u1 Q3 W+ o& l7 _3 ~check
% \+ W' _! P$ @, i This option enables health checks on the server. By default, a server is$ f9 ?. W. ^' S2 e
always considered available. If "check" is set, the server will receive% ~7 e1 m3 {- P0 P' C
periodic health checks to ensure that it is really able to serve requests.+ U' b7 B6 p2 g! A# m+ S
The default address and port to send the tests to are those of the server,- G6 h2 ~# V" s
and the default source is the same as the one defined in the backend. It is
* d6 k* q; @6 d% @6 F8 F: U m& V possible to change the address using the "addr" parameter, the port using the
+ N; b2 v6 n6 P9 U" N% O# s* | "port" parameter, the source address using the "source" address, and the
6 @1 p& {) z2 u4 y2 x interval and timers using the "inter", "rise" and "fall" parameters. The7 D# m1 W/ Q0 `) F- z( {
request method is define in the backend using the "httpchk", "smtpchk",: |/ Q# o6 e" |( R9 C
"mysql-check" and "ssl-hello-chk" options. Please refer to those options and
0 U5 D$ o9 o- n7 a parameters for more information.
- O& L" d' M; R6 O4 Q% U* {7 ?: ^. c# |
Supported in default-server: No
4 Q- u+ o& q, s" u* x9 |% W0 G$ ]8 m4 @/ J3 W* x8 a6 y% ]
cookie <value> _# s# B3 s# ?7 z4 h
The "cookie" parameter sets the cookie value assigned to the server to+ ]% k0 b; o' E9 K+ W8 j
<value>. This value will be checked in incoming requests, and the first2 B, y4 \/ n' h- X1 g& c
operational server possessing the same value will be selected. In return, in
! Q4 p- N! X- ^: P& H cookie insertion or rewrite modes, this value will be assigned to the cookie' B- ], I5 O$ a8 i) Q8 S
sent to the client. There is nothing wrong in having several servers sharing( d6 _# o/ y# n9 ^
the same cookie value, and it is in fact somewhat common between normal and
1 [6 Z: n0 a! U" J/ Z9 G backup servers. See also the "cookie" keyword in backend section.) ]" f$ K. W) {5 W, i4 Q
# L# S, b" J9 k, ~/ m Supported in default-server: No/ Q+ A/ f/ G$ W( S; X5 C/ c
1 c- l4 c9 G$ J% w
disabled, ^" P7 q3 P$ I1 w: E+ P
The "disabled" keyword starts the server in the "disabled" state. That means
h, c- p- \5 i6 M G& V' [) O that it is marked down in maintenance mode, and no connection other than the
; @# S/ Y6 n- s" f! } ones allowed by persist mode will reach it. It is very well suited to setup, B6 q& ]9 [* B0 y
new servers, because normal traffic will never reach them, while it is still3 v/ t5 l+ \4 s( j
possible to test the service by making use of the force-persist mechanism.; T2 I( H7 L: g7 ~; f# {: w, Q, ~9 o! Y
7 i/ |6 u/ J1 G
Supported in default-server: No: V3 U v0 I+ f0 q* h2 {- z
0 B9 s( c' }2 r; i) i) n0 V& X+ O
error-limit <count>
/ u6 O' ^$ r! F2 M. D If health observing is enabled, the "error-limit" parameter specifies the1 a4 W( T& t" [; {4 W
number of consecutive errors that triggers event selected by the "on-error"- y# ~4 k( P1 c9 h
option. By default it is set to 10 consecutive errors.% `9 N5 ~" ?+ G8 E1 X* `
' A/ c8 \3 k2 y/ r- B3 w' f7 ~ Supported in default-server: Yes, ~: y+ [% ?( n' [7 a1 T
; o! T! n. T4 d" Z* D! G+ J See also the "check", "error-limit" and "on-error".3 @! v. g4 I) \8 a. B
. W3 A: W4 E$ X! F7 e3 X- L! E8 jfall <count>$ H# V2 T0 O& t( g8 ~2 z# `
The "fall" parameter states that a server will be considered as dead after0 [& ]; y& v( s7 X2 N+ K
<count> consecutive unsuccessful health checks. This value defaults to 3 if( i: B5 }8 V" R7 H1 Y1 r
unspecified. See also the "check", "inter" and "rise" parameters.% [6 l* u h5 v2 g" L8 v* d
6 ?" I! Z. I- N; P; r; q
Supported in default-server: Yes
4 r. q& q0 g' ]; s/ V- c
2 p) B# a) z& n& c3 j4 Kid <value>
5 M. g4 J8 f/ o- }1 \. Y1 i Set a persistent ID for the server. This ID must be positive and unique for ~* q6 U7 W& @+ q, v5 C
the proxy. An unused ID will automatically be assigned if unset. The first; U- Y4 |+ Q U: `# V5 F1 m: h! `) p
assigned value will be 1. This ID is currently only returned in statistics.
; f5 `: W, _% W1 ]! T- I9 P0 Q; `5 ]$ n% z9 l: V% i2 `2 Y
Supported in default-server: No7 \7 Z/ l( e% M" w3 a$ g
& T$ V p5 X X2 l( O" R! n; _
inter <delay>) ?& L% K. ^0 `9 a# f" M& ?9 N
fastinter <delay>
7 i% Z' a* r* V+ Xdowninter <delay>' z t: M8 a' w
The "inter" parameter sets the interval between two consecutive health checks. V- q& k5 ~# X# R; D6 D
to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
& g$ e8 E. |2 C2 v* O, A It is also possible to use "fastinter" and "downinter" to optimize delays
9 V5 n/ }( a* S2 t3 ]4 Z# F between checks depending on the server state :% R) G( H6 j4 {! `2 y% u7 Y# o' b
- `) I3 p& C" y$ K' Z8 Q& L Server state | Interval used
" @! ?' E$ n& e7 p0 { ---------------------------------+-----------------------------------------1 [! a# F* n( T6 {$ m; o! ~- r
UP 100% (non-transitional) | "inter"
) W( w, O* I1 @ ---------------------------------+-----------------------------------------6 n7 B; Z( F/ C! q9 F9 X
Transitionally UP (going down), |- X/ K/ y* U. x, E) t, k9 x4 A
Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise.! s5 k% Q) R. G) l" S/ @
or yet unchecked. |) V2 C2 p0 y: F: K
---------------------------------+-----------------------------------------
( b# ^2 C; I6 A, Y2 y" @" B! F ] DOWN 100% (non-transitional) | "downinter" if set, "inter" otherwise.
8 P9 z: H* a. z8 D ---------------------------------+-----------------------------------------: R9 K) d1 z' j( t ^6 t- F
0 N& n: _% B: {
Just as with every other time-based parameter, they can be entered in any
) ?6 b5 ^+ g; i$ }' X1 U other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also
( P- ~; v. N0 ^* Y/ i serves as a timeout for health checks sent to servers if "timeout check" is0 J$ l/ g5 x6 g8 ~; {
not set. In order to reduce "resonance" effects when multiple servers are+ P+ i. q" R2 r! Q8 r
hosted on the same hardware, the health-checks of all servers are started
2 [- n% [$ A3 E i, W9 g with a small time offset between them. It is also possible to add some random0 I0 ^2 J: Y* m6 b- E5 q& |2 Y
noise in the health checks interval using the global "spread-checks"' k; J8 O. }2 W/ F& g6 g( \
keyword. This makes sense for instance when a lot of backends use the same
0 K! ^1 E8 X* I1 N servers.
4 h' i P1 N3 c0 y" C* a
& S! R( p+ A# Z0 b, w8 L) t! X Supported in default-server: Yes! [( q$ Q8 a& J
" X8 s0 K. T3 W) ? e
maxconn <maxconn>
) g) E0 A- R( n. P0 }6 _ The "maxconn" parameter specifies the maximal number of concurrent
& |7 g: u% Y7 w connections that will be sent to this server. If the number of incoming
: A$ h2 d. g3 s2 \1 b7 p concurrent requests goes higher than this value, they will be queued, waiting
5 p! A5 F) Z. |5 s2 @! J for a connection to be released. This parameter is very important as it can
Q4 J" v9 w+ U) A9 a5 b* m3 n save fragile servers from going down under extreme loads. If a "minconn"
. u. u9 ?6 q/ J parameter is specified, the limit becomes dynamic. The default value is "0"* S6 X! Q& K( z; R; r5 J/ K
which means unlimited. See also the "minconn" and "maxqueue" parameters, and/ Z a3 V4 ~8 l. U# [0 q: M* D/ P4 W
the backend's "fullconn" keyword.4 U& x8 u. l4 i3 L8 P, t
3 O9 H; @$ Q7 H# {: v1 x1 J, N Supported in default-server: Yes! P% ?3 C( R/ X1 \& D0 s% S2 [
5 e& c4 r. m N1 e P$ X
maxqueue <maxqueue>1 D1 h2 }( a' S9 ] D
The "maxqueue" parameter specifies the maximal number of connections which/ L% U2 f1 Q+ A* R
will wait in the queue for this server. If this limit is reached, next
9 e2 h+ g* v) }* g/ b requests will be redispatched to other servers instead of indefinitely
1 C+ m) W4 H+ y# {; K5 a+ w# d waiting to be served. This will break persistence but may allow people to4 B2 r, S# P3 c; {
quickly re-log in when the server they try to connect to is dying. The# ~4 u9 ]" O. F. o* `5 D) K
default value is "0" which means the queue is unlimited. See also the
" m( s1 L. Q2 p$ D, i' W9 { "maxconn" and "minconn" parameters.
+ @( [' O! z) @7 Z% n8 E3 ]. {! Z4 H: Z- V* w, c" O/ J* H
Supported in default-server: Yes
: O& y$ x7 z1 ?8 O2 Y. b
7 L4 }0 _& S% ?! V, Gminconn <minconn>9 a/ U6 ]) v* F( r8 C. t) h
When the "minconn" parameter is set, the maxconn limit becomes a dynamic
' y. q$ Q6 E7 b' m limit following the backend's load. The server will always accept at least
( a$ Y0 F2 U+ P* g <minconn> connections, never more than <maxconn>, and the limit will be on
* m( T5 W; u" \! E the ramp between both values when the backend has less than <fullconn>
, d5 o6 g; I- z4 p* k. A concurrent connections. This makes it possible to limit the load on the' D, s6 b5 T, D) r: V* n$ z& M
server during normal loads, but push it further for important loads without1 k& Z7 S6 c- |8 {+ N3 s
overloading the server during exceptional loads. See also the "maxconn"
( s' {; P# N, y1 s' u% x and "maxqueue" parameters, as well as the "fullconn" backend keyword.
) H Y3 @, g5 j! U% e
6 m6 X4 ?1 W" E; T7 u& v( Z Supported in default-server: Yes0 G9 j& w' w' k/ c& c- K* n
9 i# P. k+ h1 s: c& r; K" `observe <mode>, y# _1 V) P" A. b
This option enables health adjusting based on observing communication with! z6 ]& L# N; {5 W. B
the server. By default this functionality is disabled and enabling it also: Y+ R4 `/ n D7 ] |/ n
requires to enable health checks. There are two supported modes: "layer4" and
/ x) c' ^# H! V/ G# t) X "layer7". In layer4 mode, only successful/unsuccessful tcp connections are
: Y" V! |3 ~* o k$ w significant. In layer7, which is only allowed for http proxies, responses% m3 r- O/ ^, G. `, v* u1 Y
received from server are verified, like valid/wrong http code, unparsable
+ l# Y0 p* h- P& k, |3 E headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.6 t) `, {- P6 C$ Y
1 Y( _/ U" y+ x" X- |4 _6 `/ x/ r Supported in default-server: No" S6 H) H# K/ c* e( L$ o$ ^
# l* H+ G0 }0 j See also the "check", "on-error" and "error-limit".
: C; H! C4 N ~4 `- E5 u. r* l* S
) i8 u" b5 b* P& Pon-error <mode>: R' @: @9 G4 N
Select what should happen when enough consecutive errors are detected.
2 p" X, l Z6 W- S" s# K' C( ~# T6 T Currently, four modes are available:
9 m1 i1 I( L$ @+ _5 K6 S0 |1 m - fastinter: force fastinter
3 G) q/ g. ^: a& @$ |4 |# r - fail-check: simulate a failed check, also forces fastinter (default)
; B! M/ O! V4 E6 z5 D - sudden-death: simulate a pre-fatal failed health check, one more failed
3 S9 X! e" E7 o; Q/ D check will mark a server down, forces fastinter2 @2 k$ B& e! p! R+ N- l/ H* Y
- mark-down: mark the server immediately down and force fastinter
5 g ]/ A* J/ X" c5 p4 n8 q6 X1 Q% D9 |) Z% @
Supported in default-server: Yes8 S! {, p, Z- B5 D# y% I# L- D
1 @1 _7 i) o0 ] See also the "check", "observe" and "error-limit".
7 `3 c; O& ^5 q W6 m1 O% W
7 F8 M" q( g# Fport <port>; _' }2 i3 H, d% w+ S0 w) k& A/ _
Using the "port" parameter, it becomes possible to use a different port to* {" l/ Q% {2 G
send health-checks. On some servers, it may be desirable to dedicate a port' `9 u9 |! G7 G
to a specific component able to perform complex tests which are more suitable* D/ ] s; V& n
to health-checks than the application. It is common to run a simple script in% W& }! m" @! ^
inetd for instance. This parameter is ignored if the "check" parameter is not% M: g2 \5 B7 I) O5 @
set. See also the "addr" parameter.
' T4 d* D! [4 n( }; \. S0 P( R; v7 k' b, c _9 A
Supported in default-server: Yes) z5 v \% F( }1 h1 W9 K9 S4 V
% w+ N( K' u- O$ K' G7 eredir <prefix>
" b4 L4 P2 a2 D) C$ X+ } The "redir" parameter enables the redirection mode for all GET and HEAD
" C3 V) |4 o* v2 ~2 ~. _+ J requests addressing this server. This means that instead of having HAProxy" ~4 x) l: D) n# K4 F/ D& I
forward the request to the server, it will send an "HTTP 302" response with( C' f5 r5 I5 c5 W0 }& [
the "Location" header composed of this prefix immediately followed by the
# c. r' @( e( |3 ]& m* v: q3 k requested URI beginning at the leading '/' of the path component. That means9 I4 z& K- j/ Z1 w! t6 N
that no trailing slash should be used after <prefix>. All invalid requests
. L% x9 h) o3 u. g' R will be rejected, and all non-GET or HEAD requests will be normally served by8 _4 w! I) b4 }. `" S* [
the server. Note that since the response is completely forged, no header% m) @& }9 K& J
mangling nor cookie insertion is possible in the response. However, cookies in
7 l5 a; f; y& E9 w7 _ requests are still analysed, making this solution completely usable to direct1 C5 i0 x) p5 E( D- ^! q
users to a remote location in case of local disaster. Main use consists in: K3 v( ?# Q/ j( v5 |0 I, Z
increasing bandwidth for static servers by having the clients directly
! U! u1 o( x9 t connect to them. Note: never use a relative location here, it would cause a, M- t& c/ ~& u' \/ u9 j; Z: ]
loop between the client and HAProxy!# D! ]+ G5 [1 K! I; q8 X) D
8 l, K( {4 g0 v* }+ j
Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
4 a, c( R" n0 R* E2 Q$ A) Y. H' s2 ^7 w
Supported in default-server: No
: H9 `* S2 N) h6 ^1 e
1 y" i& Q' n" b0 R% ^9 K" Lrise <count>0 ^/ E+ [0 {( w a# H+ \9 F
The "rise" parameter states that a server will be considered as operational
) |7 }3 h- y% U+ N% z6 U after <count> consecutive successful health checks. This value defaults to 2
/ _9 B& L* l* T" T- ]/ z' N* Y if unspecified. See also the "check", "inter" and "fall" parameters.
2 t0 X$ _" P I
5 ^; l$ S3 g) Y; V# L; y Z% V Supported in default-server: Yes
8 q+ ^, T$ a3 o; i K
$ Q8 q- f' E' N3 [' xslowstart <start_time_in_ms>" j. r* Z- F7 k/ f- { [& ~ F! _1 W
The "slowstart" parameter for a server accepts a value in milliseconds which
$ m% Y4 D7 a. x) v- M# `5 ^ indicates after how long a server which has just come back up will run at
/ ?- ~! y& K+ _6 S. I full speed. Just as with every other time-based parameter, it can be entered
4 M3 u1 A h7 q* u in any other explicit unit among { us, ms, s, m, h, d }. The speed grows
4 Q7 _" }3 x$ W: P% Y- H linearly from 0 to 100% during this time. The limitation applies to two" Q8 l4 ?" l! y2 s0 c: g
parameters :2 m7 Q6 S9 m% _4 w8 Q
9 o( F: F, p, |* `3 a - maxconn: the number of connections accepted by the server will grow from 1
& H* E2 O& [) y, _4 ^ K) m* { to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).) }: H$ E! o4 }1 t& k: c* l
& m9 C4 @' g- s+ j# ?* P - weight: when the backend uses a dynamic weighted algorithm, the weight
, h" j9 d3 D o5 l% I ? grows linearly from 1 to 100%. In this case, the weight is updated at every
# F% @! P* S) M$ t, Z+ J1 p% ? health-check. For this reason, it is important that the "inter" parameter& g+ v0 M' @! d Q+ c
is smaller than the "slowstart", in order to maximize the number of steps.
# t# U; g! F6 W$ v
# W( K/ Q3 ~& V8 W* g8 g The slowstart never applies when haproxy starts, otherwise it would cause, R5 S- r/ O8 F1 e& |
trouble to running servers. It only applies when a server has been previously
# E- t- h8 }8 W2 h3 @0 [ seen as failed.
+ ~+ d& S* U* {2 ]8 I$ X7 _% c" e2 |
Supported in default-server: Yes
5 f$ w4 [1 ?. @2 {
* A# R& @8 n$ o' \ I5 zsource <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]( E- r, P! p8 l) \; L% T
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]/ g8 J' c3 N7 [. }! v3 {, w
source <addr>[:<pl>[-<ph>]] [interface <name>] ...
6 O2 P7 ]# I9 K' ]" a4 T, a. f7 N T( _ The "source" parameter sets the source address which will be used when
: K# L' v; O, t connecting to the server. It follows the exact same parameters and principle% L/ o5 b4 w5 V! W
as the backend "source" keyword, except that it only applies to the server
2 P; I$ g/ P$ W3 h1 ^; M* @ referencing it. Please consult the "source" keyword for details.6 O& L( Q+ o+ l/ ?
6 a8 ?$ I3 z9 s( x' d Additionally, the "source" statement on a server line allows one to specify a) i, @% f& H6 `$ \7 ?
source port range by indicating the lower and higher bounds delimited by a3 K! `7 Q' D) K/ z
dash ('-'). Some operating systems might require a valid IP address when a- p, P" K' m$ E2 C
source port range is specified. It is permitted to have the same IP/range for7 e! D6 y% }' V/ k# e
several servers. Doing so makes it possible to bypass the maximum of 64k6 r* ]# c6 M" w$ ]6 [, k
total concurrent connections. The limit will then reach 64k connections per
# I9 Y: G d p8 \: X4 B server.$ p2 d% z6 K# H" s+ Z, [) i
5 x/ R0 D4 Y& x0 c7 W* M. q- X
Supported in default-server: No
6 B. m/ h# ?, J; b* Y9 {1 T; L
+ C e2 C, [$ d$ Vtrack [<proxy>/]<server>4 F$ E9 |4 W* L4 P
This option enables ability to set the current state of the server by
. l# k- J$ P4 P8 g$ ?( s1 P! _% E tracking another one. Only a server with checks enabled can be tracked
+ N0 v+ L4 O# Z$ _" {% d+ e* R so it is not possible for example to track a server that tracks another
a1 k7 y6 b5 A) o# h) X; Q% \" P one. If <proxy> is omitted the current one is used. If disable-on-404 is
6 u8 F5 F5 X- @2 }8 b used, it has to be enabled on both proxies.
& D3 e% f7 v% p1 P; B0 I- ]
' w( A% o8 @ j5 l% O, D Supported in default-server: No
5 f/ A8 r* y$ f4 N+ n3 l8 E6 _- _0 m% n2 m# g
weight <weight>
$ X0 Q7 U1 S- k- l The "weight" parameter is used to adjust the server's weight relative to
% N4 @6 J1 c5 z0 I3 b) }+ B* ]8 R other servers. All servers will receive a load proportional to their weight
1 ~! H, ~9 h. f w' `6 s( m relative to the sum of all weights, so the higher the weight, the higher the
% ~' |1 ~3 y7 p+ |( W! b8 m+ ^% X load. The default weight is 1, and the maximal value is 256. A value of 0" E* K# B& E# N* B! W& c7 s. M; B
means the server will not participate in load-balancing but will still accept
( ^0 K+ G' }. V: f0 C persistent connections. If this parameter is used to distribute the load4 g/ w+ o# W; W! X. q S( c
according to server's capacity, it is recommended to start with values which
* h0 x9 w# B7 E! B" w8 [' M. i can both grow and shrink, for instance between 10 and 100 to leave enough- N# l6 o- A- S u) Z
room above and below for later adjustments.
! N1 C7 n& h( r! z* S6 I1 R9 d/ W. r
Supported in default-server: Yes! @$ g! g2 l5 E: a6 M
* V/ W& M0 `) u G
x, q6 R) F5 {( R. C) [% k) f6. HTTP header manipulation$ \4 j, Z/ m ?' v& p' _
---------------------------
' d, y5 T' `9 p: `7 S; h. W$ m: Q; I2 M5 h* g J
In HTTP mode, it is possible to rewrite, add or delete some of the request and
, x+ w- A2 {- h/ M [0 ^response headers based on regular expressions. It is also possible to block a
2 q8 C* b. F# w* \; h& n1 Nrequest or a response if a particular header matches a regular expression,
0 [# A8 E# g* P0 p7 Uwhich is enough to stop most elementary protocol attacks, and to protect/ X- I& g. x; t2 B2 a! M6 n
against information leak from the internal network. But there is a limitation
c$ {7 n: H; m6 g% U+ eto this : since HAProxy's HTTP engine does not support keep-alive, only headers4 H* s6 r% ^3 c( I
passed during the first request of a TCP session will be seen. All subsequent
- r# W$ u; T- Y" S( I$ zheaders will be considered data only and not analyzed. Furthermore, HAProxy6 E6 V% q" Q% M. F# o8 l
never touches data contents, it stops analysis at the end of headers./ d) S* Z2 A/ F# q$ G, }' N
2 K8 ?1 z5 Z8 z: }
There is an exception though. If HAProxy encounters an "Informational Response"; d- v$ X' [# {, H2 N9 g }$ \
(status code 1xx), it is able to process all rsp* rules which can allow, deny,
* ?, [2 ]0 H6 erewrite or delete a header, but it will refuse to add a header to any such1 x& @. g& `3 P, n3 l( o7 x
messages as this is not HTTP-compliant. The reason for still processing headers
3 ]0 u, o6 t# N9 g# Qin such responses is to stop and/or fix any possible information leak which may9 B! Y" M/ Z# r- O5 q
happen, for instance because another downstream equipment would unconditionally! L7 H/ N0 Z$ X
add a header, or if a server name appears there. When such messages are seen,
?2 L# a+ ~6 P- S1 h# Qnormal processing still occurs on the next non-informational messages.$ J3 X, T# E4 @* y5 r
( Y/ f& Y t* A) xThis section covers common usage of the following keywords, described in detail
; E: B" `. y! p- m; [" c- ?$ |in section 4.2 : D0 u; y& _$ E$ q. |
4 Q" N2 K/ U% p: f- c! x
- reqadd <string>4 s8 a8 N' j+ |! c# J n0 C
- reqallow <search>
) ?$ U% O+ f9 F! M5 }6 X - reqiallow <search>
5 E+ F2 o% ^% g+ J, ^% A - reqdel <search>& \: E: Y& M3 z1 a \
- reqidel <search>5 g$ }+ T3 T# a# B/ v% Z) L
- reqdeny <search>
. N5 C3 Q! \) z" b4 I# W - reqideny <search>
- C) L; ^" y6 w9 o+ f: s8 L0 X( s. \ - reqpass <search>
4 j& w/ o) m' x6 A# I. a - reqipass <search>! V$ Z, _: l6 F0 a6 ?* F: v4 R
- reqrep <search> <replace>. w4 U: E* x' j4 \$ F
- reqirep <search> <replace># Y% D, D" f# ]& j
- reqtarpit <search>
* v. ~' N) E2 I2 {% a - reqitarpit <search>
% o! ~% \, H+ m) r c6 }7 d! G - rspadd <string>
9 j& Y/ c8 f$ W2 Y4 Q+ ~- Z - rspdel <search>/ f2 \5 I! E) c
- rspidel <search>4 s2 E: y. T/ `; x5 ^: V
- rspdeny <search>& ~9 u! r0 R: j5 Q: |; R K
- rspideny <search>
# Q. A- K: S7 U+ u/ w - rsprep <search> <replace>( ]/ g8 n, U. p, z
- rspirep <search> <replace>
( t7 U7 X! |7 Q: Q
. e) r) L4 b! a9 V* fWith all these keywords, the same conventions are used. The <search> parameter/ R6 {7 S9 ]+ e( M9 l1 @( ^
is a POSIX extended regular expression (regex) which supports grouping through
; c' z8 Q- \3 b' Nparenthesis (without the backslash). Spaces and other delimiters must be
$ T. S! d6 H4 w; L. A. @prefixed with a backslash ('\') to avoid confusion with a field delimiter.
, z# b* K8 ~0 t# m4 W2 ]Other characters may be prefixed with a backslash to change their meaning :, X! }* A0 U1 ?( O* |
# M" u: f) S' a, Q+ u8 b# p" B
\t for a tab2 f: x' i/ N1 K, V# Q) _% z+ S
\r for a carriage return (CR)
# P+ _( L3 O/ X5 z, T- {& | \n for a new line (LF)
& ^/ d ^, E1 B: T$ ?% m- v \ to mark a space and differentiate it from a delimiter6 V( C* j- W* {" m: A$ r6 ]0 P1 P
\# to mark a sharp and differentiate it from a comment
7 k" h* F! h7 T, V+ E, k \\ to use a backslash in a regex6 U% T9 B) ~0 ^+ }, t W* v4 Z
\\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)
: u% T3 s# S9 E( ~. V \xXX to write the ASCII hex code XX as in the C language
# T" P& O- X' d$ v' n( j
0 a& k, L. R+ I3 O" Q( F) d6 t/ P3 a6 XThe <replace> parameter contains the string to be used to replace the largest
5 o/ i; H2 F' pportion of text matching the regex. It can make use of the special characters6 r. M9 ?+ @" e- O
above, and can reference a substring which is delimited by parenthesis in the) u% B: Z; t7 Z5 e$ D+ a2 O. Q: ~1 U
regex, by writing a backslash ('\') immediately followed by one digit from 0 to- P0 T1 B. ^* k' B1 f
9 indicating the group position (0 designating the entire line). This practice
1 f* t: _. N! P# i+ i7 xis very common to users of the "sed" program.
( ^6 R1 n7 u8 Q! b- a$ {' @2 n* F$ B5 q2 W2 b
The <string> parameter represents the string which will systematically be added
# I! F/ p3 P9 ~. |after the last header line. It can also use special character sequences above.
0 K" h* i: K4 G4 L3 ~1 `# X' o: s" W. Q" ^ b9 c
Notes related to these keywords :
2 f4 }& ? Q" V" Y& Y* [; G---------------------------------
) Y3 h" t1 |1 ?5 [: [8 `# s - these keywords are not always convenient to allow/deny based on header
+ S$ ~( F5 W# a4 }7 C$ |, { contents. It is strongly recommended to use ACLs with the "block" keyword
u+ E. V0 m. K( v) J# M instead, resulting in far more flexible and manageable rules.
! H# z/ G' k5 G
/ ]$ Z* M. z( b! i( N - lines are always considered as a whole. It is not possible to reference e& O5 J/ u* P, G/ P2 H
a header name only or a value only. This is important because of the way
; ?) u! z6 ~0 m6 ^) f headers are written (notably the number of spaces after the colon).% s( s8 Y# V F
( ]. x z3 O) O
- the first line is always considered as a header, which makes it possible to) q; k+ a. v0 r( H( E$ F# c6 R& ^/ J0 l
rewrite or filter HTTP requests URIs or response codes, but in turn makes
( F. a- k4 o# p it harder to distinguish between headers and request line. The regex prefix# [ R) v4 C* ?! S# \2 j5 }. ? m
^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix3 _9 c1 A, ], l, t4 g) s6 x
^[^ \t:]*: matches any header name followed by a colon.
5 v& ^6 j3 a/ b8 v: g2 D7 _, e; v8 ]; p" |1 x
- for performances reasons, the number of characters added to a request or to
5 g7 A4 L' {* ^$ Z a response is limited at build time to values between 1 and 4 kB. This
h5 m- ^# W0 t% m should normally be far more than enough for most usages. If it is too short
& I5 c N+ J( S on occasional usages, it is possible to gain some space by removing some
: L- B& G" I' m" s useless headers before adding new ones." q" Y( m7 C/ Y# y
5 @) j L; Y2 \5 [1 S R
- keywords beginning with "reqi" and "rspi" are the same as their counterpart
9 Y/ ?/ A$ a( i. l) ?1 F without the 'i' letter except that they ignore case when matching patterns.* |9 M8 `7 o& m0 B( j
8 I' v h' g& @" X, W. k4 E
- when a request passes through a frontend then a backend, all req* rules
0 q3 B; x& o1 F+ M! l: Q from the frontend will be evaluated, then all req* rules from the backend
) f. t; J7 I8 \) m2 E: Z7 C will be evaluated. The reverse path is applied to responses.0 `' t# l: Z; B, L5 b: p+ b* k
) F' A2 l5 v: v0 {; G+ x5 g
- req* statements are applied after "block" statements, so that "block" is
3 R/ k0 s3 a. ]: h always the first one, but before "use_backend" in order to permit rewriting; t% w/ \/ Q$ W; j' o7 V
before switching.
9 B0 R* h8 U ?4 d5 ?
% M6 u0 s7 B2 i/ q3 z8 R, P3 d2 v5 }; A) g2 u1 i% A
7. Using ACLs and pattern extraction
7 h- n% u- \9 P/ v3 ~. L7 _8 l* z------------------------------------
1 H/ n) h3 H7 [. g/ Y r" P. e
6 e/ h# d# Q9 }, `( }+ ^( F1 ]The use of Access Control Lists (ACL) provides a flexible solution to perform$ n! d: h% {/ K, _
content switching and generally to take decisions based on content extracted
: X& I% U( N5 M: n0 Z2 W) u4 Bfrom the request, the response or any environmental status. The principle is
: X2 d& K+ C2 |* s. ^) O. Vsimple :
8 s% n4 k& y# S; F
$ ] G% f! n) d4 z$ {4 M# z - define test criteria with sets of values# |6 u& l; ?: ~6 u( `. ~
- perform actions only if a set of tests is valid3 @" s' n6 [, `; z% l) g
9 ^( d4 {2 _; S) UThe actions generally consist in blocking the request, or selecting a backend.
( `3 i/ D+ {) V0 F& l- g1 X
8 P; z. V6 Y7 PIn order to define a test, the "acl" keyword is used. The syntax is :; z; }6 a. v5 l: u* z# q
6 r" v6 h+ q; q; I0 D
acl <aclname> <criterion> [flags] [operator] <value> ...
4 N; K/ E: z* D1 C) y6 K& q% n9 E0 J
0 K- f1 U* T$ ~$ Q0 p8 j3 uThis creates a new ACL <aclname> or completes an existing one with new tests.
" i7 g- V! G1 N6 }3 ]Those tests apply to the portion of request/response specified in <criterion>
4 [+ Z" l# I h/ S' u. ^0 land may be adjusted with optional flags [flags]. Some criteria also support9 l5 b+ k) Z( ~* d3 l: z% b' t
an operator which may be specified before the set of values. The values are B! Z! M1 E* F O6 p
of the type supported by the criterion, and are separated by spaces.
& H R' V, o% @) I1 \* S+ j9 f. x$ b; d/ y( j$ O/ {% L; k
ACL names must be formed from upper and lower case letters, digits, '-' (dash),
+ F. u4 \$ R, p0 |1 k- t8 O'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
, I8 r; X; w$ R; F/ b8 V$ Gwhich means that "my_acl" and "My_Acl" are two different ACLs.
1 Y' A, J: f2 Z! i6 }
1 P# g" s3 x! S, `There is no enforced limit to the number of ACLs. The unused ones do not affect
# U+ T8 X2 ~3 ?! `9 Zperformance, they just consume a small amount of memory." j N- g5 } F2 G% e
- d* w# q+ J7 j- n! e; ?The following ACL flags are currently supported :+ a! M! ]2 U- s$ [! c2 y; ?
3 N3 \7 E3 M3 I9 j' D# p" R* a
-i : ignore case during matching of all subsequent patterns.
+ x* F/ S& ^4 h* C% Y -f : load patterns from a file.2 I; C& Q9 z0 e0 b' N& C: I
-- : force end of flags. Useful when a string looks like one of the flags.
' c c2 _* F! P; i1 y
8 L. K- r) s, k- K7 CThe "-f" flag is special as it loads all of the lines it finds in the file7 B2 F" \- ?; l, c2 r3 p
specified in argument and loads all of them before continuing. It is even) _. {, G' B8 n; f
possible to pass multiple "-f" arguments if the patterns are to be loaded from
7 }5 p) o4 L3 E. _multiple files. Empty lines as well as lines beginning with a sharp ('#') will
5 h. E* P! I5 a) e$ |8 U/ l. Gbe ignored. All leading spaces and tabs will be stripped. If it is absolutely
5 a: C, S8 M, H7 d. vneeded to insert a valid pattern beginning with a sharp, just prefix it with a8 P+ V1 P" z2 q9 @! [% S# E3 \9 q/ j
space so that it is not taken for a comment. Depending on the data type and
8 Z( I# I1 G! p, G0 j2 Kmatch method, haproxy may load the lines into a binary tree, allowing very fast
0 w' k2 l2 `& ~4 blookups. This is true for IPv4 and exact string matching. In this case,
! Y* a) w$ a3 s7 d7 a. wduplicates will automatically be removed. Also, note that the "-i" flag applies
) D8 T3 S1 ]) _ R. P' }to subsequent entries and not to entries loaded from files preceeding it. For
- S3 R9 ]9 S# d2 j! ~8 E9 linstance :
k3 h; `" e! Q% U6 o# L P6 y* i! @& F* G- C/ o5 T
acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test5 r/ A- s( t( k+ A
4 `! R1 J) N! I0 ^- U; I$ h" yIn this example, each line of "exact-ua.lst" will be exactly matched against8 R4 e, L5 m; I1 ?/ f
the "user-agent" header of the request. Then each line of "generic-ua" will be1 M' k7 F K' X7 B. N
case-insensitively matched. Then the word "test" will be insensitively matched8 e. f( X. K4 V" a5 _5 V
too.# N" v% v! b8 U! v8 S! |
4 F* t3 C5 F5 ]& [4 m
Note that right now it is difficult for the ACL parsers to report errors, so if
/ p) T( G {4 A6 H1 P- K Za file is unreadable or unparsable, the most you'll get is a parse error in the
) a0 } G b% [$ `ACL. Thus, file-based ACLs should only be produced by reliable processes.
* [3 j3 N" x. p! F3 ]
* E }: ?6 g* z) mSupported types of values are :
% |$ Q1 N( p9 A9 ~5 m/ L" p) k
- integers or integer ranges; z) n4 U' K$ B4 [ G
- strings
% D& ?4 |$ X7 q7 s0 F - regular expressions- h: D3 O2 v! C: A# f- J1 B
- IP addresses and networks' N" y, U3 r% O' V7 d& e; V
: O, F% U7 i- s$ x2 O l8 p s# C) L( T0 M1 O, e7 ~( T/ G F
7.1. Matching integers6 o5 a* b5 T1 K9 {
----------------------7 G0 I6 b# O% J
& a& I, S3 O' Z
Matching integers is special in that ranges and operators are permitted. Note
! m) n# }* ~: |, I9 ethat integer matching only applies to positive values. A range is a value5 a* X! {' z) X9 J) a
expressed with a lower and an upper bound separated with a colon, both of which
( |: V& S2 W( ~8 e- U3 O6 \may be omitted.
1 E7 @; {4 @* ~: y2 x( R/ r
( | E9 ^; D% sFor instance, "1024:65535" is a valid range to represent a range of( y: u/ M8 F' }% l3 v) s# K
unprivileged ports, and "1024:" would also work. "0:1023" is a valid$ z3 M2 K/ a* c" k" C: @5 N
representation of privileged ports, and ":1023" would also work.. x! j* \7 e* P' m) g ~
0 Q) L; N% J1 O/ P" E
As a special case, some ACL functions support decimal numbers which are in fact- \1 G& _( l" t7 o+ x5 Q; x
two integers separated by a dot. This is used with some version checks for5 b9 z" Y/ Y9 J
instance. All integer properties apply to those decimal numbers, including
2 e4 Y, q, D) X) _% x% X4 U( N! franges and operators./ |' `+ e7 c: K7 T& m) k
3 B* `7 Y( }) l+ E5 y
For an easier usage, comparison operators are also supported. Note that using7 I/ W# m* c( b3 u' v1 i2 d
operators with ranges does not make much sense and is strongly discouraged.0 s$ J. ~+ B0 X+ ]' j- A
Similarly, it does not make much sense to perform order comparisons with a set
/ y6 }2 ~4 [& z/ g, ?of values., o' E0 s6 S7 d, J/ h
/ O$ t; ^" D' _+ K
Available operators for integer matching are :
" W- z( o$ ], o0 \* ]6 ~) j+ L5 X0 [
eq : true if the tested value equals at least one value4 _! {+ C# \, {0 H% ~
ge : true if the tested value is greater than or equal to at least one value
7 c5 e# J% y$ g1 R- [, Z# Q h4 u; g4 F gt : true if the tested value is greater than at least one value
0 e; Z7 V. r# R# M le : true if the tested value is less than or equal to at least one value
& Q) c4 g. Z: i( M8 D; n8 J lt : true if the tested value is less than at least one value
4 S1 a) W# ?2 K% U5 n
: {6 D, P8 @ F) x: y5 x5 t/ u( b& tFor instance, the following ACL matches any negative Content-Length header :
8 M( N G* ~6 D9 v6 A C: N# M# d9 c9 m/ N7 D
acl negative-length hdr_val(content-length) lt 0
0 x6 x5 @ e0 m2 q' A9 k
, B' Z7 N* r" M/ j: o9 KThis one matches SSL versions between 3.0 and 3.1 (inclusive) :
- G$ p) L% v% s$ k; c, v7 s0 C- |6 n7 P- a7 m8 t& z' L! Q" [2 [7 C
acl sslv3 req_ssl_ver 3:3.1* v; x) H; u1 Y
8 D6 u f+ U' K- }
+ _" d. V/ L1 J% l& q7.2. Matching strings
5 D) p, Q d3 E( k--------------------- L. L5 s9 T9 h6 V2 B
! c: H; W/ Q x9 H) w5 lString matching applies to verbatim strings as they are passed, with the, O" b! D" m( C5 x1 r/ ~/ y
exception of the backslash ("\") which makes it possible to escape some# u9 ]( D1 y+ v0 x( c& f
characters such as the space. If the "-i" flag is passed before the first! ^, |8 B7 j2 O7 ~% W; }8 f
string, then the matching will be performed ignoring the case. In order, z7 {* w* E7 j) @# n
to match the string "-i", either set it second, or pass the "--" flag* Y+ B' J: R- O6 j
before the first string. Same applies of course to match the string "--".3 p) B$ ]6 c- p, i' p' t
7 W5 ]& D1 i5 l0 M$ L
' B# j3 t, l8 l7.3. Matching regular expressions (regexes)7 p5 H5 q( `% n! Z. p( _
-------------------------------------------
+ x( }" d1 b. |/ o* Z; V& e" k+ S+ Z" A
Just like with string matching, regex matching applies to verbatim strings as% C: d7 e8 T! T6 |7 R2 i
they are passed, with the exception of the backslash ("\") which makes it, v1 i1 `+ |9 y' ?+ q
possible to escape some characters such as the space. If the "-i" flag is$ g9 e" o! \6 }8 N/ h! ^* E0 D
passed before the first regex, then the matching will be performed ignoring
3 q+ @" o/ ]. v. a6 Z. uthe case. In order to match the string "-i", either set it second, or pass7 S$ u1 Z" p" }4 [5 e. p- M
the "--" flag before the first string. Same principle applies of course to
, }. j: T O9 wmatch the string "--".
0 R' a; n' K4 m5 b, T+ r' g; L) M% [ G; w v# v
! E% i( `- b( b: A8 l" }: ]8 [7.4. Matching IPv4 addresses7 a" w# m# ^/ H, J3 \
----------------------------
7 Z2 Y6 { x g; I
1 C- E: F+ K9 I' Q NIPv4 addresses values can be specified either as plain addresses or with a1 }# y! t; I. L6 I# L9 f2 v
netmask appended, in which case the IPv4 address matches whenever it is) i9 J" _9 [( b' @# m- d+ v0 m
within the network. Plain addresses may also be replaced with a resolvable
( G# y$ s# W/ chost name, but this practice is generally discouraged as it makes it more" K( Y1 X" ^/ x
difficult to read and debug configurations. If hostnames are used, you should
# G% Q6 A& y) Jat least ensure that they are present in /etc/hosts so that the configuration2 }1 w2 y2 M! d8 P
does not depend on any random DNS match at the moment the configuration is. I. P* z6 I9 J4 }: T; E
parsed.
s$ `( \- l) g0 T0 l2 P5 @5 H9 Y# G' V, k( j0 n! ?
+ Q7 f4 O7 U2 j+ z1 s# K
7.5. Available matching criteria
6 I' c0 M' U/ ?8 k5 h8 a--------------------------------
" e7 U! k: ?" Q* U* N
6 N% B: O# y1 F) k7.5.1. Matching at Layer 4 and below
; O# d$ y1 Y/ m' V------------------------------------
9 ^% } L4 d: p; t; {( ~& i
5 m" C: T( G0 C% _6 ?A first set of criteria applies to information which does not require any
: q$ C- k( |4 f# \& w4 Wanalysis of the request or response contents. Those generally include TCP/IP' \( K) w1 C" H" _1 D' O
addresses and ports, as well as internal values independant on the stream.$ W4 @) U, ?& @' ^0 y7 V9 R
/ c5 P$ [; U0 l1 C. Talways_false8 W5 B! N) H" D
This one never matches. All values and flags are ignored. It may be used as
W, b$ q/ K2 T6 e4 c* { a temporary replacement for another one when adjusting configurations.2 j) ]& \+ r* t2 Z: X% j
6 X+ p2 ?5 m; O' J4 C& v
always_true* t' {" U) r, W+ W _2 o. U
This one always matches. All values and flags are ignored. It may be used as
% l- k3 C! E& C; n6 B3 v. H9 h; ?5 J a temporary replacement for another one when adjusting configurations.
# G/ ~, X# M4 ^% x
' O Y4 W9 a! }7 Mavg_queue <integer>& {/ J- \- v* q% C3 f
avg_queue(backend) <integer>+ t7 C9 k' ?( M, L" i9 p5 a
Returns the total number of queued connections of the designated backend+ A# @7 r& G' o: l8 A) L$ g3 P+ R# Z& e
divided by the number of active servers. This is very similar to "queue"
( z4 b! \" _$ U$ y8 q9 E except that the size of the farm is considered, in order to give a more
0 A+ U" L. ~+ i; H' C3 v- ~1 d+ N accurate measurement of the time it may take for a new connection to be
$ O( M0 S, C0 M' l/ g2 _. V: p processed. The main usage is to return a sorry page to new users when it
: [ y4 U0 v9 \4 F- ^ becomes certain they will get a degraded service. Note that in the event, r9 t. ?8 @2 v$ D( N
there would not be any active server anymore, we would consider twice the
z5 B# ?6 F8 Q T' ~ number of queued connections as the measured value. This is a fair estimate,# S7 l. X' \/ @1 B" b
as we expect one server to get back soon anyway, but we still prefer to send
. B5 V6 i) N9 M6 P new traffic to another backend if in better shape. See also the "queue",
B) W" K2 ] q: m "be_conn", and "be_sess_rate" criteria.
9 Z0 D( O) w4 U+ H+ r( ?) u- Q
* _5 p5 Q: J% ]: l4 fbe_conn <integer>( \# ?( V [) ]5 A; d
be_conn(backend) <integer>! m2 [6 a+ [+ y2 J+ z6 j7 P5 U" l
Applies to the number of currently established connections on the backend,
4 H/ F- m. W" P possibly including the connection being evaluated. If no backend name is
5 h$ U; F; j" h0 Z specified, the current one is used. But it is also possible to check another
B3 N7 N' Z5 B% o8 K7 p backend. It can be used to use a specific farm when the nominal one is full.; ]+ L# {/ m; R( o
See also the "fe_conn", "queue" and "be_sess_rate" criteria.+ k$ P+ J4 m: I3 o O1 G+ V4 w
2 S# `- E9 M; w! ?& D. O3 b
be_id <integer>2 t% B5 n9 r0 e" L
Applies to the backend's id. Can be used in frontends to check from which
; X: h/ a1 d- \0 q: r2 p backend it was called.
5 T Z' b# X( m/ Y" X
1 T+ R/ Q5 H9 x1 i5 ^be_sess_rate <integer>
j, V) K& ~6 l/ Dbe_sess_rate(backend) <integer>
- M# i; o. i4 S1 d Returns true when the sessions creation rate on the backend matches the
4 X. C/ _% \2 a. N specified values or ranges, in number of new sessions per second. This is
3 [" i4 P* N) |0 T& Z5 D used to switch to an alternate backend when an expensive or fragile one
% q0 z$ b( j7 H) e* O+ p reaches too high a session rate, or to limit abuse of service (eg. prevent' h- h {/ K0 a, [/ E
sucking of an online dictionary).
4 c3 n, E" X. y) k+ Z ]: Z
3 ^- p2 [2 d$ A* k1 Z1 ^) ~; U Example :# Q8 s8 L! o$ r% N% a7 E
# Redirect to an error page if the dictionary is requested too often7 _2 V8 G6 P" z3 R2 r9 U5 R( ?
backend dynamic
9 h" j# S, y6 P. |4 u mode http
/ f" R8 b6 ^5 m; I/ U acl being_scanned be_sess_rate gt 1001 O# j) I1 q3 o2 X# Z
redirect location /denied.html if being_scanned
' I, z' L( u* [. M. @1 Y
) i: C+ O5 l$ C' u U7 U; n" @$ f& E/ @& Cconnslots <integer>, V+ f5 k) b$ L# J4 x" _
connslots(backend) <integer># `- X# R! i F7 ^, E( X$ p
The basic idea here is to be able to measure the number of connection "slots"
" R8 [* L8 a& D: s still available (connection + queue), so that anything beyond that (intended0 {6 H" R. |1 j" i9 d
usage; see "use_backend" keyword) can be redirected to a different backend.
5 B3 E0 v+ ^! E3 |7 A% P/ J8 X! u' ?) v! `
'connslots' = number of available server connection slots, + number of4 _. _' _" `' ~# P' ^
available server queue slots.3 K" _$ g! I5 s h
2 f9 b3 @& c6 [/ d
Note that while "fe_conn" may be used, "connslots" comes in especially V, G0 P$ {8 N/ \
useful when you have a case of traffic going to one single ip, splitting into) r# q6 W) U( W7 `
multiple backends (perhaps using acls to do name-based load balancing) and. o2 u8 ?( `: B5 B- z; `
you want to be able to differentiate between different backends, and their
5 I E/ K) E( Y! O4 w) ~2 o available "connslots". Also, whereas "nbsrv" only measures servers that are$ m$ ?; V/ F8 n# Z, t' C( c
actually *down*, this acl is more fine-grained and looks into the number of
3 W! w; o1 [9 M! r+ z+ r available connection slots as well. See also "queue" and "avg_queue".
9 R% H6 n9 t) l/ r- d4 v$ y6 Q/ e$ X, S) O
OTHER CAVEATS AND NOTES: at this point in time, the code does not take care! n3 i6 }+ W, R/ g. N
of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,
* d7 B& X7 p2 \( a5 a1 R$ X then this acl clearly does not make sense, in which case the value returned
- Q- k' h' e, y( s& m) J4 x will be -1.$ V# Y3 s: W" ^6 @ U2 R6 V. S
& G8 W# Y+ o) K4 x( d. G3 [
dst <ip_address>
/ Y) h( M# W: V7 @( ] Applies to the local IPv4 address the client connected to. It can be used to+ P1 L Q( v, g2 V1 e+ o* E
switch to a different backend for some alternative addresses.; O- p/ y7 d6 _: i) U5 u. T
2 u4 w$ N* `; l4 [) Q& l! k( g2 Y
dst_conn <integer>
( `5 O' a2 H; h3 z- ]! D8 v Applies to the number of currently established connections on the same socket+ k% ]6 c) J% n
including the one being evaluated. It can be used to either return a sorry
6 j3 C6 Y6 P, \; }# g page before hard-blocking, or to use a specific backend to drain new requests
+ r2 G. \% S7 S0 N0 p! F9 d when the socket is considered saturated. This offers the ability to assign
- T6 p. \2 @, O1 f' }5 Q* p3 \ different limits to different listening ports or addresses. See also the
0 K, b& e: `( [% f) w/ O0 g% k "fe_conn" and "be_conn" criteria.7 T% z' @9 ]" d% g
. A) q& J8 |# f- v6 _& tdst_port <integer>9 o+ i5 k/ l, J# y
Applies to the local port the client connected to. It can be used to switch3 i3 Q% J, B! ~) p) M; q
to a different backend for some alternative ports.
7 ?3 d* V9 V% r8 k
7 `) O' T+ V3 {% r2 T2 Z, a- Jfe_conn <integer>( Y+ r& n+ m; j/ D( O! r1 z( \
fe_conn(frontend) <integer># j( r6 T: Q( a' m
Applies to the number of currently established connections on the frontend,1 J. M. P9 \- s( n; l p
possibly including the connection being evaluated. If no frontend name is5 {& ~/ p+ Q& B* F1 o' Y# D
specified, the current one is used. But it is also possible to check another4 M6 @/ C! ~2 B6 x) ^
frontend. It can be used to either return a sorry page before hard-blocking,% B2 X6 ~$ ?) u c# }" j2 |, w7 \ M) d
or to use a specific backend to drain new requests when the farm is# x3 ?7 t; t1 H1 n9 @. Y& x/ w
considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"% H. I: X0 B( y% T/ R9 a
criteria.
{6 \8 I8 Q# p+ P5 b. E4 D/ ]0 X4 k1 y5 @2 [, | }8 v
fe_id <integer>
2 j5 ?+ U* G' x' m Applies to the frontend's id. Can be used in backends to check from which" ] |4 l" z3 M& {% s' P
frontend it was called.
. c9 U7 D, W5 p6 Y! Z' k+ V' X( ], {, f3 I5 h" u
fe_sess_rate <integer>
" `/ t- d6 X U3 a5 T5 rfe_sess_rate(frontend) <integer>: G5 i! m0 U0 y+ w2 I
Returns true when the session creation rate on the current or the named
4 y; u! n" K( {% ]. v; @ frontend matches the specified values or ranges, expressed in new sessions9 W0 g3 O& o; R* m
per second. This is used to limit the connection rate to acceptable ranges in
7 V& J( e$ Q: \9 w order to prevent abuse of service at the earliest moment. This can be3 x. w ^; ]4 g3 M
combined with layer 4 ACLs in order to force the clients to wait a bit for$ K; S9 K5 n% R5 A$ l
the rate to go down below the limit.
: b" r0 e) a* x9 e8 A; ]
: M b& |" e; C+ r) J( P+ ^ Example :5 w/ n. y7 R9 I, X: ^
# This frontend limits incoming mails to 10/s with a max of 100
6 Z; g; C- t* L) \1 D' O2 x( ?0 @ # concurrent connections. We accept any connection below 10/s, and' }* V3 ]+ L; _" m* Q
# force excess clients to wait for 100 ms. Since clients are limited to0 u/ D. r( v& y+ i7 {" s
# 100 max, there cannot be more than 10 incoming mails per second.: X i3 B2 A, \: X8 T& V
frontend mail
7 @7 t7 @ Z% k# G9 t bind :25
' V( D- g" }/ B9 c' r mode tcp
. U* H4 p* B* b) J5 ~; `7 K/ ` maxconn 100
, G4 W) J$ P% F0 H. a acl too_fast fe_sess_rate ge 10" U+ E3 G0 W8 x% j% d/ Z' {
tcp-request inspect-delay 100ms
7 a* {: _0 P8 W3 M" b tcp-request content accept if ! too_fast4 L5 |$ U j% `+ y$ H1 t
tcp-request content accept if WAIT_END
, T: X7 J/ b2 o3 W! n: I0 a8 L1 T! u/ I
nbsrv <integer>9 c0 W! z+ r# q: N4 [$ S( P" i- b
nbsrv(backend) <integer>
$ P- v; V0 T( _( ^7 P Returns true when the number of usable servers of either the current backend
. q" K6 R3 }( @3 G" P or the named backend matches the values or ranges specified. This is used to
0 G1 Z5 |! b: _% a, R4 s switch to an alternate backend when the number of servers is too low to" ~" K3 ^: M9 y) s0 @
to handle some load. It is useful to report a failure when combined with( ]4 k# g4 N; P
"monitor fail".: C- B% U/ k7 \) l' G. j
% E2 [8 L6 y# M! U3 d0 B+ L; vqueue <integer>% K$ y$ n' h0 l+ K8 o; w
queue(backend) <integer>: s; s& K/ q( b% v* I0 J& f
Returns the total number of queued connections of the designated backend,
; }; z0 e2 j/ c1 i3 c* O2 Y6 ` including all the connections in server queues. If no backend name is
$ ~4 l/ y. ~/ |- ?1 g specified, the current one is used, but it is also possible to check another) e- a2 v) x% Y& L( j
one. This can be used to take actions when queuing goes above a known level,! l8 _5 z, Z& q4 R
generally indicating a surge of traffic or a massive slowdown on the servers.2 x4 P3 Z. \# Z6 N
One possible action could be to reject new users but still accept old ones.8 S( e% o o5 {2 a
See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.
4 i( z$ J0 X; {, J) q; h/ D7 J% C0 j) h
so_id <integer>
* e! C: ?( s3 J3 O' v Applies to the socket's id. Useful in frontends with many bind keywords.5 v, u9 G' W# l% @( ^$ [
+ m: C: X* O7 _ isrc <ip_address>+ {! k% u5 T2 ?* r9 g# F: L5 d
Applies to the client's IPv4 address. It is usually used to limit access to! t8 ]1 x. I1 A
certain resources such as statistics. Note that it is the TCP-level source9 C$ q' B5 |+ Z3 g2 z
address which is used, and not the address of a client behind a proxy.2 Z7 h9 r& d' I9 y6 I5 T2 S! {
( X& f B/ e) p4 c8 W; Tsrc_port <integer>
- B! a6 }) r& o9 d ]/ r6 Q2 Z Applies to the client's TCP source port. This has a very limited usage.
$ M8 V% {2 j" I' T6 L4 g# p$ x3 e# c' f, [- Q, L/ K, Q$ {; |5 ~$ K( Z
srv_id <integer>6 D/ E& G! ~% ~* |, n% ^; ?4 ]
Applies to the server's id. Can be used in frontends or backends.
& Y, z# z4 a* c/ d9 ~, m T
' B1 d' G( l. G# zsrv_is_up(<server>)8 f1 F% x9 N, w4 [6 m! M1 Z/ v% f+ {
srv_is_up(<backend>/<server>)4 E* W8 E8 H9 w& K/ C
Returns true when the designated server is UP, and false when it is either
& F/ V2 e* W: J! ^7 g( Z& J3 |) Q DOWN or in maintenance mode. If <backend> is omitted, then the server is
" m- C6 A, F$ I y: j looked up in the current backend. The function takes no arguments since it( R) X; n* Z( s7 c& a2 Q0 U
is used as a boolean. It is mainly used to take action based on an external2 ^0 o) z7 }/ s7 F6 {7 _7 h" M
status reported via a health check (eg: a geographical site's availability).. v; c; [7 N1 x" m! ~
Another possible use which is more of a hack consists in using dummy servers( R* {" x5 G+ Q. D
as boolean variables that can be enabled or disabled from the CLI, so that
& c9 R5 ]" I0 R2 t# S+ h B$ ]9 q rules depending on those ACLs can be tweaked in realtime.
8 q7 V6 f, Y9 s; }
( m: n5 D4 F. i+ F7 f; d4 x* @: |# x) p
7.5.2. Matching contents at Layer 4
: u: j! S6 _: }- ^2 m# U6 f-----------------------------------
6 ~% n, d+ O, T o$ L1 w' @% w4 X V/ X- t8 P0 q1 ?6 G
A second set of criteria depends on data found in buffers, but which can change- Q% {& M, y; v3 W
during analysis. This requires that some data has been buffered, for instance
1 h2 h$ z( ], O# L1 Vthrough TCP request content inspection. Please see the "tcp-request" keyword4 X5 E$ r% K- a3 F; s( j
for more detailed information on the subject./ a! f8 r+ m. k I, \
' w$ J+ V5 B) z0 R: `% L- r
req_len <integer>
) h: _. x. e$ ^/ ] J4 P' S Returns true when the length of the data in the request buffer matches the
' b1 ]' [( a, B2 Z7 D$ R9 d' W specified range. It is important to understand that this test does not$ Q% v4 K2 R. ?0 @! j. E
return false as long as the buffer is changing. This means that a check with
3 t4 @' b3 k0 i* W4 D) J equality to zero will almost always immediately match at the beginning of the/ M2 A+ g5 |; {5 v+ x# k
session, while a test for more data will wait for that data to come in and
, T$ m, A4 L; a/ H return false only when haproxy is certain that no more data will come in.3 x! O3 c% ^3 O0 G- q3 x
This test was designed to be used with TCP request content inspection.2 i+ t4 |7 Y n7 }: {
6 Y0 _3 T; i& s8 V. {/ a* |+ j4 p
req_proto_http @; i" M- a4 I; f' ]) a7 _- V
Returns true when data in the request buffer look like HTTP and correctly; A- V% a0 k, R" f, b& x; R& `
parses as such. It is the same parser as the common HTTP request parser which
0 P& B$ y7 _$ s6 j0 v( |" | is used so there should be no surprises. This test can be used for instance. o8 E2 a8 V) Z! `" Z2 r6 j. A
to direct HTTP traffic to a given port and HTTPS traffic to another one: ^% s- B1 I) |! Y8 q P" Z# D
using TCP request content inspection rules.6 u- [* `: L- V [
4 Q0 x; U% e7 o* treq_rdp_cookie <string>
: h# f, w+ r5 b0 l; treq_rdp_cookie(name) <string>/ w7 k, W, i' d+ q6 c: r k2 h
Returns true when data in the request buffer look like the RDP protocol, and# z6 V' D0 M7 h
a cookie is present and equal to <string>. By default, any cookie name is
0 p: f% b. W1 j5 W0 `7 W checked, but a specific cookie name can be specified in parenthesis. The1 u# l/ D6 i9 {
parser only checks for the first cookie, as illustrated in the RDP protocol
: ^. \ L) T4 b9 e' l5 j2 ?( n+ V specification. The cookie name is case insensitive. This ACL can be useful
+ w8 A# _# e1 o with the "MSTS" cookie, as it can contain the user name of the client1 A7 g1 O$ B* u1 Z) B& r0 e" ^
connecting to the server if properly configured on the client. This can be
* f& W" T7 E5 w- x used to restrict access to certain servers to certain users.
- H7 }8 b; G J) Z9 `2 K: f6 k: H7 H* R) Q* H
req_rdp_cookie_cnt <integer>% C) H+ i' E' C+ E
req_rdp_cookie_cnt(name) <integer>& Q2 H+ a6 I% \- H; Q/ |
Returns true when the data in the request buffer look like the RDP protocol# p9 Q9 W1 I# s
and the number of RDP cookies matches the specified range (typically zero or# x; U; Z8 I4 \6 A0 c
one). Optionally a specific cookie name can be checked. This is a simple way
0 X# [. x% g8 i* F of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH; K9 [; S' x9 _9 Y8 G* \
cookies.+ H! t' r* s# Z+ ` k( x, C+ s
7 o( o1 m) o* r4 k* q7 `
req_ssl_ver <decimal> o+ h" Q$ Z( g7 q6 F
Returns true when data in the request buffer look like SSL, with a protocol
1 @3 d" X/ Q( {1 z: g1 j8 T version matching the specified range. Both SSLv2 hello messages and SSLv3
- s4 N+ f5 }/ {! y messages are supported. The test tries to be strict enough to avoid being
; b! z b" ^) h: E( D& \ easily fooled. In particular, it waits for as many bytes as announced in the
2 P1 y. r( D3 _: r- e1 M$ { message header if this header looks valid (bound to the buffer size). Note
. o1 [) ~, F8 c# A$ U8 ]4 t that TLSv1 is announced as SSL version 3.1. This test was designed to be used7 k1 j! L7 X: g# B) o5 ~
with TCP request content inspection.
3 z* Y3 q( E+ C5 V6 Z' |$ _2 ] O( E
wait_end
. v; \- V: ~4 e3 I Waits for the end of the analysis period to return true. This may be used in
8 a" o6 I9 A7 Q& l: v+ B: K conjunction with content analysis to avoid returning a wrong verdict early.! e' e7 Z: Y( r) a( t
It may also be used to delay some actions, such as a delayed reject for some# X& q; S! C7 U6 a' M# z
special addresses. Since it either stops the rules evaluation or immediately+ D$ j9 S: c o. Z7 u
returns true, it is recommended to use this acl as the last one in a rule.( e* d8 j7 F$ v3 C) U* G4 L# D
Please note that the default ACL "WAIT_END" is always usable without prior+ H$ X3 w$ W. Q) H( L& K
declaration. This test was designed to be used with TCP request content) X% y& r/ @$ v2 F, X
inspection.
2 v# {) g1 Z# D& t5 s8 D6 |! G( Y3 l6 k' i
Examples :% g. y0 B8 _2 A! u0 n
# delay every incoming request by 2 seconds
: L* U! T4 {* ~' {. q6 S: | tcp-request inspect-delay 2s
/ e( Z) o9 k$ F* T6 J* ]- t" ? tcp-request content accept if WAIT_END9 t4 g% u9 v- W5 @4 q3 X* o8 E; j
$ i! |: g' B; q; ~1 ^' w
# don't immediately tell bad guys they are rejected
: y" _* o9 g2 v4 b& p tcp-request inspect-delay 10s# W0 o& S! U7 B$ r& T
acl goodguys src 10.0.0.0/24 [+ H, q9 Y, D8 J# o3 H3 F6 L+ V
acl badguys src 10.0.1.0/24
3 Y& L7 _- z2 a/ ]% l+ s tcp-request content accept if goodguys5 a& Q/ D# S( ?. r1 v
tcp-request content reject if badguys WAIT_END: m' v$ ?- t% V n, z d
tcp-request content reject; _9 v' }- i' E* A: l1 {. W3 W: v
) Q, A, K3 ~7 K( y; U
( z* q+ m0 |3 |4 _/ t7.5.3. Matching at Layer 7! Z2 ~' D8 L1 F* u
--------------------------
/ u( W5 w. f& b$ t; L% F! ?% Y4 l0 o# @* T; A1 }) @2 H
A third set of criteria applies to information which can be found at the+ {- k: B9 O* ]1 A' u& w; ]$ R
application layer (layer 7). Those require that a full HTTP request has been! K% b2 _; z1 b( D; d! z; d& w
read, and are only evaluated then. They may require slightly more CPU resources1 k& R6 Z) w4 O1 C2 B5 W* Q' v
than the layer 4 ones, but not much since the request and response are indexed.5 J9 Q% ^) R* A. z3 s
" |# P& V5 { n q( `. z) Ahdr <string>/ h5 Z: d% b" X+ v. j9 g8 w& M
hdr(header) <string>
) j) U& k% p& |* S' ~- s Note: all the "hdr*" matching criteria either apply to all headers, or to a
* U. U, d% G9 q3 r2 k particular header whose name is passed between parenthesis and without any" ~' c1 C0 ~1 [# S
space. The header name is not case-sensitive. The header matching complies
J p1 O7 n9 l" E! ?0 {" ? with RFC2616, and treats as separate headers all values delimited by commas., Z) N' C! _: Q% S+ x8 v# W7 v
Use the shdr() variant for response headers sent by the server.
' f+ ^2 }, F( X7 o; U3 L- W; e. k% S! k* ]
The "hdr" criteria returns true if any of the headers matching the criteria
# S& M! i* R6 p3 ~) a# U3 i match any of the strings. This can be used to check exact for values. For
' h2 V0 k) P6 f6 Q2 F: v# K instance, checking that "connection: close" is set : u- s2 s( o* l$ @" C& f
7 h4 W K: B( _( C5 M, A4 @
hdr(Connection) -i close2 y" ]& ?/ U/ b- H r, |
- s; X& y3 |+ ~
hdr_beg <string>
+ U0 ^& m: r* S9 v% Phdr_beg(header) <string>
( R7 m/ k! a- d6 Z4 Q5 x! S9 Z Returns true when one of the headers begins with one of the strings. See
/ B/ }! r9 J( P( a "hdr" for more information on header matching. Use the shdr_beg() variant for
7 l$ w# P: D" ]7 |4 ^. b7 b y+ c response headers sent by the server.
9 s5 ]1 P/ W( E$ [
* c" A% |* O: G# y5 }/ c, c k+ ghdr_cnt <integer>3 y; e' ^9 }& [" m
hdr_cnt(header) <integer>' u' F9 z( v& j3 j2 A' l8 i! ]
Returns true when the number of occurrence of the specified header matches, c, \6 T o$ X2 N. M, s/ K- q
the values or ranges specified. It is important to remember that one header
& r- T+ |# C7 j# m7 e. g" V/ ? line may count as several headers if it has several values. This is used to7 s( }+ d1 S, h# V {8 B+ H
detect presence, absence or abuse of a specific header, as well as to block/ R: L2 H) x: q; D$ p, L& _' R5 D
request smuggling attacks by rejecting requests which contain more than one
5 N" b' m6 I9 l* H7 v* I0 L of certain headers. See "hdr" for more information on header matching. Use3 D) M, _* O3 I9 O5 o
the shdr_cnt() variant for response headers sent by the server.
8 C! @2 S+ x% K/ l' s; ]
0 T3 y' o; `/ L% @7 v5 t: khdr_dir <string>: b4 R6 D# n& C& p$ x
hdr_dir(header) <string>* L; s* x4 U) q `2 w# p$ O
Returns true when one of the headers contains one of the strings either
3 y1 Q6 S ]( [' X isolated or delimited by slashes. This is used to perform filename or. D R$ F ]) C. h/ a9 L
directory name matching, and may be used with Referer. See "hdr" for more/ b" K ^' G4 U' V
information on header matching. Use the shdr_dir() variant for response0 |! J7 i( v( {% B V
headers sent by the server.
* L; N, a" o5 }4 j0 T6 G: n. J6 A; t P/ N/ R' Q4 |2 e( e: l0 O
hdr_dom <string>
/ T0 w4 {; M$ |, uhdr_dom(header) <string>8 t$ C$ k, P. M7 A3 |: R' s5 m
Returns true when one of the headers contains one of the strings either" s8 ~4 }" k+ k/ D5 x8 }
isolated or delimited by dots. This is used to perform domain name matching,
3 o" \% C C! t( }6 N. Y0 ~ and may be used with the Host header. See "hdr" for more information on* q% r1 W; N3 r; ]
header matching. Use the shdr_dom() variant for response headers sent by the
/ }' @0 I9 k& T7 Z0 D+ C$ L2 ~ server.
& z3 X! p3 e) a, N9 ]. f* X& N0 k
hdr_end <string># U& z7 k( B. o
hdr_end(header) <string>
+ X8 T* f9 N4 i& B, u0 p; F5 U& x Returns true when one of the headers ends with one of the strings. See "hdr"% n, D9 a2 A# z/ g: g
for more information on header matching. Use the shdr_end() variant for
: `. i; X7 E3 A9 k' A: Q+ w response headers sent by the server.
. B0 |3 z! Q3 R6 y+ G. N8 l! ^& g" W$ \
hdr_ip <ip_address>
3 Q* N# _, F* ~9 p* {7 w1 Ghdr_ip(header) <ip_address>
3 t6 H/ `* {8 G( Z# R Returns true when one of the headers' values contains an IP address matching
+ W! ]. I6 L& w <ip_address>. This is mainly used with headers such as X-Forwarded-For or9 a: o# Z% C7 A
X-Client-IP. See "hdr" for more information on header matching. Use the
* A% {9 H0 m) O6 M7 J0 f1 s shdr_ip() variant for response headers sent by the server.
; P3 O6 ]; Y/ i+ S5 J" e( T
8 i0 I4 q p2 ^hdr_len <integer>
* d0 S& A: W) G9 w& Lhdr_len(<header>) <integer>, D p3 l" R4 G8 U$ w- w0 z
Returns true when at least one of the headers has a length which matches the/ w8 F' u9 D" U9 c
values or ranges specified. This may be used to detect empty or too large
+ \6 v9 z0 E& ]) ?) V5 @ headers. See "hdr" for more information on header matching. Use the, @3 E+ ^/ k/ n
shdr_len() variant for response headers sent by the server.
! F: f) s, p# f9 H( b5 Q, ~0 C( Q3 W! [6 Q; Q& l
hdr_reg <regex>
5 b7 R' u+ w( |" E+ B% b" `hdr_reg(header) <regex>' k+ ?# @. T. h9 d! M
Returns true when one of the headers matches of the regular expressions. It: x3 ~; P7 T) b, `2 ?
can be used at any time, but it is important to remember that regex matching
' U+ q3 i1 r/ ]3 [# e is slower than other methods. See also other "hdr_" criteria, as well as, }9 g1 [' R T5 e
"hdr" for more information on header matching. Use the shdr_reg() variant for
. O0 T q8 O4 ^; J response headers sent by the server.
0 K" d* c4 y4 [) ]% s2 K) D* S( @* {' k# L7 n) J& w3 i
hdr_sub <string>
. a5 C8 H# _/ H, v0 ~0 khdr_sub(header) <string>4 a4 U1 ^* W. n+ k7 l4 f" U
Returns true when one of the headers contains one of the strings. See "hdr"
9 U% F$ H4 x( q$ w$ [. | for more information on header matching. Use the shdr_sub() variant for
! _, u. [7 d9 ^1 h$ ^- ]! @$ d response headers sent by the server.
; M% g! L: T+ Z8 U* c! W8 z% _. U) h) {4 `# N( w3 Q) x
hdr_val <integer>% P+ S( z' ?* j
hdr_val(header) <integer>
/ V: {7 L' H6 w# f2 E6 I Returns true when one of the headers starts with a number which matches the" E3 ~6 a" F% e
values or ranges specified. This may be used to limit content-length to
$ ^+ i6 e' E) S3 }, M acceptable values for example. See "hdr" for more information on header3 Z5 |+ W! k9 t$ {, k
matching. Use the shdr_val() variant for response headers sent by the server.
$ F$ z" J9 l6 ]8 L8 R) i7 r7 r7 [! E" g. w
http_auth(userlist)
9 [# e; M9 f/ e2 Nhttp_auth_group(userlist) <group> [<group>]** q5 _" K+ B9 @! B, z/ ~
Returns true when authentication data received from the client matches
. y& m8 W" E$ p/ ^* O username & password stored on the userlist. It is also possible to6 c5 X6 k7 f( ~/ T5 E6 c0 n
use http_auth_group to check if the user is assigned to at least one
! W. d/ `. E8 {4 U. f of specified groups.7 S* g- B q; x @7 v' X
; ]! B+ B8 F9 z
Currently only http basic auth is supported.3 W% Y* Y! D3 u! k8 D
! G+ R/ F6 h u: V
http_first_req" f! S- t6 {. ^; m. H9 S
Returns true when the request being processed is the first one of the
. T% J) D, ]0 {8 K connection. This can be used to add or remove headers that may be missing6 Y, c0 c0 n" L1 ]" @4 H$ y; i# j
from some requests when a request is not the first one, or even to perform f8 R' y7 @* H& m" [/ P& W* \/ b' H
some specific ACL checks only on the first request.
3 l6 D2 L- K- j2 T; B3 ^* L4 d9 T/ g0 O. q6 R7 g) Q c
method <string> t& D% S1 _. T0 v" F7 e
Applies to the method in the HTTP request, eg: "GET". Some predefined ACL5 ~0 M' O+ k" M" @% M$ f
already check for most common methods.
6 k! E/ a, o a. }
& t$ p$ \! S$ `1 M- I$ a+ apath <string>3 {: ?/ V" T. a9 e R1 h5 d
Returns true when the path part of the request, which starts at the first0 x) q S4 F0 v9 v
slash and ends before the question mark, equals one of the strings. It may be$ Y4 f3 Q& J u3 Y
used to match known files, such as /favicon.ico.& c M3 W' v0 A& t1 q$ t- I
6 k R, r+ K' B( ^) \$ c o |
path_beg <string>
3 f: e5 E+ R/ S( z4 O' u Returns true when the path begins with one of the strings. This can be used$ K y. a1 A" }, ]# I& `. q
to send certain directory names to alternative backends.. V# i! e# h# n) i/ x
1 p7 S1 c% C. mpath_dir <string>/ ~4 n+ u( j# d |; u
Returns true when one of the strings is found isolated or delimited with8 ]% S Z, @7 j$ u! L$ c
slashes in the path. This is used to perform filename or directory name; }$ v* X- s) `
matching without the risk of wrong match due to colliding prefixes. See also
; R4 Y0 T' i% p$ S( J: c' H "url_dir" and "path_sub".
: l6 j+ u6 v$ V
3 L# S$ c* L9 |* B4 O0 Dpath_dom <string>2 q0 ?( Z! x- W- u$ x
Returns true when one of the strings is found isolated or delimited with dots
% { P. x% f7 R& A# w in the path. This may be used to perform domain name matching in proxy
) S/ M8 ~' K& y requests. See also "path_sub" and "url_dom".
& v5 M4 L: _* c( a3 Z
" c4 o$ B0 ~5 H2 hpath_end <string>
5 _8 ]6 d9 W# G- n, f$ t Returns true when the path ends with one of the strings. This may be used to# E. H3 Z- C+ ~& E# h
control file name extension.' }0 C9 @6 E/ Q
! Y# L! m1 a: d* y7 H/ d* q" T5 r
path_len <integer>
9 ?5 l1 u) K* |5 K2 R+ U Returns true when the path length matches the values or ranges specified.# b* J; t0 R2 M0 E3 d; {
This may be used to detect abusive requests for instance.
8 L, M% z7 y0 {! T8 d% h' D# l
0 G9 ^ [" }% ]' t( H* W: L8 Opath_reg <regex> z- V5 F, {, Q q# [4 z' z
Returns true when the path matches one of the regular expressions. It can be/ s+ f& \" ]; x' m1 V
used any time, but it is important to remember that regex matching is slower
" @7 O- d* ^; [9 D2 Y than other methods. See also "url_reg" and all "path_" criteria.+ U# N/ O5 H7 E9 m1 i' F( l' c
0 k& e( j L3 n t4 Y e- |1 Rpath_sub <string>; p" A; C8 H- L$ u j, ^% N
Returns true when the path contains one of the strings. It can be used to
" {+ V; t& g T- \% r detect particular patterns in paths, such as "../" for example. See also
- x( P( C: S/ @* i' z9 U5 q& V+ L* ^ "path_dir".3 L# @" W" z- W
" R: K8 N1 f% B X. Zreq_ver <string>
5 I7 |/ T1 x# j' w9 s5 W0 N% N Applies to the version string in the HTTP request, eg: "1.0". Some predefined5 K6 b8 \4 ^- A
ACL already check for versions 1.0 and 1.1.
, @. y' n7 R# {; y3 w. h% a% t6 T9 Z R9 G) c4 ~
status <integer>
) I) k, g# U% a2 l1 v* b Applies to the HTTP status code in the HTTP response, eg: "302". It can be" T* S2 B Y5 a9 _
used to act on responses depending on status ranges, for instance, remove
0 Z4 d6 ^4 r/ L' ^- A$ Y% A any Location header if the response is not a 3xx.# \. ]1 u2 Z- ^5 N/ h$ j2 t
! G. g7 ]4 k9 a2 P: t1 q/ P
url <string>, k% V8 f \" o7 Y+ ^
Applies to the whole URL passed in the request. The only real use is to match
9 [9 ]: @/ t( y "*", for which there already is a predefined ACL.$ j% N5 J9 \: T/ @6 w
) ~( R0 C8 |3 Y
url_beg <string>
! ?: c5 l8 `: R' |" G/ z2 W) t; q Returns true when the URL begins with one of the strings. This can be used to) ]' S7 l/ O. P8 p. T
check whether a URL begins with a slash or with a protocol scheme.
* y2 E* u' D* g( k+ m+ w( i
. }3 s& z7 J" b3 c: vurl_dir <string>! X" g! N0 c, Q' c- w4 m
Returns true when one of the strings is found isolated or delimited with
/ h6 E$ E4 p8 ]9 A1 r slashes in the URL. This is used to perform filename or directory name) F3 L- I+ B# D. k. s
matching without the risk of wrong match due to colliding prefixes. See also
5 v! z# \4 h- Q. C0 z, D* U "path_dir" and "url_sub".9 W9 {5 l! O" C# x6 w
$ `1 o% S- C: m5 j4 x4 S
url_dom <string>
7 c2 v9 J: g- Z3 [1 p1 D Returns true when one of the strings is found isolated or delimited with dots& e9 r9 w( p2 E$ O
in the URL. This is used to perform domain name matching without the risk of% e4 L$ K a" I! R) e
wrong match due to colliding prefixes. See also "url_sub".
# K5 y5 g2 Y+ |- g' n$ v
: [% l4 c: R% r( |url_end <string>
, i8 q; s2 s3 J8 b Returns true when the URL ends with one of the strings. It has very limited
: f! Y" T+ t& e- V$ N use. "path_end" should be used instead for filename matching.6 P) S# ~2 A4 v1 K, x/ y6 Q- O* @
1 k, |# x) K: g4 R% {5 F% Q* S f
url_ip <ip_address>
0 }; y4 `/ f$ ~6 b/ s% L Applies to the IP address specified in the absolute URI in an HTTP request.; k. l0 Z7 z" i' @' n9 L) {2 Y
It can be used to prevent access to certain resources such as local network.
, @ G% a6 f; T* s& _% H It is useful with option "http_proxy".0 g% i, J6 F# o2 D y% h! k! E
: J7 \, E, X! K3 g/ n" K& furl_len <integer>
4 {8 h) O/ j$ ^- u8 Z$ [( }8 \ Returns true when the url length matches the values or ranges specified. This
6 O9 J1 h; W+ p% i0 l may be used to detect abusive requests for instance.
5 D6 k5 Z5 a+ \. R/ `* ~7 Q, ~0 @% j$ Z5 [! Q e. H, ?% A; ~
url_port <integer>0 [& F* c5 R3 j) r* |% O
Applies to the port specified in the absolute URI in an HTTP request. It can
( p3 C, [# f% h9 Q. r) A be used to prevent access to certain resources. It is useful with option3 @# a6 Y9 ^, b4 Y% D& g* v
"http_proxy". Note that if the port is not specified in the request, port 804 |& H+ e: C5 \& x
is assumed.
+ f: t8 J; `5 `$ Q/ J7 |$ ?, d! O \7 b4 f% `5 G8 P
url_reg <regex>; x: A5 i! a+ s5 s0 k) m; B
Returns true when the URL matches one of the regular expressions. It can be
& q; \9 l0 g+ E' j used any time, but it is important to remember that regex matching is slower
; u# O+ x* Y- Y8 b& [ than other methods. See also "path_reg" and all "url_" criteria.
1 j2 f" e! y( m: a4 |( M \# E* [/ a6 o) V d; h1 Y
url_sub <string>! q% A. ?- ?2 M; N, n6 X7 E. B
Returns true when the URL contains one of the strings. It can be used to. K) r! }# `0 N, s# I# j- h( P( k
detect particular patterns in query strings for example. See also "path_sub".6 i0 r( H2 a% t G( m: f8 A* b, H
/ Q! s' v3 z0 ]& N' O4 Z- g$ }+ {" U0 K- p! X9 {/ K5 ~
7.6. Pre-defined ACLs! G+ A; y7 e* ?$ {
---------------------( |' i: J+ c) F3 x
. M+ T' _! Y! {; S6 f% c& k: @+ y5 i+ }2 dSome predefined ACLs are hard-coded so that they do not have to be declared in
# S5 B, ~' X2 Q+ ]3 {3 ~& r$ Devery frontend which needs them. They all have their names in upper case in8 k! a* C4 N! D' \+ G @+ {. {" U
order to avoid confusion. Their equivalence is provided below.. d4 G0 V+ o' z2 N; D0 M7 E
V% w) {3 q( a
ACL name Equivalent to Usage
+ g. H$ [: P$ Q; u! T---------------+-----------------------------+--------------------------------- [" k- v* x5 Z8 X) J
FALSE always_false never match
4 O9 d* s9 f% \1 `* v0 P3 V" S, A$ AHTTP req_proto_http match if protocol is valid HTTP" U8 W2 j) {* a3 b4 `/ I5 w; C
HTTP_1.0 req_ver 1.0 match HTTP version 1.0, v' w7 U$ O' y$ ~% L8 t0 U
HTTP_1.1 req_ver 1.1 match HTTP version 1.1& y6 a: [# a; y: J
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
3 r( P# g# q9 pHTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme/ L7 b0 q, \$ E& U
HTTP_URL_SLASH url_beg / match URL beginning with "/"6 k8 j8 x5 c7 |
HTTP_URL_STAR url * match URL equal to "*"
8 Y; J& C5 ^1 P% L" W# PLOCALHOST src 127.0.0.1/8 match connection from local host; j/ U+ V3 {$ U9 v: S8 M4 d
METH_CONNECT method CONNECT match HTTP CONNECT method& H& U8 D" } Z% ]
METH_GET method GET HEAD match HTTP GET or HEAD method
$ w d( A: r6 l) CMETH_HEAD method HEAD match HTTP HEAD method1 f' f4 X7 ~/ P( c( T& }
METH_OPTIONS method OPTIONS match HTTP OPTIONS method
8 t9 w, ^, L) i! ?9 C& ~METH_POST method POST match HTTP POST method
# d/ d5 s# l0 L$ u+ x( A! p2 h8 xMETH_TRACE method TRACE match HTTP TRACE method+ ~% D6 L/ T2 V4 k
RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie* H7 A( A& l- t
REQ_CONTENT req_len gt 0 match data in the request buffer$ t5 E/ ]' d* u6 p# F9 X) |+ G; q
TRUE always_true always match
, q/ w/ y6 z8 Q; HWAIT_END wait_end wait for end of content analysis
' o) [6 g! r& a. ~% g& L---------------+-----------------------------+---------------------------------
3 S5 d" ]2 U; y. a q# ]4 B; l- i& b5 M9 Y
) K. R& T& ^8 L3 h; s, E/ U0 S4 S
7.7. Using ACLs to form conditions6 W" `5 g% w1 B
----------------------------------
2 G# X8 G/ {+ Q( c
& ]: |1 |) N8 O; ], A' ]1 h' r6 ?) ]Some actions are only performed upon a valid condition. A condition is a4 H8 c o! P- l) X1 U& t3 H3 E) r
combination of ACLs with operators. 3 operators are supported :
( J: n! a& Z8 e% v" Z7 e9 C5 k% X) ?7 `& `2 g- d
- AND (implicit); J5 Y7 |' |5 e) D5 W. |6 T6 l* P
- OR (explicit with the "or" keyword or the "||" operator)# _6 ]! L7 \7 \0 K0 ^2 ?
- Negation with the exclamation mark ("!")
0 {7 [5 O5 d" g' _% B, U4 g
$ r1 I2 L4 o, I0 |" ^, U: x9 fA condition is formed as a disjunctive form:) u0 e8 F; ^, @8 X) m! I& Z
9 g& C0 e% _; j3 h5 s1 r
[!]acl1 [!]acl2 ... [!]acln { or [!]acl1 [!]acl2 ... [!]acln } ...
# E8 g# l: L5 l9 W3 R" D3 V
% ~# z" Q7 J. `Such conditions are generally used after an "if" or "unless" statement,0 ^0 W U% U5 F) i# I" @: V2 @
indicating when the condition will trigger the action. k( y* ~5 c( v8 C
( ^, g. j, Q" }; h0 Z
For instance, to block HTTP requests to the "*" URL with methods other than
+ n" P6 ]- U; ^* X2 A"OPTIONS", as well as POST requests without content-length, and GET or HEAD
* Q! q/ k |' c/ y. P7 drequests with a content-length greater than 0, and finally every request which
; O1 X) n" d5 T8 Vis not either GET/HEAD/POST/OPTIONS !/ Y; Y3 [9 L, _; }5 J5 |4 u% Y
1 n: n$ n, Z: S( Z9 B2 D" S acl missing_cl hdr_cnt(Content-length) eq 0
( r. B: r& ^0 ^5 e1 y block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl2 C$ Z5 [6 e% h6 W' Z
block if METH_GET HTTP_CONTENT
1 J" @- y4 S h' W- E block unless METH_GET or METH_POST or METH_OPTIONS
; d! o* W1 v5 C2 i+ a: H) c! g! @. V. K" j
To select a different backend for requests to static contents on the "www" site
" V& y4 }8 t% m8 d. E3 W6 }and to every request on the "img", "video", "download" and "ftp" hosts :8 P2 x D/ U: P: V" |! x$ X; h. `0 U- S
4 K! _* G3 {3 b* `4 M) N% {+ R
acl url_static path_beg /static /images /img /css
7 G+ q7 D6 h# n1 J: |& i% A2 ~ acl url_static path_end .gif .png .jpg .css .js6 ~. j: _' U/ g# {+ m& \
acl host_www hdr_beg(host) -i www
% Y9 U2 _! ^5 k. B' p; v6 _6 a acl host_static hdr_beg(host) -i img. video. download. ftp.
" N& j9 d- `3 r% ?
; l/ h- j( z$ x# u' ^( H # now use backend "static" for all static-only hosts, and for static urls
: K- A" U5 g, d& `5 J: G # of host "www". Use backend "www" for the rest.
) \4 a5 ?! s9 ?1 [4 X% ?! c+ X7 X use_backend static if host_static or host_www url_static
. y$ R2 z6 V3 w2 I; X use_backend www if host_www$ I# y+ \: M; Q; H8 w1 e6 J [
, ?7 D; h+ z0 uIt is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
) g/ r% W3 W p) ~9 Hexpressions that are built on the fly without needing to be declared. They must
F5 F+ i) k8 pbe enclosed between braces, with a space before and after each brace (because
# L( q5 H( U9 e4 N0 D9 T/ Gthe braces must be seen as independant words). Example :4 ]/ a5 O$ b& N( r7 g4 x
]1 b7 k i8 v, L( s
The following rule :% X) b6 l ^ U3 A ?4 \* K
" D( X- G0 P( k' |- B7 u acl missing_cl hdr_cnt(Content-length) eq 0
2 F* p6 `' H. o! |8 D block if METH_POST missing_cl
& j' L/ k& w2 d, c- d! [4 }
" c; A2 f! T. c4 o4 k Can also be written that way :
- i0 [6 e+ S" ^( E/ p; Y: F& B
8 e8 T3 L" w* r; Q; q; q* F9 J3 d5 S block if METH_POST { hdr_cnt(Content-length) eq 0 }$ |1 O6 v( Y1 J$ Y
+ |3 t# L" U+ J7 q( B6 dIt is generally not recommended to use this construct because it's a lot easier
! y4 L5 J, L/ o- a3 |1 @to leave errors in the configuration when written that way. However, for very
8 P+ p, m9 B4 Y; u4 A1 f, Msimple rules matching only one source IP address for instance, it can make more
' L( `1 B& a" o+ q1 @1 hsense to use them than to declare ACLs with random names. Another example of
( B- s/ b9 X/ g( c* \4 c7 k0 y# ogood use is the following :6 a! k6 L& z5 p& E3 ] W D
" ]* ]4 F7 D; Z, Q: A
With named ACLs :: P7 b& g; |& ^9 N8 e9 p6 P& j
( l8 c4 w B' v2 U- p$ ]
acl site_dead nbsrv(dynamic) lt 24 o) o, Q; W; K4 i$ ~
acl site_dead nbsrv(static) lt 2
2 O6 f/ D$ Z# K* ?+ ^- B monitor fail if site_dead
: I0 t8 u5 |, P( t5 w
v6 F5 N, X- S; {5 A6 i With anonymous ACLs :: y' r. V- r, A# ^0 Q2 B q
' ]. _1 x, O+ E+ O: u ?, p0 ^ monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }8 A, s: }$ r3 W2 a
. K B% R- B9 A" l
See section 4.2 for detailed help on the "block" and "use_backend" keywords.- F+ ^& y0 F) i P+ _8 Q7 B- u
# Z3 N5 S, f: Z5 Z' c7 [
9 T( {3 [+ j/ ?+ f3 q7.8. Pattern extraction
8 n9 V* n4 N/ x-----------------------2 X/ ]1 V: ~2 w; e
# V M* g) q z% U7 K; dThe stickiness features relies on pattern extraction in the request and
) g, L+ ]* ?+ V! k2 Oresponse. Sometimes the data needs to be converted first before being stored,3 @9 o: X4 x q% C6 x0 j9 k! _
for instance converted from ASCII to IP or upper case to lower case.
! A6 ?( k" N, I) N! x
6 [9 e4 ?2 W2 N; d( {All these operations of data extraction and conversion are defined as
/ ^$ U0 m5 j+ y. R4 ?* f"pattern extraction rules". A pattern rule always has the same format. It
0 |5 A/ P4 V" g( h/ i, D- Ibegins with a single pattern fetch word, potentially followed by a list of
8 }& t+ l: S' F6 ?, Harguments within parenthesis then an optional list of transformations. As1 [7 u# y" K" @$ e
much as possible, the pattern fetch functions use the same name as their
/ Q1 W" ]" Y0 ~. F' cequivalent used in ACLs.
0 B( z: A8 [* z" Z/ |0 I) N( _6 H5 U7 Q4 v) m( ^% _ T1 ?' [% o
The list of currently supported pattern fetch functions is the following :' W8 T( Q( I" L
0 m2 l- I7 I6 U5 ^! o1 Y src This is the source IPv4 address of the client of the session.
0 ^# g7 v: E, d8 K( F It is of type IP and only works with such tables.* u* U2 D/ b* c3 q' u
4 d/ L8 b! l. a+ x dst This is the destination IPv4 address of the session on the) Z5 K! ]& q4 r0 l8 }5 H7 y! g h
client side, which is the address the client connected to., @3 o9 M% q& t) ?7 _
It can be useful when running in transparent mode. It is of. j* i: D3 R( ]) ?2 ]; C/ G
type IP and only works with such tables.3 Q6 h7 Q/ o j0 V8 ^. `3 |$ u4 W4 l
$ {% ^6 j. w* R P/ }5 O dst_port This is the destination TCP port of the session on the client, s) _2 X/ j+ ^' t/ c, J
side, which is the port the client connected to. This might be; a" Q( W7 E$ ^/ U$ }( n; ]) d
used when running in transparent mode or when assigning dynamic9 A& A- P, X5 `/ P
ports to some clients for a whole application session. It is of2 `" z/ M- M6 D/ j! l" n; l
type integer and only works with such tables.9 t4 h# X* H4 v
# d* ?3 k3 M0 W+ v
hdr(name) This extracts the last occurrence of header <name> in an HTTP
5 l9 E \, m/ L: f3 w0 q: _ request and converts it to an IP address. This IP address is$ j+ ]7 N7 E/ g, s7 Y& ^
then used to match the table. A typical use is with the, M7 }) o3 T; V: M
x-forwarded-for header.5 V1 U q, p+ ~% u& x# D
" R$ T3 {4 I5 s2 a" Y: ~6 W4 C) Q7 ]- m5 {2 @( `, K
The currently available list of transformations include :
) a8 P& a' e+ g; x
5 ~2 h. D, _5 i1 l1 N lower Convert a string pattern to lower case. This can only be placed7 g" r) n g T/ O v. j
after a string pattern fetch function or after a conversion+ p7 L3 b @5 H3 t# V
function returning a string type. The result is of type string.: `7 z) T, j A* w2 w
) u: z# A8 a" x; N; h6 u upper Convert a string pattern to upper case. This can only be placed
& ]* I# m% p$ O/ B after a string pattern fetch function or after a conversion
; v b* B( q8 H, M8 u function returning a string type. The result is of type string.2 G% `, d# r( R2 I) [" ?
) J1 n& q% ]0 j5 ^( h! t ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups
% X4 t& q& T3 S2 M6 h; }9 \8 D and storage. This can be used to make all hosts within a
% U3 c$ A0 Y: l( G! _0 f9 ~ certain mask to share the same table entries and as such use
6 C" u1 P7 [' S ~" D the same server. The mask can be passed in dotted form (eg:
, l7 k1 k e, l0 f h! M1 M 255.255.255.0) or in CIDR form (eg: 24).
4 `8 y1 x% ]: J8 o$ g4 d' o. s9 p- A/ G& l
2 G0 w0 n* @. R% I6 \8. Logging! D. Z: m: i+ j6 G7 T
----------
5 H, d0 P+ v( Q& b
& _& @# n& D; `. e) X+ O# B: D; pOne of HAProxy's strong points certainly lies is its precise logs. It probably
5 s3 l. k" x7 G7 J$ r) K7 L) jprovides the finest level of information available for such a product, which is
/ `8 b/ {+ k! s" g4 d8 l+ kvery important for troubleshooting complex environments. Standard information
R' f4 f6 U2 O) `4 F, r2 A! d/ Dprovided in logs include client ports, TCP/HTTP state timers, precise session6 _( l1 r) i$ a( v7 H x3 c2 i
state at termination and precise termination cause, information about decisions% O3 I! f6 `3 W/ d: [
to direct traffic to a server, and of course the ability to capture arbitrary+ s8 ?& d7 M/ U2 O
headers.
R. [3 s' c) a' V
9 W$ {' V8 F/ p* QIn order to improve administrators reactivity, it offers a great transparency* m1 q/ R% K! f- @. x3 R* q
about encountered problems, both internal and external, and it is possible to* d' E1 B6 Y- h* l/ P) S
send logs to different sources at the same time with different level filters :
, |7 a1 d6 {; E% c, [, A5 D3 g5 r8 U* v
- global process-level logs (system errors, start/stop, etc..)6 l, I( W" I" A0 x5 T
- per-instance system and internal errors (lack of resource, bugs, ...)' r4 E* t# Y# z; I m
- per-instance external troubles (servers up/down, max connections)* P# i2 m. {9 U9 H+ N, ^1 v
- per-instance activity (client connections), either at the establishment or( |0 @* \4 R) U2 e1 s4 K, j6 [
at the termination.: z6 k4 E7 T4 L: |
8 @- X$ F8 N% k3 c9 b& w! q
The ability to distribute different levels of logs to different log servers
8 \% K* O- q: M/ g# ]* yallow several production teams to interact and to fix their problems as soon, ^4 c5 h, x6 }* p7 E: x
as possible. For example, the system team might monitor system-wide errors,! ~& m) l* N: M5 G% H
while the application team might be monitoring the up/down for their servers in1 p) \& b& i/ _/ w) j/ F
real time, and the security team might analyze the activity logs with one hour
0 J/ E: u5 ?: Z j: |) Qdelay.- ^# S! S" e3 X3 ^
# `4 t7 ?6 a) Z# v; M* i
. D, h; A1 |5 z% M2 [. w/ s8.1. Log levels
2 h& G8 X/ d& T7 `. U1 b+ S3 }8 Z---------------" x" d+ d! W1 N4 n x" R8 M7 s. W7 x
! ~2 ~5 G2 I5 G TTCP and HTTP connections can be logged with information such as the date, time,
! \! o8 U8 q! l* l% S# gsource IP address, destination address, connection duration, response times,
9 h; b$ N' L+ ~# p$ L# d9 SHTTP request, HTTP return code, number of bytes transmitted, conditions
" {$ I3 s1 g$ S+ X$ c( ^1 Z- w' Ein which the session ended, and even exchanged cookies values. For example
- `% G7 [: I) l |1 Wtrack a particular user's problems. All messages may be sent to up to two
9 }+ b$ ]% v4 u; ]+ J" a: | rsyslog servers. Check the "log" keyword in section 4.2 for more information
, q0 w# } h Q( v( \/ a+ z& W. labout log facilities.
6 ^0 ] i; [" ~& u0 x
: J: X6 q3 k$ s1 z! n1 P6 ? n' n" h
8.2. Log formats5 {8 d0 G% Q. `! i G
----------------9 R8 L% n1 e5 }
0 a7 x3 `2 P* O( g& PHAProxy supports 4 log formats. Several fields are common between these formats
! M) j& y r! d$ i+ Mand will be detailed in the following sections. A few of them may vary
2 w6 {) i/ W+ n+ dslightly with the configuration, due to indicators specific to certain
# i' g A$ W$ Q; R/ W yoptions. The supported formats are as follows :) H E. n7 t' ^5 T6 h
! A6 x# w: M: a6 @/ D - the default format, which is very basic and very rarely used. It only2 L. p/ L% T* J+ K9 A3 Q
provides very basic information about the incoming connection at the moment/ [7 Z, ^% u/ }5 l2 X# r
it is accepted : source IP:port, destination IP:port, and frontend-name.# x' }; N5 P, W# x u, x+ `
This mode will eventually disappear so it will not be described to great
" ?9 M8 r4 W1 h0 `4 P& @9 N- i extents.
3 G, ?4 x" P+ w4 r# Y/ t2 a2 O
( @; ^; x1 Q @$ _ - the TCP format, which is more advanced. This format is enabled when "option$ M: J. x' ?' K/ F& `( {
tcplog" is set on the frontend. HAProxy will then usually wait for the
5 [ a' b. v" g" ^5 Y connection to terminate before logging. This format provides much richer! Y Z# Z, X. y' t; K% U
information, such as timers, connection counts, queue size, etc... This
% a- X& c2 e5 j l# Q% R3 l! u format is recommended for pure TCP proxies.% x- N0 @( M: T1 P# X
( m" p/ l y# ]8 u
- the HTTP format, which is the most advanced for HTTP proxying. This format
7 s+ K: e- F4 o! C7 Y9 L is enabled when "option httplog" is set on the frontend. It provides the r- A* K$ D3 A- L* R! Q
same information as the TCP format with some HTTP-specific fields such as; }9 v+ s/ R5 G* K' P+ z' G
the request, the status code, and captures of headers and cookies. This
$ ~0 T q& y8 }& j F format is recommended for HTTP proxies.
+ N4 p* U5 J6 b' ]5 E7 H6 Z, M: B; {( Y4 H& b# ~9 i6 q
- the CLF HTTP format, which is equivalent to the HTTP format, but with the2 g; F; _" D ^8 Q4 {$ n2 p) Q
fields arranged in the same order as the CLF format. In this mode, all
! h. s t# U- j! n7 R- n8 w$ F timers, captures, flags, etc... appear one per field after the end of the
6 P7 F& q3 ^% ~: p) U' I& T7 n3 m% ] common fields, in the same order they appear in the standard HTTP format." h0 \% R0 ?( t7 X; h9 G
- L4 W' Q8 y5 O
Next sections will go deeper into details for each of these formats. Format
2 y+ Y. v. q1 Y2 [/ lspecification will be performed on a "field" basis. Unless stated otherwise, a4 j3 i6 M; b$ h7 Y
field is a portion of text delimited by any number of spaces. Since syslog
" G0 x2 P6 K/ h. @servers are susceptible of inserting fields at the beginning of a line, it is6 V1 B0 H! V9 u. \- A* M
always assumed that the first field is the one containing the process name and
# V: I7 q3 l Q U0 |7 d! oidentifier., s5 S. r& J' D) a, U1 F& Y& q& C+ }
2 z# L) e$ i/ `: P$ _2 D" N# Z
Note : Since log lines may be quite long, the log examples in sections below
! V7 d& C% ?2 C2 l$ i7 y might be broken into multiple lines. The example log lines will be
' v+ W7 R( I7 v0 N/ @5 ?5 D prefixed with 3 closing angle brackets ('>>>') and each time a log is9 m$ l2 Q6 O' Z& z
broken into multiple lines, each non-final line will end with a. O/ {3 @6 u; E" l- \
backslash ('\') and the next line will start indented by two characters.7 d o& i A' R+ |; I
; y+ y8 W8 F! s
) C& H |' o# X3 {' d [8 y
8.2.1. Default log format
1 L% v/ o) o) j8 E: |) [-------------------------& r4 d+ W# v5 n; w4 M/ U2 E1 O
. f! o4 P5 ~% S$ [ TThis format is used when no specific option is set. The log is emitted as soon9 I4 @: i9 y. c& w7 G5 L" p( c
as the connection is accepted. One should note that this currently is the only+ l5 u5 {/ O$ V1 P: e1 ^
format which logs the request's destination IP and ports." P7 |- p, }4 S h
& L T' r) ~+ A/ H1 d4 p Example :
! y$ F" _9 ]* Y5 g; b listen www0 _7 Z0 F, d% ^( r! m- H' U
mode http
8 [# c& Q; O; L/ r/ n! x log global% [: o/ S' ?2 e' ^2 R
server srv1 127.0.0.1:8000& O$ [( V) a5 y. y6 ?
) k1 y# `7 I" D% i# ]7 M$ l! A >>> Feb 6 12:12:09 localhost \
& L7 V: B i/ z q0 j haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \; F, F% }) I' k: C0 N4 K
(www/HTTP) |# L- C' v0 [# N m
. L( v+ ^+ U; `( @
Field Format Extract from the example above: L: [# g% s5 c0 J% X) p! Y# r7 X+ O
1 process_name '[' pid ']:' haproxy[14385]:
% }* P7 D, \& I( P 2 'Connect from' Connect from
1 t7 m C- [8 ~2 _ 3 source_ip ':' source_port 10.0.1.2:33312" s* m; L% U! M8 N! A) A1 d* Z
4 'to' to
8 ^2 z$ B' _( ^- N( T 5 destination_ip ':' destination_port 10.0.3.31:8012 j( H% {$ f S8 v0 \, e
6 '(' frontend_name '/' mode ')' (www/HTTP)7 k8 C2 v- v( Y$ r
+ G; {% ^1 L* F W& ]$ ^- V) R( V
Detailed fields description :
0 U0 @) h! j9 ~( G - "source_ip" is the IP address of the client which initiated the connection.
7 S: j" h+ H4 ^- K$ K: j - "source_port" is the TCP port of the client which initiated the connection.8 o9 b# |5 C2 A# x5 E
- "destination_ip" is the IP address the client connected to.' ?: `8 O& Q. ^2 U' P, G( |0 Q& P: T
- "destination_port" is the TCP port the client connected to.
) [' ]+ L( h* W/ ` f - "frontend_name" is the name of the frontend (or listener) which received
- \+ A& _7 `5 V5 F and processed the connection.: q) O8 g z5 f) Q
- "mode is the mode the frontend is operating (TCP or HTTP).8 s5 \: x# X1 ]; I0 m- W% G: |3 p1 B
/ n h* C! O, B) jIt is advised not to use this deprecated format for newer installations as it4 W: h$ k: u# E% C* W
will eventually disappear.
, Q- \( _7 e1 e9 K o- L$ x, O7 T3 i0 m$ m, a- T% E2 E% O
, u% N m+ e- f0 E4 D# ^! v
8.2.2. TCP log format5 q* r0 e, [$ `) @1 J
---------------------
_( ?/ z$ d3 {7 S9 n% l* B+ V5 _5 s
The TCP format is used when "option tcplog" is specified in the frontend, and' V* O5 U# ]0 i! G# D+ |2 h# D
is the recommended format for pure TCP proxies. It provides a lot of precious
7 \' l5 b- t% x, qinformation for troubleshooting. Since this format includes timers and byte
3 z3 P& c/ D$ Q* X+ kcounts, the log is normally emitted at the end of the session. It can be# D& l% \: Y& }, s6 U( D
emitted earlier if "option logasap" is specified, which makes sense in most
. B4 D; l" g ?5 Ienvironments with long sessions such as remote terminals. Sessions which match
0 W" p# @ ~3 Dthe "monitor" rules are never logged. It is also possible not to emit logs for8 J! k( z7 N$ D# U
sessions for which no data were exchanged between the client and the server, by! X4 J4 [, Q1 ~( z+ B
specifying "option dontlognull" in the frontend. Successful connections will
/ Q! h3 E6 M# x {8 }not be logged if "option dontlog-normal" is specified in the frontend. A few
: f8 {( ]! D/ ?+ W3 p% k9 Bfields may slightly vary depending on some configuration options, those are, Q. K, g% R8 Q6 |4 p$ E& \
marked with a star ('*') after the field name below.. _" V: @$ D! {$ F6 _
; p/ @; V. Z( v0 {. r$ D Example :6 F/ d. z R. w( I; C% _ G7 ^; v# c( h
frontend fnt
( C1 n1 ?! O3 ?( I$ Z+ x. C mode tcp
/ A3 I; s2 T& ]5 G( _$ f( Y; t option tcplog
1 H4 l+ A/ {& [3 o8 }5 |* W& o: i* _ log global$ r: W! e' e. Q- u c5 f
default_backend bck4 d- M8 B7 J, P( p2 R) I* i& o6 t
3 \2 |3 P+ N9 B# V
backend bck
* V' X" d2 L2 V2 a2 Z) C server srv1 127.0.0.1:8000, W" }, N j( N% A' y0 R" j* Z
4 q* V5 M- s2 Y
>>> Feb 6 12:12:56 localhost \9 v H) t5 O( I1 p/ N# Z
haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \8 n9 _9 t4 M9 _6 R/ q5 o m0 N2 |
bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/08 S" c& W# v/ O" B K( A
! z3 H& T/ s5 @ x0 b$ u0 Y
Field Format Extract from the example above
( d7 w2 |7 k) ~+ }; \9 V5 U 1 process_name '[' pid ']:' haproxy[14387]:
1 l/ Y7 e* e5 d7 V 2 client_ip ':' client_port 10.0.1.2:33313
* E0 \" ?6 _/ X; u& x p 3 '[' accept_date ']' [06/Feb/2009:12:12:51.443]5 k) \! a) Z G% U
4 frontend_name fnt
' v9 n4 k$ X, V+ h3 j8 S 5 backend_name '/' server_name bck/srv1
1 e- y1 s1 y, ?2 J9 o 6 Tw '/' Tc '/' Tt* 0/0/5007
9 B2 H* [+ y/ x5 _* c3 u 7 bytes_read* 212) L& k5 s( m# z g
8 termination_state --7 v' h) Z$ f& a. C" d
9 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 0/0/0/0/3! ?7 L, [, h% I6 [' S/ A4 B: ]& z2 X
10 srv_queue '/' backend_queue 0/0- @3 z' A6 T; n
5 f$ Q4 S6 r* d4 IDetailed fields description :- j* i7 T8 ?3 M2 \# k
- "client_ip" is the IP address of the client which initiated the TCP7 d+ Z0 O) H ?0 n/ F$ x8 R
connection to haproxy.
6 f. [3 V) Q; j0 o$ b; P
8 u) [. I9 \ a0 o3 W - "client_port" is the TCP port of the client which initiated the connection.
}: Z. S& O% ~8 j. h3 {4 _' w+ C" I7 {+ y) c3 g5 N5 J! O
- "accept_date" is the exact date when the connection was received by haproxy
' r0 b& z+ R: l! Z* j3 U (which might be very slightly different from the date observed on the" {+ y7 {( {* s+ X1 g
network if there was some queuing in the system's backlog). This is usually
; ?- {. \9 v3 j# t* R the same date which may appear in any upstream firewall's log.. X4 y( v. o8 |1 X3 e' o( p
2 A% l. @$ J r9 C- H
- "frontend_name" is the name of the frontend (or listener) which received* A, f+ u- u, O' M+ o0 K
and processed the connection.: F# [3 }4 L8 o' X. B
. f" {4 T4 M* X' l# ]
- "backend_name" is the name of the backend (or listener) which was selected
% |, y$ Q, r$ h8 D" p7 v to manage the connection to the server. This will be the same as the
" T! l+ B+ |" \8 B+ s4 M; F" ^7 w. S frontend if no switching rule has been applied, which is common for TCP
2 i7 q1 I' Q& Y" l applications.% G/ n: q. v3 N( j) Y0 b
3 F$ r0 ~4 k# U - "server_name" is the name of the last server to which the connection was
6 G4 E) M6 t X5 n; C% Z$ Z sent, which might differ from the first one if there were connection errors
( n) A E' W3 i( O! A* J2 R" f8 I and a redispatch occurred. Note that this server belongs to the backend0 R6 @' E5 g$ z8 V
which processed the request. If the connection was aborted before reaching; a6 w) g- d) x8 o/ I" H
a server, "<NOSRV>" is indicated instead of a server name.$ j h5 Z! J& b
6 i7 \; j6 k5 h' f - "Tw" is the total time in milliseconds spent waiting in the various queues.& `5 ^3 v! ?; X" T! i, S9 }
It can be "-1" if the connection was aborted before reaching the queue.
5 g }- `4 C5 m" F See "Timers" below for more details.; {7 B: O* V1 O' a7 O; F: `# }
; R2 G1 F5 D+ k6 e. {4 g; ]% H9 D8 V - "Tc" is the total time in milliseconds spent waiting for the connection to4 V s' ]! n# v
establish to the final server, including retries. It can be "-1" if the
" n: F% s5 c/ N connection was aborted before a connection could be established. See; K7 L' j. F% S F( _# U, H
"Timers" below for more details.& t. j( W1 W: g* y z
# ? y( @! W$ }3 `1 {
- "Tt" is the total time in milliseconds elapsed between the accept and the
+ B+ r# v% g; @! F4 `3 j- P last close. It covers all possible processings. There is one exception, if5 \. i3 f7 l* e0 U K2 z
"option logasap" was specified, then the time counting stops at the moment
. ^! {/ R4 t$ ^1 v6 h the log is emitted. In this case, a '+' sign is prepended before the value,
4 T$ W7 ?7 o( L3 c; p: h4 Y indicating that the final one will be larger. See "Timers" below for more5 A* E; u; W& N z( ^
details.7 ?4 [9 i9 d4 ~7 ?2 j& c C$ U
/ C2 d: m) d9 r8 m
- "bytes_read" is the total number of bytes transmitted from the server to
5 \3 \ V/ l" O the client when the log is emitted. If "option logasap" is specified, the
1 n6 q% a& l+ S- } {7 Z8 C this value will be prefixed with a '+' sign indicating that the final one5 J& o- L: D) p' \+ \- \
may be larger. Please note that this value is a 64-bit counter, so log. y( [" T, e, @. P4 \
analysis tools must be able to handle it without overflowing.7 F; m* r/ s8 V w5 q3 D6 k: l& G
/ F& b9 e$ \" ^; @1 m - "termination_state" is the condition the session was in when the session
1 J$ w0 Z/ @; J2 L$ ? ended. This indicates the session state, which side caused the end of
, o5 |) Z4 V8 T session to happen, and for what reason (timeout, error, ...). The normal
0 U2 N1 {9 ?7 D% Y- \7 S1 r0 [) c flags should be "--", indicating the session was closed by either end with
7 r; M4 S2 f% F) `3 l no data remaining in buffers. See below "Session state at disconnection"" p+ t! `( z6 X4 {8 P" t: h( a2 T7 F
for more details.
: b- H+ [& d8 H# d3 A. o; N+ O/ i) c1 O2 v) `7 N
- "actconn" is the total number of concurrent connections on the process when
2 V9 K; m% ~! z, {% a6 S the session was logged. It it useful to detect when some per-process system( P, Q9 ~' L8 [- Y
limits have been reached. For instance, if actconn is close to 512 when
# d) q9 v: r) p9 `6 e4 Q multiple connection errors occur, chances are high that the system limits
6 E0 ~# Z) @# v: n. g the process to use a maximum of 1024 file descriptors and that all of them
, E4 C; V4 d* m4 X5 e are used. See section 3 "Global parameters" to find how to tune the system." U7 O+ m# E* [
8 ~/ c9 [9 k+ N2 L) K
- "feconn" is the total number of concurrent connections on the frontend when$ ]1 t1 V, j, {
the session was logged. It is useful to estimate the amount of resource
) v7 K% n) }1 g1 e3 ?' B required to sustain high loads, and to detect when the frontend's "maxconn"& S) x# [0 S& W
has been reached. Most often when this value increases by huge jumps, it is7 i' K3 N3 k3 G1 O- E# A
because there is congestion on the backend servers, but sometimes it can be
( @- ]* p' L2 W% B caused by a denial of service attack.$ [; z9 s6 b% ]3 I
, j$ f8 J- P7 m& M - "beconn" is the total number of concurrent connections handled by the
! Q7 Y2 \- ?. v5 a# v backend when the session was logged. It includes the total number of
$ P( @7 S0 e3 E' a7 g9 T3 Z# e4 E concurrent connections active on servers as well as the number of' U/ Q( A+ e# E2 _
connections pending in queues. It is useful to estimate the amount of
& H i# S' p# b, R. D( t3 c# W b additional servers needed to support high loads for a given application.
3 r S- r8 i3 V Most often when this value increases by huge jumps, it is because there is
6 v# p) U1 e' j congestion on the backend servers, but sometimes it can be caused by a
" s0 p# A+ }" P7 M X! p denial of service attack.
# i/ w9 G; o8 _& X: I! ^* I: ?
8 `7 V a$ ?7 `5 _0 v - "srv_conn" is the total number of concurrent connections still active on' R$ Y* x2 k! J; P
the server when the session was logged. It can never exceed the server's
+ S4 W- K8 h: k" ] configured "maxconn" parameter. If this value is very often close or equal
# j4 U; @4 _. ?5 \ to the server's "maxconn", it means that traffic regulation is involved a
2 U6 r$ ~) ]7 V lot, meaning that either the server's maxconn value is too low, or that2 J5 B8 c; [. D
there aren't enough servers to process the load with an optimal response9 H9 o' i. N! C% {
time. When only one of the server's "srv_conn" is high, it usually means
" W, G8 O# A# s. g# l# F that this server has some trouble causing the connections to take longer to8 a& I/ Y$ D4 b1 V& W' h
be processed than on other servers.
' `1 S* r! S9 A/ U2 j0 H* H1 W
X5 q4 @% R' q( N- C E- l# }( k - "retries" is the number of connection retries experienced by this session
% a2 D+ x7 Q4 [# l( {% { when trying to connect to the server. It must normally be zero, unless a4 W4 g# J. @6 |# M
server is being stopped at the same moment the connection was attempted.+ _) }; W* ^4 ?( h) v
Frequent retries generally indicate either a network problem between) i8 i: H) O/ ?3 D8 J
haproxy and the server, or a misconfigured system backlog on the server
! y4 B& w3 v: F9 ]& v+ f' B preventing new connections from being queued. This field may optionally be) ]# V$ K( x! m1 x* g
prefixed with a '+' sign, indicating that the session has experienced a2 M2 n6 w( L% x: {* H. x7 c- d D
redispatch after the maximal retry count has been reached on the initial
2 N2 N# F3 R3 a) V4 ?2 E$ r server. In this case, the server name appearing in the log is the one the, @7 u$ L+ g& t
connection was redispatched to, and not the first one, though both may
* x7 S/ j9 N+ A1 U) f' K sometimes be the same in case of hashing for instance. So as a general rule
6 ^& K% i* Z. K/ U of thumb, when a '+' is present in front of the retry count, this count
8 z8 l2 _- ]+ s1 L$ j( v" X9 J should not be attributed to the logged server.
$ f( N& ~+ E4 o. I
/ ?* k- q/ N. T6 ?! R8 P! D& l# } - "srv_queue" is the total number of requests which were processed before
]2 r8 e1 s+ s this one in the server queue. It is zero when the request has not gone
8 Q2 i3 l. {8 x+ A5 h9 e R through the server queue. It makes it possible to estimate the approximate1 p5 P) O- Y% `! Q: Z
server's response time by dividing the time spent in queue by the number of. B- o; c) v6 ?1 L8 `
requests in the queue. It is worth noting that if a session experiences a, X2 j3 o7 |5 A3 q1 N
redispatch and passes through two server queues, their positions will be6 ^% s% a' ?# r3 s: s& t: B
cumulated. A request should not pass through both the server queue and the
- N# J( P/ x! E) q5 K6 o: D" x backend queue unless a redispatch occurs. A* }% r3 ^4 R) Y& h& \
3 ?( y0 Y( h: U: M0 w1 o - "backend_queue" is the total number of requests which were processed before F/ k& H- S, u/ W5 o& e9 o1 K2 U3 Q
this one in the backend's global queue. It is zero when the request has not" z3 @' z' o$ `) o3 C6 z
gone through the global queue. It makes it possible to estimate the average T5 Q! k( j3 q" @# a' j
queue length, which easily translates into a number of missing servers when
0 g: z0 K9 k$ Z4 v( [ divided by a server's "maxconn" parameter. It is worth noting that if a! }& R5 c; n! \
session experiences a redispatch, it may pass twice in the backend's queue,! f l2 C8 w1 F; `2 y9 [( i$ W6 m
and then both positions will be cumulated. A request should not pass
( w0 A$ t8 V! T9 m through both the server queue and the backend queue unless a redispatch9 i! J+ c3 Z3 B! K. U
occurs.7 N2 F1 E6 E* N" N/ h9 F" |7 L6 B
% T" n8 A3 V* ?8 O8 ?3 |1 F
) r: j O3 y" O i8.2.3. HTTP log format8 Y3 A, m0 `6 R2 f' ^* h; d) H2 b
----------------------+ m7 K8 \# r n8 F( t1 s0 G
; |1 o5 ]- s# OThe HTTP format is the most complete and the best suited for HTTP proxies. It
! i: r6 O! b8 j9 ~8 q% ais enabled by when "option httplog" is specified in the frontend. It provides
2 ?7 T5 B( e* q; ]the same level of information as the TCP format with additional features which
$ E K( z* C' ware specific to the HTTP protocol. Just like the TCP format, the log is usually
; y( Z8 M2 w C4 t" Hemitted at the end of the session, unless "option logasap" is specified, which
. k2 ?) m+ F7 g1 _& r8 ]generally only makes sense for download sites. A session which matches the0 ]" y @3 Y' l# _' y& l& ~. z; X
"monitor" rules will never logged. It is also possible not to log sessions for" m6 \4 N+ ^" e/ d' f
which no data were sent by the client by specifying "option dontlognull" in the
" x H$ L; A! | Gfrontend. Successful connections will not be logged if "option dontlog-normal"6 V: g0 `3 \( j, R5 N
is specified in the frontend.
/ m. Y, {2 H6 z }4 ~
0 [, U- J) q2 v$ sMost fields are shared with the TCP log, some being different. A few fields may
" x/ r( O' M" w! h! k( F* C8 Cslightly vary depending on some configuration options. Those ones are marked
4 v9 y. M$ _/ O1 vwith a star ('*') after the field name below.* P7 R- n) j. h r
: M- N* a4 C" M5 h& f9 l x
Example :
; _* R T0 D! B7 j: x frontend http-in4 X0 D: G7 d/ }$ a/ c& \1 `
mode http% m. e! A3 W- B I4 O
option httplog" S: P' k* x8 G* J* y6 a4 X
log global; L9 O: q, a- x- ]5 H" X
default_backend bck
1 k' R6 [/ [, v( @4 q3 i+ m. J' F( R: |
backend static
0 i1 {2 {8 ?* W server srv1 127.0.0.1:80007 n* r9 s2 s) [* Y6 ^ P6 o* i
& R1 I/ R9 h2 B; M7 {4 D0 y8 ^ >>> Feb 6 12:14:14 localhost \
4 g! V; A& N& s# e3 t haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \6 _% ?2 |, f: V3 }, s P i. ~
static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \% X& Y/ }" s" \7 ]8 d( c
{} "GET /index.html HTTP/1.1"6 ]( J9 q8 r5 P" X
0 A( @% R2 ]. S
Field Format Extract from the example above
/ g/ F2 i- l3 `; K/ p! y 1 process_name '[' pid ']:' haproxy[14389]:
1 \3 u8 o, z/ ?7 W 2 client_ip ':' client_port 10.0.1.2:33317
6 x |8 V, Q3 ]5 R. T 3 '[' accept_date ']' [06/Feb/2009:12:14:14.655]; b1 [% ~/ A2 ]4 [7 ~0 }$ g9 F3 q
4 frontend_name http-in
) V4 d7 K1 ^ i# j$ \& ^ 5 backend_name '/' server_name static/srv18 P4 w7 t+ r3 w( A3 v6 T# @
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt* 10/0/30/69/1094 Z/ p% |6 X* W; ^( V8 H* A
7 status_code 2008 S( y6 |! g5 G! _1 ~
8 bytes_read* 2750
Y9 k4 y( F$ Z- ?* n0 l 9 captured_request_cookie -$ v0 t- A9 f, {6 K& m
10 captured_response_cookie -
" j& r3 K( h3 r" D 11 termination_state ----& N* A2 [$ U! S0 W3 A
12 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 1/1/1/1/0
3 B/ l) [4 w% b 13 srv_queue '/' backend_queue 0/0, q6 P- Y9 `" N
14 '{' captured_request_headers* '}' {haproxy.1wt.eu}8 ?3 L: }0 J* u6 x/ H1 n
15 '{' captured_response_headers* '}' {}
: I* i' l5 U) I5 o6 L: J& M 16 '"' http_request '"' "GET /index.html HTTP/1.1"6 X- I1 n |4 i" @/ k
1 t: t; k0 }* `
! x" b- {) w# sDetailed fields description :
. V& M7 h4 ~# q1 m - "client_ip" is the IP address of the client which initiated the TCP) s2 V4 ~' R' s% V% @5 _8 P: V
connection to haproxy.
% I6 n7 L$ S3 ?( G2 s/ p6 ~- F% `! v2 x" l& w' M
- "client_port" is the TCP port of the client which initiated the connection.9 a: w: S. H, G. V
: P3 Z+ _& W, { - "accept_date" is the exact date when the TCP connection was received by1 f$ @8 ~# d/ Y) C+ q- H
haproxy (which might be very slightly different from the date observed on
3 e" {# A2 L, P. ~, _! {$ U the network if there was some queuing in the system's backlog). This is
( @0 ^- C# m4 V; ]4 m- P usually the same date which may appear in any upstream firewall's log. This
+ O! I9 ?. v1 e! u# j( W+ E does not depend on the fact that the client has sent the request or not.1 Y1 |( |! h# w0 w
$ q# e( s- K0 c X5 {- w4 F
- "frontend_name" is the name of the frontend (or listener) which received5 a; `, J" I4 W9 |6 y5 G1 y
and processed the connection.
8 x. |6 c* t/ D4 F0 \
0 c* p$ Y, |8 n+ X - "backend_name" is the name of the backend (or listener) which was selected
# ]. h3 p( r* [2 Z2 k to manage the connection to the server. This will be the same as the& d9 B9 D! |- k9 z* T2 @
frontend if no switching rule has been applied.
+ W, g$ K2 b0 N
( b- H$ ~2 _- F% Y; j2 v - "server_name" is the name of the last server to which the connection was
- m: m) h: {+ J/ G sent, which might differ from the first one if there were connection errors: a- P7 G, \0 [$ k: p) w0 `6 n
and a redispatch occurred. Note that this server belongs to the backend
" Y+ o1 _) C/ w; e) _& k which processed the request. If the request was aborted before reaching a/ b% O$ D# m. q
server, "<NOSRV>" is indicated instead of a server name. If the request was0 {' |: C- m0 F0 F
intercepted by the stats subsystem, "<STATS>" is indicated instead. \ {2 X# F3 h
V/ M% F0 r6 F - "Tq" is the total time in milliseconds spent waiting for the client to send
4 g- o; }- } f4 Y. d0 W a full HTTP request, not counting data. It can be "-1" if the connection
+ ~+ r0 E4 Y% [% e! O3 f was aborted before a complete request could be received. It should always
4 ]+ t7 ?! J& _+ o be very small because a request generally fits in one single packet. Large
9 F( d0 T( H% M. \! G+ O times here generally indicate network trouble between the client and
1 r* b7 D' X3 L4 p haproxy. See "Timers" below for more details.
: o) s4 U1 w8 C% S' V, m# i* N
+ K4 i. ]2 j I6 m9 N - "Tw" is the total time in milliseconds spent waiting in the various queues.8 i4 a/ S$ L5 K1 F2 X+ X- X! n* I
It can be "-1" if the connection was aborted before reaching the queue.
" Z) n! }9 O$ W) x/ R% X6 V! c See "Timers" below for more details.- d: ~- c7 f" Y0 W
4 A; `$ ` _* G3 O) ]
- "Tc" is the total time in milliseconds spent waiting for the connection to
7 N, U. _; R" n6 d2 ^ establish to the final server, including retries. It can be "-1" if the- T& ~5 |5 n# M- M" @
request was aborted before a connection could be established. See "Timers"" H/ h8 Z8 t; y$ P
below for more details.* v, n9 p2 C9 _( v) r, R
0 A: F9 G& E4 N* w
- "Tr" is the total time in milliseconds spent waiting for the server to send
3 ~1 t% e$ u7 @- c6 Y a full HTTP response, not counting data. It can be "-1" if the request was
1 B r) I e/ c' l2 m' K' f; F aborted before a complete response could be received. It generally matches( U2 w/ Q) r# q7 K& G0 A8 F
the server's processing time for the request, though it may be altered by- i! q0 V( W7 J
the amount of data sent by the client to the server. Large times here on
; a4 U" C/ S4 w: S "GET" requests generally indicate an overloaded server. See "Timers" below
& n2 c! N g4 V for more details.
' B9 i& z3 m2 v+ e- A. n% j# m* B. M: N) D7 Z
- "Tt" is the total time in milliseconds elapsed between the accept and the1 [. ^6 D* _0 v5 _6 U" x8 Q: F+ _- {
last close. It covers all possible processings. There is one exception, if# n% j" M) V0 R6 H* T' ^3 q$ k
"option logasap" was specified, then the time counting stops at the moment9 k* \/ o& V6 B7 Q
the log is emitted. In this case, a '+' sign is prepended before the value,% E8 L2 A3 w6 p* P
indicating that the final one will be larger. See "Timers" below for more- B% P: K! A, i: m8 ]. X
details.
4 U4 f7 c! z5 b/ J/ t5 L+ |& u
; R. }" K4 Q5 x- M - "status_code" is the HTTP status code returned to the client. This status9 t: m5 E, P% }2 P
is generally set by the server, but it might also be set by haproxy when' D) ?* s7 q8 R" [0 Y$ m
the server cannot be reached or when its response is blocked by haproxy.0 C$ x7 N+ x" M$ ^- u, j3 S* g
- r+ Z. K' l! S5 i5 n; y
- "bytes_read" is the total number of bytes transmitted to the client when
0 c; w; F, ^' ^: d the log is emitted. This does include HTTP headers. If "option logasap" is1 y2 M U# L4 B4 s
specified, the this value will be prefixed with a '+' sign indicating that% g) v3 M C" N8 r8 q
the final one may be larger. Please note that this value is a 64-bit* Z r' ~4 H4 b
counter, so log analysis tools must be able to handle it without
! A1 G* u* _. ~8 L: p overflowing.
; e5 N+ z6 d+ U5 A; Z, `
# k0 D+ z; K. F' l3 E. `* x" Z - "captured_request_cookie" is an optional "name=value" entry indicating that4 b' `( S$ m5 a$ H8 ^! L
the client had this cookie in the request. The cookie name and its maximum
( j+ ~2 W- H& X3 ~3 T length are defined by the "capture cookie" statement in the frontend% X5 t3 e: M& V: u
configuration. The field is a single dash ('-') when the option is not
8 B. E) [7 L3 I set. Only one cookie may be captured, it is generally used to track session' P' [6 c8 M+ ~+ Y; o
ID exchanges between a client and a server to detect session crossing
% I' t$ K, u4 f- B! g between clients due to application bugs. For more details, please consult6 S9 f9 L+ k2 E5 g% {: d
the section "Capturing HTTP headers and cookies" below.
\3 _/ G/ @$ G# x4 [: i: i2 n' d3 Z5 r* [6 S. N. I$ c
- "captured_response_cookie" is an optional "name=value" entry indicating' y8 q. P l9 m6 C8 ` R3 _
that the server has returned a cookie with its response. The cookie name
( E x# W x6 a9 T. u5 i+ n and its maximum length are defined by the "capture cookie" statement in the- M# O# H2 Y( W, L6 t7 k6 f# p/ [2 r
frontend configuration. The field is a single dash ('-') when the option is
( k+ S: n0 a/ N+ P& p! s7 n$ | not set. Only one cookie may be captured, it is generally used to track
4 C' p/ M! G; e# |$ K session ID exchanges between a client and a server to detect session/ w" V( V/ j2 T6 o
crossing between clients due to application bugs. For more details, please
4 _6 X2 Y2 I7 I. g- @5 Y consult the section "Capturing HTTP headers and cookies" below.$ v7 y" I' h: M" {! n( B
. d1 _& m( r3 `' |1 L* ?) u - "termination_state" is the condition the session was in when the session% f4 t" A8 t, t6 t- O$ H1 a
ended. This indicates the session state, which side caused the end of: V) I3 V. h3 K# x* {; a. b
session to happen, for what reason (timeout, error, ...), just like in TCP
1 p5 s& X/ C* K/ G2 N3 V logs, and information about persistence operations on cookies in the last
& o9 x. M3 H% ~: |* W# {- g: O+ _ two characters. The normal flags should begin with "--", indicating the
g! X; x% L$ u3 X7 c! H session was closed by either end with no data remaining in buffers. See$ u' [9 B2 k' J" S9 t# w0 u
below "Session state at disconnection" for more details.8 m V( z! [9 a. F
, z- s W# g" K8 L( ]! A0 L - "actconn" is the total number of concurrent connections on the process when1 Y" m" t6 y' c* E& N
the session was logged. It it useful to detect when some per-process system* k" p @( G2 G6 h& v' N& U
limits have been reached. For instance, if actconn is close to 512 or 1024" a5 \/ j2 L/ L' r
when multiple connection errors occur, chances are high that the system
0 [2 Q8 N3 ]0 @/ n limits the process to use a maximum of 1024 file descriptors and that all
$ M( Q1 G$ g8 _! l" a3 R of them are used. See section 3 "Global parameters" to find how to tune the+ c3 S) `1 s9 [/ H# A
system.) E+ x5 K3 ~( ^: v* T* ?3 v# S
1 i8 w$ W" \; w2 j) I2 q
- "feconn" is the total number of concurrent connections on the frontend when1 k' t2 V V, N( {# Y: C% I0 A2 l
the session was logged. It is useful to estimate the amount of resource" l, V$ }+ l* W; }
required to sustain high loads, and to detect when the frontend's "maxconn"( A% _8 t: B- W; n
has been reached. Most often when this value increases by huge jumps, it is
- M2 u* X5 w* U6 q8 L; D+ }) S because there is congestion on the backend servers, but sometimes it can be1 ?7 H0 |, C% B4 U$ \2 s
caused by a denial of service attack.+ p- V* u5 y5 Q; `" p- W1 q
% p/ o# f8 C! R- S% e4 e - "beconn" is the total number of concurrent connections handled by the
- N3 Q+ k/ f" U1 l8 c9 \* d backend when the session was logged. It includes the total number of3 L2 F6 M7 ~( `3 w
concurrent connections active on servers as well as the number of- Z5 L6 l* Z- k8 R4 a7 N0 x* N
connections pending in queues. It is useful to estimate the amount of4 S# x5 F6 B$ @- l- G
additional servers needed to support high loads for a given application.
: g2 m; J+ z3 ^7 U3 A$ q1 O$ E- _ Most often when this value increases by huge jumps, it is because there is) k3 ^2 s; C# S5 _
congestion on the backend servers, but sometimes it can be caused by a
f" g. v3 v/ |) ]+ l9 f. ~" l denial of service attack.: k( b* S( m+ v6 f E) ^ V
. Z% S: i+ X6 z' \9 V: V
- "srv_conn" is the total number of concurrent connections still active on: c1 y2 {/ N# i
the server when the session was logged. It can never exceed the server's$ T! d- S- s, \- U5 C# H% K: F, R
configured "maxconn" parameter. If this value is very often close or equal7 F/ a, v; P) p2 d
to the server's "maxconn", it means that traffic regulation is involved a6 C! g( E9 M! {! e; m3 N4 k
lot, meaning that either the server's maxconn value is too low, or that
( e: ^7 }. T) k" h1 ^ C there aren't enough servers to process the load with an optimal response& @! e C, Q% v% u
time. When only one of the server's "srv_conn" is high, it usually means$ H4 n; T4 l& R6 A, Y- j
that this server has some trouble causing the requests to take longer to be* b% e$ q( V4 x4 B# R; h
processed than on other servers.
Z) X7 \6 G( Y2 P' s. a* A
; ^+ c! G! q C$ j3 [# y - "retries" is the number of connection retries experienced by this session* P2 r; f [% q- t% J+ B
when trying to connect to the server. It must normally be zero, unless a$ ?. J1 Q$ K# o; n* b
server is being stopped at the same moment the connection was attempted.7 C+ i; I" g" e$ {
Frequent retries generally indicate either a network problem between; x: D r/ t- q5 T( @; P/ H/ g
haproxy and the server, or a misconfigured system backlog on the server
; c2 G. X v4 |- ~2 D8 { preventing new connections from being queued. This field may optionally be
. I% c* n' C/ Z prefixed with a '+' sign, indicating that the session has experienced a
( J5 a7 o! p. i5 N+ \- |! | redispatch after the maximal retry count has been reached on the initial
3 k. {% C. K" u" p' m/ \# I server. In this case, the server name appearing in the log is the one the
4 ~$ ~1 n I9 b) M1 k( l: C connection was redispatched to, and not the first one, though both may
7 F4 ^% e9 Y' T& N/ ~" s6 j9 V sometimes be the same in case of hashing for instance. So as a general rule
; m$ f0 K* p9 h# N& } of thumb, when a '+' is present in front of the retry count, this count' |/ S5 ^4 t. g+ i6 `
should not be attributed to the logged server.
5 `* L0 w2 }4 O' y& k
" [# l7 o& P/ i$ [0 u7 Q - "srv_queue" is the total number of requests which were processed before. i; b% H- j1 l8 o* v5 M
this one in the server queue. It is zero when the request has not gone
& ^' {* y* B+ C. Z6 w" s* s5 I through the server queue. It makes it possible to estimate the approximate4 \: X) ?2 X- S5 _) Q
server's response time by dividing the time spent in queue by the number of& E4 m: E, W3 r! r
requests in the queue. It is worth noting that if a session experiences a
9 P' e) S1 G; }% N; D% Y5 K redispatch and passes through two server queues, their positions will be. B6 D8 D1 B2 o$ ~4 v
cumulated. A request should not pass through both the server queue and the
8 X( T5 ]$ s& R3 k' B7 N* [, ]( l0 C backend queue unless a redispatch occurs.
: G% T$ K2 x, ^& {$ k( `4 u3 T3 K- W6 h3 i( T
- "backend_queue" is the total number of requests which were processed before
7 S9 P2 `( Z6 a# V this one in the backend's global queue. It is zero when the request has not
1 k' \4 L4 U3 }6 V; @ gone through the global queue. It makes it possible to estimate the average
2 _" V# b* V. O' R queue length, which easily translates into a number of missing servers when* _+ D9 p. J0 X+ T0 w
divided by a server's "maxconn" parameter. It is worth noting that if a0 N$ W' z6 |2 w
session experiences a redispatch, it may pass twice in the backend's queue,
2 ?9 Q4 Z1 w9 G& b* \2 z- T0 @ and then both positions will be cumulated. A request should not pass4 t0 f7 u; v7 t/ d- ^
through both the server queue and the backend queue unless a redispatch
: C" S- o7 |& z2 r occurs.' ?; f- ~9 _3 f
& V1 m8 n6 i1 m0 j8 ?* G- k
- "captured_request_headers" is a list of headers captured in the request due
0 ~1 }: J& ^( y% {/ O! u0 u2 P to the presence of the "capture request header" statement in the frontend.
' C1 l; k* A& ?' G Multiple headers can be captured, they will be delimited by a vertical bar
/ Y% i$ ~0 ^& t2 i ('|'). When no capture is enabled, the braces do not appear, causing a: C! r1 f. A. k# |6 s" W7 b
shift of remaining fields. It is important to note that this field may
* U2 y9 f& ]9 _$ O, I contain spaces, and that using it requires a smarter log parser than when
3 T2 \/ E" e, z/ ~ it's not used. Please consult the section "Capturing HTTP headers and! J) O& j5 I t' ]* j
cookies" below for more details.- p# U9 D7 { t" V5 t, Q4 e/ y. G
8 j7 P/ M K( a+ ? i K/ M - "captured_response_headers" is a list of headers captured in the response, v+ v a0 d+ u
due to the presence of the "capture response header" statement in the
6 I5 s. Q4 q- p frontend. Multiple headers can be captured, they will be delimited by a; o! |- v6 h" V* M& G& ^+ F" X
vertical bar ('|'). When no capture is enabled, the braces do not appear,
; \3 @0 k! y+ s9 w: \ causing a shift of remaining fields. It is important to note that this
# H+ B( u2 V+ O7 g. p- s field may contain spaces, and that using it requires a smarter log parser5 h1 C) s+ y* |- U" ]# O
than when it's not used. Please consult the section "Capturing HTTP headers
/ a5 f4 ~1 X0 C3 r$ A: D and cookies" below for more details.
$ ^% ~ N7 V# j2 c: n+ e! s" l
- "http_request" is the complete HTTP request line, including the method,, \9 ^; K9 @ Z: w0 @5 G9 T
request and HTTP version string. Non-printable characters are encoded (see* r `) s# G- I9 \$ r
below the section "Non-printable characters"). This is always the last
# X7 Y* G7 S7 }% Y field, and it is always delimited by quotes and is the only one which can6 E3 r! u* N' L1 C4 A, ?9 o
contain quotes. If new fields are added to the log format, they will be- m3 H! a4 f3 z0 J3 J
added before this field. This field might be truncated if the request is
: i& B* Q4 c2 I" n/ p" J' X: z huge and does not fit in the standard syslog buffer (1024 characters). This
! S8 ]: Y5 T7 A6 ? S is the reason why this field must always remain the last one.
" B! p0 N* y0 B, |% U! r! z! ^5 D2 p d, |% V
$ }4 p, I- S5 d0 C# q3 I! b! y5 L6 C8.3. Advanced logging options4 y7 n2 v4 A% L
-----------------------------$ t' O2 J) c7 l; m
& u0 y& ~- E, _% x+ F" |2 KSome advanced logging options are often looked for but are not easy to find out
/ N$ W1 n: C/ C. E$ [1 t2 r3 |just by looking at the various options. Here is an entry point for the few
$ P* B5 k0 Y) T" r" u' Loptions which can enable better logging. Please refer to the keywords reference w8 T6 L4 l* _: [6 T
for more information about their usage.5 Q. U7 o4 w1 h( P( N: |
5 u; e- h. c' m0 `" ?1 I O5 P! U
, t0 B2 d! c" d* I1 i5 E8.3.1. Disabling logging of external tests
3 Z4 | P+ T6 A4 n------------------------------------------5 q" n/ U9 t; j
4 T# K9 N( X2 P- q* T. P/ {1 BIt is quite common to have some monitoring tools perform health checks on# ^1 O4 D( |. {( a0 Z8 _
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any( X! @0 o/ b5 @( Y; ~; g
commercial load-balancer, and sometimes it will simply be a more complete4 Z ~. m! K* Y1 T O- J
monitoring system such as Nagios. When the tests are very frequent, users often# C; a9 L( U5 ~# s
ask how to disable logging for those checks. There are three possibilities :1 P- F9 J' ^) j( D. H) l
4 _+ h( i( R) s0 U. {$ B! {4 y/ f - if connections come from everywhere and are just TCP probes, it is often
9 G) B6 S+ H+ O+ w- C- F ] desired to simply disable logging of connections without data exchange, by
$ Z/ l! J0 h% _2 Z setting "option dontlognull" in the frontend. It also disables logging of
- P+ x% E7 @- L; T$ A port scans, which may or may not be desired.
1 h3 M2 E9 [" @7 l3 v7 M! [$ G. G
) |& Q3 `! p* ~1 H; [1 v4 ^ - if the connection come from a known source network, use "monitor-net" to
2 A: B& V5 m! e4 V- ?3 ^( j- i" l! k declare this network as monitoring only. Any host in this network will then7 a; F, S+ s. m7 |) ?/ D1 I
only be able to perform health checks, and their requests will not be& r% M' h- J7 T, E
logged. This is generally appropriate to designate a list of equipments1 J: W& i, Z4 M5 Y6 Z7 k" \' X7 w
such as other load-balancers.
1 I/ H x# M, I, S( ~
; J& z7 A J* G" w' ^ - if the tests are performed on a known URI, use "monitor-uri" to declare
]3 v1 S |) U# H this URI as dedicated to monitoring. Any host sending this request will
+ a* p8 G" x, m+ H& P/ M: n1 C5 `; q only get the result of a health-check, and the request will not be logged.
% k0 l9 Z/ D$ C0 w0 s' K B9 J1 L/ l s2 C# o' p& s
- @6 `: h3 x" O8.3.2. Logging before waiting for the session to terminate3 H+ W$ K7 c4 B6 h0 e4 `
----------------------------------------------------------1 q; _- J* \; s
; h4 \7 [1 ?# J! W$ u+ yThe problem with logging at end of connection is that you have no clue about- s& L+ A% T* w
what is happening during very long sessions, such as remote terminal sessions7 D8 q( w, |! Z, m$ U
or large file downloads. This problem can be worked around by specifying
6 D* ~; o, K- }"option logasap" in the frontend. Haproxy will then log as soon as possible,
8 b% _+ ` ]6 V: L0 zjust before data transfer begins. This means that in case of TCP, it will still
& N8 U5 B# r1 |" O3 R$ C+ r `log the connection status to the server, and in case of HTTP, it will log just! O) K" | `; I1 ^1 B2 l
after processing the server headers. In this case, the number of bytes reported
: |- |7 f3 W1 G( m/ H1 Xis the number of header bytes sent to the client. In order to avoid confusion4 i- q3 k+ T/ F. x
with normal logs, the total time field and the number of bytes are prefixed5 R+ }, ?2 w7 e6 P& D7 |' E& d1 O
with a '+' sign which means that real numbers are certainly larger.
" e! d8 q/ |( d% F! a
/ p) f% c0 L* m1 V# F
1 l2 B y5 A9 ]- |% K3 ?3 s. ^8.3.3. Raising log level upon errors
; a ^( ?6 Z1 w------------------------------------! w! r8 d' i E7 K# \% Q! q
% B: [+ {4 f! ~6 o- c8 G/ {( aSometimes it is more convenient to separate normal traffic from errors logs,. i% j" ]1 W9 ^& ?& N
for instance in order to ease error monitoring from log files. When the option3 f2 u- B2 ]& @* q
"log-separate-errors" is used, connections which experience errors, timeouts,; w8 t* w. N% y% [
retries, redispatches or HTTP status codes 5xx will see their syslog level6 l+ e. Y: b6 W! S' w
raised from "info" to "err". This will help a syslog daemon store the log in p; Y/ W l6 {
a separate file. It is very important to keep the errors in the normal traffic$ N( ?1 e9 v4 k4 m0 F! s2 K2 {
file too, so that log ordering is not altered. You should also be careful if
1 e q$ c* `. Xyou already have configured your syslog daemon to store all logs higher than
- G" B6 ?8 M# y& B* Y% j"notice" in an "admin" file, because the "err" level is higher than "notice".3 ?% O4 ^% v$ C) g
7 l7 K7 x+ d8 f2 Y- y
& J* e- n- n7 I. j3 @- q8.3.4. Disabling logging of successful connections
. \+ h+ C0 b `2 X--------------------------------------------------& D# E6 ^2 g4 _
7 V; _: m4 z0 E/ `Although this may sound strange at first, some large sites have to deal with
" n; I( s3 s. Pmultiple thousands of logs per second and are experiencing difficulties keeping
: H6 U7 m/ z, A7 `: T/ g! othem intact for a long time or detecting errors within them. If the option
8 [5 E8 E+ V3 b; @! N"dontlog-normal" is set on the frontend, all normal connections will not be
5 |) z+ N% n+ E( b/ ~/ r8 b5 Hlogged. In this regard, a normal connection is defined as one without any
7 P9 R# ]4 x8 x8 V: O1 q5 ierror, timeout, retry nor redispatch. In HTTP, the status code is checked too,
: E7 G3 \' A/ H j ^9 N4 Q+ D( ?and a response with a status 5xx is not considered normal and will be logged* B. T: A! \! b5 a+ m
too. Of course, doing is is really discouraged as it will remove most of the0 R2 G& M6 X% X5 q0 z
useful information from the logs. Do this only if you have no other( n0 f5 m; ^: u8 Q/ C6 ~. @
alternative.
4 o7 r$ H# [. j; O7 C7 }% T; O3 l. Z' q, G
9 X/ p% I5 d3 r1 F+ r: N- h* G
8.4. Timing events6 N6 c9 F `% ^) P3 \
------------------/ t& l7 b9 {4 b- H: b5 t( h- I8 ~7 V
0 F4 I1 A5 M3 RTimers provide a great help in troubleshooting network problems. All values are7 Y; z" Y. q# m4 W+ v. q6 W( P
reported in milliseconds (ms). These timers should be used in conjunction with- ^ B h+ i: P9 ~: D
the session termination flags. In TCP mode with "option tcplog" set on the
0 M! d" C, _2 J4 v0 L4 H$ ]frontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP0 a/ S8 x: M% T7 v# d
mode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :
h- E- Q3 w3 v4 `
4 o$ [/ B8 B$ t, i7 \ - Tq: total time to get the client request (HTTP mode only). It's the time) A' C" r; q/ @7 ~# X
elapsed between the moment the client connection was accepted and the Q) n) E0 v, q' o- G4 m. f1 J" w
moment the proxy received the last HTTP header. The value "-1" indicates, m% N8 d6 c2 n' S' m! T
that the end of headers (empty line) has never been seen. This happens when# { k+ T4 `' b
the client closes prematurely or times out.; P8 g8 b' ^3 l4 G9 V% [, w& l
% U, a% b. y& [/ [3 Y! G# h+ g - Tw: total time spent in the queues waiting for a connection slot. It5 P# X8 y2 s4 l. d3 B+ g" p6 |, C
accounts for backend queue as well as the server queues, and depends on the
' B! A0 r6 M: h: G queue size, and the time needed for the server to complete previous
" k6 ~( [# [$ D3 m requests. The value "-1" means that the request was killed before reaching. V5 p2 C9 M: Q9 n
the queue, which is generally what happens with invalid or denied requests.% M+ z( C3 e: b
. C9 f+ x' B8 F% f/ w v6 Q4 x, D& ^
- Tc: total time to establish the TCP connection to the server. It's the time
" K; d3 g, e1 n4 t7 ? elapsed between the moment the proxy sent the connection request, and the
, M) i! n# h, @* t* \ moment it was acknowledged by the server, or between the TCP SYN packet and
: k* K. A9 g5 z, c3 j7 _" l the matching SYN/ACK packet in return. The value "-1" means that the9 C* e' n; o# S \
connection never established.8 J, r: f( Y5 l) K1 v d C
8 a3 T4 j8 V$ O4 |2 [
- Tr: server response time (HTTP mode only). It's the time elapsed between+ V% W7 c) y7 ^, b0 v
the moment the TCP connection was established to the server and the moment! B9 w8 M$ t7 j! ]; g! w
the server sent its complete response headers. It purely shows its request% d E! x! d6 E& c
processing time, without the network overhead due to the data transmission.5 e3 `0 G$ {3 A! c+ G2 y) k
It is worth noting that when the client has data to send to the server, for" l: x% d& V' G/ c5 u
instance during a POST request, the time already runs, and this can distort1 h: k( R1 R8 `& |+ e
apparent response time. For this reason, it's generally wise not to trust
. i$ M) X% w& w/ J8 M9 C too much this field for POST requests initiated from clients behind an
2 ^+ @: \- l/ l5 W- |! g6 E untrusted network. A value of "-1" here means that the last the response+ e" G0 J3 R+ R* |
header (empty line) was never seen, most likely because the server timeout: J; K( n$ ^1 K! l) q8 Z# l, u. T
stroke before the server managed to process the request.
! q3 w$ o3 J4 m/ E
: A7 [+ g" h' L! q - Tt: total session duration time, between the moment the proxy accepted it
, X1 X$ O5 n, H2 |+ I* Q, e* I and the moment both ends were closed. The exception is when the "logasap"
6 ]6 V% b; f" j3 W; c9 o5 ?8 E option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
5 ~: r. {; m$ x' h- Z, p- }/ J prefixed with a '+' sign. From this field, we can deduce "Td", the data+ D0 s5 K& Z4 a
transmission time, by substracting other timers when valid :
G' Q$ |1 ?. ~/ C$ k( }2 V
) W5 Q2 l! t; i( |5 f% {/ F9 y+ N% r( v Td = Tt - (Tq + Tw + Tc + Tr)
) N; u4 c4 G7 s* o) f, m, g6 c
Timers with "-1" values have to be excluded from this equation. In TCP
: u( S+ {0 {1 C. w- T) q3 y1 p mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be: ~9 F5 M" C' C
negative.6 d' D ?$ Y' H! J' |
3 C$ m+ G' H7 i: ZThese timers provide precious indications on trouble causes. Since the TCP+ t2 Q: c# }2 q% T3 ^" T0 C
protocol defines retransmit delays of 3, 6, 12... seconds, we know for sure! A+ r# C7 w5 Y; e. ~) i
that timers close to multiples of 3s are nearly always related to lost packets
; ^0 Z0 C4 H2 w) Cdue to network problems (wires, negotiation, congestion). Moreover, if "Tt" is9 w6 j' P; V6 Y6 ]0 v! V5 _2 P7 N
close to a timeout value specified in the configuration, it often means that a- G+ x' F- I: \ o/ C/ s
session has been aborted on timeout.' q. m- e& b. T) X- J% V
/ F8 ~6 T4 M) m" W' u( z3 D
Most common cases :
! G8 l/ [3 Y& n% p2 b
: `9 s, O) w, L( ~% f: V - If "Tq" is close to 3000, a packet has probably been lost between the: ^. C! ^, h3 ^/ V4 |2 `4 {9 V
client and the proxy. This is very rare on local networks but might happen
G" X) p! u8 J [5 H when clients are on far remote networks and send large requests. It may# D( s- O S8 U9 [9 l
happen that values larger than usual appear here without any network cause.
M" g. m, j( s# P; Q" T Sometimes, during an attack or just after a resource starvation has ended,9 f8 w2 W: Y/ ]% s% Y# [
haproxy may accept thousands of connections in a few milliseconds. The time% ~% e6 @% ~" G; y$ l; C8 ^
spent accepting these connections will inevitably slightly delay processing
: p8 N- @" z, K. P% V! v+ j of other connections, and it can happen that request times in the order of7 Z4 Q6 f( V% |) g
a few tens of milliseconds are measured after a few thousands of new: t2 p1 J! F$ S; V% X: Q0 v
connections have been accepted at once. Setting "option http-server-close"& N4 _1 b+ ?: a/ |
may display larger request times since "Tq" also measures the time spent
1 ?3 V+ n* H5 E& U( X waiting for additional requests.
2 U* D$ v7 l! d; t: U% b! h: A: [" c5 L% T: U/ g* h/ F( s* |
- If "Tc" is close to 3000, a packet has probably been lost between the/ i8 K8 \* D7 `" J+ v% c
server and the proxy during the server connection phase. This value should( W4 H) X- t7 X' Q
always be very low, such as 1 ms on local networks and less than a few tens
3 x) ]* T$ N% H+ X0 e, C of ms on remote networks.3 K D! T" a9 W" t
4 a; Y b" _) ^4 S5 p9 O* T - If "Tr" is nearly always lower than 3000 except some rare values which seem
9 U' A+ H, l4 x5 t% c0 v to be the average majored by 3000, there are probably some packets lost; ^ c$ i" T- [1 f9 v: M9 P! F
between the proxy and the server.7 H2 L% s8 L. ?
# V& _3 G6 W& B( X0 M& T d- V
- If "Tt" is large even for small byte counts, it generally is because+ j/ I0 I' z' ~. V7 A8 F$ S
neither the client nor the server decides to close the connection, for" ^7 W: d4 V' C$ r
instance because both have agreed on a keep-alive connection mode. In order
# q$ D: ?- d3 J0 F4 O! J$ M0 Y to solve this issue, it will be needed to specify "option httpclose" on: E/ f" E) }7 M, l! d0 e" D
either the frontend or the backend. If the problem persists, it means that9 N7 f5 ^& O1 M; l0 g6 ]
the server ignores the "close" connection mode and expects the client to
3 ?4 h$ v6 o" o, y: l g close. Then it will be required to use "option forceclose". Having the0 p% y3 \/ w: A% [" X9 t
smallest possible 'Tt' is important when connection regulation is used with) \2 }! S, r g# o
the "maxconn" option on the servers, since no new connection will be sent) E: \. B. x4 x' j! b9 u$ R
to the server until another one is released.! A9 t% S! _7 R3 B4 K5 Z S3 x
b! p. A( N0 {Other noticeable HTTP log cases ('xx' means any value to be ignored) :
1 l" }! E u. [" W- U. A
. e& ^* x. y7 Z6 }! O Tq/Tw/Tc/Tr/+Tt The "option logasap" is present on the frontend and the log& N2 {2 }; N& g* N! s# @9 t9 ]
was emitted before the data phase. All the timers are valid
d6 `- s9 a5 _- k2 s except "Tt" which is shorter than reality.
6 q @4 r" `& ~0 v5 O" Z: p) L0 `3 d* S# x; F* M. U
-1/xx/xx/xx/Tt The client was not able to send a complete request in time
- p3 ^2 h) D4 I7 B8 f1 s+ s5 H or it aborted too early. Check the session termination flags$ \4 z+ ]0 I9 T. M& z$ i/ ~
then "timeout http-request" and "timeout client" settings.' n: T% Z; \7 |% X n, m
2 k: G5 E; h* ?0 W9 j$ q0 A8 v; _ Tq/-1/xx/xx/Tt It was not possible to process the request, maybe because
+ t2 @0 H$ D% D; _( u* [: k" m1 d servers were out of order, because the request was invalid
1 d$ I O X- c1 K5 q or forbidden by ACL rules. Check the session termination
9 T: e3 B7 e: ? flags.. f, H" z2 h3 k6 I, ~/ N6 R
J- ~1 M9 t( m$ C \
Tq/Tw/-1/xx/Tt The connection could not establish on the server. Either it! I0 e: c8 r3 F" @( c
actively refused it or it timed out after Tt-(Tq+Tw) ms.
+ x5 V$ v: e1 F Check the session termination flags, then check the
! ]" V& ?) C8 R "timeout connect" setting. Note that the tarpit action might" U; Q: }# M$ T: {6 X% R5 {
return similar-looking patterns, with "Tw" equal to the time
1 P. ]8 n2 }+ G5 a( ~ the client connection was maintained open.
' V; A* Q- j3 Q" N5 Z) i* h f
- @) n* K8 {* ~4 ] Tq/Tw/Tc/-1/Tt The server has accepted the connection but did not return
. O* o' P% K; H { a complete response in time, or it closed its connexion% Q2 q9 x3 P+ b0 W2 Q
unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session2 m' T! H, v0 H- c1 \0 ~
termination flags, then check the "timeout server" setting.3 |0 T0 O4 W) y8 _
e* E: D+ [/ k0 A* ]" T( B4 `! }4 A
8.5. Session state at disconnection
( w& k- N" T' p- W5 V5 }-----------------------------------/ z; l9 G/ a$ W( k$ q
' p' x2 S, t: f& h# KTCP and HTTP logs provide a session termination indicator in the
, b7 `* _" A" @; k- s' ~; g"termination_state" field, just before the number of active connections. It is: `9 a' o1 ~- |+ d9 G- K& S
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,9 D% s- a" R/ M, I
each of which has a special meaning :
4 @: V7 L' ` E) h( M$ }3 H% r8 J- ~ d* H
- On the first character, a code reporting the first event which caused the& |8 y& M9 ~5 Y r
session to terminate :: I* L. g2 [+ q, f" M( _
% I }" Q* l+ R* R/ F9 @3 P' i
C : the TCP session was unexpectedly aborted by the client.
( K, G* T5 l* a, F( c" d2 n: X6 }+ m. N
S : the TCP session was unexpectedly aborted by the server, or the: c" ]4 w4 j" x; H6 j, Q
server explicitly refused it.$ t7 |, ]7 @7 {8 H
; \) `4 \! M5 o% y0 a9 R- B# `
P : the session was prematurely aborted by the proxy, because of a
3 N& q7 Y. A! }2 M connection limit enforcement, because a DENY filter was matched,
- o) I; C _, ?5 t because of a security check which detected and blocked a dangerous8 t+ {& J" T) D. E
error in server response which might have caused information leak
* `" f! a1 K, \/ C (eg: cacheable cookie), or because the response was processed by$ B' j2 }. s: c6 f& c$ C
the proxy (redirect, stats, etc...).
) X3 W }# T( V$ Z+ h& k; q7 s. k
+ [; F% }( `# l9 a R : a resource on the proxy has been exhausted (memory, sockets, source
* p/ ~- g1 ]9 d" ^2 H ports, ...). Usually, this appears during the connection phase, and
/ p5 ?) J+ R2 u* O3 P6 [( T: e system logs should contain a copy of the precise error. If this
" l1 k5 f0 t, Z happens, it must be considered as a very serious anomaly which" o5 S$ k; h9 O
should be fixed as soon as possible by any means.
5 y+ D$ j9 Y) s W, ?$ _7 S2 b9 Y
* {# {2 c7 X! N- \3 ?' o. m! g( C I : an internal error was identified by the proxy during a self-check.
* N7 W- P6 p G' O/ V. v7 x This should NEVER happen, and you are encouraged to report any log1 x; H$ A( s: ]9 I( k H$ S( S
containing this, because this would almost certainly be a bug. It1 s4 X) {) t7 X" |! G
would be wise to preventively restart the process after such an
: r6 A1 n! v, W3 R e event too, in case it would be caused by memory corruption.' ]- {8 v: e9 Q0 }; H
n6 f/ C8 r9 D; _* J2 x+ F+ w
c : the client-side timeout expired while waiting for the client to
! j/ K, w0 S! x) O+ A send or receive data.
' f3 _6 F! T n, }, \1 r3 k) o0 h$ U b" I- D
s : the server-side timeout expired while waiting for the server to
! }( I# C8 e |- O2 Z' O send or receive data.
% A7 Z5 e# |$ w. c# r w! K
+ }9 @' ^% `; a0 ?6 z1 ~4 T - : normal session completion, both the client and the server closed6 ]' q X6 t% M' v" f# j0 E& N6 F! `5 w( K
with nothing left in the buffers.1 _! Z+ k' A$ H$ ]/ E& u
" F( p" Q+ T& T - on the second character, the TCP or HTTP session state when it was closed :! T2 ^/ c( L% u2 o0 t/ q9 o; A1 D# i
9 x) v3 d5 ~' d6 Z9 K; P R : the proxy was waiting for a complete, valid REQUEST from the client) _. k$ M7 c8 s' q/ e x4 A$ l
(HTTP mode only). Nothing was sent to any server.$ W7 ]) n/ S! N+ J4 {# |0 `
) Y# S4 V- |0 Q2 O
Q : the proxy was waiting in the QUEUE for a connection slot. This can
3 X. i( C9 H2 Z( Q% E only happen when servers have a 'maxconn' parameter set. It can% H5 d: C3 S1 T; l6 E
also happen in the global queue after a redispatch consecutive to
8 X V% q% t I# G8 X" z* b a failed attempt to connect to a dying server. If no redispatch is
, t& Q1 Q2 D( O1 m8 ` reported, then no connection attempt was made to any server.
: ?$ D( k1 _ Z' {' s4 n; H
. ]6 J" Z R) w2 k, z/ Z- }, F% f C : the proxy was waiting for the CONNECTION to establish on the# a" c( @ H X6 L- n3 M. N' s; `
server. The server might at most have noticed a connection attempt.
k& I5 E7 y; n. i
+ O0 P7 T1 U8 i8 L% p H : the proxy was waiting for complete, valid response HEADERS from the
: X! x* \2 }0 x$ o3 A server (HTTP only).1 X' _+ X2 |- ~& o9 b; A
. g) o2 b7 a0 B: j D : the session was in the DATA phase.
2 H+ _+ i9 M4 Z! G8 X5 |6 _" J: o, }9 i1 c3 A, W
L : the proxy was still transmitting LAST data to the client while the! H6 H: m7 W+ Y' T& x" }5 s4 R
server had already finished. This one is very rare as it can only
5 S/ T# M2 v0 t& {$ C( | happen when the client dies while receiving the last packets.
* Q {" x7 r' f2 ~! y5 P8 C$ ], q; K4 ?$ {
T : the request was tarpitted. It has been held open with the client( Q; u0 _% \" [; M( e' J4 W
during the whole "timeout tarpit" duration or until the client
. ~' H: X% W: c; d6 T closed, both of which will be reported in the "Tw" timer.7 B5 L& b1 b- X* q6 T
6 ?8 ]0 G/ z7 `0 q' X8 A) a5 F* F
- : normal session completion after end of data transfer.
0 ]" d8 j9 {& a' I& k+ Q2 u) [3 D# P6 g" l' h/ Q% P0 P
- the third character tells whether the persistence cookie was provided by+ |1 C/ {& g* T' D* k! ]# v
the client (only in HTTP mode) :6 ~$ m9 r2 x# D
8 X7 A# y4 \6 g2 F* E5 H N : the client provided NO cookie. This is usually the case for new+ Y7 o0 [ y! r Z9 b
visitors, so counting the number of occurrences of this flag in the
1 n: S" m9 @% o) X3 } logs generally indicate a valid trend for the site frequentation.
0 b& Z- t) p1 q5 w/ g/ W+ }$ T- f
+ G- T) I& u! ~$ z& A& ] I : the client provided an INVALID cookie matching no known server.* H, V9 Q+ l. t1 i; J- a
This might be caused by a recent configuration change, mixed
) P* [- D* S4 k. Q( S cookies between HTTP/HTTPS sites, persistence conditionally5 X6 p3 R8 B4 y. L0 A
ignored, or an attack.- Q5 R) K' {# ~# d
; m! l, j ]/ @8 B; T2 K
D : the client provided a cookie designating a server which was DOWN,
% a$ f, _/ B0 b( \% r% }# L7 Y5 e so either "option persist" was used and the client was sent to
3 \( B4 R& |! Z9 F! x this server, or it was not set and the client was redispatched to G' ^- V6 v" r/ W6 z
another server.
& X7 U% e; F1 L# ?8 E
) z/ H( p5 g: z3 a- D. x. R, T V : the client provided a VALID cookie, and was sent to the associated3 k$ q7 v, H/ J! Z
server.. o/ b* J% x; T5 ?: R* b5 l$ u+ U
, f& e; h) e- [; j6 m% w E : the client provided a valid cookie, but with a last date which was: U2 A1 r) L4 K7 p' P& H
older than what is allowed by the "maxidle" cookie parameter, so
( o( D- r' w" H& b the cookie is consider EXPIRED and is ignored. The request will be; ]; d. @) Y2 E. Y0 c
redispatched just as if there was no cookie.) {$ k* {) u" W! q; m
5 A, c) L8 b% K O : the client provided a valid cookie, but with a first date which was
! @" ]- R4 Q0 j- O0 Z d" ~& W! R: T older than what is allowed by the "maxlife" cookie parameter, so
7 |2 |& V8 l. i/ A& q! g the cookie is consider too OLD and is ignored. The request will be5 S p' w9 g& Y9 D- N6 S
redispatched just as if there was no cookie.5 a: V$ O6 Z; K, A0 Y
* n" t7 F1 \& N+ O k5 q - : does not apply (no cookie set in configuration).4 X# `( @: F5 e
/ s6 S6 q2 M7 @7 a- T, ]1 e1 R - the last character reports what operations were performed on the persistence7 j+ L% `* e8 j: R" N
cookie returned by the server (only in HTTP mode) :
( Q |6 T% g# S c( I' L' c' ?2 ^( P i2 R9 o" ?( O% Z2 A
N : NO cookie was provided by the server, and none was inserted either.
: B: }' g* {0 k m S, B$ ^+ J3 m9 p/ F* [" T. h+ B
I : no cookie was provided by the server, and the proxy INSERTED one.
! d# b: O; t" W, \$ ` Note that in "cookie insert" mode, if the server provides a cookie,9 P$ M3 u6 G) T4 S
it will still be overwritten and reported as "I" here.
- O ]* d6 q# q( {3 t! `* i
+ F, Q7 ^3 J9 Q [( ? U : the proxy UPDATED the last date in the cookie that was presented by
$ O7 Q! a( j6 R. Y _* i the client. This can only happen in insert mode with "maxidle". It
; O) K" ~ M& S happens everytime there is activity at a different date than the
8 J. v+ |9 d4 w! _1 }/ `8 V date indicated in the cookie. If any other change happens, such as. o3 `6 o# z! c" @
a redispatch, then the cookie will be marked as inserted instead.
5 X% r1 w* V% u% r: Q' |- t
8 E3 Y7 X& D+ j- |6 u2 K$ R3 q P : a cookie was PROVIDED by the server and transmitted as-is.) V' r) h) N7 I& Z" l
5 V* e2 w0 J4 i R : the cookie provided by the server was REWRITTEN by the proxy, which
8 M4 w2 ]) `2 A5 t; I$ R* P happens in "cookie rewrite" or "cookie prefix" modes.
j( i' a. r. g. e
6 `9 G+ Z" M- } D : the cookie provided by the server was DELETED by the proxy.4 P! n* N- k6 ]
( O( a$ h! K8 ]) h! P
- : does not apply (no cookie set in configuration).
% M. w% e& i7 O& q: ?( t2 P2 x! q1 Y% W3 \; |' } L8 ~5 _
The combination of the two first flags gives a lot of information about what
: u' Z! F2 M9 g% ?3 c# Wwas happening when the session terminated, and why it did terminate. It can be& b2 B9 t# o2 L5 S9 E5 A5 k- P
helpful to detect server saturation, network troubles, local system resource
; d4 C- w5 A9 ~& h0 jstarvation, attacks, etc...
0 E) c! {/ s; a4 {7 B7 L! n* p' I6 ]* T; \/ Y% p" J
The most common termination flags combinations are indicated below. They are
9 R2 F2 \# _( T! V" W- n" aalphabetically sorted, with the lowercase set just after the upper case for# y1 ^7 N5 c. G# R* u/ U$ M7 Z
easier finding and understanding.& d0 Z3 g' q" z. q( B5 \4 C
9 Q; N& L/ [3 i1 u5 V Flags Reason6 d6 m) T4 c) s% [2 `0 a
' V& F: u1 @3 ?, H% A( r8 L -- Normal termination." F$ y) z$ v% c6 H* D( ?9 J
$ x4 e7 ]# l7 O" u/ B9 ]
CC The client aborted before the connection could be established to the8 m& r! L. J: h' t& g- p
server. This can happen when haproxy tries to connect to a recently
2 S3 F* K1 L, r7 ` dead (or unchecked) server, and the client aborts while haproxy is
$ J6 x6 [6 k) s: x! |- n7 Y! n waiting for the server to respond or for "timeout connect" to expire.( h* I- x1 z3 d' b0 L6 x
' C1 a/ m" q& I1 ~& J1 y0 f3 |9 Y
CD The client unexpectedly aborted during data transfer. This can be" n/ `" p/ Z0 c
caused by a browser crash, by an intermediate equipment between the
& t% M& M. k/ T3 v6 w client and haproxy which decided to actively break the connection,
. n: e5 Y, \ }& F by network routing issues between the client and haproxy, or by a
$ c0 H. I& }. L" Y4 @ keep-alive session between the server and the client terminated first8 k1 B3 p2 s$ A0 D
by the client.6 Z) g8 g( I" g- Y2 t) u; h
. X; l- {6 K3 F8 w7 A7 |1 f) u' L cD The client did not send nor acknowledge any data for as long as the8 A4 H2 t6 d1 \$ u Q1 H. V
"timeout client" delay. This is often caused by network failures on
2 Y% C& A7 F1 }) `' Y, {! Z the client side, or the client simply leaving the net uncleanly.
$ t% u! z0 w9 D' K, ?( ~# Y" ^7 I1 f* Q9 ~
CH The client aborted while waiting for the server to start responding.
7 \1 p6 n1 y' j3 C2 h1 Q It might be the server taking too long to respond or the client
. o/ j& G% S' u9 D2 L clicking the 'Stop' button too fast.
) C0 `' ]$ J# z/ d: o
. _7 h5 U0 [' F. ]7 n+ P+ g cH The "timeout client" stroke while waiting for client data during a
6 |- N- Z9 _) D+ v POST request. This is sometimes caused by too large TCP MSS values7 l/ z+ Q3 h2 l) |1 ~# [: l
for PPPoE networks which cannot transport full-sized packets. It can
1 R x) |' n0 a2 {! e also happen when client timeout is smaller than server timeout and/ C7 k# Y* r, I
the server takes too long to respond.; H: Z1 J/ D, G" }7 O7 U8 O
. T5 F+ P1 f7 P6 L CQ The client aborted while its session was queued, waiting for a server
7 u9 C! p+ q1 X6 c8 ~0 n) ? with enough empty slots to accept it. It might be that either all the/ m4 I' y9 H8 E0 Z+ t. Z Q
servers were saturated or that the assigned server was taking too$ t6 A3 }* F0 d& Y- d5 V& n
long a time to respond.
% T! R/ J* X0 _# {" d
8 B8 u* r9 s, m CR The client aborted before sending a full HTTP request. Most likely( G1 z; X+ d% _3 c
the request was typed by hand using a telnet client, and aborted8 ?2 e4 c+ D1 W8 k
too early. The HTTP status code is likely a 400 here. Sometimes this
. s9 l) @ n' ]9 E- U might also be caused by an IDS killing the connection between haproxy
6 T0 z1 k/ V# \; y and the client.
8 C6 u$ {4 a6 d3 U/ S; @- M* B3 B
L# \- k2 S0 H u0 } cR The "timeout http-request" stroke before the client sent a full HTTP* K g8 i/ x" l1 g0 ^
request. This is sometimes caused by too large TCP MSS values on the
! i0 Z4 z( r9 s U% m- c. @ client side for PPPoE networks which cannot transport full-sized; p2 ?- ^* \ Q1 W x; v
packets, or by clients sending requests by hand and not typing fast- j9 A& g: V6 C! o- ]' {
enough, or forgetting to enter the empty line at the end of the
2 s8 [1 m0 O. }) K request. The HTTP status code is likely a 408 here.
& {2 B1 h, |( A9 v/ X; U! |/ v7 F+ P9 N1 M; U0 C0 O+ F6 s# R, z
CT The client aborted while its session was tarpitted. It is important to' w" t* q, E7 r' i P& C
check if this happens on valid requests, in order to be sure that no
3 A# G7 Z5 n' u7 \& p9 ^- p" W+ ^( @ wrong tarpit rules have been written. If a lot of them happen, it9 O* S8 D$ Q/ A) S- d5 o6 c5 n
might make sense to lower the "timeout tarpit" value to something
' R2 Y3 f- W3 I# m$ e6 x/ N0 \& T closer to the average reported "Tw" timer, in order not to consume. I; w; i4 e! x) B
resources for just a few attackers.
4 H; e5 R" _; @# Q+ S5 F5 l8 ~. ?8 }, m# O- k+ m, A
SC The server or an equipment between it and haproxy explicitly refused
0 m- _+ b6 A: @ x) r( c the TCP connection (the proxy received a TCP RST or an ICMP message. l/ Q: g+ A# y
in return). Under some circumstances, it can also be the network) Y: ]' q* T% h1 E% q$ s( \) Q& @
stack telling the proxy that the server is unreachable (eg: no route,
5 `" _( l1 q* H or no ARP response on local network). When this happens in HTTP mode,5 F2 M5 s* @5 H4 B5 ?7 U, G
the status code is likely a 502 or 503 here.
, `1 i9 d' [: a3 q* Q( S0 o3 I( L: W
sC The "timeout connect" stroke before a connection to the server could3 Z( y$ {' Q; W' h6 P% J2 h% m
complete. When this happens in HTTP mode, the status code is likely a
; W v1 T8 W+ w; \8 p! J 503 or 504 here.
6 s; D( A" ]# F9 n7 F! N* V0 l- ^9 V2 S) v/ Q
SD The connection to the server died with an error during the data
' s# `) P# |3 q8 s# h transfer. This usually means that haproxy has received an RST from
% h1 O! D; T3 d the server or an ICMP message from an intermediate equipment while
# N9 j" ?# h% A exchanging data with the server. This can be caused by a server crash: T ~ z. @# s# n, L) x
or by a network issue on an intermediate equipment., q/ A5 [) i% l; p. Q
& |; h3 s, B$ w
sD The server did not send nor acknowledge any data for as long as the. [" V, e9 B1 q, m; _. u' }4 O
"timeout server" setting during the data phase. This is often caused
( h* a) u& D6 G1 r& I by too short timeouts on L4 equipments before the server (firewalls,
3 l' ]4 V2 _4 \" V/ c1 i% } load-balancers, ...), as well as keep-alive sessions maintained
" G7 e3 W% V5 c$ R between the client and the server expiring first on haproxy.
% O- Q7 S/ v2 S6 Y; o& U# k, p% s8 t4 s' b! {
SH The server aborted before sending its full HTTP response headers, or
8 Z9 `' Y0 t; o% a it crashed while processing the request. Since a server aborting at: o+ z/ h; @3 e# {# U3 `% p
this moment is very rare, it would be wise to inspect its logs to, j5 l% N) k2 p l7 `: j/ N
control whether it crashed and why. The logged request may indicate a
8 v2 Y$ }8 r* {; Q. N4 P3 o O$ @ small set of faulty requests, demonstrating bugs in the application.
4 t; V B: x0 e Sometimes this might also be caused by an IDS killing the connection
/ r5 m; W4 V2 B. T between haproxy and the server.2 d+ S& k9 q. ]
' Y8 G4 e1 k j( q+ q0 e3 ?
sH The "timeout server" stroke before the server could return its' C [9 [: D( p; ~; }9 ?
response headers. This is the most common anomaly, indicating too: W ~8 n( [5 F- R1 J
long transactions, probably caused by server or database saturation.7 j( `4 G' f) m: b( _/ a
The immediate workaround consists in increasing the "timeout server"' z# Q7 k# A8 s3 ^& ^
setting, but it is important to keep in mind that the user experience
5 x0 j6 q1 [$ J3 L% \/ U will suffer from these long response times. The only long term* @$ p) B0 ?4 Q9 v6 F, U
solution is to fix the application.
3 G4 p* l+ p9 `; d! O2 ^5 Q! ?) r
5 m# q- l3 d) q$ } sQ The session spent too much time in queue and has been expired. See# a& x1 {9 o5 k0 {2 C* P! a1 w
the "timeout queue" and "timeout connect" settings to find out how to
6 h9 m3 d$ d- i5 E2 d- M fix this if it happens too often. If it often happens massively in4 J/ c/ i, i6 A0 C# [
short periods, it may indicate general problems on the affected+ k2 H3 P0 N/ _6 I) c8 H, i2 ?2 [
servers due to I/O or database congestion, or saturation caused by/ M: ~- G8 @3 T0 ?( {
external attacks.
. U$ u* I& k! u% @3 ?' i! L4 g) Y$ V2 z; L! D/ L
PC The proxy refused to establish a connection to the server because the8 |1 U0 M7 f0 g7 |
process' socket limit has been reached while attempting to connect.
$ G- T, T3 g3 E! f5 f' Z" X3 d The global "maxconn" parameter may be increased in the configuration6 ~% ?3 H) p" h+ n( `# `0 J
so that it does not happen anymore. This status is very rare and9 T$ C7 D* n& F
might happen when the global "ulimit-n" parameter is forced by hand.+ C. Y& y' v7 ~
2 A9 e* _$ E6 L$ l2 b! U PD The proxy blocked an incorrectly formatted chunked encoded message in- a. ^4 _; i3 X! \& k
a request or a response, after the server has emitted its headers. In
% l5 p! ]! U+ B9 P most cases, this will indicate an invalid message from the server to0 f) x" a# g0 j9 I; T
the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647' T7 J) x6 o6 R4 `
bytes). Any larger size will be considered as an error.1 P! E+ ~' z! p6 k. T- O
8 C) d2 i3 ?+ X
PH The proxy blocked the server's response, because it was invalid,
# r( s5 A- ~7 N* D% x) c* p; J incomplete, dangerous (cache control), or matched a security filter.
7 N! ~. [& v" y) [' w9 O- F! Z In any case, an HTTP 502 error is sent to the client. One possible
; A) ^! _: d! T5 o2 l7 F1 ` cause for this error is an invalid syntax in an HTTP header name
9 H! e+ F# T: Y% ~; ?$ p containing unauthorized characters. It is also possible but quite* f. y8 W7 O C: T5 m
rare, that the proxy blocked a chunked-encoding request from the4 x; r" I5 n. Q9 ~$ W( a2 c# h
client due to an invalid syntax, before the server responded. In this
6 s$ c, T1 c8 N$ n case, an HTTP 400 error is sent to the client and reported in the$ S" [( f7 Q0 H z1 p! J
logs.
% Q# B! y3 w; `' q# `0 S& Y1 P$ X6 g
PR The proxy blocked the client's HTTP request, either because of an/ m% F6 c/ ~- u# ^
invalid HTTP syntax, in which case it returned an HTTP 400 error to
4 k9 q6 X- _$ t the client, or because a deny filter matched, in which case it
) K. g3 g& r/ T( ]: S$ d returned an HTTP 403 error." I0 G: R4 p7 n }0 i/ {: w
' ^2 w& E ~1 B7 c7 W2 Y PT The proxy blocked the client's request and has tarpitted its9 [: x8 q, |, [5 E/ P _
connection before returning it a 500 server error. Nothing was sent
. U& f' U$ g" G! C( Z: M to the server. The connection was maintained open for as long as+ R- G9 g( Y9 _ X2 u: {) t: L' v
reported by the "Tw" timer field." ]$ ]9 w% h* J W, o2 H/ `, w$ i
% c% I6 ]1 k i6 z R% n3 a) G RC A local resource has been exhausted (memory, sockets, source ports)
7 s5 s/ q* D+ H" Y. e* S1 H* N preventing the connection to the server from establishing. The error$ L0 l* U: x# _$ @3 [% h, @
logs will tell precisely what was missing. This is very rare and can
! X( L; D+ @ q( a0 Q! e8 j2 r k7 ] only be solved by proper system tuning.2 Z6 r* N5 ^8 K$ j1 m2 Y
3 i* M; s7 W7 }, yThe combination of the two last flags gives a lot of information about how% ^6 t. e5 f2 T/ C
persistence was handled by the client, the server and by haproxy. This is very3 J x0 ]0 O1 D: z! I8 d9 Q& I8 |# @
important to troubleshoot disconnections, when users complain they have to( V' ^) e! `$ s0 |5 w+ G6 L
re-authenticate. The commonly encountered flags are :
; p$ r: v# j) I# W* B3 V" N, E% ?) n2 a; K, d
-- Persistence cookie is not enabled.# [0 G8 r V8 n; {6 k7 f
0 D- ] P. c: O: {3 f
NN No cookie was provided by the client, none was inserted in the1 [, L- p( | S0 h3 ]/ X
response. For instance, this can be in insert mode with "postonly"1 ]3 L. g$ _6 a2 J4 q& w" J' n; l0 t7 }
set on a GET request.9 S) o6 y; G' T7 J$ _
" C" W/ g- Q8 X9 ]
II A cookie designating an invalid server was provided by the client,, [% n! n: [. F* O, o# A
a valid one was inserted in the response. This typically happens when
W) r, q( \: E: H0 S, w1 ? z a "server" entry is removed from the configuraton, since its cookie; w! s. |) x$ _1 s- U0 V) w
value can be presented by a client when no other server knows it.7 W4 o/ ]$ n- |: q( ?
; I% r9 u8 s4 M* L" n s NI No cookie was provided by the client, one was inserted in the- W( A* C! W8 {0 X* ^! i
response. This typically happens for first requests from every user3 Q r5 S( J+ l1 u! E
in "insert" mode, which makes it an easy way to count real users.
# P& m5 U* O0 S+ c' F5 U9 n G# q: N- j. Q) c
VN A cookie was provided by the client, none was inserted in the9 [" @* @2 Q4 w5 v% V
response. This happens for most responses for which the client has
. E/ G2 k2 Z+ i* M% O# r already got a cookie.7 C5 u5 F: V+ @
' ~$ X' K' F' p6 U4 M s VU A cookie was provided by the client, with a last visit date which is
0 a, p, d+ ~! w3 x, x% m not completely up-to-date, so an updated cookie was provided in) g9 y# U1 h) e# q l x7 a4 u$ s
response. This can also happen if there was no date at all, or if
$ F& a! m2 Q8 U5 c0 `5 D$ ] there was a date but the "maxidle" parameter was not set, so that the
6 Z, n" J: K! p4 P cookie can be switched to unlimited time.
6 e9 e, L3 w+ G, l& j
0 Z7 O$ w+ u- `* W3 o+ X2 i! Y5 b EI A cookie was provided by the client, with a last visit date which is) {+ b* @; k* ]5 o5 ]+ n
too old for the "maxidle" parameter, so the cookie was ignored and a5 }1 ~0 E! j9 `9 T# R; N
new cookie was inserted in the response.' `9 [; j3 O+ h3 d* C
0 g( |/ s2 P! _* E U o& a& r$ | OI A cookie was provided by the client, with a first visit date which is4 H/ e2 V0 ?4 Z
too old for the "maxlife" parameter, so the cookie was ignored and a
# Z8 c7 [% H% v+ A: b( G9 a! j new cookie was inserted in the response.8 F+ Q- T' k9 `( x0 C# |. f
' t2 a2 A) _- X6 @8 j! y. p
DI The server designated by the cookie was down, a new server was6 W. N) Q: F' U+ z: }5 W8 z! S5 ~
selected and a new cookie was emitted in the response.: Y) Q. ?) w: q. n
' _4 a$ @2 U& L5 n
VI The server designated by the cookie was not marked dead but could not
2 x! Q4 {/ o0 ?' @% q0 I# B; W: `/ w be reached. A redispatch happened and selected another one, which was
; _8 a. Y0 i. ^& a& N% [& e then advertised in the response.' {7 M0 u+ V9 l' N$ m
' |! ]4 {- m/ R) _# \$ I8 K5 E% E2 {+ U
3 o9 M3 y7 \+ `& \8 m8.6. Non-printable characters
+ b' E0 R& R" N$ S6 q- D ^! C-----------------------------2 t( {; c# Z7 ~1 e0 ?9 z6 \
' l/ u: m+ p( b: G; [, g* Q4 e
In order not to cause trouble to log analysis tools or terminals during log
' T1 z: y' F7 Lconsulting, non-printable characters are not sent as-is into log files, but are
1 n5 |* g6 r. O6 V4 Q8 Z F6 Uconverted to the two-digits hexadecimal representation of their ASCII code,
3 S ^ X5 M8 E) q" Gprefixed by the character '#'. The only characters that can be logged without: T, R" n% S9 J" D1 e, _. B
being escaped are comprised between 32 and 126 (inclusive). Obviously, the8 z5 F9 z: }. p$ K% `( O
escape character '#' itself is also encoded to avoid any ambiguity ("#23"). It# O) c( e" }5 H) h
is the same for the character '"' which becomes "#22", as well as '{', '|' and9 G! o9 W: d9 [, r# u6 j
'}' when logging headers.
6 i8 b( a5 v$ I4 n, i
% P& K+ H3 k- O9 {% S( TNote that the space character (' ') is not encoded in headers, which can cause' A' }5 p0 J& ]5 M2 T2 q
issues for tools relying on space count to locate fields. A typical header
' S) n. s3 I6 tcontaining spaces is "User-Agent".
2 V- Z/ { i* k& p
8 c) n$ S2 c% X* w! ~4 LLast, it has been observed that some syslog daemons such as syslog-ng escape
+ `6 |9 l2 t$ Q1 s4 d6 x* ?3 [the quote ('"') with a backslash ('\'). The reverse operation can safely be
* X8 X& L3 o, ~performed since no quote may appear anywhere else in the logs.
- g# _) a8 o. l w1 T7 w! F' m+ R# Q$ i7 N' d6 W: p
8 y% |' \$ g# Q* Y5 H2 n! Q
8.7. Capturing HTTP cookies5 W. K7 a3 g7 z F+ T
---------------------------; p3 K: O M" V5 h
6 e' h& n4 L9 Y
Cookie capture simplifies the tracking a complete user session. This can be
. t$ t: V& |5 Qachieved using the "capture cookie" statement in the frontend. Please refer to3 a; g9 O+ s5 ?, c$ Q6 e
section 4.2 for more details. Only one cookie can be captured, and the same
0 A3 {4 g2 P3 }8 v4 \( kcookie will simultaneously be checked in the request ("Cookie:" header) and in
* m5 q! T1 B+ @/ b/ w3 h8 Zthe response ("Set-Cookie:" header). The respective values will be reported in; ]: K4 T9 ?2 k7 V2 ~, J' |
the HTTP logs at the "captured_request_cookie" and "captured_response_cookie"
$ O* ]% N4 m2 L a, Vlocations (see section 8.2.3 about HTTP log format). When either cookie is
! f5 W9 ^, m* y* p5 Jnot seen, a dash ('-') replaces the value. This way, it's easy to detect when a( P7 F9 U: j( K- N( N
user switches to a new session for example, because the server will reassign it
- {4 H( s! h$ X; Y) Ba new cookie. It is also possible to detect if a server unexpectedly sets a
4 i: { {4 g7 ]* P+ jwrong cookie to a client, leading to session crossing.
) i1 n/ m9 k$ }! N2 b; j$ e9 \& ^8 p" y4 ]% Z0 E' w. G. a5 h
Examples :
E6 o2 B' ~5 {: H0 A$ B( }9 c% k$ c # capture the first cookie whose name starts with "ASPSESSION"
# L; i( m& P( N. r2 N1 n& ? capture cookie ASPSESSION len 32& G' J+ l0 r! x, H
: p. ]7 n% g$ t6 g # capture the first cookie whose name is exactly "vgnvisitor": G0 e+ [5 w8 T9 m2 K: [
capture cookie vgnvisitor= len 32
% o& h9 N5 D% r& r6 {$ N; _# O; ~2 O/ c+ X0 X4 V) R0 r
1 \, ~3 y; R/ @+ ^# U5 P
8.8. Capturing HTTP headers
* J7 y. p! n) N! {" ^ p# M, n5 o, ]---------------------------8 C5 _+ ]' i9 U! T
/ L& w% y) b# B+ b% M3 mHeader captures are useful to track unique request identifiers set by an upper* O! y: x' Y, ^0 Y6 Q% Q
proxy, virtual host names, user-agents, POST content-length, referrers, etc. In! F$ _8 w X& B$ c3 Z1 ~
the response, one can search for information about the response length, how the
; ?( z8 m8 b* |5 ?4 {" Qserver asked the cache to behave, or an object location during a redirection.
$ f4 N. N$ j* I/ y% V0 w- q. R; |$ t0 R4 N1 a6 i
Header captures are performed using the "capture request header" and "capture, R5 f/ o8 l9 Z0 l3 ]* M
response header" statements in the frontend. Please consult their definition in
& r% |: Q) U6 M! ~$ @6 Fsection 4.2 for more details.( t7 s6 M0 f9 h C
" @- D0 ?% }; T; JIt is possible to include both request headers and response headers at the same; |) i z1 X* N# U
time. Non-existent headers are logged as empty strings, and if one header- _, L, V1 ?( v: K$ L) Q
appears more than once, only its last occurrence will be logged. Request headers
: _" R9 m d' lare grouped within braces '{' and '}' in the same order as they were declared,8 s# C+ ~/ b6 f( Y1 z/ I1 {
and delimited with a vertical bar '|' without any space. Response headers( d8 O! o3 x5 I
follow the same representation, but are displayed after a space following the
2 c, F) }8 Q$ [" Q4 o V7 grequest headers block. These blocks are displayed just before the HTTP request1 k! t( \! y+ N2 D5 Y. X
in the logs.
% U- s* m3 j2 _- r$ C+ { z4 U4 Q% j! B7 h: p! j& j3 S
Example :
2 R, J) W- z P: z% f # This instance chains to the outgoing proxy
' N! J3 I3 P5 A Z+ e/ s1 X listen proxy-out
G. {" c5 k% ]% K! t7 G5 G) x mode http
+ S9 ^6 i1 ?* N4 H9 n# G option httplog
- Q1 W3 b/ v; W- W& E4 D option logasap0 K+ \( @. v p; g1 R1 r
log global
! }8 f6 |* r1 m: j server cache1 192.168.1.1:3128
. |. C4 S. G; _/ q' ^5 y' ?8 n$ u M. Z) X+ Q+ ^; c
# log the name of the virtual server4 O7 Z: k6 ]* |3 T) z
capture request header Host len 20
! ]- e3 q- Z% q" K B6 U+ w4 W: j* U& q5 o4 m
# log the amount of data uploaded during a POST
4 P6 y# w5 `# E) B, }4 w5 @ capture request header Content-Length len 10
9 P0 x( V* v5 H0 @' d) V9 w/ ^9 z* ~4 ]6 D8 V. m9 ]* G. _
# log the beginning of the referrer
6 Y1 Q% {8 D' O* ]9 { capture request header Referer len 20; o" t- o" t' C5 e. C" A0 I( j
: z( Q3 m, E* Y' V# d # server name (useful for outgoing proxies only)
& b( p# g5 m* S5 Y1 h& H capture response header Server len 20
# T) e+ X& ^; Z' I* `+ |
; o$ q! {& P! e! ` # logging the content-length is useful with "option logasap"
' W& q* s) J9 R9 ]& R- l capture response header Content-Length len 10
5 M' |$ {$ z( f+ P9 ]& ]3 Q6 X* Q! N2 G7 f
# log the expected cache behaviour on the response/ ~" N" u' z1 y2 ~" Y! \- s
capture response header Cache-Control len 8
# f! s3 F r: \% {9 d j3 k
6 y# o) X0 K2 @# ], e& W # the Via header will report the next proxy's name: J9 e% z$ y+ |% `
capture response header Via len 20- m7 N' H( G ]( l
Y4 B; \' L6 i, } # log the URL location during a redirection6 j, V) ]0 A+ O z' u
capture response header Location len 20% O$ J$ D* u5 \4 K: t
: p, U: F) b! y" x& k5 Z1 x2 @
>>> Aug 9 20:26:09 localhost \8 J3 c, }+ x8 D; _2 j' M
haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \! K6 ?1 M f4 y. F2 a. e
proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \# [8 M, U1 n! ~
{fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \
' }. K' f% l# |3 R "GET http://fr.adserver.yahoo.com/"
) j ^7 Y) Q H# L4 S$ g+ ?1 E- U2 P1 t) b9 F# z
>>> Aug 9 20:30:46 localhost \
* j% J2 a) }" T A: W5 [ haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \
) [* ^' n7 k' k2 W9 A( _ proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \1 ]1 }. k2 K" D' u5 z. t( ^. Y
{w.ods.org||} {Formilux/0.1.8|3495|||} \( ?/ T7 O1 t; S0 n( ^. E& z
"GET http://trafic.1wt.eu/ HTTP/1.1"
* M1 X' Q; _+ i( }, A
. x. C& a, ]- j >>> Aug 9 20:30:46 localhost \ E6 x7 X4 q( F
haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \$ \ K- z. v0 }) K; U h" ]
proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \
, K& C. y) U, T: N r' U( f; L {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \
- }/ e0 n4 m5 q; U0 `+ E" U3 l# k {Apache|230|||http://www.sytadin.} \
; R/ Z% f- C; |2 t( a "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
) U% i7 t* k( R) Z9 `2 U7 ]4 Z9 U, \8 P4 c* B9 k" B! g" X
- e# ]8 S% h) k" C N1 Y( T: W. z
8.9. Examples of logs
( Q$ q( c( C* r5 y---------------------6 i7 [4 v8 A+ r& \( J7 v1 a
$ H* b$ W3 V+ F% I
These are real-world examples of logs accompanied with an explanation. Some of
/ s6 z P1 R5 B" o: _them have been made up by hand. The syslog part has been removed for better: ~+ p# s* Y$ S2 |
reading. Their sole purpose is to explain how to decipher them.5 a: o* d5 x' g
+ Y: Y5 o7 t# L' f: D+ N
>>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \/ y9 [* \/ ?0 L J; y9 v U" b
px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
- M; I! z: v2 q/ W "HEAD / HTTP/1.0"
. Z- e) a4 e5 Q3 O* H' T s: w
( E8 `0 z) C; |8 f => long request (6.5s) entered by hand through 'telnet'. The server replied
# h* K! |1 [+ @, u3 a" Y) f in 147 ms, and the session ended normally ('----')$ b. u; k! _) z
9 }" }" {* s& `6 ~! c# A
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \" u! [* R+ h! }4 q
px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \# [* x5 T7 e& t! ]: L
0/9 "HEAD / HTTP/1.0"
; }4 r8 a& i! p' J5 `- a) O. U: w8 i- R: Q3 a3 P6 P% ^
=> Idem, but the request was queued in the global queue behind 9 other o/ T o. V6 O( ?6 [+ t; d4 L( d
requests, and waited there for 1230 ms. ^& u% C6 F/ n- N. G( h# Y
% O. v& V/ ?4 m- w
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \
5 v. d7 _& }0 L4 G# F# v; N px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \7 {" {& L1 U4 h, f$ Q' Y3 o
"GET /image.iso HTTP/1.0"
' J' k6 T; i6 m5 @0 e/ L1 l0 |! u
=> request for a long data transfer. The "logasap" option was specified, so
: l- h9 j: m6 Y the log was produced just before transferring data. The server replied in
& ^, n4 G& I: B) {4 q6 c0 j 14 ms, 243 bytes of headers were sent to the client, and total time from* [! R5 K" v' ]& Q
accept to first data byte is 30 ms.; b" j, [/ z9 B! n
# J6 T6 `) b3 l+ M1 }; K o
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
5 z4 g! }9 p2 A* q; t: C! [2 I px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \2 A7 E9 ~, x! @
"GET /cgi-bin/bug.cgi? HTTP/1.0"
3 L- }' [; S2 `8 I/ f
8 v6 y; L# g4 ?2 C" b( L => the proxy blocked a server response either because of an "rspdeny" or' p. I' L* A) } c! Q; _4 _
"rspideny" filter, or because the response was improperly formatted and: |4 u# k+ m- G
not HTTP-compliant, or because it blocked sensitive information which( T( l' B) l' {, ?$ _
risked being cached. In this case, the response is replaced with a "502( u3 ?& G0 O6 @. e5 Y
bad gateway". The flags ("PH--") tell us that it was haproxy who decided. R/ J# Q' b' g& ` V2 i
to return the 502 and not the server.
5 q$ K4 t! ^ ? s7 c. H" D$ Q: S, F* B' B/ a
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \& y c/ k9 H9 e% C' [! k( p3 R
px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""% E; S: \2 \/ j7 }. n$ s/ t
, x+ h4 X8 `5 X% N
=> the client never completed its request and aborted itself ("C---") after% R& A" W' `( f- p
8.5s, while the proxy was waiting for the request headers ("-R--").5 D `' L/ P, f" d3 E" ]
Nothing was sent to any server.
$ p/ r0 w) R# M5 |5 {9 p+ _
3 u! Q8 H2 Z6 |% T >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
2 s; Q4 j1 o. E g' G5 D1 ^ px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""- l+ k6 d( f$ g( |$ @
7 a/ e: c s, t0 Y1 l( g; m% p0 P- O => The client never completed its request, which was aborted by the8 s8 _! D& R5 ~! C9 U3 |
time-out ("c---") after 50s, while the proxy was waiting for the request' j7 a7 ]- M7 X* }' ^
headers ("-R--"). Nothing was sent to any server, but the proxy could
' M4 B9 |1 m+ L6 @ send a 408 return code to the client.% _/ e% ]: d/ K9 g+ ~ u9 w# ?
7 |. `5 s$ Q1 X- V >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \
1 P4 U/ q0 z7 d& ]: t4 n/ A px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
$ I( U' I1 b! Q% H/ m# Y! b& g5 C* e& X4 M9 t5 o
=> This log was produced with "option tcplog". The client timed out after* k' ]) S8 y/ y) w! R
5 seconds ("c----").; ^" r- l. X; C
+ J4 g1 c8 |8 k6 s. @5 h, o
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \) W8 G7 D4 S4 e
px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \1 v a" ]8 Y! K( @, U
0/0 "HEAD / HTTP/1.0"
' V1 j- A7 Z/ g& C5 l2 }
{- a- ]* Y w( b- _7 o => The request took 3s to complete (probably a network problem), and the
' T+ x0 n0 V. m8 b6 N! l connection to the server failed ('SC--') after 4 attempts of 2 seconds
( Y0 Q7 o, Y, b6 R; }. _! m (config says 'retries 3'), and no redispatch (otherwise we would have& ~5 D7 s# G. B, K$ v r' T
seen "/+3"). Status code 503 was returned to the client. There were 115
5 p+ Z- @4 W& d$ l. u& \* @0 u connections on this server, 202 connections on this proxy, and 205 on
6 h: r2 U; N% y' {9 `5 B the global process. It is possible that the server refused the
4 }' i' E3 \" h0 R- M0 c connection because of too many already established.% Y* O% c& W+ D; C" D
, z7 Y7 F3 S# t8 J6 I. y
2 I$ v) j: C9 n3 j$ ?
9. Statistics and monitoring, b. U- r4 I0 y' A
----------------------------
3 E o2 c* p$ E0 d0 n
5 M: x8 z# G2 `5 b2 U$ v. HIt is possible to query HAProxy about its status. The most commonly used
0 }( A! h! R; U7 A4 C$ M! Ymechanism is the HTTP statistics page. This page also exposes an alternative* y4 s: T: ~ `: f, p
CSV output format for monitoring tools. The same format is provided on the- T: m' b. D1 ]/ k1 u
Unix socket.
6 e m) E7 B# L+ s1 e1 t
. C# }5 M, V W# L2 H* X5 ~6 }$ E: b. }* @
9.1. CSV format D+ n2 w* q5 \# c3 S" Z
---------------# G5 X& G4 d9 F8 B- i0 s0 j
+ s' j3 | A0 J6 g0 Q$ W& J
The statistics may be consulted either from the unix socket or from the HTTP3 t% p& Y5 z3 D; s5 @
page. Both means provide a CSV format whose fields follow.
$ v+ @ X( @) b) \
( r% T0 b% f& h: o5 n" ]$ S$ u 0. pxname: proxy name
. t$ [. _+ N# Z$ V4 ] 1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
+ @2 r) l! [( S" N for server)- i9 K' ]. ^2 B C0 C% g. d
2. qcur: current queued requests
8 X2 e: Q2 f1 X 3. qmax: max queued requests
# Y5 w' ]& k+ |& J2 j3 y 4. scur: current sessions
+ q | A) H3 N; h% q 5. smax: max sessions! K# ], ~, c- }& T: K
6. slim: sessions limit+ A4 R! W/ O w; g% H! q
7. stot: total sessions
8 k- ~3 N0 P6 X& Z; _ 8. bin: bytes in* O# ~1 s* Y& ~7 x" ]1 Z
9. bout: bytes out' |: P8 _' a, P, F
10. dreq: denied requests
* {) p/ k9 ^: s" E, [$ J 11. dresp: denied responses
' Z" `8 u. {3 \+ U 12. ereq: request errors
. N3 \& |/ E' B' T 13. econ: connection errors |7 R8 C- n0 k5 s7 h) z: q4 d
14. eresp: response errors (among which srv_abrt)
! x! w. s7 O/ U$ ` 15. wretr: retries (warning)( y! W: |9 P, |. j2 t
16. wredis: redispatches (warning)
% Z- z* {2 z0 ]# v3 L! g6 A% g 17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)- _ ]) Z6 n$ v1 B5 A# A' A
18. weight: server weight (server), total weight (backend)5 k' J8 |' B, }- Y3 a! G
19. act: server is active (server), number of active servers (backend)* Q/ |8 t- p1 s! G4 n7 b; D d" p
20. bck: server is backup (server), number of backup servers (backend): M3 {! J S3 f) W$ |
21. chkfail: number of failed checks
* P: e1 J# A& H9 b 22. chkdown: number of UP->DOWN transitions
- V, X4 p% e( D# r* j 23. lastchg: last status change (in seconds)
8 u2 \7 a0 `, ~0 q6 {: E 24. downtime: total downtime (in seconds)
. j. F' P. Y/ t" Z7 ^ 25. qlimit: queue limit
; n! w; v3 [ Y# y9 `8 ^ 26. pid: process id (0 for first instance, 1 for second, ...)' b ?4 U9 G% e8 {( R0 ]) H
27. iid: unique proxy id9 z* j/ V8 E, ^, H5 J% J
28. sid: service id (unique inside a proxy); t, ?* A! K! Z9 e* M% f
29. throttle: warm up status
! p) t0 G% W9 J" ?3 G# A 30. lbtot: total number of times a server was selected
( }# A: Y2 p: \0 ^3 I$ K& Z) Z/ ] 31. tracked: id of proxy/server if tracking is enabled
9 R" q5 |: b* X1 W; D- ?+ ` 32. type (0=frontend, 1=backend, 2=server, 3=socket)7 c+ Q7 Q; m$ R2 j
33. rate: number of sessions per second over last elapsed second
) e* N: Q6 w5 J a1 j7 ` 34. rate_lim: limit on new sessions per second
( B1 I6 Q F4 j8 f7 q# A* k 35. rate_max: max number of new sessions per second# |0 X8 a7 e( \6 R+ `/ g0 e7 c2 z4 p5 E
36. check_status: status of last health check, one of:
" L, m0 q; ?1 t1 K {2 B( I UNK -> unknown
5 X$ w- p! N0 Z& ^3 i7 D4 i+ e INI -> initializing
9 f& w0 H) S7 t7 k, b3 \/ z SOCKERR -> socket error5 x( m6 b& Z" _6 H/ [. Q
L4OK -> check passed on layer 4, no upper layers testing enabled6 ?9 c W6 D3 j, j5 h# }! U1 [
L4TOUT -> layer 1-4 timeout& {' Y$ d1 o7 Y8 [* t7 ~! M$ e% L# C
L4CON -> layer 1-4 connection problem, for example
2 w5 ~" m7 b7 Z$ m% N% z0 \) \ "Connection refused" (tcp rst) or "No route to host" (icmp)) f" k" Y; b; F* v1 H+ A
L6OK -> check passed on layer 6 U8 E4 Q) h- g1 |' R) c
L6TOUT -> layer 6 (SSL) timeout
3 B( Y' ~# T6 B9 ^: i, q+ B' M L6RSP -> layer 6 invalid response - protocol error
. m! o7 i9 b: R3 o2 T. _+ B3 H L7OK -> check passed on layer 7
4 E9 Q( B, ~! D, ~% ]# e; V L7OKC -> check conditionally passed on layer 7, for example 404 with" _% |! I1 M4 l; T- w- \5 e
disable-on-404: s {' S; d3 S$ z
L7TOUT -> layer 7 (HTTP/SMTP) timeout% n! A7 b, y; I4 c, e3 O
L7RSP -> layer 7 invalid response - protocol error0 x/ r5 i% @6 ?
L7STS -> layer 7 response error, for example HTTP 5xx% u/ z4 U y- r( C: N7 S7 X
37. check_code: layer5-7 code, if available
" z8 V3 ~- Z3 r( Z9 I 38. check_duration: time in ms took to finish last health check
! U/ y( v6 \$ A X* v 39. hrsp_1xx: http responses with 1xx code
! V9 S$ |+ L# i# o# Z+ S 40. hrsp_2xx: http responses with 2xx code7 n- ?1 ]' H4 f0 ]' T6 F- o
41. hrsp_3xx: http responses with 3xx code
* h A$ R9 `) u5 K4 V 42. hrsp_4xx: http responses with 4xx code
9 K, m& i& F: _" x 43. hrsp_5xx: http responses with 5xx code; Q" O# K. N9 k9 q: v4 S2 G7 y
44. hrsp_other: http responses with other codes (protocol error)
/ `" L6 r- q/ Z4 R) V 45. hanafail: failed health checks details
7 \7 p! Y V- ~, j0 d 46. req_rate: HTTP requests per second over last elapsed second
& u; Z' J4 U( {% r, _ 47. req_rate_max: max number of HTTP requests per second observed
4 d8 E, r8 c0 Y# P0 c: O5 t 48. req_tot: total number of HTTP requests received; o" C0 Q; r, R ^ f, G4 ^
49. cli_abrt: number of data transfers aborted by the client
/ }; N" e7 T- `- o 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
: R5 a* N/ I1 _' T0 T* J, j. I9 k1 {/ Z+ v2 I4 |
6 j3 Q# F5 x- O* H" F6 \! o
9.2. Unix Socket commands
9 N4 E8 j5 g! H1 E7 B-------------------------
2 V L7 f7 N1 ^2 L3 d
' {! t2 ~- C, H0 h" UThe following commands are supported on the UNIX stats socket ; all of them
0 _5 o5 A& {) w$ C4 y8 w [must be terminated by a line feed. The socket supports pipelining, so that it
" `1 E2 h& s4 V- I+ C7 Iis possible to chain multiple commands at once provided they are delimited by
+ S! c/ C# r' o& Y- ua semi-colon or a line feed, although the former is more reliable as it has no( t4 R, o2 ^7 t6 K
risk of being truncated over the network. The responses themselves will each be, F @" g7 _# {7 ?5 w5 \ i
followed by an empty line, so it will be easy for an external script to match a
) I3 z7 _ d+ x6 X% F. U. ^given response with a given request. By default one command line is processed6 }& ^+ k3 H( i( V9 W5 C7 L0 j m
then the connection closes, but there is an interactive allowing multiple lines- ]8 ?) R" r! \" y
to be issued one at a time.
! J, N1 P3 l/ z6 I: z, X
% L& z& F; N+ YIt is important to understand that when multiple haproxy processes are started
5 o Y/ U6 i3 @5 q2 q& r0 d2 Uon the same sockets, any process may pick up the request and will output its
# t8 Z! @ [) k4 Q3 zown stats.! d+ Y7 y, J8 u# B
8 t, n; N! V" T6 G5 Y7 H- i- Yclear counters0 R6 P4 E' `' c
Clear the max values of the statistics counters in each proxy (frontend &
N7 i- }/ f8 ?1 {6 D* y6 O; T9 x) K backend) and in each server. The cumulated counters are not affected. This
* V6 Z( g2 @+ N$ C+ i( ^$ [# Z# t can be used to get clean counters after an incident, without having to
! v5 e- X: n2 v2 `% e7 w$ H* o% F restart nor to clear traffic counters. This command is restricted and can% f2 y0 A& W& ?+ D' p; T; H1 M% S
only be issued on sockets configured for levels "operator" or "admin".
8 N: w6 t- R4 X' V* A% P1 t) Y2 U! Q! Y4 y5 _2 } P" M- b6 B
clear counters all
7 |8 E: j/ |3 V! R) Q8 m Clear all statistics counters in each proxy (frontend & backend) and in each$ n1 v; g, x! C
server. This has the same effect as restarting. This command is restricted7 @. {# D( z& J4 k# Z# c4 G
and can only be issued on sockets configured for level "admin".
9 E- S* I$ _7 r+ r8 u1 a
# W9 q8 ?7 w. p+ vdisable server <backend>/<server>
( c* M' k7 z6 E9 N3 W Mark the server DOWN for maintenance. In this mode, no more checks will be8 Z L3 E3 g d% Q M* L
performed on the server until it leaves maintenance.8 g8 l, B, g$ x: n" v
If the server is tracked by other servers, those servers will be set to DOWN
; ^' N7 G6 G/ I during the maintenance.
$ x+ e1 B+ t$ z2 E+ @
- i% n. f L, ^! `2 M! ` In the statistics page, a server DOWN for maintenance will appear with a8 U3 a5 ^2 i) P2 g9 H" [
"MAINT" status, its tracking servers with the "MAINT(via)" one.9 I! U. B# \) D2 E" B, o; O
. W0 k/ G% b7 W$ x/ a
Both the backend and the server may be specified either by their name or by
; g' y7 U E: y their numeric ID, prefixed with a sharp ('#').
0 z& J+ C/ U3 r- ?1 }, C5 G7 |( ^3 J
This command is restricted and can only be issued on sockets configured for
' n2 z. B" x# }, z8 \2 |( a level "admin".
4 [$ `- c& } Q5 g: u" Y
7 x" R7 k( z/ q+ [. B7 v* I) kenable server <backend>/<server>
6 a y( H. D9 b2 G3 R/ s' e; N- t If the server was previously marked as DOWN for maintenance, this marks the
. e" A3 t! Y' f. o$ i& \( C server UP and checks are re-enabled.5 X" d0 U6 G& K2 }: m& T
8 F% K5 i5 Z' N( E- @ Both the backend and the server may be specified either by their name or by
& g# O5 n$ y- H0 t" {- {' R their numeric ID, prefixed with a sharp ('#').
4 j9 V6 [* r2 y/ G5 l$ Q
8 X) W( I3 ]' t* I3 F% G/ r# } This command is restricted and can only be issued on sockets configured for
- b x; g+ s$ ~" g S level "admin".; |: {4 H7 }8 F1 C [1 m0 E
9 l* b. O7 ^2 Y) O$ S- E5 q$ Sget weight <backend>/<server>
4 u3 _$ E& n) f1 {, Z Report the current weight and the initial weight of server <server> in
. M M: m0 G1 h) @. {- `& ]% {* `( o backend <backend> or an error if either doesn't exist. The initial weight is* H- a& N" T1 L0 {+ w
the one that appears in the configuration file. Both are normally equal) L3 b( N/ Q B, T2 X7 K2 B
unless the current weight has been changed. Both the backend and the server
: n# m, K1 v! r: s may be specified either by their name or by their numeric ID, prefixed with a+ h/ z; k/ M# [$ |# v5 X# W/ r% N% v
sharp ('#').7 y3 x* n- I9 g, }& _- \
8 C0 I6 e n) x9 v
help) \/ ?: k- s$ A6 D. H+ p$ `, E
Print the list of known keywords and their basic usage. The same help screen1 f9 Q5 ]; B" H7 w
is also displayed for unknown commands.
. m+ p2 t6 h! c
- e; j5 O0 o& _! Y3 F, A$ W& Q, Y4 Uprompt
0 b z; q- R) {% M Toggle the prompt at the beginning of the line and enter or leave interactive. O( c1 m$ \- V' s) O
mode. In interactive mode, the connection is not closed after a command
6 b# l' K2 \3 c) F( H completes. Instead, the prompt will appear again, indicating the user that5 @* Y. t# E" V6 F
the interpreter is waiting for a new command. The prompt consists in a right4 d; t1 x! i+ x: V+ p0 i! ?
angle bracket followed by a space "> ". This mode is particularly convenient
: X6 ~# {' j5 E0 V7 Z+ ? when one wants to periodically check information such as stats or errors. Q& b6 P3 m% N
It is also a good idea to enter interactive mode before issuing a "help"
1 {+ t5 X3 Q" ^+ P( E7 [$ D# U command./ k( s7 N( M$ G: p# y
5 u* }) L! { J1 n& {* S( _
quit: y$ P" I. I1 @1 m
Close the connection when in interactive mode.
* E! C1 e* K$ W( L" }3 ~, p% O+ W' {( C; Y& R
set timeout cli <delay>
: D H3 d6 |9 Q+ }. i# J+ B6 O# P j Change the CLI interface timeout for current connection. This can be useful9 _- p. X* {+ [/ n
during long debugging sessions where the user needs to constantly inspect
9 \! n" P4 e2 Z9 [8 X1 _ some indicators without being disconnected. The delay is passed in seconds.7 P% f B. {% |) ]5 ~
4 M4 }! w1 t' _8 A, t9 `# Wset weight <backend>/<server> <weight>[%]* Z& u, S0 [, k& b
Change a server's weight to the value passed in argument. If the value ends
* U+ C- X* B* [* ~. i+ j with the '%' sign, then the new weight will be relative to the initially
0 q" O2 Q4 n# G4 E L configured weight. Relative weights are only permitted between 0 and 100%," h8 [- X9 b6 A, M
and absolute weights are permitted between 0 and 256. Servers which are part
& B9 I. r$ Y) k: M- w4 V of a farm running a static load-balancing algorithm have stricter limitations! @* D+ T; l: H( e; E" P! }" ^
because the weight cannot change once set. Thus for these servers, the only
/ |3 N/ B6 E0 |+ [ accepted values are 0 and 100% (or 0 and the initial weight). Changes take
8 N/ `3 A8 W. g( ]" ^& t/ B* X effect immediately, though certain LB algorithms require a certain amount of8 u3 ]& J+ {: s5 V d! |
requests to consider changes. A typical usage of this command is to disable
0 C: P' _" R! D1 T a server during an update by setting its weight to zero, then to enable it K9 ~+ d7 D( p$ t6 h
again after the update by setting it back to 100%. This command is restricted
1 \. v l3 w2 `( ~ and can only be issued on sockets configured for level "admin". Both the
0 G! p" ~, S8 X, O backend and the server may be specified either by their name or by their
$ e; k3 L4 L- n! t' e# G) N3 J' q numeric ID, prefixed with a sharp ('#').: i/ a' [# t+ t; H$ N T8 i) S
$ X& b; `+ H2 f9 W% x) E7 `) dshow errors [<iid>]
& [. r4 b3 l' S- T1 e Dump last known request and response errors collected by frontends and# U* O4 i. C7 w' v' j L4 B1 z
backends. If <iid> is specified, the limit the dump to errors concerning
4 E x/ ]2 i; S* Y, H0 O either frontend or backend whose ID is <iid>. This command is restricted
. C+ q1 B. V7 ] r4 ~; R and can only be issued on sockets configured for levels "operator" or5 I* T6 c0 P& r/ ?5 g
"admin".4 |6 @3 B. J6 N& c) t& `
, o' r5 A$ m y5 f7 b: p5 P
The errors which may be collected are the last request and response errors( q8 n9 h b' D" q; Q4 H
caused by protocol violations, often due to invalid characters in header' [' l# F) [+ |7 s+ a" M/ C
names. The report precisely indicates what exact character violated the
0 ]) L7 I0 l* z( y3 I* T' {) o protocol. Other important information such as the exact date the error was
2 J% \* D& m& L0 V8 @* M, ] detected, frontend and backend names, the server name (when known), the9 l1 Y' {6 a! e" m
internal session ID and the source address which has initiated the session( ?8 H% ]% `) ^2 w2 K5 a
are reported too.
4 ~2 n1 U& q* r' U
" c8 |' q$ o d% c3 Z M5 Y) u" @1 c All characters are returned, and non-printable characters are encoded. The
. R1 K+ L7 Y r0 R+ F% B most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one
: ?3 P2 r9 c8 W! [ p letter following a backslash. The backslash itself is encoded as '\\' to2 E% y" M7 l [, T2 i8 G
avoid confusion. Other non-printable characters are encoded '\xNN' where6 ]0 }' t, s0 q
NN is the two-digits hexadecimal representation of the character's ASCII A3 H, p$ A: l h/ v
code.5 F' a; J/ I9 E& N
7 W* g8 ]. ]' E
Lines are prefixed with the position of their first character, starting at 0
5 h/ @/ l! v" j& w/ g for the beginning of the buffer. At most one input line is printed per line,
8 }, t. g$ L3 g$ U3 s7 [ and large lines will be broken into multiple consecutive output lines so that% M9 R8 W9 K3 P7 A
the output never goes beyond 79 characters wide. It is easy to detect if a/ Z$ L' Z1 b9 g8 K) r0 P: w
line was broken, because it will not end with '\n' and the next line's offset
; i6 |! [" J# _" j4 O7 ]* K$ ~ will be followed by a '+' sign, indicating it is a continuation of previous
' N& x; v: v% E2 {, ^3 ~! I* Y line.8 n$ L/ `6 V: o3 \" r
" Z% n# l. o* Y4 d Example :) s( U- _& D5 f6 P( \
>>> $ echo "show errors" | socat stdio /tmp/sock1
) {9 h+ Z) Z5 X2 C [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response
$ P& n! T* M' d4 \, z8 M& b src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)
6 x% y& h* Q) a4 w7 G response length 213 bytes, error at position 23:
4 r2 r- P' {: a: d& w; b& d+ ~( d2 |9 V7 @) Q" h0 n6 y0 f
00000 HTTP/1.0 200 OK\r\n
, J8 w, @( f- F v 00017 header/bizarre:blah\r\n( K" A! c. | l) H1 V( r, c, C
00038 Location: blah\r\n9 d& P5 T4 o0 q6 T
00054 Long-line: this is a very long line which should b" x0 E* C4 `: [+ U
00104+ e broken into multiple lines on the output buffer,. x' n: q# Z- b- t% [
00154+ otherwise it would be too large to print in a ter( E8 Q0 R( R3 g
00204+ minal\r\n
# a1 w# C: a$ y 00211 \r\n6 ] Q% T# Z1 X8 z7 y
- e1 f) X$ N9 w4 _, i: G3 Q/ Y In the example above, we see that the backend "http-in" which has internal
; `/ z8 T! D" q3 @& s. `9 \9 s ID 2 has blocked an invalid response from its server s2 which has internal
& @, ^% }9 x9 P& |7 }2 v ID 1. The request was on session 54 initiated by source 127.0.0.1 and1 s5 C( U6 b/ x
received by frontend fe-eth0 whose ID is 1. The total response length was
9 J% ^4 x8 Q0 I7 w7 [) g- N 213 bytes when the error was detected, and the error was at byte 23. This
" `, A0 K2 o& @) Z is the slash ('/') in header name "header/bizarre", which is not a valid
' k9 i" f& `/ ^5 C% u HTTP character for a header name.
b+ W6 s& B3 S9 \) M
- P1 v- m3 H7 ?4 h% i9 b Hshow info' G% _ g) ^4 @2 s9 X: F
Dump info about haproxy status on current process.
0 w& P% S1 B4 Y' ?9 _
; o6 K$ V9 R* Ishow sess4 B. c, n# H1 n- O4 d+ a7 ]1 g
Dump all known sessions. Avoid doing this on slow connections as this can
* I1 _# {( A* |' B% [7 r2 b be huge. This command is restricted and can only be issued on sockets
5 d0 ~' }) d- Q7 s configured for levels "operator" or "admin".
/ ]# S+ ~2 L4 S ^6 c7 D k5 A' s5 Y& F1 c- R `
show sess <id>
4 M% P% v% t! F w: c0 a Display a lot of internal information about the specified session identifier.
7 D. o* @3 f# u& i$ q1 [ This identifier is the first field at the beginning of the lines in the dumps& B: n" b) y2 c! A
of "show sess" (it corresponds to the session pointer). Those information are
& G% v ]2 S5 z+ a2 {5 m" a0 |- I) z useless to most users but may be used by haproxy developers to troubleshoot a" Y/ s% B+ g4 Y8 f- b5 _
complex bug. The output format is intentionally not documented so that it can
+ S" q( P0 S* |0 f! c2 y freely evolve depending on demands.
1 N+ G/ o9 ^- f- j8 C
, ~( E$ M1 j% W- bshow stat [<iid> <type> <sid>]
2 I$ J' ~/ P, J5 } Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
. O& @4 ]3 S1 H possible to dump only selected items :7 {( h* T5 p. J8 Y/ o( j- C6 O% v
- <iid> is a proxy ID, -1 to dump everything
" R- x6 e; Z; H' { H! p - <type> selects the type of dumpable objects : 1 for frontends, 2 for# c* j, O/ D; k' a9 o+ f
backends, 4 for servers, -1 for everything. These values can be ORed,
7 \) V( Z" X% d* |( c for example:' b4 `- m$ r! h% m- l
1 + 2 = 3 -> frontend + backend.
: x" | v2 N- q' Y0 _ 1 + 2 + 4 = 7 -> frontend + backend + server.
/ B& t6 U3 R) V - <sid> is a server ID, -1 to dump everything from the selected proxy.
$ J6 F. T7 S0 g6 P: j* K, X3 c' G5 a
Example :6 @$ T9 d; o( n6 A
>>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock1( i4 c3 K: X8 h% Z9 g4 F0 v
Name: HAProxy! |) q0 `& X# C# y( y$ i- G4 A
Version: 1.4-dev2-495 W% F7 }7 J$ { J
Release_date: 2009/09/23$ `+ n* Z/ V2 F# B* c
Nbproc: 1; V- v! g5 ]* l9 f
Process_num: 1
: H! ^7 e% M) r! f" C( E/ a (...)
) _" _; t# L7 |( c' e, K, h( Q+ N) ^& |: |+ B; U5 Y
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq, (...)
: _) [5 x9 {, C- `6 o3 J4 b stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
# F5 y3 c4 `9 V7 a/ H stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...)
2 B- U7 P7 \; J) `! S/ b' E (...)+ J$ K, D6 ~3 {( i; T' r5 W
www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)& K2 q4 R) S. {( x# M
( M" d4 r( \8 V3 K# q5 F4 r $$ d, T! F( r8 F J p# f/ l, ?
8 Y6 C& C- Y' C% [% e
Here, two commands have been issued at once. That way it's easy to find
# d, y4 o% g: j- F which process the stats apply to in multi-process mode. Notice the empty2 U6 X' ]3 P7 y) O& e+ G# \: c
line after the information output which marks the end of the first block.( m5 b6 M- {9 M9 ?) G
A similar empty line appears at the end of the second block (stats) so that
; ]7 C B/ `) m/ ^+ r the reader knows the output has not been truncated.
- C+ C) f1 U, L. }! ~/ o) R1 \; \9 c9 G
+ x1 z- Y* @- C/*
$ ^: x- u/ w" ^$ B$ F6 M4 B! r& l O, V * Local variables:$ ~- c5 }" E Q P: x' A( k! Z
* fill-column: 79. f) t7 |2 t. h4 M9 y3 s
* End:
6 U! _6 e6 ?6 _2 d- G& K& E' j' O */5 p2 l( c* ]6 \* P, B
1 J9 R) `" L! A: O. t0 x
* ~6 D3 A) ?# `: z6 u |
|