|
|
----------------------
/ }6 T3 w; q+ s HAProxy
1 Z2 i @- K2 S7 h% {! D; O Configuration Manual
6 g' l5 D! V3 A& P: I- ? ----------------------
! o8 r d. ^% P }3 W) J0 [ version 1.4.275 H* M& Y* }1 d: I6 g) F- E
willy tarreau
8 O5 u) h% M m+ \1 [ 2016/03/13
: u3 {7 U+ R. C q2 C1 c' _; W
4 r/ Q K5 d u2 Q2 \8 I% ^& j
& t6 w* Q" w6 j; k& |' x) lThis document covers the configuration language as implemented in the version# O$ ]( D* B( r( M1 L! o" n
specified above. It does not provide any hint, example or advice. For such3 j! @9 z! d' {
documentation, please refer to the Reference Manual or the Architecture Manual.0 Z. l/ E: ]1 u, R, O
The summary below is meant to help you search sections by name and navigate
; C7 D |" H; J* J1 n& H% Ethrough the document.0 ?8 a J+ V8 A+ ?3 t5 }
. P% R( x$ W$ S3 @ k
Note to documentation contributors :
|$ B( N7 ^) `- f# T This document is formated with 80 columns per line, with even number of4 i8 R6 `* s/ ~
spaces for indentation and without tabs. Please follow these rules strictly
: X) X# A! [* Z- T& \* b# q" D5 Y so that it remains easily printable everywhere. If a line needs to be8 K% j% m, I |2 i" z! M5 U# z
printed verbatim and does not fit, please end each line with a backslash
/ f @0 m. [" M9 H) | ('\') and continue on next line. If you add sections, please update the
, z; _2 j/ t3 W; K8 b3 e( _ summary below for easier searching.
+ ^& _9 @- R5 o1 H' m# N
2 Y/ q% U- p+ k+ v! f/ Y, _# W9 X. a2 y m6 ]; g" e
Summary
# Q' p! |% x- B3 u3 J-------0 E/ y' M* T# b* A
' i8 V( ]: \6 }1 l) t1. Quick reminder about HTTP' D, S# ]6 R5 r+ I: n. x) E) H: j
1.1. The HTTP transaction model4 B, |% l3 t' z6 i0 j
1.2. HTTP request( b6 G) |, M# H( f
1.2.1. The Request line0 w( N7 e) {: v0 L) L
1.2.2. The request headers3 a) u' J% \# @/ [- e
1.3. HTTP response
3 }( a" t3 s% o. r2 U9 x( J1.3.1. The Response line5 f8 X5 ~2 {: a% ?& h
1.3.2. The response headers
: h) @' r" A V% D2 N# s
8 H7 Y. e2 \# b2. Configuring HAProxy$ A- _7 w2 s: _' p0 o1 Q3 D
2.1. Configuration file format
8 n; Z7 q4 a: ?/ W2 a2.2. Time format5 }- M% n1 E- @2 Q: `/ Q* {
2.3. Examples
7 T7 b7 _/ W9 J4 R! t% M9 D5 w% A/ E+ c6 `# m4 K2 Z
3. Global parameters
9 P) A4 c8 P3 [3.1. Process management and security
0 {: N* E/ h7 s8 F3.2. Performance tuning
/ R, j1 h# h6 a! [9 t: r6 l* B w3.3. Debugging
. D- N K* L9 I& D7 }1 p3.4. Userlists1 v# w# J* w" T9 [; ^
4 o+ T" a2 m m$ R: s. _5 O1 o4. Proxies9 P4 {/ r" l$ v/ O: T4 Y
4.1. Proxy keywords matrix% a0 T' b; S* E" W3 j# g# Z$ o& j7 M
4.2. Alphabetically sorted keywords reference+ M% l5 Y0 G( V# ] t) k5 ^6 t8 P
2 u, S6 ^* O- h
5. Server and default-server options
1 f" p( E) W. J# f
" a, [" U! o/ ^$ D, h2 D! [/ ^8 _6. HTTP header manipulation
) M0 X8 c6 {# N6 t! \8 o& e3 o# z/ p, i& i8 m* f) V+ _' t
7. Using ACLs and pattern extraction
. j% @5 A0 l# G# T1 s% g7.1. Matching integers( O5 b; a* w' }' t& s4 n- f: m" I9 C
7.2. Matching strings
5 J9 Z/ z9 k; r c1 V7.3. Matching regular expressions (regexes). ?4 }" W, E0 v4 U
7.4. Matching IPv4 addresses7 t7 X# I. I$ X' H
7.5. Available matching criteria
% @2 C8 n' B# B4 t K7.5.1. Matching at Layer 4 and below
0 T2 y7 X* h- X6 a, Q$ ]6 |7.5.2. Matching contents at Layer 4" k/ X- j& v( C: d+ T
7.5.3. Matching at Layer 78 A5 d6 t4 P, Y8 l4 J
7.6. Pre-defined ACLs) o# f5 g% T- j
7.7. Using ACLs to form conditions7 V4 k- R! ~7 H4 F& [$ R
7.8. Pattern extraction
$ D" q: C2 E* _ u. I+ X& ?. s" I6 c1 @) K
8. Logging% l% D# }0 Q0 O& J' _
8.1. Log levels
5 G: ]/ @8 d2 Y9 E5 v. m8.2. Log formats
) d. d6 W! P0 s5 s+ l8.2.1. Default log format
3 G# B/ E* c* M/ e4 O/ g- F8.2.2. TCP log format1 p4 t3 b$ L2 S: L- b
8.2.3. HTTP log format
8 i6 V0 Z; H& c, Q" ^, F8.3. Advanced logging options
( e) k' `6 n' l1 r7 B# E4 O8.3.1. Disabling logging of external tests
& g. D; E; _) @. y; J: @8.3.2. Logging before waiting for the session to terminate
2 J* \+ E* A' `1 U8.3.3. Raising log level upon errors
3 V8 h7 z' ?1 I% |8.3.4. Disabling logging of successful connections; M8 d+ d$ y" @) d/ y. _
8.4. Timing events* a2 [) `- d" |8 n
8.5. Session state at disconnection2 V! F7 c5 r7 t8 V
8.6. Non-printable characters
: t6 |1 r6 C. T9 a5 i" f8.7. Capturing HTTP cookies
2 y/ [. u8 v* p6 Y8.8. Capturing HTTP headers% S+ S. q. |6 q& P. y
8.9. Examples of logs4 |( {# V* h8 p8 ?) ?) x* V
. C+ i9 v' w/ l' O& l0 q) o: R
9. Statistics and monitoring
' g& i9 Q$ Y2 h1 N" a9.1. CSV format; Y+ r6 Z0 U) G& P+ y% w, W
9.2. Unix Socket commands/ z1 q2 h1 j& ~, [3 F: R
J: D, y/ t ^1 N2 ]: r! h
4 F; A" S- o* m4 D! Q) ^: t1. Quick reminder about HTTP# ?8 c6 w. P V. m
----------------------------
6 C. h& R5 F9 }, b# ^3 y1 V8 h* _, s; R: a( I7 l! E
When haproxy is running in HTTP mode, both the request and the response are) F& x5 `/ E; k0 B7 a' s( f
fully analyzed and indexed, thus it becomes possible to build matching criteria
) [( G$ N' @6 o/ J$ Won almost anything found in the contents.
% \! i q: o+ {* D6 U- i; N4 ?+ E7 p: _: f8 |& R
However, it is important to understand how HTTP requests and responses are' X5 _+ s! R% ~8 ?. s
formed, and how HAProxy decomposes them. It will then become easier to write
* a2 U7 y& W6 H- Xcorrect rules and to debug existing configurations.9 a }7 h& w# [
$ q8 w# E. d- a, C& t
o" v7 B, k2 e! t8 Q% |! V" J
1.1. The HTTP transaction model
' J4 |+ F2 [; D! w# h-------------------------------$ q% D/ j/ Y# ]" i4 M) ]
1 |! q( X7 r. LThe HTTP protocol is transaction-driven. This means that each request will lead# \* b( K) o; U
to one and only one response. Traditionally, a TCP connection is established) y! o, U& K2 s$ h+ p' h
from the client to the server, a request is sent by the client on the+ O( T. ~ [, Y5 |1 k
connection, the server responds and the connection is closed. A new request2 c0 m% i. t" E: W% N
will involve a new connection :2 u8 k' L" ~' G6 ^* {7 K7 ^' C
! w$ E0 E) ~0 }$ {0 u! j0 q
[CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ...
! m" D$ W- P; a( h/ k! u/ c3 o4 J1 y3 Q
In this mode, called the "HTTP close" mode, there are as many connection
2 z+ s$ _6 W6 c* } k. b1 kestablishments as there are HTTP transactions. Since the connection is closed
3 G) z) U, e& M, q2 ~* Q9 Oby the server after the response, the client does not need to know the content
% d8 O. E% _: U6 M: tlength.
) g- q P& m5 _+ V4 m& Y
3 X7 s: B! Y' |: Z4 Y' UDue to the transactional nature of the protocol, it was possible to improve it3 @9 E( K' X6 G, S, h8 [
to avoid closing a connection between two subsequent transactions. In this mode
" N! l' q0 ?/ l7 O ]- [2 H0 Ihowever, it is mandatory that the server indicates the content length for each
3 F! {" K4 z/ K3 yresponse so that the client does not wait indefinitely. For this, a special0 h# w# l) @' O# w4 k
header is used: "Content-length". This mode is called the "keep-alive" mode :: \4 |- {+ @* B+ _) X2 f9 J
0 n4 ~ T4 G' K3 p [ D: {% E5 c [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...
' j6 x( G; D1 S1 ?; R( Q. A0 {8 C0 `6 _
Its advantages are a reduced latency between transactions, and less processing% t8 u. q" B/ n( [
power required on the server side. It is generally better than the close mode,
5 F6 c0 G5 Y: K' Zbut not always because the clients often limit their concurrent connections to0 Y- {8 I1 X8 b/ Q7 v* u# |0 @
a smaller value.% p9 |! B* j5 u' p( v
1 Q7 U( N2 U5 ]
A last improvement in the communications is the pipelining mode. It still uses% U. C, a+ g) M; F$ N% l
keep-alive, but the client does not wait for the first response to send the
. W+ ^( `8 N0 m& f. f$ Nsecond request. This is useful for fetching large number of images composing a
o& N; j- x5 F h( c3 ~4 Vpage :
i( d/ ]" O7 U/ W8 t" u+ P" j. z7 l( M2 t/ ] G* O( p, {
[CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ...
4 Y; X3 c, R/ r6 E
+ k! | ^ u; h; W, Q3 V( `This can obviously have a tremendous benefit on performance because the network
& t5 Z; }2 @3 q$ C. w: g; B Flatency is eliminated between subsequent requests. Many HTTP agents do not
, c: `) Z1 I( R [4 F/ z7 Jcorrectly support pipelining since there is no way to associate a response with+ N2 t+ R c+ T
the corresponding request in HTTP. For this reason, it is mandatory for the+ p0 ^7 n2 ]$ M) [2 w% o
server to reply in the exact same order as the requests were received.* {6 _8 i5 F- H2 Z& ^/ p
4 ^: o8 V g; r# F! E' O/ n( v
By default HAProxy operates in a tunnel-like mode with regards to persistent
: h' E9 T) o4 a# F* econnections: for each connection it processes the first request and forwards
1 q& W0 y: \1 U7 T% w7 S8 Teverything else (including additional requests) to selected server. Once# B2 \/ s. R3 C5 I0 w
established, the connection is persisted both on the client and server$ D7 X( A$ f+ h& _$ A
sides. Use "option http-server-close" to preserve client persistent connections3 A2 U/ A5 f n
while handling every incoming request individually, dispatching them one after
4 X1 L2 n4 J9 ~. i2 {4 tanother to servers, in HTTP close mode. Use "option httpclose" to switch both1 K( C/ Q' v2 [7 E/ ~
sides to HTTP close mode. "option forceclose" and "option
2 M1 [0 [9 f- G( Z- khttp-pretend-keepalive" help working around servers misbehaving in HTTP close
% X1 ]# z3 C# @7 Y: Y+ E& xmode.
3 r" }! |8 r/ n \/ F
- d5 L5 h: S& i' x# |
% |# S0 D7 C& l) [6 s; x1.2. HTTP request; s- V8 i! j+ O% A! b0 f3 ~& G
-----------------
3 y( e0 k- s8 G; {6 |3 G
& L* m! i4 d3 H. `. J! RFirst, let's consider this HTTP request :- j1 O' Z2 Z' \; u" ^
) o! v8 I- o. ]$ v Line Contents* P. H/ X; _. H9 G# A- ~
number$ q. G2 ?$ Q$ E
1 GET /serv/login.php?lang=en&profile=2 HTTP/1.1$ h4 V0 t- o# ]) @3 l3 N
2 Host: www.mydomain.com
! n5 N1 F8 Q, I9 W7 x+ M- \/ Q0 D 3 User-agent: my small browser
. n% e& W I1 L# c+ h0 Y8 p 4 Accept: image/jpeg, image/gif5 n9 b/ c+ Z8 i, z i- \* j+ x3 B" h
5 Accept: image/png e6 e5 Z- e7 [8 G; T: I! E1 ^
7 j+ \5 W3 }1 H1 g
( y! @. u, U# l8 g) D
1.2.1. The Request line
* J: {1 B" X! I9 t5 U-----------------------
6 M8 v- n/ ]) [2 M. q) @" M% I0 ~2 B2 c, X
Line 1 is the "request line". It is always composed of 3 fields :, S k# l% T' x5 u7 G
5 P- c) T9 e/ v% b( x4 {% U
- a METHOD : GET
# `' y7 |& Q% T& j, o - a URI : /serv/login.php?lang=en&profile=2 Y, b3 o6 L8 n4 }& z" J% w& V
- a version tag : HTTP/1.1
) [- m( f* \6 X
. q0 L# l: f2 c$ i( j- sAll of them are delimited by what the standard calls LWS (linear white spaces),+ V3 @0 C- H* B6 k
which are commonly spaces, but can also be tabs or line feeds/carriage returns
r5 L. U0 Y( l; L. v/ ?; Jfollowed by spaces/tabs. The method itself cannot contain any colon (':') and
/ L0 K ~% F; y% C1 E* His limited to alphabetic letters. All those various combinations make it
" ?$ a. T* x+ ^* R1 Cdesirable that HAProxy performs the splitting itself rather than leaving it to* @( @2 o: r: u0 t+ h' g
the user to write a complex or inaccurate regular expression.
, e. I, i G) ?1 G# y T) }) F$ |: p; }1 {* W
The URI itself can have several forms :
# m' H. u# K, o) Z4 Y1 r$ i( \& H2 ]7 I
- A "relative URI" :
E: U6 y! A! d# }2 b( s' h, G) F( ?0 F1 k
/serv/login.php?lang=en&profile=2
, `( m3 H6 n3 R
8 h7 t" ?/ }4 r, P$ a! H It is a complete URL without the host part. This is generally what is
, f8 a- X! q% |) q received by servers, reverse proxies and transparent proxies.
0 W' W4 S5 w; b! z4 u- U! q, M% w9 k. T# d
- An "absolute URI", also called a "URL" :6 H( F4 v( a3 e% w, _/ N
! ~! i$ C! \: F. L
http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
# u3 |. Y* L. Z: x5 H+ [& M* Z5 t7 F' J6 r+ \2 t& N( N3 @
It is composed of a "scheme" (the protocol name followed by '://'), a host
0 n7 S8 I% V" H, |7 [: X name or address, optionally a colon (':') followed by a port number, then
$ l4 J* s4 g/ `$ M: A, f* P# f6 v a relative URI beginning at the first slash ('/') after the address part.
( u* V7 S' Y1 q+ u1 c This is generally what proxies receive, but a server supporting HTTP/1.1
! w4 o* `: n' E must accept this form too.
* y' n% L! `! R, U; f* n6 @: o2 Z! B3 O! f4 W# u/ U0 b
- a star ('*') : this form is only accepted in association with the OPTIONS
, j1 G% G. L" \ method and is not relayable. It is used to inquiry a next hop's
, M" ?* k5 h8 ?2 s: ~ capabilities.8 y |0 _/ W: @3 X/ f, j$ D- @
: T1 ?1 e5 B" {
- an address:port combination : 192.168.0.12:808 `6 s6 z, ^' w% ~/ a8 G
This is used with the CONNECT method, which is used to establish TCP
( B5 R8 H; J, g1 k& F8 J$ x/ J- b% s tunnels through HTTP proxies, generally for HTTPS, but sometimes for2 d/ I8 U0 R. C/ W
other protocols too.
8 J) Q# R! j7 z+ {$ q& ?: {& ~: G3 x4 u- F. J
In a relative URI, two sub-parts are identified. The part before the question
8 A+ K' Z& ?4 M- Nmark is called the "path". It is typically the relative path to static objects
2 ~: z0 A; i% J$ U3 v, lon the server. The part after the question mark is called the "query string".
$ V7 V4 D$ P5 X! ]3 jIt is mostly used with GET requests sent to dynamic scripts and is very# H9 i" U9 v/ R( P3 i, ~ U% J
specific to the language, framework or application in use.
3 R3 b3 |2 }, S. K; B$ n+ Q1 I/ G' B8 \( Y2 u- A% l
9 O8 F1 j" X- ?+ M2 y8 R
1.2.2. The request headers* G. `0 E5 F! f& `' V- g
--------------------------% d1 y) }. x7 P" j; Q3 [2 x* D# y
+ Z" C' }# A, `5 n, \9 d
The headers start at the second line. They are composed of a name at the* ~# {, |, t% T+ G/ |" t
beginning of the line, immediately followed by a colon (':'). Traditionally,
7 p1 ^ D! L5 `& E2 ^' Kan LWS is added after the colon but that's not required. Then come the values., o. C8 }0 Y' R& }1 _
Multiple identical headers may be folded into one single line, delimiting the
' n7 E$ X! i, y8 Fvalues with commas, provided that their order is respected. This is commonly. n# r% S# w9 z7 E% O
encountered in the "Cookie:" field. A header may span over multiple lines if
4 J' V% G5 w& G/ D w2 dthe subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5
4 x; c, m7 o* M! f5 xdefine a total of 3 values for the "Accept:" header./ }# Y( `) n8 J* G# r
$ x5 L8 ^* u, f- c! f- R& zContrary to a common mis-conception, header names are not case-sensitive, and4 P3 V& C& I8 d; Y
their values are not either if they refer to other header names (such as the' W+ H3 d6 S) r, y
"Connection:" header).$ U8 k9 N5 ? E) I4 r+ }
+ c6 f0 `) k: zThe end of the headers is indicated by the first empty line. People often say& A/ G4 d- A+ T
that it's a double line feed, which is not exact, even if a double line feed
, j+ x7 I( U0 S, z, Z Jis one valid form of empty line.4 p; u H% h# f3 f
; D$ E$ i4 A4 I% q9 M7 o2 C. H
Fortunately, HAProxy takes care of all these complex combinations when indexing
0 j8 W/ F* ?# B. e ?$ Jheaders, checking values and counting them, so there is no reason to worry+ s- n7 D0 ]1 P; }
about the way they could be written, but it is important not to accuse an% i1 J, H9 M# F+ c
application of being buggy if it does unusual, valid things.. @$ b" `; F# h
$ ^1 |+ E4 @3 d0 Y# b+ AImportant note:. r7 Z( h9 t. w0 V+ o, Y. L
As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks8 i/ i4 z/ P, X' \3 H
in the middle of headers by LWS in order to join multi-line headers. This
3 A7 }( d) V/ `# @ is necessary for proper analysis and helps less capable HTTP parsers to work# M/ n3 P2 u9 V+ }* l7 t
correctly and not to be fooled by such complex constructs.
! c4 V+ `! p# P$ f# [7 D
4 P- C) c% _' `7 ^7 V' G" }/ k4 I6 i5 [4 ]* ?: m
1.3. HTTP response ?) t# H3 l3 ?2 l/ L, F7 K
------------------. d X1 W: L3 {& J# W+ ^; g
# x( V( Y4 q y3 b2 PAn HTTP response looks very much like an HTTP request. Both are called HTTP6 @5 r, T, y) h
messages. Let's consider this HTTP response : y0 b# z3 k5 F0 ~2 K
% D5 h' H# Q j$ N Line Contents1 R. h0 C9 ?2 M) Q# {$ v/ F" y
number/ p6 X1 k8 T0 W! e) _" q9 o& h& z) r. C
1 HTTP/1.1 200 OK7 s; H. D# f9 t( N
2 Content-length: 3509 X7 Y' I! z' {3 p5 O; u" M2 q8 Q
3 Content-Type: text/html; O! Y/ e8 a4 W
5 N3 }6 A% \9 d1 FAs a special case, HTTP supports so called "Informational responses" as status
% x/ ?' N" L: y n( D1 Lcodes 1xx. These messages are special in that they don't convey any part of the
' J7 b# A2 F; o; r: ^response, they're just used as sort of a signaling message to ask a client to
1 J6 g: V* R3 j. T* v: bcontinue to post its request for instance. In the case of a status 100 response+ {; f l2 M5 \2 t
the requested information will be carried by the next non-100 response message- o4 S3 ~6 Z- F- q& B
following the informational one. This implies that multiple responses may be
5 h9 S. D4 O' m/ k1 Csent to a single request, and that this only works when keep-alive is enabled4 U. I! j# U% ]% e" a$ C
(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to* k3 G" N+ T/ I$ k: {
correctly forward and skip them, and only process the next non-100 response. As
T) N/ p6 l; H$ U, Y5 {) usuch, these messages are neither logged nor transformed, unless explicitly
* i7 T2 H! C* t; C, Istate otherwise. Status 101 messages indicate that the protocol is changing
8 X/ d6 T! \; I, {/ d9 J. Iover the same connection and that haproxy must switch to tunnel mode, just as9 g5 b* \$ p; R" l$ y. L
if a CONNECT had occurred. Then the Upgrade header would contain additional
( C+ X( w r" V) J, ninformation about the type of protocol the connection is switching to.# w" u% |, J: }' d1 v) n+ g
9 O6 H- s% ] q+ E# }7 |% ~; n
: H8 y4 p1 q- z1.3.1. The Response line
! ~0 O8 \' ?: s- L5 F6 o( w------------------------/ q) y4 J2 I5 v) Z2 [
, a2 ], q; {5 N( S" c0 aLine 1 is the "response line". It is always composed of 3 fields :
3 H) S$ G( @. Y- C
0 N$ Q3 @8 r; D! U! @7 f - a version tag : HTTP/1.1
1 l4 g) Y! s& H& M( x! _4 r - a status code : 200
9 Z. ^) j- | g; ]& H9 g" E! | - a reason : OK
- j# M9 n; G! q! |. J+ e
/ B; L R$ i: n' h6 \' fThe status code is always 3-digit. The first digit indicates a general status :
) f- b4 v& Z% k2 J - 1xx = informational message to be skipped (eg: 100, 101)
1 C0 N& T! i0 r$ P. ~9 C% e - 2xx = OK, content is following (eg: 200, 206)
/ S+ ]+ V5 I2 I1 l7 i - 3xx = OK, no content following (eg: 302, 304)1 R$ N& N" a% I
- 4xx = error caused by the client (eg: 401, 403, 404)4 ^, q* i& M* t+ H( `
- 5xx = error caused by the server (eg: 500, 502, 503)
" K- i% T3 E3 H# z
7 [* Z Y4 k9 U% U* x$ f3 f. SPlease refer to RFC2616 for the detailed meaning of all such codes. The7 p0 X4 b3 _9 E& {
"reason" field is just a hint, but is not parsed by clients. Anything can be
; A" b% T( K3 g( E @ H( Q1 ~found there, but it's a common practice to respect the well-established- p/ K) X$ Q6 H' R$ u+ R! y5 c
messages. It can be composed of one or multiple words, such as "OK", "Found",
7 e o( q3 F0 n( H. c: u" xor "Authentication Required".
7 |# u \" U; k5 ?, y- \4 ?& l/ ]4 u e& \
Haproxy may emit the following status codes by itself :+ J* {& S3 i: e) W! Y+ I8 u ]
! ^% b _: a2 v2 C) G% u/ N Code When / reason
: h- H& a3 X4 d Z _ 200 access to stats page, and when replying to monitoring requests) l) W$ _+ z. I! v1 t: V
301 when performing a redirection, depending on the configured code
# {1 V1 N- N% k" [& R/ o 302 when performing a redirection, depending on the configured code# b1 ~6 d$ a. h1 s3 O( A: O
303 when performing a redirection, depending on the configured code
( D r/ p8 K% b3 z0 f3 f p 307 when performing a redirection, depending on the configured code* m- {" H8 P' U
308 when performing a redirection, depending on the configured code
& ]4 Z5 ^* a7 r3 b" ` N% D 400 for an invalid or too large request {: P6 ^' U+ Z, n* b1 h
401 when an authentication is required to perform the action (when
* R8 H; |( ]( W1 C/ v* j/ H accessing the stats page)
" ^" q5 _ M8 G9 o3 m/ J 403 when a request is forbidden by a "block" ACL or "reqdeny" filter( r! W5 m* D2 S' \& @
408 when the request timeout strikes before the request is complete7 V t/ {' e8 g6 d, ]
500 when haproxy encounters an unrecoverable internal error, such as a
/ \ X. ] t2 Q) `& W. e memory allocation failure, which should never happen# y2 q L% Y( a2 B7 Z" R b r$ Q e
502 when the server returns an empty, invalid or incomplete response, or
; C$ U9 l d& c4 \# B4 m when an "rspdeny" filter blocks the response.
, D2 C* C6 F6 E# t; R: k: G4 ` 503 when no server was available to handle the request, or in response to9 W k! j( @& ?9 X+ n) s
monitoring requests which match the "monitor fail" condition5 r! n* P, U9 h0 H4 I
504 when the response timeout strikes before the server responds8 \$ |6 I" c0 W5 x: o* ^! `5 P
7 A% m- F0 @9 u" F7 R
The error 4xx and 5xx codes above may be customized (see "errorloc" in section
* D1 w' r. z( L- v4.2).
& C$ I- U/ V, w i. X: T' F
: B% E" s0 d$ Q0 D5 i' S& v# o9 c2 F; q" X
1.3.2. The response headers
% z- _, G# O0 S, t' Q, i---------------------------
2 ^5 ^& G2 E0 a& g5 Y! ^9 Y1 o9 ~' d/ M
Response headers work exactly like request headers, and as such, HAProxy uses; C$ M* X! Q4 w6 O$ C- V
the same parsing function for both. Please refer to paragraph 1.2.2 for more1 R$ U+ Z0 K" i; O0 S' u
details.
9 K$ x. y3 Y8 a8 Q( w! D
! f# U8 m1 J) h9 F( E; U5 A# `/ ^
, x( x+ v' u9 \" _' G- P2. Configuring HAProxy
4 R& j, a# K; Q4 ]( n1 k, w----------------------
) Z7 f( M% J/ K; `9 E; p! H) L9 z2 o$ v0 K" |! @
2.1. Configuration file format
$ T1 F' x( ? X, F. W* I% p1 S( K------------------------------
* h$ u5 J2 T' |2 m* ^) J" E, E( Q/ |! \+ w
HAProxy's configuration process involves 3 major sources of parameters :
1 S5 a. R! j4 q# w1 W4 S9 |1 X
* \, V; \3 T" C5 M - the arguments from the command-line, which always take precedence8 w, m5 V& S* |( {3 L8 Y, w$ ^6 V
- the "global" section, which sets process-wide parameters: b5 c& c: b+ a* ^
- the proxies sections which can take form of "defaults", "listen",
0 ?" H i5 k8 m) Q6 q "frontend" and "backend"., B. q; K& g* ^/ t1 Y
- K$ g! n) Y+ z" W: P
The configuration file syntax consists in lines beginning with a keyword
* e0 L) p" ~, n: N, \% B8 lreferenced in this manual, optionally followed by one or several parameters
! I+ Z% O4 k* B6 B1 Jdelimited by spaces. If spaces have to be entered in strings, then they must be, a0 d: T7 f# b! N; C& i v
preceded by a backslash ('\') to be escaped. Backslashes also have to be
0 h1 N2 [3 {+ d. F5 _, Hescaped by doubling them.
; Z6 _' A2 L. l% X+ H0 n/ T! l9 ^
* y. A+ C! f- l* I( h! _8 [/ R2.2. Time format |2 \5 h2 D& I" g m W& b; ]( r4 ?
----------------7 G: U- w$ d! S+ J* Y4 A5 Q
! i2 t( g4 t6 [Some parameters involve values representing time, such as timeouts. These6 S+ x( u7 G6 |5 C# t
values are generally expressed in milliseconds (unless explicitly stated' M+ z" U9 _ D9 s* O% S$ T
otherwise) but may be expressed in any other unit by suffixing the unit to the- X0 h, Z e) d* O
numeric value. It is important to consider this because it will not be repeated
3 d8 [3 p; |" {for every keyword. Supported units are :+ O5 U4 g: n7 P$ m5 K! {0 R
7 Y6 w1 m1 O1 Y" ? - us : microseconds. 1 microsecond = 1/1000000 second
: j$ Z/ g" _8 D. h/ U - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.
+ c$ J! S6 g, ?6 v+ {, F3 Y - s : seconds. 1s = 1000ms2 g0 [4 F& `* P
- m : minutes. 1m = 60s = 60000ms
" ?5 T) X3 O! X" w P" L) q( F - h : hours. 1h = 60m = 3600s = 3600000ms
1 e0 K' k, c$ B- ^4 N. S8 w - d : days. 1d = 24h = 1440m = 86400s = 86400000ms( ?5 M- G0 H. @2 M! i/ V! S
! t7 D, B: y9 y1 T7 t
. m k- p: K s* C& z4 c( e5 |2 M2.3. Examples( a/ U) U! B/ w1 q- v7 c
-------------
, s r. R3 T/ U: A* R3 S# f1 s. G+ d3 y8 Z+ I4 v0 S6 t
# Simple configuration for an HTTP proxy listening on port 80 on all
( A2 P! t U" g) W # interfaces and forwarding requests to a single backend "servers" with a
0 b9 b. i9 r! ~, r # single server "server1" listening on 127.0.0.1:8000; u3 e, G! t/ \
global
3 h. K+ w# ], i daemon. @. }7 q* j' D; N+ i- L/ \& L
maxconn 256: R: }' p1 p) I- j8 N. J
7 t8 d6 G+ y0 Z/ c0 ~0 d defaults
' \; d2 i w& t% M4 H# y mode http3 c3 h0 d# A! }
timeout connect 5000ms6 [5 g) E E+ f7 Z& B) u
timeout client 50000ms
c& y# |0 z( @1 r timeout server 50000ms# `5 {0 u- T# k2 O2 V& {7 ^
1 \; z) P. P; Q9 p9 `/ Y
frontend http-in/ f2 t2 o, }/ x- J! h% ~% r4 ~7 |4 K5 i
bind *:806 ^; x. H4 ^# ?4 z4 d1 M% v
default_backend servers. e% t; Z: v* C, S F6 z
- A6 h/ }/ G1 m
backend servers; n' N, P0 q8 k! S+ N' U
server server1 127.0.0.1:8000 maxconn 32
% I; F6 F5 `4 d, F3 N0 E
& R/ F0 M, ^! e, s: x/ N1 ^0 f e
* ~/ B- ]) W( D2 q # The same configuration defined with a single listen block. Shorter but
Z, n2 P6 `7 V# U" d # less expressive, especially in HTTP mode.5 J9 j8 @$ `# B6 i: m. }2 f
global
2 k, [ P* q, u2 `. U6 ~+ ? daemon8 P& I2 L) k2 J2 ^
maxconn 256
9 R( X, E- y; a* Y: m6 n# l% E4 s% [6 v) ~ j }
defaults- L6 g( Q$ n: A2 Q; X% \# c; Y" U
mode http3 ~: g" Z8 X5 t9 s+ l/ S6 a$ T
timeout connect 5000ms
6 B+ j h# l- F* `- Y, p timeout client 50000ms
3 U! e1 b( n% D; e' s' _ timeout server 50000ms/ k3 b2 q9 v6 @# t7 t. n% G4 _0 o
_/ D6 x4 V; B2 \7 u; Y. r
listen http-in
( g2 r7 E' O# t! E- W3 Z bind *:801 o( X* D, @; }; k; c2 m
server server1 127.0.0.1:8000 maxconn 32
1 L6 G* o( h6 \; ^1 ]& {
W# Q( J+ ~. z f" z- P& h% M6 f
$ N3 \$ H1 Y' S9 B! H' w( KAssuming haproxy is in $PATH, test these configurations in a shell with:& u8 n0 b3 B2 h# B( e: B. r F; e
2 p! O. Y: A, x# U: y; N* J $ sudo haproxy -f configuration.conf -c4 c1 Y! c, T+ Y- m$ D( ~+ ?' `
$ ^# B9 @3 K- B F: X$ K( m5 J6 V
* k$ B5 Q% S4 \8 `0 ^3. Global parameters! |9 L. y' r) r6 h8 F4 o
--------------------
* j* ]" Y8 l2 I: w) L1 w0 e- _( _3 D# [$ {' Y7 a" B8 a( w6 y; V
Parameters in the "global" section are process-wide and often OS-specific. They
& l$ R5 k8 K" n! K/ Xare generally set once for all and do not need being changed once correct. Some8 t( j+ L/ O7 J) C# ~
of them have command-line equivalents.
. `/ b& R- N; e A8 t7 \" y ~ D4 g
The following keywords are supported in the "global" section :5 |+ F7 u' Z7 q; D) ^
! x5 e' J$ B% M' A$ v
* Process management and security
" C$ j0 }- \2 Z5 r) N - chroot. Y9 r% j4 q! o# ?
- daemon; v* A- G2 L% a( a. k
- gid# }, y Q& S5 e* A; d
- group( J8 R8 h7 O o
- log
5 b, A6 U0 D% E! L7 ?; Y' F( A! f - log-send-hostname
9 H/ W' v: H! q* q) M- ~5 d* i - nbproc
# N! n. h! n* E+ N' W; k1 U1 q - pidfile" @; |2 s; F1 \& B
- uid ]& D: s- g) c: h; _$ \
- ulimit-n
6 |, u) v% h. d - user, N. t! `/ h0 c
- stats
/ k7 U* t2 Q m; m: z8 C i - node! H& z9 M" P6 n. A4 X. |* C
- description) b. w1 R$ k( m8 Q# _: p
, ]- c: m! g7 p- F% I, u# { * Performance tuning
8 I' |8 l4 x- a3 j c5 @. D2 \ - maxconn
- T" p& \2 E0 M - maxpipes5 o7 M% N' C Q6 C- B% m
- noepoll% J1 [, A' x5 z' l9 |
- nokqueue+ p3 T- c$ X( i0 f
- nopoll
# L9 t5 l2 d$ Y - nosepoll
6 @- F& }/ Z! n, n) w - nosplice+ [0 E4 z+ d* _7 r. V$ s2 }
- spread-checks
% Y. s/ [0 k7 J. o; c - tune.bufsize7 @6 b* n8 Z- G/ W
- tune.chksize! w( w' Q0 G& L& l" U3 R# h$ o* a
- tune.maxaccept
2 H7 [" l9 w0 C' m1 {$ _ - tune.maxpollevents' O+ S; v9 \" d! ?
- tune.maxrewrite
- }$ H+ ]% B; `0 f0 {( s$ z - tune.rcvbuf.client
: T* k1 x2 g& Z- l* ], ? - tune.rcvbuf.server( v: A0 u( }- ?# d4 Q) J- Z
- tune.sndbuf.client
' Z% p& g8 r4 r% q- J, p - tune.sndbuf.server
/ o% p+ m7 M" d' a6 Y+ g7 y
; L9 R2 ^5 m% _+ L * Debugging" z$ g8 [' F) m+ L1 h
- debug
5 |9 U8 o( A: ^$ b5 O B) B - quiet# i: ` w" z% K0 L7 u2 P/ W7 G% D
: `; i: M' L. W% f p- y
+ W% J" i% y7 B
3.1. Process management and security
! W0 L+ p, f# D, C. F------------------------------------
! R4 R+ r5 c* B8 `3 r- n v- u5 V" O, ~: s1 r, W8 b( J
chroot <jail dir>
/ O6 K1 c$ V, B7 j h Changes current directory to <jail dir> and performs a chroot() there before
0 ^' e4 T3 ?% Q; `$ \ dropping privileges. This increases the security level in case an unknown, @5 Q9 _( o) X
vulnerability would be exploited, since it would make it very hard for the
, N+ B- P' Z# @9 o; c attacker to exploit the system. This only works when the process is started9 t4 |# A j3 z
with superuser privileges. It is important to ensure that <jail_dir> is both
, T2 q1 ]9 n- b/ Y empty and unwritable to anyone.
* W- A, [' C$ S! l8 E$ y1 M$ }5 u8 c7 ~; J9 U
daemon" G* D! H- _9 T! a5 k
Makes the process fork into background. This is the recommended mode of
& P# g, @: B x9 r# d% z operation. It is equivalent to the command line "-D" argument. It can be* h% y' F) H5 a/ |
disabled by the command line "-db" argument.
, s! H( h) c L4 C
' X; b. c4 c1 b+ [2 n3 I7 _* Qgid <number>! t5 i9 R4 L% m k! n9 s* {
Changes the process' group ID to <number>. It is recommended that the group6 ~. G$ a) i9 f3 k2 q8 @
ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must
/ z5 Y1 X2 L: K" \; C be started with a user belonging to this group, or with superuser privileges.
5 x+ M7 j+ Z: s7 v1 W5 a$ _ Note that if haproxy is started from a user having supplementary groups, it
: }4 r0 m- e+ ^ will only be able to drop these groups if started with superuser privileges.6 D0 ?( ?% c) \( \; s
See also "group" and "uid".
& a& r( H4 a% \, f r2 W- s# S! d; H4 o7 b& `" t- Z4 A) A
group <group name>
/ ^. Q0 x; P$ c8 u5 a Similar to "gid" but uses the GID of group name <group name> from /etc/group.: m2 T- E& `& y b4 ?
See also "gid" and "user".' Z7 `5 n3 @: I' s# D7 L: n5 h+ M$ U
3 o$ v: Z" M" \log <address> <facility> [max level [min level]]8 i: ?) b6 p2 x, b
Adds a global syslog server. Up to two global servers can be defined. They
, A8 ?4 F- j6 k5 N* M will receive logs for startups and exits, as well as all logs from proxies
) C4 u# X) [( Z1 S configured with "log global".$ w7 k5 b6 k p4 n. p& \& R9 O1 w
# E$ F! A, B4 _& o5 A( X4 d7 c8 S <address> can be one of:
; b8 C8 s4 V1 e! }0 U
2 e2 K, v; G ]* f9 Q$ `9 O - An IPv4 address optionally followed by a colon and a UDP port. If
) ]8 u5 W2 j* g' { no port is specified, 514 is used by default (the standard syslog
8 b' ~3 S+ _$ Q& A port).
7 u+ I i% Z* N
' @1 [7 n# U. F( ~5 o - A filesystem path to a UNIX domain socket, keeping in mind
: |8 ~# s) v% H: d9 k, S3 ?8 i considerations for chroot (be sure the path is accessible inside! A2 e" Q) O# x9 t1 B
the chroot) and uid/gid (be sure the path is appropriately$ k! {. q/ _; n, D& z1 h
writeable).6 D: H$ R0 J- S0 Z$ l# S# `/ ~
0 h. T* u$ `9 L. c2 z <facility> must be one of the 24 standard syslog facilities :
% b A. P/ | z+ d; {' c$ P& \* u" u, A0 h2 a0 X
kern user mail daemon auth syslog lpr news- ?$ W8 c. ~! ? \/ W
uucp cron auth2 ftp ntp audit alert cron2
! E4 l0 f; v m( x8 p local0 local1 local2 local3 local4 local5 local6 local73 F) l0 n$ T& c! C8 b% w& @! Q
0 V. F6 k8 P. O) d An optional level can be specified to filter outgoing messages. By default,5 E# \8 x3 {* I5 P6 V
all messages are sent. If a maximum level is specified, only messages with a3 @, N$ ?% F2 o
severity at least as important as this level will be sent. An optional minimum
0 _! P! \7 ]5 l5 M" Q9 Q level can be specified. If it is set, logs emitted with a more severe level$ H& v0 I* H, n5 b ?
than this one will be capped to this level. This is used to avoid sending
0 w! E* _/ W: ^% W7 @ "emerg" messages on all terminals on some default syslog configurations.
* \$ S9 B7 y. g$ y Eight levels are known :3 a0 v X) x% P& ]+ t0 F9 @/ ?
' |. V6 F$ u; Y: d# O, b# I( ?; } emerg alert crit err warning notice info debug
7 q- y# p' H+ D6 q$ l: }) \1 m4 b6 S7 ]5 I6 s: n
log-send-hostname [<string>]& t+ i8 K+ w7 n& L& w
Sets the hostname field in the syslog header. If optional "string" parameter+ _' B; h2 \% {. d- X0 [6 d
is set the header is set to the string contents, otherwise uses the hostname
: J& h+ n, ], n& ]+ i2 i) j of the system. Generally used if one is not relaying logs through an
; e/ x0 j8 b3 u5 J; v% V, Q4 ^9 i intermediate syslog server or for simply customizing the hostname printed in! T( b( Y) F6 d T, S4 c! u% D! E
the logs.1 `& x# H7 i" v8 a
( U. ~7 n0 M6 Y' f \7 E
log-tag <string>
' p8 B1 _' N7 q( }+ P. Y5 J Sets the tag field in the syslog header to this string. It defaults to the6 h4 j, w! o( v+ o/ v- K
program name as launched from the command line, which usually is "haproxy".
6 Y6 r- D* h' w+ o" {; M Sometimes it can be useful to differentiate between multiple processes% o! ]& z9 ^6 e7 X3 i
running on the same host.
1 v9 G/ f+ r1 ~" P" y- G* y- n7 a% B0 _9 U
nbproc <number>
2 h2 h; W& h& r9 j) X* P Creates <number> processes when going daemon. This requires the "daemon"
7 ?3 H* C1 D+ O mode. By default, only one process is created, which is the recommended mode
( w5 ?- s: u6 x c0 T of operation. For systems limited to small sets of file descriptors per5 S- F4 N% Q, U
process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
2 W* y; w% n R IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".+ o0 s; ?$ P5 S4 T
* H* `' d9 m# U1 j6 |pidfile <pidfile>
# u u' P6 M/ n I2 p; U; N Writes pids of all daemons into file <pidfile>. This option is equivalent to
4 T3 i. h' r3 ^& r3 N the "-p" command line argument. The file must be accessible to the user
7 g; r0 x9 C; H/ j+ h starting the process. See also "daemon".: S3 f2 F" j2 |& S+ }$ u9 ?) b& y
/ C8 u3 k# D% k- \7 r. Qstats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]
" j$ A" o7 U: H' I2 W5 ] [level <level>]
: M; e; R7 U7 x# n* {" _4 L0 B- `" ^
Creates a UNIX socket in stream mode at location <path>. Any previously
$ R @, N6 E0 p! T1 {) ` existing socket will be backed up then replaced. Connections to this socket
& O" }3 ?6 }% ^. W) h+ w8 W will return various statistics outputs and even allow some commands to be
1 f$ @& R3 S3 w; k. g3 M8 C; r- {; @ issued. Please consult section 9.2 "Unix Socket commands" for more details.
# `' a. m4 ]# h/ g3 _9 Y4 g
p5 U2 Y$ q) O# d) y An optional "level" parameter can be specified to restrict the nature of
/ I* ]1 h( U4 V( Z7 m# F. {6 Q2 h the commands that can be issued on the socket :
. J& s4 w9 ]& a/ { - "user" is the least privileged level ; only non-sensitive stats can be# \# Z4 T9 [8 h- a- K$ V
read, and no change is allowed. It would make sense on systems where it; ~! p e2 W. K7 n; M5 |2 C( k
is not easy to restrict access to the socket.. \" D6 q% K- Y' {; [
0 t, f. k }. T9 @ - "operator" is the default level and fits most common uses. All data can
$ H5 e8 d" R V* ]- S be read, and only non-sensitive changes are permitted (eg: clear max
3 s0 n" u a) R+ V, @& Q counters).% W( d) q* e8 f8 m7 a& U
5 V4 q! g" @1 f$ W- s. M8 s - "admin" should be used with care, as everything is permitted (eg: clear
5 u$ e! v4 o, `6 P all counters).. X8 |( E3 a1 l' ?% X; L A! T
6 n& {# {5 E9 y2 e
On platforms which support it, it is possible to restrict access to this0 z+ l+ H6 t6 S u5 K* b
socket by specifying numerical IDs after "uid" and "gid", or valid user and) ~: k& m! c q" S
group names after the "user" and "group" keywords. It is also possible to0 y3 E! D4 B; m5 A) j5 }
restrict permissions on the socket by passing an octal value after the "mode"
9 I/ n! t2 _' P/ J keyword (same syntax as chmod). Depending on the platform, the permissions on" L7 `4 [8 p) K0 p8 ~
the socket will be inherited from the directory which hosts it, or from the9 i& P2 o/ x; }! e( y5 p# L, X6 l$ @
user the process is started with.2 F( {6 t: W5 G, c& i% W4 @( E1 c
7 @% b( h5 m' |- {) v* {
stats timeout <timeout, in milliseconds># z; J4 l& `4 I) ?
The default timeout on the stats socket is set to 10 seconds. It is possible
; L% j+ l: s' h7 j8 W7 f) Z to change this value with "stats timeout". The value must be passed in
& V0 K4 V! V* q. E/ Q" Y milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }.
. C: I8 m4 P) L5 Q: g& w( Q5 l; C/ l ?' H5 i: }
stats maxconn <connections>* [" \3 t" I' a
By default, the stats socket is limited to 10 concurrent connections. It is
3 \2 ?" j. s) k( `' _! X) Y; H9 T possible to change this value with "stats maxconn".
( L% G0 d! w$ `8 I) D6 c- X
% e7 U! ?" Z; i- y# \* g y: yuid <number>
5 I+ y5 x9 V5 A& D Changes the process' user ID to <number>. It is recommended that the user ID% S1 K9 w3 \) D5 `! w" l) s
is dedicated to HAProxy or to a small set of similar daemons. HAProxy must
5 t# _2 w( Y7 ~8 e! W% M be started with superuser privileges in order to be able to switch to another
! {4 I8 K; H: L$ h2 _ one. See also "gid" and "user".
) M+ _4 a2 w" E5 w7 ] }. R" a& Y+ x# B, J
ulimit-n <number>
$ y% j3 N* G! f1 B; ` k Sets the maximum number of per-process file-descriptors to <number>. By% M* q! c/ |5 A1 W( N
default, it is automatically computed, so it is recommended not to use this- q& X# ^2 C" U, D% j: r6 |
option.: j, J" \( v p/ l) t4 b& T
+ A9 o K/ y0 i" cuser <user name>' f+ |4 [% r& _7 V4 [; F, C
Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.7 | a; H1 k$ W5 s; ?, r0 M
See also "uid" and "group".
! e4 e- B$ R5 X0 `2 G1 p# Q) v) R) H
node <name>
" O! m2 M+ H- v8 | Only letters, digits, hyphen and underscore are allowed, like in DNS names.
& F: Q. L4 N$ u" C& p( k$ }9 v8 h0 A' b. Z3 X3 Q( [& z
This statement is useful in HA configurations where two or more processes or
9 q! p. f- x: | servers share the same IP address. By setting a different node-name on all
3 w, P+ W1 [9 {0 [; n8 K nodes, it becomes easy to immediately spot what server is handling the
4 g5 i2 ]; ]: O' A! w% |3 O3 q5 ] traffic.
& V) V$ n8 s% R9 g5 m
& ]. a) K3 q6 c- [7 adescription <text>: y' v" J! Q2 ], a" Z- Y
Add a text that describes the instance.9 {7 |6 n# {; @3 ]; A. P4 j
, O0 [4 v! [' ~$ C6 o
Please note that it is required to escape certain characters (# for example)
5 {1 V% Q, J6 d$ F& Y and this text is inserted into a html page so you should avoid using
8 L) b# S8 h3 l! H0 E "<" and ">" characters.
. e# W' z* O% v' E2 z' ?
* g" p! O5 p( v# V' `; ~: k
" M) O N# }# y4 C r3.2. Performance tuning3 P: S" q; }2 L: G _8 o- _; F
-----------------------
D6 S$ v: [ N$ ~
4 ^' g3 {; ^% N& ~maxconn <number>
9 D! o* K0 n6 e: H* N) X Sets the maximum per-process number of concurrent connections to <number>. It
9 `( Q9 W/ D# \7 ?+ s$ j6 ~ is equivalent to the command-line argument "-n". Proxies will stop accepting
& n% j8 h& Y9 `1 R6 f' j( o8 o connections when this limit is reached. The "ulimit-n" parameter is1 R+ D2 l6 Y t7 _0 H) _
automatically adjusted according to this value. See also "ulimit-n".
' s4 {! ~4 k- U! }$ o: X! {% [) ?: y
maxpipes <number>
9 J+ A; J6 G8 V1 @2 V0 ?3 X) q Sets the maximum per-process number of pipes to <number>. Currently, pipes
+ l0 \1 z. M3 \8 y: Y5 Y are only used by kernel-based tcp splicing. Since a pipe contains two file
; Z7 O& S7 d N descriptors, the "ulimit-n" value will be increased accordingly. The default
/ @+ d) V! A+ A) A1 `. v! n: U7 \ value is maxconn/4, which seems to be more than enough for most heavy usages.
: |# k9 g4 @. ^3 _. |' c% V The splice code dynamically allocates and releases pipes, and can fall back
7 }5 b4 Z# H; ` to standard copy, so setting this value too low may only impact performance.
8 }9 P2 m( P/ R: a1 f1 Y* Z; A+ a$ e( R7 u+ I
noepoll
/ g* B8 H$ T/ |. j* C; q Disables the use of the "epoll" event polling system on Linux. It is4 k; `1 r6 G( `
equivalent to the command-line argument "-de". The next polling system
0 @. [7 u* Y, F" k c t used will generally be "poll". See also "nosepoll", and "nopoll".
1 [0 c& z, m. V8 Y8 Q% r( n# R+ u. b# ]+ b
nokqueue
8 x' v( V+ `" n8 E) P0 w" v, L7 J Disables the use of the "kqueue" event polling system on BSD. It is
0 S) Y2 q' h' e& [ equivalent to the command-line argument "-dk". The next polling system
7 e) b* W% o3 a1 Q used will generally be "poll". See also "nopoll".
; y: L7 e; c6 d
' a$ g! ~6 H, w, Z5 Ynopoll+ J: o6 S$ }* u( s( c) |3 w8 N
Disables the use of the "poll" event polling system. It is equivalent to the. H# l% f9 u' i7 W& y# W
command-line argument "-dp". The next polling system used will be "select".% ^; v7 W1 ?5 M! q) c$ t5 V
It should never be needed to disable "poll" since it's available on all
. Y; M8 ?% y! D platforms supported by HAProxy. See also "nosepoll", and "nopoll" and# q; d7 } t3 t T9 Z( h( f1 X
"nokqueue".
( n; Y5 }9 @/ b* x1 M9 ^1 g- y' @# L- {% e
nosepoll
9 o) W. R6 G9 A# x3 P5 B6 s4 ~7 x Disables the use of the "speculative epoll" event polling system on Linux. It& n- ^* K' U2 s* x5 Z- Q6 n2 K* f
is equivalent to the command-line argument "-ds". The next polling system
0 z6 R! T: d- s8 n2 S used will generally be "epoll". See also "noepoll", and "nopoll".
0 O; k" E# ?1 U$ m, S6 d$ w- C9 H5 L- \2 m" B$ n+ O
nosplice
( t4 d9 R# Q: q( ~+ q, i Disables the use of kernel tcp splicing between sockets on Linux. It is
& C/ U+ Y6 y, L, U# {* A equivalent to the command line argument "-dS". Data will then be copied
* s4 D' S" I! S/ x( X using conventional and more portable recv/send calls. Kernel tcp splicing is u8 H7 L0 j) t. j' A- f( O, X
limited to some very recent instances of kernel 2.6. Most versions between s( j2 z7 ]! [- g' T
2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not
6 @3 r0 b: N/ P$ x# U+ [. S be used. This option makes it easier to globally disable kernel splicing in9 |/ @4 B7 D5 P
case of doubt. See also "option splice-auto", "option splice-request" and4 W2 e) q6 j) B
"option splice-response".
( D& W% P9 ?" K! B- s5 q; L# P/ t$ _- f" r" d+ q
spread-checks <0..50, in percent>: J; ]( Z+ u, {: Q' \" N4 w
Sometimes it is desirable to avoid sending health checks to servers at exact# G: j E# h9 S7 M
intervals, for instance when many logical servers are located on the same; w# Z( j% x8 ^
physical server. With the help of this parameter, it becomes possible to add. X3 d) [' e8 L" v2 J& t& o- q
some randomness in the check interval between 0 and +/- 50%. A value between$ V8 m4 r( X. }6 n( ~# d% \' G
2 and 5 seems to show good results. The default value remains at 0.
: H5 K' o/ }9 L& s, @' K& v- W! D4 `
tune.bufsize <number>
( ]. d2 r; P/ H Sets the buffer size to this size (in bytes). Lower values allow more8 |* H9 ~0 p) W3 S* ^
sessions to coexist in the same amount of RAM, and higher values allow some
0 \" G ?, ~, w* P6 C& R, c applications with very large cookies to work. The default value is 16384 and
# F1 H% B2 D+ V" B R# R can be changed at build time. It is strongly recommended not to change this
2 H2 N# {' E! C- F1 t4 q$ r+ [ from the default value, as very low values will break some services such as
6 s8 U( s/ X) B) z statistics, and values larger than default size will increase memory usage,5 D; I) ~# M/ R& W2 O! Q8 z
possibly causing the system to run out of memory. At least the global maxconn- U* B3 C1 f9 h7 n$ Z) [; U( O
parameter should be decreased by the same factor as this one is increased.- t2 D# u0 L: w# o' r
9 }2 h! Y* M* I
tune.chksize <number>4 h$ \, [) \8 X$ |) C3 T
Sets the check buffer size to this size (in bytes). Higher values may help
! f4 X" j( `7 R4 u' P find string or regex patterns in very large pages, though doing so may imply i1 j( x% m/ u
more memory and CPU usage. The default value is 16384 and can be changed at
* D$ M, I. x7 I8 D6 g; W" o2 | build time. It is not recommended to change this value, but to use better9 ?! U' C$ Y) S, a1 l- I9 ]* y
checks whenever possible.
# i8 z3 A" Z5 Q/ O. U6 I- s" ^8 E" V" M% `# E- U
tune.maxaccept <number>
% E; _$ { M: ^, @ Sets the maximum number of consecutive accepts that a process may perform on0 }8 w# T1 f9 X; Y9 q, e5 B
a single wake up. High values give higher priority to high connection rates,- w) j% i+ X J# O
while lower values give higher priority to already established connections.' N4 j) K( e# Q. s) q
This value is limited to 100 by default in single process mode. However, in
9 p/ ]& ~5 v, {" a+ N; A4 G9 Y multi-process mode (nbproc > 1), it defaults to 8 so that when one process
; @% o7 N6 ~/ ^# g' j- f wakes up, it does not take all incoming connections for itself and leaves a
- s2 R/ X8 @/ u: ]4 a& Y- { part of them to other processes. Setting this value to -1 completely disables
- | C3 c% \- E1 R2 t- T, v; v the limitation. It should normally not be needed to tweak this value.
6 G% o+ P$ m! F' D0 E& n9 f! c5 D4 C6 X1 Q; k# k* w2 u5 w
tune.maxpollevents <number>5 v2 Q5 e) g3 S, T! L& M2 {
Sets the maximum amount of events that can be processed at once in a call to
) R# i, A( X8 {! H) i2 f the polling system. The default value is adapted to the operating system. It
1 c& r. }3 h, M has been noticed that reducing it below 200 tends to slightly decrease1 }( k, d6 ^+ P; j
latency at the expense of network bandwidth, and increasing it above 200
2 v4 T' V( g6 L tends to trade latency for slightly increased bandwidth.
9 L$ A J3 ` X, \! K' b5 \$ W$ {1 Y% @/ l
tune.maxrewrite <number>
' N' I; k* t% o. f4 U1 F Sets the reserved buffer space to this size in bytes. The reserved space is
, ]% \1 x8 B! | X) J2 y6 V5 ~+ L used for header rewriting or appending. The first reads on sockets will never. b. i1 |- R2 }$ W; n4 ^8 i* w+ G$ G
fill more than bufsize-maxrewrite. Historically it has defaulted to half of+ @ e0 Q8 s6 t# R) z7 E
bufsize, though that does not make much sense since there are rarely large
) ]; @2 p; H8 y5 d: { numbers of headers to add. Setting it too high prevents processing of large" y" r0 n- Y1 W4 U; v/ g5 E
requests or responses. Setting it too low prevents addition of new headers4 S' x) E0 N/ f8 M/ E9 O
to already large requests or to POST requests. It is generally wise to set it7 u! ?& H9 E& c* {* v j
to about 1024. It is automatically readjusted to half of bufsize if it is
. y- }% t+ {2 s+ D2 S larger than that. This means you don't have to worry about it when changing) [9 D3 P3 M4 O: l" p6 D3 I
bufsize.' P8 B7 P: W, G) E: Z# J! k) t, u
' ]3 _ r3 e3 Jtune.rcvbuf.client <number>
7 E# B5 W q+ O! N7 Z6 V/ Ctune.rcvbuf.server <number>5 C3 O8 |" j7 v8 C+ W
Forces the kernel socket receive buffer size on the client or the server side
1 Q1 b( @6 P$ Z to the specified value in bytes. This value applies to all TCP/HTTP frontends" {! h, T2 y' Q6 F
and backends. It should normally never be set, and the default size (0) lets6 [% w0 Q6 Y5 h: ?
the kernel autotune this value depending on the amount of available memory.
! m3 m; x% H1 Y+ M However it can sometimes help to set it to very low values (eg: 4096) in
6 W3 | u3 S+ J; O4 E |0 ?8 _7 u3 ] order to save kernel memory by preventing it from buffering too large amounts
: \ _8 R1 x2 A7 X4 a of received data. Lower values will significantly increase CPU usage though.# k; m3 o$ y1 P- J. T) X8 T
6 \7 w3 V6 u$ D4 J
tune.sndbuf.client <number># {4 A5 { ~$ U3 C0 X
tune.sndbuf.server <number>, I' p$ R: z' \, F
Forces the kernel socket send buffer size on the client or the server side to+ |( f! N- ^' i B
the specified value in bytes. This value applies to all TCP/HTTP frontends
/ y! |2 \( X4 {8 i4 d! `- S" y' A8 B and backends. It should normally never be set, and the default size (0) lets6 I$ N3 U' L* R$ ~6 W; l+ I6 I
the kernel autotune this value depending on the amount of available memory.9 \5 f* e* f( j
However it can sometimes help to set it to very low values (eg: 4096) in
) ?" x: O, P2 \& q; c order to save kernel memory by preventing it from buffering too large amounts% _' y) Z; |3 A
of received data. Lower values will significantly increase CPU usage though.
2 ^* e! G3 K2 e+ U( C( m Another use case is to prevent write timeouts with extremely slow clients due
5 C- n% m) i9 f7 l& O to the kernel waiting for a large part of the buffer to be read before9 R6 k9 c* C6 y# H( W% R" b
notifying haproxy again.9 v3 |, p( a+ C- J, _9 e3 @
7 n0 g/ p+ w. {* y7 q# O2 k/ m3 ?$ N4 j# X+ E! A
3.3. Debugging, s8 D# W8 F) |
--------------9 R& A3 ^# E; N. y( F) M: z
, Z& k8 S+ A# {, s- M
debug
- y' {& X0 A- r Enables debug mode which dumps to stdout all exchanges, and disables forking
0 m9 v" U8 K3 i3 B into background. It is the equivalent of the command-line argument "-d". It
4 ~) r1 [8 X: b" ? should never be used in a production configuration since it may prevent full- D. q3 e4 D* W6 I" b/ w( M
system startup.4 {; V9 f% e& d) w' T7 W
* a2 M6 n% }+ q0 Y* j
quiet
2 a% s ^* v; v2 e, t% E Do not display any message during startup. It is equivalent to the command-
l. f0 x7 p/ w; x7 o line argument "-q".( ?+ W" `: A3 F) C# w
3 y( ^" h1 w- F4 K$ ~+ R# O. E3.4. Userlists
7 ?2 t; ]8 ?! c% l--------------' w1 t6 W5 N% x* a' F) ?) b) i
It is possible to control access to frontend/backend/listen sections or to2 q2 h. W" L, c; L) t/ [& \
http stats by allowing only authenticated and authorized users. To do this,
4 N J2 V! \- U. v5 _. m. kit is required to create at least one userlist and to define users.
# v1 B9 e0 m. O: ~" E5 J7 z2 B0 d3 y1 E2 a0 x4 ]
userlist <listname>" @# {; n4 N# `0 @+ B8 V
Creates new userlist with name <listname>. Many independent userlists can be( Z$ n6 N" P' p5 L6 |# Y
used to store authentication & authorization data for independent customers.2 W+ P/ V. n2 z, S
# C( y! ]3 |7 f$ m
group <groupname> [users <user>,<user>,(...)]3 P; _/ p' n. Z9 F# y, _4 h
Adds group <groupname> to the current userlist. It is also possible to
% W: a+ `1 K% i+ \/ g" S# o! x, a& o attach users to this group by using a comma separated list of names
; R5 P2 C" Q4 p" w proceeded by "users" keyword.8 }' a% J. D, H( O
+ B9 e) u6 @* `' j7 z
user <username> [password|insecure-password <password>]
8 m6 Z8 Z* P j& z. | [groups <group>,<group>,(...)]( \8 z# Y! j, u' r
Adds user <username> to the current userlist. Both secure (encrypted) and6 R/ m/ x9 \5 h8 M8 o5 L4 h
insecure (unencrypted) passwords can be used. Encrypted passwords are
( @+ \: D! [, f0 M& _" ?8 w evaluated using the crypt(3) function so depending of the system's
0 p' Y4 }+ y& A6 n- ~ capabilities, different algorithms are supported. For example modern Glibc# ]" I# f& ?$ F, i
based Linux system supports MD5, SHA-256, SHA-512 and of course classic,
' }% L! W8 P6 ]7 ?3 I% j& \ DES-based method of crypting passwords.! R: _0 x; z) b3 j. n% r. }, k" N9 {
) O- |$ p2 P+ \3 i% A& z
5 `0 p# H0 G" V/ _: G/ J
Example:$ S& N) E2 R( O
userlist L1# y/ ~4 O8 q* }5 [# m
group G1 users tiger,scott
" v! J7 r9 W4 ~ group G2 users xdb,scott* e. _/ {! m) u/ h, c% A2 Z
+ W' Z5 m1 Q2 e6 J. ]/ \ user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91
# D1 _$ p% W! r$ B. Z, Q user scott insecure-password elgato+ D2 v3 c& A% f" K( u& w" N( z+ ~
user xdb insecure-password hello, i5 ~, E( Z6 `2 w, {
$ F& K8 I( W# ?' O
userlist L2
9 d4 J$ _) Y8 I4 V3 D: _: ~; b group G18 n( C0 T2 V% J: Q o/ ~" ?: u6 p
group G2
" \" z/ z" V/ F6 r2 v
4 ` |/ d& m7 z" z+ T& S4 c user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
; J9 A6 n2 |' R6 \ user scott insecure-password elgato groups G1,G2
$ Z: T0 p3 Y4 M+ {+ b8 s4 | user xdb insecure-password hello groups G2
- r# f0 g3 S6 y
, k# {+ \ o& P' p, t8 y( K) N Please note that both lists are functionally identical.9 G/ Y2 H% Q7 f" I* a
8 V6 Y4 \% r: I! a% N
4. Proxies( y" u! J0 e! I* t2 {& u
----------- B2 |0 v2 n7 G9 q m
9 H6 U& ?$ H0 P# DProxy configuration can be located in a set of sections :
/ q% \. P( Q2 b$ d2 _" b# @ - defaults <name>
7 T( \- l) t1 m" o( c5 A n6 V1 ~ - frontend <name>
' N" s9 r9 \( G' f8 | - backend <name>
/ ?1 `; i6 N+ \" l) ^% o& g - listen <name>' Q1 k! |) n5 z1 p9 x+ p
: D$ t4 `0 ?* f% H8 K4 G' RA "defaults" section sets default parameters for all other sections following
, T6 Y* j, g6 D7 E7 Y% _its declaration. Those default parameters are reset by the next "defaults"3 E9 a: ~, ^, u ?3 l3 a, @" L
section. See below for the list of parameters which can be set in a "defaults", `' `0 D' `1 O9 n& Q+ J0 x" \. N2 T8 I
section. The name is optional but its use is encouraged for better readability.( Z; }; ^' H0 ], g; U
2 f7 F' Y3 o; F: FA "frontend" section describes a set of listening sockets accepting client
. r0 H J k9 q; B* [% econnections.* \: F3 x8 r/ K; z0 }1 H7 }! i* ?9 x
3 u: r- @# ^. H1 ^" x JA "backend" section describes a set of servers to which the proxy will connect
9 f2 J0 r! U& W! w5 H; Bto forward incoming connections.0 a$ X. U' U& V
0 g' {5 ~( R7 q9 |
A "listen" section defines a complete proxy with its frontend and backend
# f; g+ L( N. X, x" [parts combined in one section. It is generally useful for TCP-only traffic.$ J; k; [4 X3 p/ X3 A# ]& e1 ?7 k8 }
: D1 w' R9 L" ^
All proxy names must be formed from upper and lower case letters, digits,* w: a: e9 v: E: i" A# ^
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are# n* T8 N- a8 p% {4 V( }9 w* e
case-sensitive, which means that "www" and "WWW" are two different proxies.
: ^9 O* w6 K9 m$ a9 F: _
; ^2 v- P# g9 M3 k. a* v2 r- @Historically, all proxy names could overlap, it just caused troubles in the6 O# E) @9 v% T) \
logs. Since the introduction of content switching, it is mandatory that two
. J4 R" N2 T3 h/ Gproxies with overlapping capabilities (frontend/backend) have different names.0 [$ `6 {9 v; s% p
However, it is still permitted that a frontend and a backend share the same/ e9 S& g+ D8 y& U
name, as this configuration seems to be commonly encountered.) f7 c2 ?. j* s2 ?
4 G! n4 z- Z- s$ K
Right now, two major proxy modes are supported : "tcp", also known as layer 4,
& o2 Y. i! p2 X, A5 Oand "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards: | I5 c: P! U
bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the& r2 O) z/ ]' X a5 p S
protocol, and can interact with it by allowing, blocking, switching, adding,* e( h: ?; V- f8 Q; T' U8 O+ V4 \
modifying, or removing arbitrary contents in requests or responses, based on
3 S6 N. v1 T/ o# N( Varbitrary criteria.7 o) p7 E6 U) ^+ n! w! U/ \
- q& y, J) } K
, [' a: z, |9 [' m5 P4.1. Proxy keywords matrix+ s$ S0 N/ j0 w4 x/ ~) U" Y
--------------------------: w+ U% O1 ^: V& l* G9 p" h
1 M5 r ?8 R6 Z4 r: v! q/ b7 Y" |The following list of keywords is supported. Most of them may only be used in a
- \6 T, k4 F" h' Y- v* C2 O1 rlimited set of section types. Some of them are marked as "deprecated" because" P1 D4 h6 m& k5 t. K; U( H# [
they are inherited from an old syntax which may be confusing or functionally1 @8 ]# }) k" D( F; T
limited, and there are new recommended keywords to replace them. Keywords& {% z1 A) Z+ \9 \
marked with "(*)" can be optionally inverted using the "no" prefix, eg. "no
. `" M% m, g/ \. c& Q* M- o, \option contstats". This makes sense when the option has been enabled by default& P* b6 }3 X( ^, _
and must be disabled for a specific instance. Such options may also be prefixed
5 Z! e3 u& H3 |* [, twith "default" in order to restore default settings regardless of what has been
% l+ x$ ~, s1 Pspecified in a previous "defaults" section.
* w8 ~4 `! K7 Y* b# Z% n, @6 N& }6 t% r( ^8 C
, x; i8 A' P i ^0 Z8 H keyword defaults frontend listen backend
4 b1 [5 n _; r& f- j------------------------------------+----------+----------+---------+---------/ O G9 @; N' F5 Y! _
acl - X X X
3 O8 o. E* B$ P8 pappsession - - X X
3 p, y* S8 C9 L1 b/ bbacklog X X X -
# T( s6 D+ C% @; n; N) Jbalance X - X X1 `* a# v: D0 M: K7 ^& ?
bind - X X -
4 ~- c% ?2 u. u! }% x1 Qbind-process X X X X4 k/ j4 Q' i% e
block - X X X
- c# h2 O4 f8 icapture cookie - X X -0 C3 j! P; [" w7 \* W
capture request header - X X -
: I1 _6 e. ~% ]2 qcapture response header - X X -0 l8 a; e5 s( Z( [/ U9 W6 z r% P
clitimeout (deprecated) X X X -
0 [- k) k( d3 h! Icontimeout (deprecated) X - X X
q m- l7 |# I' u" d' \% L Q# gcookie X - X X
8 G( X4 _8 I. p9 v; ydefault-server X - X X
1 U p- M& O/ y B i" X9 }default_backend X X X -
) l, X ~8 |& j; Ldescription - X X X
3 u5 ^; @7 n" M; _3 idisabled X X X X2 o1 V3 n( S3 q; B0 s
dispatch - - X X) h. C1 t9 e3 z; a
enabled X X X X
3 O$ z" _/ Q/ S/ \' F4 P5 Oerrorfile X X X X
" e: r9 e: K1 T6 @8 c3 Eerrorloc X X X X
\$ L6 }. o5 b v: H) z+ k) |0 ]errorloc302 X X X X+ V& n. l* @, H0 f
-- keyword -------------------------- defaults - frontend - listen -- backend -8 i' J2 x! [5 l+ u
errorloc303 X X X X
. t, l8 h* K2 v( y$ {3 L) tforce-persist - X X X6 v# |' n: r/ U9 d+ f/ U
fullconn X - X X
7 A8 E& D" ?, dgrace X X X X
7 D0 x2 K! A+ ihash-type X - X X2 s. P* ~% j' I A; K$ {" h
http-check disable-on-404 X - X X0 F/ t$ Y( W5 _% O
http-check expect - - X X! ^- _( T$ o3 K' X8 ?$ N# G3 }
http-check send-state X - X X; X. L) J& B1 i \- w2 @4 L9 C* F- I
http-request - X X X8 Y5 i3 o& S! n2 s* A* E" @
id - X X X! k5 ]2 I& {2 t; e9 i
ignore-persist - X X X
7 `; H# s) `4 elog X X X X; Y; b4 V! \ F S* U% z
maxconn X X X -
- X' @' r5 k" umode X X X X) i. B& a4 `) l+ x8 a$ Z9 I0 F
monitor fail - X X -, p; v& y P+ M) W7 F
monitor-net X X X -: U' x9 a/ l/ c9 m" n. f( k1 k
monitor-uri X X X -
" ^6 V8 [% u: `option abortonclose (*) X - X X" { A$ k+ v1 r3 k9 w8 z) V+ c( Z
option accept-invalid-http-request (*) X X X -5 i1 ^% n- {- a* }9 Y5 |
option accept-invalid-http-response (*) X - X X) V# t) r! \1 [0 k* F) f
option allbackups (*) X - X X
h# @5 Z) ]( a9 r7 \' Yoption checkcache (*) X - X X
( Q7 C* A/ u! @option clitcpka (*) X X X -6 N; u1 m& [' S! \+ W/ S
option contstats (*) X X X -
8 d7 y# [( t, v$ X) X2 H* d3 boption dontlog-normal (*) X X X -
0 A& n) X: r9 m# `4 Qoption dontlognull (*) X X X -) G3 V3 d, t0 d
option forceclose (*) X X X X; ?+ d9 T7 q3 y* u. B7 s; k
-- keyword -------------------------- defaults - frontend - listen -- backend -( y" @+ x7 i+ b3 x+ x5 E( D
option forwardfor X X X X7 u9 ]" Y X! f
option http-no-delay (*) X X X X
1 W1 z8 k5 ~& |$ b: R$ C8 {" noption http-pretend-keepalive (*) X X X X
2 n |& S9 O E) ]option http-server-close (*) X X X X
9 I$ S( E# O$ R7 _$ B( uoption http-use-proxy-header (*) X X X -
% n& m# S& U( E: x" O2 eoption httpchk X - X X k2 q4 }, g8 C6 r# l: _
option httpclose (*) X X X X7 A7 K" Z7 _) B; o
option httplog X X X X
* B! v7 d1 x; r3 Z4 }. m boption http_proxy (*) X X X X7 [' U9 z7 t( r$ H- ` |/ u
option independant-streams (*) X X X X4 s0 t8 ?6 f$ q1 p( i* b
option ldap-check X - X X
0 `6 H$ |& i4 I' t N! A- k) ?option log-health-checks (*) X - X X* K& S$ E X( r* F# a% _5 g" g
option log-separate-errors (*) X X X -
4 N, z& M+ F( koption logasap (*) X X X -# b; M0 M* W1 d. @% A }
option mysql-check X - X X
; S& y- k8 Z4 X5 j# G7 i! Aoption nolinger (*) X X X X8 q n" b" k; w8 U( W% t0 `
option originalto X X X X! Y; c0 G& u+ R7 \3 S
option persist (*) X - X X: @+ h# A, ]6 a/ ^; Y7 [) U+ ]8 Z
option redispatch (*) X - X X
+ r+ d1 D, X# M: Q0 h# a8 Toption smtpchk X - X X
3 k C3 a. _/ ]* ?8 Q2 ^8 T4 uoption socket-stats (*) X X X -+ X5 O0 i8 ]- J1 y0 w) z+ {+ @
option splice-auto (*) X X X X
. K4 B, u, n. U& P3 noption splice-request (*) X X X X- F6 S' W ^5 m. e9 s
option splice-response (*) X X X X
3 C' V' T) y3 B5 J; hoption srvtcpka (*) X - X X" f8 p! D) A- E" P0 W4 w( z# E
option ssl-hello-chk X - X X. a" H, a! D( I" d
-- keyword -------------------------- defaults - frontend - listen -- backend -
+ @! c/ q7 O6 Coption tcp-smart-accept (*) X X X -; m$ k& v, ~9 v9 \/ V
option tcp-smart-connect (*) X - X X. c X6 H2 c& i8 D# t* `' l
option tcpka X X X X4 \% p) c5 T# k5 S! w3 F' ^: L
option tcplog X X X X
( K6 Z% B& {6 l$ u% u# b. \option transparent (*) X - X X6 @7 m# e+ K T0 {
persist rdp-cookie X - X X
: g4 y' ~" t) R& D0 Orate-limit sessions X X X -
9 ?6 Y: p) g+ H4 n/ T' f1 ^redirect - X X X
& ^6 k i K) f' W8 [redisp (deprecated) X - X X' h3 R$ S0 z& j: m8 |5 Q
redispatch (deprecated) X - X X5 z' m9 {3 C2 H
reqadd - X X X
7 G' W/ N" R" x+ p6 W* h! }7 H4 ~' treqallow - X X X1 J V5 b6 c- D" q- y
reqdel - X X X
9 E( Z7 F/ l* E6 treqdeny - X X X3 h/ V8 L# {$ K$ O: B# m: S9 I; N
reqiallow - X X X
8 g" C( a" y8 C% w& G" a2 ]reqidel - X X X
7 D7 M4 e9 A% W* e) X8 Z) kreqideny - X X X+ M$ F# p7 q3 G
reqipass - X X X
5 @5 \5 M$ X" `" ?7 b$ Zreqirep - X X X
$ S2 [* g& I: ]2 Y+ V" {reqisetbe - X X X
- d" o3 C5 u& i/ O, s Rreqitarpit - X X X' o- h. O8 e" d. M Q( J8 b
reqpass - X X X8 X* A& N l2 N. j; w
reqrep - X X X9 W" G1 y% z- { p3 J7 J4 [4 {
-- keyword -------------------------- defaults - frontend - listen -- backend -
* s: V6 p* X0 ]1 r" Dreqsetbe - X X X
3 _) _' ^0 S& ereqtarpit - X X X
5 F: N! A2 H$ Lretries X - X X
, ^! S: i' x4 g7 V; K% m- v4 m: erspadd - X X X
& V2 X/ m8 a& v" |rspdel - X X X
) O; u M. E9 {& V+ J8 E$ Yrspdeny - X X X1 d3 U% ^' ]5 K0 |/ C4 B
rspidel - X X X- B7 x6 }3 I) v4 }2 d" R2 R
rspideny - X X X5 m/ J x: H% t+ h' o7 R! `# }
rspirep - X X X
- Q0 ?4 j/ \0 H6 b$ Lrsprep - X X X
" b5 b7 v9 t: c+ d9 X# Zserver - - X X
. l4 ^5 j7 T9 E5 G5 v% c$ Fsource X - X X: c8 C" L/ i9 ]
srvtimeout (deprecated) X - X X
: L5 Y% n- H, Ostats admin - - X X
( y/ R/ c( s. J" Z) jstats auth X - X X
8 I8 Y$ R7 c: T# E1 H4 Z% tstats enable X - X X
8 U7 u$ {5 X; G3 w2 \1 m& O7 S {- fstats hide-version X - X X3 b ]1 ?4 P$ n: w
stats http-request - - X X. }2 I" l. f8 w9 g: H' O9 D6 X
stats realm X - X X6 @3 G. v: d2 D6 n! o% I1 r+ q& V! N
stats refresh X - X X3 z& E7 W3 j# W/ e% Q6 ], g' z
stats scope X - X X+ ]& h# v+ K) t
stats show-desc X - X X" U' m6 w0 z- H: Q* r: {
stats show-legends X - X X
( h7 A; @* H8 O9 X" W' K! }stats show-node X - X X$ ^- x& B# N2 q; i1 w! |4 _
stats uri X - X X9 i N2 z- o; |' Y9 v4 k, a% u
-- keyword -------------------------- defaults - frontend - listen -- backend -) U$ s e# O5 N- |+ p
stick match - - X X$ Q: [- ]) a! j, L0 I$ m# `
stick on - - X X: @# \; s. `4 Z3 n8 }
stick store-request - - X X
* }# N# o5 z. k$ |" `$ \stick-table - - X X
( {, b/ @! M: [& H6 `- x% [tcp-request content accept - X X -; W% r4 u" C- I9 B( T
tcp-request content reject - X X -
' I! J c- I3 \5 U Atcp-request inspect-delay - X X -
* f H9 @/ w9 K7 vtimeout check X - X X/ } D' L6 n8 M2 A" L' B6 m
timeout client X X X -' ]& x/ s5 Q' n. u1 l
timeout clitimeout (deprecated) X X X -
" a4 I+ y& A- C' N' l% k+ s) u8 b5 ptimeout connect X - X X
5 M; D5 @1 A @) b$ V4 j0 G6 atimeout contimeout (deprecated) X - X X
& f! W, E8 o9 ?timeout http-keep-alive X X X X
) f0 m8 Z- _7 ^2 K: t W8 v* vtimeout http-request X X X X
2 s h5 T+ { U8 u$ J3 Q: mtimeout queue X - X X
" u- M9 E! Q( Y& X1 o( V0 g' Ltimeout server X - X X
& u* P- S! ^* J4 b2 y$ _timeout srvtimeout (deprecated) X - X X
# z- e6 W4 O9 D, ?timeout tarpit X X X X# g3 a! G6 ~/ N: z; r7 w: Z
transparent (deprecated) X - X X9 I% a) Z% N% C& y" f
use_backend - X X -9 y! q7 \' j* K0 X5 W* I2 e _
------------------------------------+----------+----------+---------+---------; Y% `1 u' k& n
keyword defaults frontend listen backend
/ k' l* @! U$ L. E& C Y+ J O/ A7 {+ E
9 s# s3 ^( X0 k% y5 q9 m. o+ w3 D2 Q" S
4.2. Alphabetically sorted keywords reference
6 A. D# V8 ?7 M G9 L---------------------------------------------
7 ^9 M! T, t+ m* G: H: M+ z: A
3 _3 Z. l6 q$ q" ]- YThis section provides a description of each keyword and its usage.6 J5 ~9 u' D5 ]1 {
# D$ O" x, Z2 ]+ E- U2 j$ @; L
& h" O" F( X+ T# X7 |5 N$ Uacl <aclname> <criterion> [flags] [operator] <value> ...
% ~, ]/ v5 Y; E o" L0 ^* [2 y# h Declare or complete an access list.
0 U$ t, f" L2 T0 z8 p9 ` May be used in sections : defaults | frontend | listen | backend2 l2 v( |9 `, X: R4 I+ P' D
no | yes | yes | yes
g* P1 E7 ]5 T, _9 e Example:
( w+ z2 H: I5 ^ f& @ z acl invalid_src src 0.0.0.0/7 224.0.0.0/3" n$ M6 q9 n- j# b
acl invalid_src src_port 0:1023
9 K9 p4 x6 l7 ~1 d5 C/ ~ acl local_dst hdr(host) -i localhost
M+ T; }. _/ {1 Y3 T4 `: Y; k0 t4 ]0 J
See section 7 about ACL usage.- \! Y5 k" I# m0 @3 d/ s
( l. O: B' ~( P; B
% ?) i$ v2 S* B8 F* eappsession <cookie> len <length> timeout <holdtime># E9 y: m7 F+ H4 S1 u
[request-learn] [prefix] [mode <path-parameters|query-string>]
; g [" Z! r1 [3 v Define session stickiness on an existing application cookie./ Z) _' m' t+ u# B6 n% f8 Q
May be used in sections : defaults | frontend | listen | backend1 ?" h8 n* X4 f2 F6 R0 N. k
no | no | yes | yes
/ P0 o0 _: Z1 o5 K- C; E+ ` Q0 O6 f Arguments :: Z5 ?/ ^5 U/ y+ s% i. D' w
<cookie> this is the name of the cookie used by the application and which" @& S- p9 c0 O& r" ^
HAProxy will have to learn for each new session.' P% ]% ?1 K3 D% l1 z. E. a
0 H- t# P$ g/ Y5 N
<length> this is the max number of characters that will be memorized and/ K- _" D5 B) D4 k8 G" u
checked in each cookie value.
. h6 Y% i. g" T- M$ E9 ~3 Z+ N0 j+ b4 L# X& g0 _
<holdtime> this is the time after which the cookie will be removed from
9 w( o( V* t8 v, g5 g+ T j memory if unused. If no unit is specified, this time is in8 p5 k- u/ f2 v$ ?# c+ X; R
milliseconds.* {: R4 R$ t# q
* V) h E8 N# x' _ request-learn6 O6 y4 e% V/ t* c6 R% }" R) F! U
If this option is specified, then haproxy will be able to learn. p1 a* \ D7 Z8 ~- t
the cookie found in the request in case the server does not
) N7 Z+ @& y& {! H( _ specify any in response. This is typically what happens with
9 h. a# b4 r/ Y7 c PHPSESSID cookies, or when haproxy's session expires before1 P0 J8 a1 ~1 P# u& K7 u
the application's session and the correct server is selected.
1 N1 _7 z f; b8 C3 d It is recommended to specify this option to improve reliability.8 ~$ E3 [; H6 T5 c2 T
, w% a2 o5 x) H0 P$ t. Y prefix When this option is specified, haproxy will match on the cookie' M* S) R% j& H6 B0 G) h9 ]
prefix (or URL parameter prefix). The appsession value is the
; Y3 f7 F, d/ \ ?4 i data following this prefix.. K- n4 F1 @+ h( c- Y8 d3 r; ~
) a7 a: \* g; u7 p. Z$ H0 Y
Example :
9 S/ I1 [- |! W7 q appsession ASPSESSIONID len 64 timeout 3h prefix
+ b9 ?* R* O, T5 ?( f2 f7 h6 j# E* S2 {2 d: D; H
This will match the cookie ASPSESSIONIDXXXX=XXXXX,
: I0 b$ H1 H. k the appsession value will be XXXX=XXXXX.
5 Y5 r6 o9 m/ T0 H
, ]7 r0 Y9 M, V7 e2 y- f2 J% I+ _. C mode This option allows to change the URL parser mode.
( c `9 |( _0 S7 W4 V1 l 2 modes are currently supported :
7 Z8 n r2 ^+ S - path-parameters :
% q4 g4 C; ?4 `" q' _9 \ The parser looks for the appsession in the path parameters5 D1 p0 \9 m# E. M: b
part (each parameter is separated by a semi-colon), which is7 L1 l" F) L% E; l
convenient for JSESSIONID for example.
9 r# v Y! Z7 L- A ] O9 L This is the default mode if the option is not set.
2 W' V1 F2 V% { - query-string :' _- W6 m$ ^/ _( b8 h7 H l0 x
In this mode, the parser will look for the appsession in the
2 P% R' E5 [- J% h# c- u) x/ K query string.. }! k) k' [ U V3 R( B* m9 M5 G
/ M- i! _; x9 G" s1 O, c" u
When an application cookie is defined in a backend, HAProxy will check when
% ]; d' p; ~4 R0 b. b the server sets such a cookie, and will store its value in a table, and/ ?2 K7 j5 v( p
associate it with the server's identifier. Up to <length> characters from
, y$ X; X9 {9 X3 X1 D- M the value will be retained. On each connection, haproxy will look for this K. z4 S+ d% p3 A) ]5 H4 X0 b
cookie both in the "Cookie:" headers, and as a URL parameter (depending on
( d' M4 V' n9 V' i* d* o% E% S the mode used). If a known value is found, the client will be directed to the
; j. ~" _) g# {$ U7 P$ x server associated with this value. Otherwise, the load balancing algorithm is, K) z1 U3 l G" r( W0 R
applied. Cookies are automatically removed from memory when they have been4 I3 J" i, z4 H. H8 T# A0 x1 e/ M
unused for a duration longer than <holdtime>.
& l7 H1 Z9 }& h* Y) O7 m( J
4 ]& Z3 o9 Z) f1 k# Y. H" o0 ` The definition of an application cookie is limited to one per backend.
+ o' {5 t( z+ J/ Z1 t
/ A9 n( u3 e9 b6 u8 m* W9 |9 [ Note : Consider not using this feature in multi-process mode (nbproc > 1)
( H8 F" z0 P9 ~# P3 j unless you know what you do : memory is not shared between the F$ M v) R9 i6 C% ^; t2 r3 |
processes, which can result in random behaviours.
2 n3 Q) Q1 ?- n- P, Q4 g
1 O8 P1 k9 p$ l0 y/ Y1 g Example :2 i* J- x. ~ p. B. U8 W( p
appsession JSESSIONID len 52 timeout 3h! E9 r9 H% I2 h4 c8 | `! X
2 z2 `' i" M* f$ n+ M2 _. ?, g& X
See also : "cookie", "capture cookie", "balance", "stick", "stick-table",# k. X" c" [" p7 W, L$ H8 \9 k* x
"ignore-persist", "nbproc" and "bind-process".8 u) Z2 s. C: s; b3 Z; ?3 e. p7 W, V
) c# T1 F! P J/ i
- ^5 H2 P" i* ]+ C& }$ o) ]" V- e: @+ E5 ^backlog <conns>, S: K' m+ @0 y0 |9 ^
Give hints to the system about the approximate listen backlog desired size8 G/ \( ~/ _4 |( X4 w+ c: k
May be used in sections : defaults | frontend | listen | backend% M* Q8 s/ n7 D/ x
yes | yes | yes | no' i* r- b/ c) z1 q8 Q2 i1 I- ~$ {
Arguments :% r) G1 V+ }; u: I
<conns> is the number of pending connections. Depending on the operating
1 \6 `# z3 f/ Q/ c- ^ system, it may represent the number of already acknowledged
0 s9 p* X+ Q: n: J( R connections, of non-acknowledged ones, or both.
. C+ u* [9 l* J- o8 j; Z& o( V
& y% ~" g) K) h9 [+ C$ X9 l6 k/ ~( ] In order to protect against SYN flood attacks, one solution is to increase( a s/ i7 }+ u
the system's SYN backlog size. Depending on the system, sometimes it is just2 Z* r; m1 `! J& q% N. S
tunable via a system parameter, sometimes it is not adjustable at all, and6 m, ~: z7 C7 m# ]" O6 c! I0 h0 O
sometimes the system relies on hints given by the application at the time of
3 M- H& `$ t! l+ | the listen() syscall. By default, HAProxy passes the frontend's maxconn value* k U: P1 V& ]+ ^* e
to the listen() syscall. On systems which can make use of this value, it can
8 q5 x0 H8 L/ B/ b0 L7 O: C sometimes be useful to be able to specify a different value, hence this
, r% T V; G6 m2 b1 g backlog parameter.* b2 A/ m O1 f$ W( q. S0 T, p: q
! X0 F; ~& a: F% E
On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is% K$ o" Y6 { a1 H( F
used as a hint and the system accepts up to the smallest greater power of
9 H$ y+ n% i* G4 n two, and never more than some limits (usually 32768).' q8 o7 @5 w4 p! T1 \8 J
5 l- E ~- ]% t
See also : "maxconn" and the target operating system's tuning guide.
0 @/ z" y( b) h- B- }* w" \ c% Z
$ ^3 u: ^. n/ b# W
balance <algorithm> [ <arguments> ]
% F5 q( c; V9 Z1 fbalance url_param <param> [check_post [<max_wait>]]$ k; U' h) {! y
Define the load balancing algorithm to be used in a backend.8 H) t2 j0 ]0 J0 W. Q
May be used in sections : defaults | frontend | listen | backend
# ~3 c' C3 a% D" ~ yes | no | yes | yes* H+ |* z1 ]5 U$ _; ?4 C
Arguments :9 j5 f5 B6 D$ [ h& A
<algorithm> is the algorithm used to select a server when doing load9 G1 m! t' h3 D& X# L
balancing. This only applies when no persistence information
3 j' {! ]3 p9 D1 f+ f" r is available, or when a connection is redispatched to another9 ~' A5 b& Y* _& }6 B, q: {: Z
server. <algorithm> may be one of the following :
3 x* l. `6 i. M7 b$ w3 J2 ~% L1 b+ ~2 o
roundrobin Each server is used in turns, according to their weights.
0 K3 E) |5 }* { This is the smoothest and fairest algorithm when the server's) Y$ }; R) I5 ?
processing time remains equally distributed. This algorithm0 V T0 ^9 a. r$ P2 R2 R
is dynamic, which means that server weights may be adjusted
% Z; f7 d9 ]: }- m9 g) d; \ on the fly for slow starts for instance. It is limited by! M& N7 `; Z% E( K6 R4 L6 h& ]
design to 4095 active servers per backend. Note that in some
9 b! Q4 }5 s* \2 Q* r% G7 l large farms, when a server becomes up after having been down
) J+ M% o. L1 m6 |- Z* s for a very short time, it may sometimes take a few hundreds
& z. Q$ C& j6 V, k+ ~- t2 P requests for it to be re-integrated into the farm and start6 }1 A, h$ q; g+ c$ |' g
receiving traffic. This is normal, though very rare. It is
; E# m/ u) G; Z9 W/ J( x indicated here in case you would have the chance to observe
; U# o( C) n; T& D it, so that you don't worry.3 S1 f4 f; g) i: V
, X- i8 h# {% X( X9 E6 q/ N9 u static-rr Each server is used in turns, according to their weights.
( t8 S' y' H( \1 w This algorithm is as similar to roundrobin except that it is! R( Y. A0 L, O2 x3 v5 a) J% k
static, which means that changing a server's weight on the$ [5 H u6 w# {8 I+ N
fly will have no effect. On the other hand, it has no design
2 V" x% _3 H2 n1 u! z4 ^ limitation on the number of servers, and when a server goes
" I& i h+ Y% f% M8 j: D8 H* ` up, it is always immediately reintroduced into the farm, once
% Q+ c0 N/ P3 v; x* J& @1 g1 E' j the full map is recomputed. It also uses slightly less CPU to
0 \! c7 G! f2 i+ _- N run (around -1%).
* g! e( t# ~% n8 {$ D" I5 d) a4 w6 B6 ]# P9 u1 {) M4 T
leastconn The server with the lowest number of connections receives the+ ~, L+ l: H w: m
connection. Round-robin is performed within groups of servers
5 |" z2 z9 @. `! h1 q" L of the same load to ensure that all servers will be used. Use
w& A1 L8 y7 X$ w; S) F/ B of this algorithm is recommended where very long sessions are; n7 f! }9 W+ R0 R
expected, such as LDAP, SQL, TSE, etc... but is not very well. K- g) ?. U# r' o2 K
suited for protocols using short sessions such as HTTP. This7 p# N* x \+ d- o
algorithm is dynamic, which means that server weights may be: M0 M9 j1 m& D! i
adjusted on the fly for slow starts for instance.* A# z" s# D5 \
; K; S& c( B+ x! i' A* E
source The source IP address is hashed and divided by the total! \6 [ |* S3 e8 l$ ^# @7 Y9 \
weight of the running servers to designate which server will6 }+ `- L s7 l) K- i& [
receive the request. This ensures that the same client IP
' @' Q* q, K' L5 x9 S+ F address will always reach the same server as long as no
6 k2 C: J9 L9 T server goes down or up. If the hash result changes due to the
( F& G7 _. U6 ?; l! e3 l- d* H number of running servers changing, many clients will be" Q& }; e1 O% ]% A `' u& g9 C
directed to a different server. This algorithm is generally4 j; i& x! ^+ |7 W4 C& [+ u) X
used in TCP mode where no cookie may be inserted. It may also
" T' [3 T6 h `$ A. H4 Y( V' U be used on the Internet to provide a best-effort stickiness1 w! A8 {/ t7 Z# d) T( u$ o" v# e3 \
to clients which refuse session cookies. This algorithm is: p9 {2 `$ I% n- [5 n' J2 B
static by default, which means that changing a server's
2 @5 a9 i- a: A; t0 @( E weight on the fly will have no effect, but this can be
2 j& X R+ b" R7 K changed using "hash-type".
2 J+ o; l/ g9 v+ m0 G8 J4 o% z- J* }( I: s: B' K& P5 d
uri This algorithm hashes either the left part of the URI (before
3 w: z7 d- j! ]) M; L1 ~/ S the question mark) or the whole URI (if the "whole" parameter' ^7 i: V" s# m) f
is present) and divides the hash value by the total weight of9 T( ~5 V7 ~6 p3 y. V% a9 U
the running servers. The result designates which server will, P5 W- C: t9 A8 G
receive the request. This ensures that the same URI will$ x( q+ o1 k; l
always be directed to the same server as long as no server
: E& c' r: h" ^: S* E' d goes up or down. This is used with proxy caches and
R z# J4 [. x, x anti-virus proxies in order to maximize the cache hit rate.1 m( n% Y P2 s N1 u
Note that this algorithm may only be used in an HTTP backend.
7 i3 x' E) t) d2 @. a This algorithm is static by default, which means that
2 t3 C. y+ G- z1 K0 y6 d% S changing a server's weight on the fly will have no effect,, B& @6 L/ @0 e1 S$ m4 i" a
but this can be changed using "hash-type".- W/ }, ]: y0 G/ k* M- v
7 x& ^2 M. _3 l* |* i9 c( m! R This algorithm supports two optional parameters "len" and
) u8 g7 U& n/ [ "depth", both followed by a positive integer number. These6 _% G2 j' `8 @4 t) c: P
options may be helpful when it is needed to balance servers, |2 k; g- g4 H" B2 _
based on the beginning of the URI only. The "len" parameter
& g6 B* ]3 T- ?# u3 ]4 }( D9 b! S | indicates that the algorithm should only consider that many
* Q: Y; M. j" v+ i. @ characters at the beginning of the URI to compute the hash.
9 C2 G) E9 s% U+ S/ N Note that having "len" set to 1 rarely makes sense since most9 M. m* ~3 T: t! N, ~9 z+ S
URIs start with a leading "/"." @4 h, w4 s5 W5 n# B% Z' ]
$ x- I( z+ V$ c# p
The "depth" parameter indicates the maximum directory depth8 Y. ^; \* L* ]4 d- m. C5 m
to be used to compute the hash. One level is counted for each
. k" @' P+ e2 R0 C% i slash in the request. If both parameters are specified, the v$ |7 {. u7 I9 {* l5 b
evaluation stops when either is reached.& j1 O# z! P& F+ Y
% l. p1 h6 m5 g% n url_param The URL parameter specified in argument will be looked up in
. G( Z! X2 b) s! m, @ the query string of each HTTP GET request.' g0 `& b0 u# X
! Z& D/ {# t; w+ g; Q If the modifier "check_post" is used, then an HTTP POST
# z) O0 p- j% e7 b request entity will be searched for the parameter argument,
' m# ^& {. K7 c1 ]4 d$ H when it is not found in a query string after a question mark% C9 l9 k8 f+ L# ^
('?') in the URL. Optionally, specify a number of octets to
; U6 y- O2 m2 J0 S% }* U# ` wait for before attempting to search the message body. If the( e; j. y U. Z! o3 a
entity can not be searched, then round robin is used for each. I. h! S9 V$ J- i, j! @$ K
request. For instance, if your clients always send the LB8 d) `% a1 K4 C& s8 a
parameter in the first 128 bytes, then specify that. The' ?' B, `% a0 v1 S
default is 48. The entity data will not be scanned until the! T% j( i$ A" q! h& A2 @
required number of octets have arrived at the gateway, this' s: b* m' c3 d6 H4 N; `. r, w9 V
is the minimum of: (default/max_wait, Content-Length or first) P& ~' R8 m0 ^- i; C
chunk length). If Content-Length is missing or zero, it does
) r, q; U5 q# m; \; k# O' M8 R not need to wait for more data than the client promised to
: N# y0 e" }( e. W1 s' } send. When Content-Length is present and larger than
; N$ x9 k6 I- M4 m <max_wait>, then waiting is limited to <max_wait> and it is2 V$ E! u" F3 N: K- ~9 \- ]
assumed that this will be enough data to search for the* E$ M- H0 l( ?6 }/ r) M: F+ a
presence of the parameter. In the unlikely event that+ y1 U% W: Z+ c) q. j; Q
Transfer-Encoding: chunked is used, only the first chunk is
. U* o2 _' J% A6 K7 Q6 H scanned. Parameter values separated by a chunk boundary, may
. j; |/ g- U* H be randomly balanced if at all.* v, U' g! s% _% v
; w$ x. h9 h# ^3 [' t
If the parameter is found followed by an equal sign ('=') and
$ T# X0 ]% V# I9 { a value, then the value is hashed and divided by the total5 J" R+ h0 K$ ]3 r. Y _
weight of the running servers. The result designates which6 l& u! H1 n, D6 |4 q" O! O
server will receive the request.
2 \$ j8 A1 V$ u; @0 `% _9 h" y) c5 k
This is used to track user identifiers in requests and ensure
; y% t4 h' p, S" f1 g% S6 d. u that a same user ID will always be sent to the same server as$ |! `+ r4 e9 s1 i! c
long as no server goes up or down. If no value is found or if
- W4 z* c l3 Q' e- J) L the parameter is not found, then a round robin algorithm is8 ^/ j5 `! S! U* @- x
applied. Note that this algorithm may only be used in an HTTP
9 G7 F; v/ T% T: a# ` backend. This algorithm is static by default, which means1 i2 A* J! y2 g C$ F
that changing a server's weight on the fly will have no
! E+ F. w& k8 ~0 |; V, b4 l+ J8 X effect, but this can be changed using "hash-type".
I- L" ^1 b- u- b& U( q
& p3 ^- Z* p J& J/ m- z6 F' a hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.4 A* P1 t! E: G; Q
Just as with the equivalent ACL 'hdr()' function, the header
# W R& Z& F% n2 p' i. ?5 C# @ S name in parenthesis is not case sensitive. If the header is' F# U$ K9 }, S6 U4 `
absent or if it does not contain any value, the roundrobin
W6 t% B* Q) }; M, {! w algorithm is applied instead.
' e& B. K7 O6 s( v" {: U. M& n ]9 b% }9 {7 s9 _3 U
An optional 'use_domain_only' parameter is available, for
5 V8 z0 d; D- J9 R reducing the hash algorithm to the main domain part with some
" r2 B* R/ z J specific headers such as 'Host'. For instance, in the Host
9 `. f$ p+ z: o9 |6 w value "haproxy.1wt.eu", only "1wt" will be considered.0 G9 x- L' \) @! o( f: J
: s% y7 G* T+ j5 k; t5 i9 m; s This algorithm is static by default, which means that
0 x" y. ]8 a( V6 u$ o) m changing a server's weight on the fly will have no effect,
9 g" h/ M, |- p6 o but this can be changed using "hash-type".) Q" v3 y ]- s, n: r( Y+ [! V
4 d7 _9 d5 ^& [1 ` \0 M5 A+ Y
rdp-cookie- s- ~7 l4 T9 z' e# j. w1 y
rdp-cookie(name)7 V! O/ J# g, b9 _! ]
The RDP cookie <name> (or "mstshash" if omitted) will be. M3 ]: s9 Z8 h( Z0 R3 M! w( v
looked up and hashed for each incoming TCP request. Just as
o8 j" Q, Z% d" V9 u+ x p5 h with the equivalent ACL 'req_rdp_cookie()' function, the name
+ D# Z0 _3 v6 q9 N, o* J is not case-sensitive. This mechanism is useful as a degraded
) o$ d4 `" M" o: Z% X$ m5 m persistence mode, as it makes it possible to always send the: P' f. M- w7 v p/ N: Y+ r
same user (or the same session ID) to the same server. If the4 C4 f$ {( [. ]5 z! V3 d
cookie is not found, the normal roundrobin algorithm is
9 @/ _' ]6 G2 o used instead.
% ]4 m: U: V) q# B+ P
7 q, ^/ L7 W) V4 ~7 d9 S. X Note that for this to work, the frontend must ensure that an L9 J# z$ w* i9 v2 S' T
RDP cookie is already present in the request buffer. For this; u. J1 E! I7 z
you must use 'tcp-request content accept' rule combined with* J/ R, p U/ l8 s1 c$ V
a 'req_rdp_cookie_cnt' ACL.
8 `: m8 |; G' H3 ^9 I- P2 r: \7 t; \! G7 w! \0 v" U
This algorithm is static by default, which means that
U: r" F6 t$ i# l0 O1 X changing a server's weight on the fly will have no effect,
7 I4 _" d" D) A' w2 I but this can be changed using "hash-type".( s7 u" G2 _9 f: a
t. v% J/ j, ~% y* P0 g <arguments> is an optional list of arguments which may be needed by some( j6 _9 P7 F$ V. T1 W z1 I
algorithms. Right now, only "url_param" and "uri" support an
. M& [7 r% U3 O% L2 a" M) K3 f) a( n9 n optional argument.9 k+ L4 I* ^4 Z5 {
5 @2 }' a* d) r9 R' q) c balance uri [len <len>] [depth <depth>]
# P& Y" Y1 Q% {3 @, _4 [1 n- z balance url_param <param> [check_post [<max_wait>]]. k7 _$ s& g% p+ n& H) C
/ t1 @7 e5 q; F/ x( b: J# X" Y The load balancing algorithm of a backend is set to roundrobin when no other
4 D; o" k L3 s! S1 w( Q) Z' z algorithm, mode nor option have been set. The algorithm may only be set once* K% T' ^7 Y! U4 p6 r( S; \9 [$ H& X
for each backend.% j9 l: u* k5 z
: ~( [$ W9 K' o& T& u1 X
Examples :
' F; c5 ~1 n f+ u3 B! A6 b6 V5 T' k balance roundrobin
- z c' b+ D/ k$ W- s balance url_param userid
' `$ n3 ~6 X& q4 G/ }# u' L# d8 T balance url_param session_id check_post 64
3 X4 g" a# z. H5 x1 d balance hdr(User-Agent)/ Y+ J: F3 `% t" g; _, d
balance hdr(host)2 N" q4 b2 c0 |1 I
balance hdr(Host) use_domain_only
9 V2 S. Y) i8 o9 l$ \0 W' ?9 y! a4 i/ ~
Note: the following caveats and limitations on using the "check_post"" W R$ }/ c" l9 E8 G2 _: w
extension with "url_param" must be considered :$ N% u: S2 @% q$ Q% r$ p9 m% U" r) Y5 \4 P
3 I# k! I r* `8 N8 a
- all POST requests are eligible for consideration, because there is no way
. J* o2 s6 v ~! g. L to determine if the parameters will be found in the body or entity which. L3 G3 B% E; z" t: u
may contain binary data. Therefore another method may be required to
3 x: S- ?5 U* M2 Z, b% Z5 |9 r restrict consideration of POST requests that have no URL parameters in- g$ I7 [. a$ S; F' X
the body. (see acl reqideny http_end)
3 {: o+ M ]& T) N- C
3 y' l9 S' M9 ~4 W2 a3 _/ { e$ | - using a <max_wait> value larger than the request buffer size does not6 U8 ~+ t; m$ B" Y
make sense and is useless. The buffer size is set at build time, and
1 N4 `+ W2 c ?" ?! q: J defaults to 16 kB.
8 R" n' B) Q) s3 B9 n. V+ y2 {/ T' O4 X" ~" U8 m
- Content-Encoding is not supported, the parameter search will probably
: F- \ J* t3 ?0 m0 E fail; and load balancing will fall back to Round Robin.
; j# B! c9 q2 Q. Y1 d- n& X
8 e; K8 I t0 Q* t: M( h - Expect: 100-continue is not supported, load balancing will fall back to
5 n6 l' y# |" S6 X: K3 s Round Robin.
) b. h/ Y! @. R; q% \; }0 ~' `
9 q% h# p0 u' D/ E* W$ O$ l - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk./ c3 k( o' D @/ r
If the entire parameter value is not present in the first chunk, the. e4 w) g5 n4 M" i" p' X% v
selection of server is undefined (actually, defined by how little0 |9 l4 w# d6 E' i" @* U2 N
actually appeared in the first chunk).9 h3 b' [( D" x! D: I7 _+ J
- C. L l' l0 w. M( O5 f6 e: A- J7 h - This feature does not support generation of a 100, 411 or 501 response.) M- x5 C* w2 E( F( E
0 |9 j2 w- P5 l8 f7 b1 r - In some cases, requesting "check_post" MAY attempt to scan the entire
! G/ j& y/ H+ W contents of a message body. Scanning normally terminates when linear
2 u0 S, l/ t: V. k white space or control characters are found, indicating the end of what3 {5 ^+ n( z7 W' z8 k
might be a URL parameter list. This is probably not a concern with SGML- P* p1 z3 |, _/ _$ Z+ e
type message bodies.7 {9 o( g Y s+ T( }. w
" ]7 d: ^5 a- L8 P( }3 h8 }3 K See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and3 \% M! W! k1 ~8 c% d
"http_proxy".. Y% w# o" P2 B. Z& ~: p
) y, J, Z* C* k0 K: K8 F
0 |6 H$ g: m. E- ^
bind [<address>]:<port_range> [, ...]! q+ f/ U' e# h& W3 c: ^5 U+ U
bind [<address>]:<port_range> [, ...] interface <interface>
+ {) ^# M% J. j3 ]$ Q) Hbind [<address>]:<port_range> [, ...] mss <maxseg>
! Q: i: Z2 p, e! kbind [<address>]:<port_range> [, ...] transparent
6 u8 S2 X1 f; `0 j. Q! R- _4 gbind [<address>]:<port_range> [, ...] id <id>
# t! t7 O: B' m: Ubind [<address>]:<port_range> [, ...] name <name>
" z i- K- l- e* w/ w7 tbind [<address>]:<port_range> [, ...] defer-accept6 U" p9 f [, ?7 Z) }0 l
Define one or several listening addresses and/or ports in a frontend.
R. ?2 o1 W; o$ F& O* ^ May be used in sections : defaults | frontend | listen | backend
2 I p' v: Q: v9 ?" b; { no | yes | yes | no0 C* \5 {( M6 O2 D0 r
Arguments :
* p* v& P. G7 B6 E' R: Y; p <address> is optional and can be a host name, an IPv4 address, an IPv6; m5 W/ l& @: k! v. E$ \
address, or '*'. It designates the address the frontend will
' y+ x8 h- f6 D1 b3 h listen on. If unset, all IPv4 addresses of the system will be
# Z7 }3 y, m( D" {+ P3 G+ d5 ] listened on. The same will apply for '*' or the system's
% r$ n/ X: G/ z( @. H! I. b6 s special address "0.0.0.0".
1 {3 ^, e- r% D! b' y3 t3 @ y+ D% d2 o* n- {; |; ?2 {
<port_range> is either a unique TCP port, or a port range for which the
* |: X6 w. _- t* h7 R5 I proxy will accept connections for the IP address specified5 p1 B) @9 x! |5 O- N( O! X
above. The port is mandatory. Note that in the case of an
) O1 I2 s3 M$ f9 W) W% I/ Z. O IPv6 address, the port is always the number after the last" e5 p# p$ e8 N7 v* \. S, h n
colon (':'). A range can either be :7 j, p% y% N3 a( i1 w7 b
- a numerical port (ex: '80')
- g' \$ c* Y" \; Y - a dash-delimited ports range explicitly stating the lower
5 s) c1 |# _ ^" O+ B @1 E! v* p- ^ and upper bounds (ex: '2000-2100') which are included in
8 E' D: ~8 [& U) E2 A; D# q the range.
# `! ^% t( k0 @8 J! S! }, X E! A) ^, V
Particular care must be taken against port ranges, because, y9 a; d6 v. Q& d3 p2 Z
every <address:port> couple consumes one socket (= a file. F6 m1 {9 {0 |# X8 z
descriptor), so it's easy to consume lots of descriptors
6 W. v& o3 h5 N with a simple range, and to run out of sockets. Also, each
5 s" B8 X3 L8 b+ M3 `' F1 G9 O <address:port> couple must be used only once among all
$ c, Z" Z. O" ? E p instances running on a same system. Please note that binding
, r! t) b) f( |# i( ^6 ]# e8 {* t9 N to ports lower than 1024 generally require particular
4 d" u7 o7 H& H/ x privileges to start the program, which are independant of
" s* O; X3 g0 J# Q/ N% h* m$ } the 'uid' parameter.% D# [2 l& m* G
0 o# Y7 x" E6 I% Q. ? ~ <interface> is an optional physical interface name. This is currently' |8 G1 [; R% ^2 r5 ?' q
only supported on Linux. The interface must be a physical* C! K' l0 O/ d/ o; d5 ?
interface, not an aliased interface. When specified, all8 P7 E( q' o8 H% i$ q9 I
addresses on the same line will only be accepted if the
* A& Y: G0 [; l9 `5 G incoming packet physically come through the designated
; K- _9 W2 c1 V, @7 p: ]. n* [ interface. It is also possible to bind multiple frontends to
& A6 y. E6 k* e R( B, t) s the same address if they are bound to different interfaces.
5 }5 D j: R M- M Note that binding to a physical interface requires root
3 |% I0 u! v0 H# t k1 ~* D% K6 p privileges.' P& I- }! h9 A; \4 e) D
* R5 {9 i$ l0 U
<maxseg> is an optional TCP Maximum Segment Size (MSS) value to be/ F% z3 Q$ G" ?1 i* L% z, Q8 e
advertised on incoming connections. This can be used to force( b6 |8 U S: ]1 Z; O, B- o, \
a lower MSS for certain specific ports, for instance for' q5 _5 h9 W3 n3 _: V# a: D! W
connections passing through a VPN. Note that this relies on a
6 ~- f' m7 S6 t2 d, f& R) c kernel feature which is theorically supported under Linux but
& E# l7 I3 q& x, |6 f% U/ @ was buggy in all versions prior to 2.6.28. It may or may not' j: R- p& ]" E3 b( P! j
work on other operating systems. The commonly advertised
. t" C- d) W. ]% d value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP).
7 F C; P* n& D$ X0 Q7 u- B; P2 v$ U! b$ \ q- h7 ]7 X
<id> is a persistent value for socket ID. Must be positive and
; u9 {% b6 q F- \: g8 m! F' |. U5 p unique in the proxy. An unused value will automatically be
0 A' z p5 S: Q" i6 g assigned if unset. Can only be used when defining only a
" J- K! x( [/ }! n single socket.2 o* N$ D% O$ I9 E
6 p* J, C0 I5 \9 Z9 x8 ], b <name> is an optional name provided for stats o8 ?, S0 [/ y
, c7 H6 {; b( t. f% ^2 i1 l( i, A
transparent is an optional keyword which is supported only on certain
; a8 ~' ^; w" _' }, j3 w, w Linux kernels. It indicates that the addresses will be bound
: t: h3 x! Z8 X( N% d even if they do not belong to the local machine. Any packet
& Q& g$ O+ x$ f+ ?/ m targeting any of these addresses will be caught just as if) i: r2 k: J; y, @" r/ d
the address was locally configured. This normally requires+ Y E. C9 J8 Q% h9 F, \
that IP forwarding is enabled. Caution! do not use this with
3 }- A0 ~: B) Y. I& p1 `9 _ the default address '*', as it would redirect any traffic for
& I* Q9 K7 R& T( g; H* R the specified port. This keyword is available only when
) A9 S5 ~4 }7 ~6 u. H HAProxy is built with USE_LINUX_TPROXY=1.
+ U. N5 p( A+ X; o
- x% k% X/ ~& k& [/ w1 G4 N; a7 Y4 Z defer-accept is an optional keyword which is supported only on certain
& A: @; R: I- C2 P Linux kernels. It states that a connection will only be$ i( N9 V" U/ ^$ ?- G
accepted once some data arrive on it, or at worst after the- a8 @2 Z q- v" V) a
first retransmit. This should be used only on protocols for: a5 x& [* D& _& H% Z# ^
which the client talks first (eg: HTTP). It can slightly
' A/ m! B* i" K# D! i8 q! U improve performance by ensuring that most of the request is* q }! P/ [% T# s! Y
already available when the connection is accepted. On the5 x3 ~8 y2 a5 j3 z1 J
other hand, it will not be able to detect connections which" _0 @& c% A" U C8 t/ K, z5 s
don't talk. It is important to note that this option is
4 i! f, [& L4 D9 f broken in all kernels up to 2.6.31, as the connection is$ M* O4 }5 ` D' t+ \% Z6 B
never accepted until the client talks. This can cause issues: D h) X( ?% w1 J- v$ y$ y' m2 g
with front firewalls which would see an established( B6 I0 n$ f$ B9 {
connection while the proxy will only see it in SYN_RECV.9 ?* c6 c) v, b
7 P6 \8 j- N& \9 \: D F/ [ It is possible to specify a list of address:port combinations delimited by9 K& k" q5 a; B. L9 @5 x! |! g
commas. The frontend will then listen on all of these addresses. There is no
+ }& v. D! R& z2 V2 J5 n fixed limit to the number of addresses and ports which can be listened on in
3 V! J9 N# ^; i0 A3 h a frontend, as well as there is no limit to the number of "bind" statements5 W, R7 P3 x* m" `4 t
in a frontend.$ I) X/ A% o; T( R( P
. P! H2 S" {& g: m' m( K Example :
$ N7 z6 |; F, |2 {: D listen http_proxy! B4 C0 [2 g5 ]# a# y$ k
bind :80,:443
* v8 W% I( \1 }. G bind 10.0.0.1:10080,10.0.0.1:10443
. J3 L& l' v" s# W; i( M' ^! Q* v6 Q" F1 n
See also : "source".- T) s! P3 Z9 B
% S6 d5 T( p0 f; h# |
) p+ a6 |1 e: y8 c0 A9 X, y9 Nbind-process [ all | odd | even | <number 1-32> ] ...
% K8 W) I' E/ `2 O( v$ ?' Z# S Limit visibility of an instance to a certain set of processes numbers.
( J a; K5 g" V' R( K+ `3 S, B$ t May be used in sections : defaults | frontend | listen | backend
9 I! v0 v0 o5 E: }6 V yes | yes | yes | yes% _ o# J1 Y- H2 U
Arguments :$ ?6 a$ ?6 m0 P7 y5 @& J
all All process will see this instance. This is the default. It6 g+ y# z' _" d3 F9 p
may be used to override a default value.
) w- Z" b& _" A$ Q0 N0 f* p; R' i" J
odd This instance will be enabled on processes 1,3,5,...31. This' N; Y& G @3 K
option may be combined with other numbers.- G8 Q7 R+ j, c9 D, }) k
& s0 p+ q0 S9 e6 }/ i9 d) S* `8 Z even This instance will be enabled on processes 2,4,6,...32. This
% c4 D7 s6 c5 [/ i% R option may be combined with other numbers. Do not use it0 T. S0 X0 C( ?4 K9 u
with less than 2 processes otherwise some instances might be/ C N$ q; C8 [$ h9 k7 a8 k5 b% B
missing from all processes.
9 N+ I/ U6 o- S- Y5 y k3 }: \8 `5 D' Q5 s. P# R) G4 ?9 y6 h
number The instance will be enabled on this process number, between
f$ k9 _# m* ?$ ^ 1 and 32. You must be careful not to reference a process: V3 O2 o: v3 z; _
number greater than the configured global.nbproc, otherwise
0 c) F2 r3 ]! n/ h# s some instances might be missing from all processes.* d1 x: r6 K% q5 {. T
. M+ Y& V5 L% i6 Z% e. L This keyword limits binding of certain instances to certain processes. This
" E' U. ]; e; u O- F is useful in order not to have too many processes listening to the same
+ q3 r! w. s1 J ports. For instance, on a dual-core machine, it might make sense to set
g+ U6 y& ~' d1 C# a 'nbproc 2' in the global section, then distributes the listeners among 'odd'
: i7 t/ O1 K5 \7 G& e, \% A and 'even' instances.
" B+ g# g% a9 m5 A( l5 ^8 c
4 ^: F; E) z# o8 w* t' L At the moment, it is not possible to reference more than 32 processes using
6 [; T, ~3 T9 d' C this keyword, but this should be more than enough for most setups. Please) L5 b O7 s# K' W7 }/ \
note that 'all' really means all processes and is not limited to the first
9 N0 `5 R0 W1 o* t! e 32.
/ ?3 M, j) z9 ^" z K: c- p! `4 I( b- R. J
If some backends are referenced by frontends bound to other processes, the' v1 ]: `' d; ?- E) M
backend automatically inherits the frontend's processes.
1 t' x9 ]/ j [$ h5 b
. O% D- \$ t7 b! c% q Example :
! Z6 k- ?: y& G listen app_ip1
9 [6 p* F9 q3 d. w bind 10.0.0.1:80" }. x0 D( P$ l |9 w! |
bind-process odd
% ^1 f g8 F J9 J+ ]
% r& A9 P* }, t listen app_ip2
+ t q; a1 B6 q6 V bind 10.0.0.2:80( R" |/ v' J3 e. F
bind-process even
) ~. R! E3 N% N' }- F3 a- F* k! { h4 c% M7 y" [
listen management0 S' i) I4 J* j: `- N8 O
bind 10.0.0.3:802 O0 C+ r' m7 y# o
bind-process 1 2 3 4- X1 Q4 m% {/ n/ |) \
3 J( G8 ]0 R3 |# V
See also : "nbproc" in global section.8 S) `" h* l/ I4 s$ ^( ~7 a
8 T1 L: ~# U* S0 }2 u. \# Y4 F0 K; c
block { if | unless } <condition>
; g, ?3 k0 _8 m; W Block a layer 7 request if/unless a condition is matched" _. m: H; L2 X: H( f+ V8 A
May be used in sections : defaults | frontend | listen | backend
" M8 Y2 ~! ]% [* d5 i6 i no | yes | yes | yes
4 F) \2 E) {+ {: W& Z, B
- w/ U9 f4 s+ f The HTTP request will be blocked very early in the layer 7 processing
' K2 m9 j" L/ F& \/ Q if/unless <condition> is matched. A 403 error will be returned if the request* C( e$ ?7 n- P
is blocked. The condition has to reference ACLs (see section 7). This is9 W7 F3 n7 f' d- `2 i$ x
typically used to deny access to certain sensitive resources if some
/ _, u- j7 l4 s. N conditions are met or not met. There is no fixed limit to the number of
) g8 V* x, E& E! q% d' `6 J% Q "block" statements per instance.1 D0 S7 M4 ]& {
9 b r# x8 W8 s2 e+ _: q
Example:( s3 w E3 b3 N& N
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
1 G, o: \8 `: I' M acl invalid_src src_port 0:1023+ L! Q3 U0 v3 f7 Q4 Y1 X
acl local_dst hdr(host) -i localhost
6 I. ^9 n( d: W2 J. q- } block if invalid_src || local_dst
: U9 v- J) L# j+ y Z5 _- p6 R, h" ?" T) \
See section 7 about ACL usage.
$ Z; ?: R5 j* k* f0 T, |% D* {. V* B
7 J; `! g; f4 P1 acapture cookie <name> len <length>! U9 ^/ `5 _" d% ]
Capture and log a cookie in the request and in the response.) x% e [3 g0 H: l& W( H c
May be used in sections : defaults | frontend | listen | backend9 w. c) W- Z0 X# @
no | yes | yes | no9 m9 ~9 \8 ^( H' G
Arguments :0 j m+ l: I0 Z5 C7 u
<name> is the beginning of the name of the cookie to capture. In order" @/ Z E0 x: H8 v [6 ]4 ?
to match the exact name, simply suffix the name with an equal. M) u+ k6 Q$ {) A% {9 l$ Q6 l, v
sign ('='). The full name will appear in the logs, which is
$ B3 ~ D1 h9 p useful with application servers which adjust both the cookie name7 ^4 f4 u' \8 {
and value (eg: ASPSESSIONXXXXX).
8 T% s& h4 H# u, U, H% W0 L+ _ e( |: v$ Z7 l
<length> is the maximum number of characters to report in the logs, which3 n" v2 p* x$ N3 t; V4 j T
include the cookie name, the equal sign and the value, all in the
2 S8 | ~4 h) {% l$ j/ `6 d+ [ standard "name=value" form. The string will be truncated on the* [$ l& J: e4 E: H) x; R' K
right if it exceeds <length>.
5 p9 Q8 a+ U+ z( S3 V9 T$ {5 H& H5 m& {" \6 [
Only the first cookie is captured. Both the "cookie" request headers and the* e0 F8 |$ _% i [- v. W
"set-cookie" response headers are monitored. This is particularly useful to
. p( J& V9 _6 P3 B) T* a/ f; h check for application bugs causing session crossing or stealing between' e3 ?. H* u6 d$ T
users, because generally the user's cookies can only change on a login page.
- Q3 s! C" I5 p& Y5 F+ z! `# j! J, T% y
When the cookie was not presented by the client, the associated log column& B9 p5 m4 S" J- f
will report "-". When a request does not cause a cookie to be assigned by the
# i6 h4 P1 a5 b L) w server, a "-" is reported in the response column.
6 O4 q+ ?6 I1 Q0 b& `1 }* O7 y) t- d* H! D( ~
The capture is performed in the frontend only because it is necessary that* I# U* a* }$ h8 X) V5 c3 w$ h' _, U
the log format does not change for a given frontend depending on the: L1 X" O+ x& `- U% A) d( s
backends. This may change in the future. Note that there can be only one0 m. k8 L9 J- a$ i$ |4 P
"capture cookie" statement in a frontend. The maximum capture length is2 ~# @8 J- R. c6 @. o
configured in the sources by default to 64 characters. It is not possible to! k8 }0 _% C& Q5 p! ?
specify a capture in a "defaults" section.
' H5 L$ H4 I) ~+ \& ~7 i
; B+ e: J! l# X% h% i6 p Example:* p% B2 E- y( O8 C9 n6 z
capture cookie ASPSESSION len 32
" @$ k: `) n: h+ d2 S; O4 a6 B' y: Q @8 M* x9 p
See also : "capture request header", "capture response header" as well as
3 N3 p! `# R) O3 u& H* ~ section 8 about logging.
, G0 u, D: D v6 a0 K! Q: n
% Q' Q5 g: c6 B) K& p$ g5 R5 S+ m' d$ e, p& u$ }2 } F3 A4 @! H
capture request header <name> len <length># q& e0 |1 y, I6 @
Capture and log the first occurrence of the specified request header.
( P7 Q# Z: b0 S May be used in sections : defaults | frontend | listen | backend" p4 ~" w; t1 ? k9 O
no | yes | yes | no6 P9 R. I$ Y4 Z( U
Arguments :) ?6 l6 H" M, Q5 Z, w: P: m5 v2 m- [
<name> is the name of the header to capture. The header names are not
/ V) K8 q7 v: S& O8 U case-sensitive, but it is a common practice to write them as they
* U* B' F# u& ?. X, l3 l appear in the requests, with the first letter of each word in
( @7 V7 E; g# r" { T8 c3 x upper case. The header name will not appear in the logs, only the& C% F1 m1 g; Z( s
value is reported, but the position in the logs is respected.
" T. m( m: _ k' Y0 B% }" W& U- ]7 H& _# q
<length> is the maximum number of characters to extract from the value and
1 U+ N) G% f! T: b; m7 c7 f report in the logs. The string will be truncated on the right if
! N6 s) X7 |: s* u it exceeds <length>.
) y+ B( f, H. j @% }- m
- r5 P3 A* x4 W4 O& Q/ l g Only the first value of the last occurrence of the header is captured. The
( y* M+ u& G! C value will be added to the logs between braces ('{}'). If multiple headers" c! x# M4 d! a# U" N' Y
are captured, they will be delimited by a vertical bar ('|') and will appear" Q; e8 K P1 l( j# k# X8 K
in the same order they were declared in the configuration. Non-existent
" ~, o0 P" q9 q" f8 c headers will be logged just as an empty string. Common uses for request
2 P5 K" X$ `/ g8 W" W# z header captures include the "Host" field in virtual hosting environments, the G4 P7 B, B2 p2 W$ f6 R( [( m
"Content-length" when uploads are supported, "User-agent" to quickly
, N! F6 m* p# J* V! _# d# J differentiate between real users and robots, and "X-Forwarded-For" in proxied
* c. D0 \- W7 ?, Y& J environments to find where the request came from.
# S* Z* `1 s: [& q* m
& }6 h3 U, }+ `* Q# m4 s3 v Note that when capturing headers such as "User-agent", some spaces may be& O% E' q+ }0 p" ?/ T" K
logged, making the log analysis more difficult. Thus be careful about what# s6 D+ B; f7 C A6 m! F
you log if you know your log parser is not smart enough to rely on the6 K9 X+ }; g D3 t3 _; k/ G
braces.1 Y( @. ~0 F' T% O) U3 P7 c
1 t' H8 h1 v1 T' W There is no limit to the number of captured request headers, but each capture0 _- ], G4 c2 h8 q4 I
is limited to 64 characters. In order to keep log format consistent for a3 x( `; O( a) T1 \( s9 u) b: G
same frontend, header captures can only be declared in a frontend. It is not& H' _% d' n' G$ ~( ]* I
possible to specify a capture in a "defaults" section.2 s% D9 J. a; a( W
1 R" Z' J; d7 ~! ~" ^- O( Z- A" p Example:! O) ]" Q$ m; f* i* ]; k
capture request header Host len 15+ j4 }$ T- X4 S4 Q% z
capture request header X-Forwarded-For len 15
$ n3 k/ N6 M6 S0 e capture request header Referer len 15
5 S% G8 d' J( I# Z9 u6 {0 N& ~! L* S( I
# q6 z% q: R: O) Y6 | See also : "capture cookie", "capture response header" as well as section 8( D$ c' i5 {/ D6 P% h6 ?
about logging.
6 E' f$ ]' u" K& h3 ~; N: X; o! M. w* h
. ?# t8 C: b- i& D. _3 \5 o3 n" v
capture response header <name> len <length>
" A( y J& `$ I3 B Capture and log the first occurrence of the specified response header.1 [" T9 u* K" n( F) B; \- ~( h% M
May be used in sections : defaults | frontend | listen | backend8 x( N N4 s) }% n
no | yes | yes | no
' b. _% N' p; c, n9 a1 P Arguments :
1 l( _# R. y8 d- W <name> is the name of the header to capture. The header names are not
8 v |- B" s! w! x" K8 {1 _+ J' K0 P case-sensitive, but it is a common practice to write them as they" `" T2 g! ]7 y9 v
appear in the response, with the first letter of each word in+ r+ v! L `! k
upper case. The header name will not appear in the logs, only the# g- ?$ i! Y: `8 _! O: Z
value is reported, but the position in the logs is respected.5 d- K! J% x1 d( {
2 [# {1 p" i9 E
<length> is the maximum number of characters to extract from the value and0 c+ R5 x) L" Q$ x
report in the logs. The string will be truncated on the right if
0 {' ?& [ g, [- V it exceeds <length>.9 H7 N# j2 }8 E8 W
, N Q3 A& I7 B n Only the first value of the last occurrence of the header is captured. The8 c9 @0 f9 I0 ]( q
result will be added to the logs between braces ('{}') after the captured' s8 ]1 i# E! m& u5 o
request headers. If multiple headers are captured, they will be delimited by
1 |% G' e* i0 N% I# l- r9 b) }' |( _ a vertical bar ('|') and will appear in the same order they were declared in
/ o0 e* J' a0 r( u- c6 s the configuration. Non-existent headers will be logged just as an empty
$ T W5 z7 D: a% t, V) X string. Common uses for response header captures include the "Content-length"1 U2 E+ \, s2 P. q" k6 i# n
header which indicates how many bytes are expected to be returned, the
4 @! P" D k0 L k* U. e/ ] "Location" header to track redirections.% U% C! I ^( u- Q3 T+ @
. |+ X; E2 n3 w- e5 E& F
There is no limit to the number of captured response headers, but each2 U5 P7 Z, k/ D4 M
capture is limited to 64 characters. In order to keep log format consistent
/ v( [! V5 ?& \ for a same frontend, header captures can only be declared in a frontend. It' R5 q: b- `3 [! e$ e8 j* }
is not possible to specify a capture in a "defaults" section./ }) [: j" i( x/ w7 t# K
0 ~) Q/ E; j, ^ Example:1 o$ P; }" _& `
capture response header Content-length len 9
" a" q1 f$ k3 y9 I( n capture response header Location len 15
$ l; d6 i- p R
# O1 D9 K# P2 U& o See also : "capture cookie", "capture request header" as well as section 8
5 y. _( G' h8 \3 K8 }* w2 n1 s about logging.
) K/ D( `7 L( G: Y# k) ]7 P: Z; l$ C5 u, A7 m/ t
- G d4 ]( Y; k g3 G4 p2 J
clitimeout <timeout> (deprecated)/ j( o1 G/ P6 v* _
Set the maximum inactivity time on the client side.
+ y6 [# m: f* O, ]( t May be used in sections : defaults | frontend | listen | backend1 m1 d; T7 b' j6 J% U% R2 T9 g
yes | yes | yes | no& B& o" n% N6 f W0 O) J8 p
Arguments :
7 h9 X- }, t8 ` T3 V" X <timeout> is the timeout value is specified in milliseconds by default, but# e) b. Y' v3 N' d W1 i2 i$ Q: f( j
can be in any other unit if the number is suffixed by the unit,7 _+ o5 Y( N- t; g1 z
as explained at the top of this document.
) g" w0 O$ d" N5 j/ o: N/ V+ ~5 s4 l# i
The inactivity timeout applies when the client is expected to acknowledge or
4 Y1 W, O0 i j send data. In HTTP mode, this timeout is particularly important to consider% B. Q0 R4 F& }! U$ a" c
during the first phase, when the client sends the request, and during the C5 f8 E# @) y! k
response while it is reading data sent by the server. The value is specified; \. w# X6 W1 G( \- N9 ]9 f6 X1 c8 P
in milliseconds by default, but can be in any other unit if the number is, W( ~% s1 Z u
suffixed by the unit, as specified at the top of this document. In TCP mode
. M) q+ c9 F' y. B' G) v (and to a lesser extent, in HTTP mode), it is highly recommended that the
; u! N% q; K' J/ W. V. m! I client timeout remains equal to the server timeout in order to avoid complex
' N7 C- i1 A+ r: R. m# z. p situations to debug. It is a good practice to cover one or several TCP packet
* q0 t, A* q9 c, v' m6 E losses by specifying timeouts that are slightly above multiples of 3 seconds
# r, n! w, l( P (eg: 4 or 5 seconds).7 {' s# @% Z& ]5 Y U& g# f
1 g+ c* T& s' f* z, F This parameter is specific to frontends, but can be specified once for all in% r6 p% ?- U1 @9 x, E
"defaults" sections. This is in fact one of the easiest solutions not to
. s' {4 u1 W* D1 e( N J0 w% H forget about it. An unspecified timeout results in an infinite timeout, which
& k5 }# K" c: b( l, I+ } is not recommended. Such a usage is accepted and works but reports a warning3 M F. l$ T- k' f7 N3 N
during startup because it may results in accumulation of expired sessions in
" B, F! Q% I; ~3 U9 i' p the system if the system's timeouts are not configured either.8 v; N0 {7 W; _
# E% I5 J$ b$ A0 _ This parameter is provided for compatibility but is currently deprecated.
2 z1 ^. c$ X. O5 k: M% D1 } Please use "timeout client" instead.
7 ?3 S% a' P) A r- P( u) t- |6 i7 Z# j6 x5 k3 v1 I
See also : "timeout client", "timeout http-request", "timeout server", and
. ?" Y, c8 s; b "srvtimeout".
8 B2 F! K) ]3 V4 t* U
6 U1 ] t4 Y: u) D5 }- M$ Q7 N1 v7 P
contimeout <timeout> (deprecated)
- n7 I* M% V# [1 g. V Set the maximum time to wait for a connection attempt to a server to succeed.
5 ?/ x: |: Y6 B, v/ @% j May be used in sections : defaults | frontend | listen | backend
; I9 F( Y1 Y" S0 g4 i% m+ R yes | no | yes | yes6 p; _; M H0 N7 _ Z( N
Arguments :
! T+ u% s% q6 @& F' ]8 s/ z# U8 ~ <timeout> is the timeout value is specified in milliseconds by default, but+ D' \( {, l8 S3 s
can be in any other unit if the number is suffixed by the unit,% B6 j4 {$ X0 K, Y! d. T8 d) ? [
as explained at the top of this document.
" T; y( T- z: _( o# K* m/ J/ V
, [: r/ w2 ~+ W If the server is located on the same LAN as haproxy, the connection should be
9 q. P! z6 w: |, ^( M1 n immediate (less than a few milliseconds). Anyway, it is a good practice to
4 o: L. ]4 N! H2 `2 O( `% x cover one or several TCP packet losses by specifying timeouts that are+ E% {7 |0 i) O8 l6 m
slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the0 u* c8 @7 c' T) m
connect timeout also presets the queue timeout to the same value if this one7 P* q4 a+ u7 g
has not been specified. Historically, the contimeout was also used to set the- @& j6 G! W& L& r6 m! n& C. q
tarpit timeout in a listen section, which is not possible in a pure frontend.& y9 \, Y. _* j5 ` J
. d7 P( d; Z) r5 j* Q! n+ k2 a This parameter is specific to backends, but can be specified once for all in% f, i, z- p# D$ |( W
"defaults" sections. This is in fact one of the easiest solutions not to8 m! c7 t2 h* Z& F4 l! S/ B
forget about it. An unspecified timeout results in an infinite timeout, which$ _- D2 i9 y! \
is not recommended. Such a usage is accepted and works but reports a warning4 s4 C- [6 }* d6 e8 g! z, n4 h3 o
during startup because it may results in accumulation of failed sessions in
( `4 ?- j8 K3 q* L# P# b/ X. {6 w1 Y1 _ the system if the system's timeouts are not configured either.
/ ?7 [7 D1 E& L. ]! C$ ?9 X
0 c3 ^% b! [: F8 K$ n This parameter is provided for backwards compatibility but is currently# a( ?. g p! y) m2 d
deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit"# D. z( x% V; h0 }
instead.
- ], o! G7 R- D0 i% T# V) _' J) X" m% ?, h; u
See also : "timeout connect", "timeout queue", "timeout tarpit",/ Q# h5 b6 p- q- }1 v; t, U4 k
"timeout server", "contimeout".) h k1 o3 D5 V" G
$ M& a9 X0 o: P0 o+ U9 r
& d e: c9 m% }- P' U# _
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
+ }% e7 B0 b& N% X" @ [ postonly ] [ preserve ] [ httponly ] [ secure ]3 ~& }' k" m- Z1 M! Q0 P
[ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
6 h9 z4 u6 s) X* H' R3 C Enable cookie-based persistence in a backend.
& O* z- T" h0 |: S May be used in sections : defaults | frontend | listen | backend8 s9 }, ^6 z1 W4 p9 v. ~
yes | no | yes | yes
8 z0 o& O$ P5 W9 b9 ^/ Z Arguments :. Z3 ~& b& T0 z7 W8 Z; Q
<name> is the name of the cookie which will be monitored, modified or
% J6 y& n8 A) \ H3 O- r' _ inserted in order to bring persistence. This cookie is sent to
8 o! b9 f. I! O: X# N the client via a "Set-Cookie" header in the response, and is
* s. G, z7 \: a. M$ k brought back by the client in a "Cookie" header in all requests.; l4 z: p, c( o) t) e
Special care should be taken to choose a name which does not% @5 m! |/ T7 s7 x
conflict with any likely application cookie. Also, if the same0 \+ M2 F( Q3 A5 J
backends are subject to be used by the same clients (eg:. A [% U, |' h4 k2 G: N8 t7 L i, _
HTTP/HTTPS), care should be taken to use different cookie names
2 E) x: ^0 K; J1 _; Q1 }1 w7 x between all backends if persistence between them is not desired.
! _* ~9 s' N2 `2 F; A+ c3 N d
2 H$ n, w7 m' _0 K rewrite This keyword indicates that the cookie will be provided by the
$ V& x6 Y# Y1 W* W server and that haproxy will have to modify its value to set the
0 b$ x1 t% |) F6 O* I server's identifier in it. This mode is handy when the management& C5 s! K. f$ _& E1 G i
of complex combinations of "Set-cookie" and "Cache-control"
: J% y* w5 t) \! q6 E headers is left to the application. The application can then& V# R; e! D, E, _, X
decide whether or not it is appropriate to emit a persistence
7 t* v, }( H0 p; x$ a cookie. Since all responses should be monitored, this mode only1 W( w& x1 e" U- L+ g: _0 b
works in HTTP close mode. Unless the application behaviour is
/ E# C# x/ L3 t: t4 w1 | very complex and/or broken, it is advised not to start with this& c( m0 J1 B$ u8 j
mode for new deployments. This keyword is incompatible with
6 a; L- g- G7 u' _ "insert" and "prefix".
9 [ j) f( U$ S; J( z, B2 v5 S8 B3 v8 r
insert This keyword indicates that the persistence cookie will have to
: v# ?' P: a2 q1 ~ be inserted by haproxy in server responses if the client did not* z7 h1 U/ e% x" x7 p
" l, H% F* C- S8 O9 D% P, \6 E- v( D already have a cookie that would have permitted it to access this
7 u1 A8 p1 G# j$ R( m& b server. When used without the "preserve" option, if the server0 H2 b0 }, X; [' _: S
emits a cookie with the same name, it will be remove before, U7 w8 Q* X: _* ^, M2 l
processing. For this reason, this mode can be used to upgrade: V6 u5 N- l* V/ E
existing configurations running in the "rewrite" mode. The cookie
" e% q6 [5 ~' E will only be a session cookie and will not be stored on the+ n5 G$ S6 I3 p6 k& i! W* g
client's disk. By default, unless the "indirect" option is added,5 \ j) M! y s; P) a
the server will see the cookies emitted by the client. Due to
" w/ c! A- ~6 Q4 ^ O caching effects, it is generally wise to add the "nocache" or4 O3 H# u9 ?7 ^+ {
"postonly" keywords (see below). The "insert" keyword is not/ D" i1 }, Q0 L( L" `3 }0 d7 N
compatible with "rewrite" and "prefix".$ w A3 [; z) k
! Q. V+ Q) |; \8 L% O prefix This keyword indicates that instead of relying on a dedicated; z: K/ m3 n% d0 v w
cookie for the persistence, an existing one will be completed.
% C% ~7 k' K* T& k5 \( Z2 q" K This may be needed in some specific environments where the client" s9 ?( U u9 e% X5 V/ d
does not support more than one single cookie and the application3 m* X+ y% d; D {4 i
already needs it. In this case, whenever the server sets a cookie* `8 t7 c0 Q. ]4 f: s5 [% P5 `
named <name>, it will be prefixed with the server's identifier$ f- L% N1 ~7 ^0 @
and a delimiter. The prefix will be removed from all client+ l4 ~, G6 e/ T" S' l
requests so that the server still finds the cookie it emitted.& F/ ~3 x! l) y- U7 z8 A
Since all requests and responses are subject to being modified,
' U8 i1 Y5 M( P this mode requires the HTTP close mode. The "prefix" keyword is7 }- v8 \5 G: A t8 E* e# Z
not compatible with "rewrite" and "insert".: V! o- {5 K, n" G
9 T# E" k6 |' }" O indirect When this option is specified, no cookie will be emitted to a
3 r0 |& D$ E# ~" ]! v+ X! o: W7 | client which already has a valid one for the server which has
7 `! R7 ?+ u3 H5 b a" @ processed the request. If the server sets such a cookie itself,
# k/ Q" I1 t8 W5 F/ K1 M- w it will be removed, unless the "preserve" option is also set. In5 P& I4 i8 m" _2 ]5 Q$ ~: a* c
"insert" mode, this will additionally remove cookies from the8 z& E6 h+ e- m
requests transmitted to the server, making the persistence
4 l7 Y) ? G* ~7 V% o' {$ g mechanism totally transparent from an application point of view.: u" i; ] @" X! S7 |9 B5 [
8 j4 i6 Q7 U3 ~- V: Q7 I nocache This option is recommended in conjunction with the insert mode
# d1 c, ^. W- X, q" T1 e" Z when there is a cache between the client and HAProxy, as it
4 q; o& u; q8 e ensures that a cacheable response will be tagged non-cacheable if1 q' z- _- [5 B8 y, _, B0 F; d
a cookie needs to be inserted. This is important because if all! Z8 I6 I, z) d( j
persistence cookies are added on a cacheable home page for
6 ^$ p' N2 b( a! X* E instance, then all customers will then fetch the page from an5 z ~" R* t8 S6 J( e& P4 {
outer cache and will all share the same persistence cookie,+ S4 t6 B6 X; `; \( S
leading to one server receiving much more traffic than others.
: k" g; ~+ N) P/ c! R$ \4 U3 m) Y See also the "insert" and "postonly" options. I) l C# f$ ~* l6 x0 g' s
0 x; L$ a/ u% O: N# g
postonly This option ensures that cookie insertion will only be performed
& i* C' U+ j R# `0 s6 f on responses to POST requests. It is an alternative to the- }) R" Q8 J* B5 h* m f) n
"nocache" option, because POST responses are not cacheable, so
( g6 D6 I( q$ y) S this ensures that the persistence cookie will never get cached. O# }, O: H; f6 R6 l
Since most sites do not need any sort of persistence before the8 F) I+ \( J- x5 _
first POST which generally is a login request, this is a very- S4 _) z7 |: ]8 O
efficient method to optimize caching without risking to find a5 e! d1 b+ L) Q/ A9 W! Y
persistence cookie in the cache.
0 P- O$ O: {7 a( E5 c2 u/ D s4 g See also the "insert" and "nocache" options.( H( `3 G2 Y" D( J. }
+ X4 t( F1 t4 t1 h4 H preserve This option may only be used with "insert" and/or "indirect". It3 f( g+ S) H# O. o% X# ~: d
allows the server to emit the persistence cookie itself. In this
+ j2 a5 t( E J7 } case, if a cookie is found in the response, haproxy will leave it5 s$ _& A0 R9 _" {, V; y
untouched. This is useful in order to end persistence after a
+ P- R2 S: I q logout request for instance. For this, the server just has to
V, R% l S& t- O emit a cookie with an invalid value (eg: empty) or with a date in
2 t3 {7 g# w# N( Y7 j$ V7 b7 `) F the past. By combining this mechanism with the "disable-on-404"! B5 D- N! A, z. _7 x
check option, it is possible to perform a completely graceful$ c6 e* j7 g& w
shutdown because users will definitely leave the server after# b- S- ~) ?! S' m- M/ j( F
they logout.
0 t+ i2 i# `% ?3 O3 `& R7 V
7 U7 I" Q/ D2 G) a3 Z, E& |, Y httponly This option tells haproxy to add an "HttpOnly" cookie attribute
0 ?9 x+ @* l1 h3 t when a cookie is inserted. This attribute is used so that a
9 F) i# u- P7 c! ^ user agent doesn't share the cookie with non-HTTP components.3 a+ I& |/ H! L! W Y, H" v
Please check RFC6265 for more information on this attribute.3 P6 Z& m2 w$ l* e# z! w/ `
) _0 b3 n- v: w+ x9 g0 i secure This option tells haproxy to add a "Secure" cookie attribute when
( q! x$ g3 D. S. n7 V: ^ a cookie is inserted. This attribute is used so that a user agent9 K" [% C3 F$ P1 {8 ]! T6 A( P( P
never emits this cookie over non-secure channels, which means
& ?0 Y0 c! v+ D8 H( n" f! v that a cookie learned with this flag will be presented only over
1 y6 {# k o- t! x7 J+ Q/ M SSL/TLS connections. Please check RFC6265 for more information on d: ^: A' m, x1 P
this attribute.9 ?, w" _; K; a7 Q9 ~: T
$ h* }! x) k- O0 X7 _( p+ f* r domain This option allows to specify the domain at which a cookie is
0 Z' P/ w. h+ f& k inserted. It requires exactly one parameter: a valid domain
$ W- S3 @, T. F8 c3 K# U name. If the domain begins with a dot, the browser is allowed to, f8 |5 ?9 Y4 o `( a0 `5 z
use it for any host ending with that name. It is also possible to
, Z) C/ c5 s7 |2 M/ a; d specify several domain names by invoking this option multiple
" ~5 b4 z: |* W times. Some browsers might have small limits on the number of
# G! k0 g" g) H- x- f domains, so be careful when doing that. For the record, sending/ T3 p( w& h. g. _! W' b4 v
10 domains to MSIE 6 or Firefox 2 works as expected.* ]' D4 U' f# A3 ?- t' v; @: E
+ T% t5 Q4 Z3 B maxidle This option allows inserted cookies to be ignored after some idle3 i) R& s8 a9 y
time. It only works with insert-mode cookies. When a cookie is
4 Z+ g) B6 E9 x sent to the client, the date this cookie was emitted is sent too.. e4 a2 n l$ b
Upon further presentations of this cookie, if the date is older
0 B" B; e6 {% n7 g& [, r- v than the delay indicated by the parameter (in seconds), it will$ _& L1 ^2 I* U- N( x5 z1 f
be ignored. Otherwise, it will be refreshed if needed when the: _5 a8 M9 H% Q" s& j8 _2 ]3 Q. B4 i
response is sent to the client. This is particularly useful to% i# j$ l8 P+ C) }* X
prevent users who never close their browsers from remaining for
( |! V z) ?( r: U C too long on the same server (eg: after a farm size change). When. n! M9 h- D1 w2 [
this option is set and a cookie has no date, it is always
6 q( Y% q7 N8 b5 |6 I* C! u8 | accepted, but gets refreshed in the response. This maintains the
+ e6 @; x5 x5 l( m5 D/ Z' W1 r: G ability for admins to access their sites. Cookies that have a
- A. O" m5 y7 y4 D4 c date in the future further than 24 hours are ignored. Doing so6 b: |, m; m4 q
lets admins fix timezone issues without risking kicking users off5 @0 s$ c# f; [1 h, B
the site.+ ~9 y& E1 N% V9 X
; d0 K2 B: `% ?9 a" i7 \/ g
maxlife This option allows inserted cookies to be ignored after some life
' ^/ q3 Z p: V% N# { time, whether they're in use or not. It only works with insert
. l% z" _6 a- _6 Z0 |! d mode cookies. When a cookie is first sent to the client, the date
: I, G% e3 M- {4 R/ D this cookie was emitted is sent too. Upon further presentations
) m/ B7 _! K' Y0 k0 q8 w% ~" N2 V of this cookie, if the date is older than the delay indicated by3 u* @ Z1 a: ?: m8 e6 O/ m- K
the parameter (in seconds), it will be ignored. If the cookie in
( S$ n* N+ q- v4 h the request has no date, it is accepted and a date will be set.
" e; J$ O/ X; S Cookies that have a date in the future further than 24 hours are9 `0 P. c: w7 t" l t7 `' T
ignored. Doing so lets admins fix timezone issues without risking" A z/ s) M' X6 ^4 ~0 j+ [) X
kicking users off the site. Contrary to maxidle, this value is1 h. j* y) A1 _3 w) e$ d7 b4 s
not refreshed, only the first visit date counts. Both maxidle and- i; Z2 P) c8 K0 ?$ C8 L' n
maxlife may be used at the time. This is particularly useful to
2 Q; ]. R& O7 f% e, F prevent users who never close their browsers from remaining for
' b+ U: _, @. G7 I: C6 g too long on the same server (eg: after a farm size change). This8 m0 ]6 w7 [. O
is stronger than the maxidle method in that it forces a
8 ~% L0 I: W8 H9 H6 y; c2 X redispatch after some absolute delay.+ n- }3 {) }9 P% q7 \% P7 X
6 Q5 I% C% U0 A8 b2 F* C* M
There can be only one persistence cookie per HTTP backend, and it can be$ r; K$ D$ Q2 w5 ?+ G" F
declared in a defaults section. The value of the cookie will be the value
8 r9 p8 T7 t3 @3 r indicated after the "cookie" keyword in a "server" statement. If no cookie
. u. m. M9 J" g/ I% s4 W& j3 w R is declared for a given server, the cookie is not set., P/ Y+ D* `5 j" ]. P5 i
8 p5 b: C, ~3 x6 b Examples :7 I5 ^* R: D T
cookie JSESSIONID prefix) H4 G, S2 y$ f5 \, p
cookie SRV insert indirect nocache+ |: f m, c# v& e
cookie SRV insert postonly indirect
9 n0 }, ]. P! y5 m cookie SRV insert indirect nocache maxidle 30m maxlife 8h. i6 j8 |) i2 g6 T) u1 N. m7 Q
) k3 F* g% O$ N$ _* i! Z" H' B See also : "appsession", "balance source", "capture cookie", "server"
9 e0 k+ p5 v y8 T K6 _ and "ignore-persist".( M- F% J4 s2 O# a/ G. y
# h7 p$ i$ a; Y! T8 ^# ]' T% V1 @/ q4 R; h9 i( O
default-server [param*] O" U0 [# f1 v3 [' w. N/ `
Change default options for a server in a backend
0 P @9 l; e1 j/ p) \2 r! f May be used in sections : defaults | frontend | listen | backend) B7 n8 ]. S7 @, T! e# I
yes | no | yes | yes
, R* d7 j: k& e- g" l3 _ Arguments:' S8 L# b2 x+ c; N" F- t2 Y( h
<param*> is a list of parameters for this server. The "default-server"
z, X6 `+ b& d# Z; ~' U: l keyword accepts an important number of options and has a complete# V s& c# f" ~1 Q7 u+ B3 F
section dedicated to it. Please refer to section 5 for more: E; q; g1 H# s1 z
details.
/ V; L9 X8 P# z) L0 N) |. d8 x. @7 S3 d/ j* o
Example :
" U- s- ~1 T4 L* r1 ?# i default-server inter 1000 weight 13, l! {/ Q2 k: o8 b3 l
* ~4 g# ?0 G+ r6 o. x
See also: "server" and section 5 about server options
9 }- D% y; s, p# W( s9 m1 P& A
$ B0 J! j, w% \: h
; ]# v4 J' N7 n6 e" d! R, ]default_backend <backend>( |' x& l9 U v; q+ i' O
Specify the backend to use when no "use_backend" rule has been matched.) G) k, A6 D o3 V( ~2 m) Q
May be used in sections : defaults | frontend | listen | backend( o! E/ c+ z1 u- [$ K- m
yes | yes | yes | no3 Q) U& ?% \1 U4 B, T) I9 j2 C
Arguments :1 ?9 W" _- ^7 S% d) f
<backend> is the name of the backend to use.! H5 M4 i6 ]( o, Q
3 X6 s7 X! Y2 Q% [& i
When doing content-switching between frontend and backends using the
7 n/ V5 ]9 n. J2 W "use_backend" keyword, it is often useful to indicate which backend will be
4 s! r" B" J4 { used when no rule has matched. It generally is the dynamic backend which4 ]) g: `8 p4 k7 @
will catch all undetermined requests.
! N2 z8 ]& w: L. V% B& B. y Y9 W" d8 r# _! S
Example :6 C1 D) R/ U0 n9 J" b
( m# H* f- `6 U% e0 J2 B. w: u use_backend dynamic if url_dyn2 Q0 v- o1 d4 B; Y0 E5 j4 u
use_backend static if url_css url_img extension_img
& ?1 M% Y: s7 p. \ default_backend dynamic
/ R. y0 O7 M" w9 M; f. r D, }* E+ `& D* I9 f* y# V
See also : "use_backend", "reqsetbe", "reqisetbe"" c" W; I( @2 B! T9 N3 a
$ p! ?- Q% Z+ q& |2 F3 j
4 |* @' B4 j, _( ~disabled
; E5 |* \8 Y& @% j r& D' E Disable a proxy, frontend or backend.2 q% G6 M$ i, x: H0 x! }
May be used in sections : defaults | frontend | listen | backend
8 W; Y" [7 @) A+ x8 ` yes | yes | yes | yes. G2 h' L1 B+ s' h' W) d
Arguments :) r4 w& |$ j3 n( T2 C5 M5 q
% C7 u' c2 g# {$ {3 l The "disabled" keyword is used to disable an instance, mainly in order to
) p' [, v4 W+ Z1 j# f' ^' d* v liberate a listening port or to temporarily disable a service. The instance
u6 V2 C6 k8 C0 c9 p# f will still be created and its configuration will be checked, but it will be
* u& K- b& m9 q1 K/ F _ created in the "stopped" state and will appear as such in the statistics. It
( q) [' V8 `( V5 B4 G will not receive any traffic nor will it send any health-checks or logs. It
7 {3 K! ?0 ]. J6 l is possible to disable many instances at once by adding the "disabled"/ i4 f2 U0 D, Z E/ v' k
keyword in a "defaults" section.
, l7 T+ K, N/ ?8 q/ a1 ~
+ O7 M5 C! f3 w4 t% [ See also : "enabled"
' \2 S; g, }6 ^+ \# H. U$ v8 ?, h& V* w
( F. p4 W5 J( jdispatch <address>:<port>
8 N/ T9 C4 ?; k. ?4 ^1 N+ ~ Set a default server address0 L! B* k" b; j3 S2 l
May be used in sections : defaults | frontend | listen | backend3 [" o# p) S9 N2 l
no | no | yes | yes; ]' N" H: @- W& [) `
Arguments : none; r3 P( [8 L% Q/ W9 z5 T; H
" k% d. L. J x& _: E: P
<address> is the IPv4 address of the default server. Alternatively, a9 }2 ^1 m. l+ n
resolvable hostname is supported, but this name will be resolved* v/ z) T! p' V
during start-up.
" a4 |6 `% c' u O& d
8 g0 j2 J9 ~4 w7 F* F5 V& A <ports> is a mandatory port specification. All connections will be sent" i& A! ^8 c" H; \7 | D
to this port, and it is not permitted to use port offsets as is
9 s* R* H; W" O3 r, d/ V: G possible with normal servers.
$ m c- f% \' J) ?
9 N8 }3 u4 _3 t; l# [5 u The "dispatch" keyword designates a default server for use when no other
6 H* Q0 h* V J e+ z8 F8 R server can take the connection. In the past it was used to forward non$ ^8 y0 c+ B: N
persistent connections to an auxiliary load balancer. Due to its simple1 U4 {& w7 \5 E' ?4 C
syntax, it has also been used for simple TCP relays. It is recommended not to0 n: l6 F" {4 r( @
use it for more clarity, and to use the "server" directive instead.! [$ X% s% R# R' u! g# l
: ?; u+ c8 G8 t6 [% @( [0 Z See also : "server"
1 L6 K5 ?# q; f- ~: |/ E; `* |& \3 r7 c8 L) u K" \2 \
$ x! ]8 Z5 h1 Z- d7 J: J3 M
enabled
r, U' V' y! t- d4 N Enable a proxy, frontend or backend.: P" c) O- P2 _7 T
May be used in sections : defaults | frontend | listen | backend
# }6 | ]) Q3 V0 ?4 @' }2 G* x# e* { yes | yes | yes | yes* A5 r$ |# b9 [# _3 y6 g, I9 U
Arguments : none8 p2 I h2 V1 l" D
g+ _* W: J8 u. V, X) N, M The "enabled" keyword is used to explicitly enable an instance, when the8 K( h( g3 C% _: k
defaults has been set to "disabled". This is very rarely used.
+ @* O' }) m' @3 Z9 R- q. W$ S
$ _0 W9 l9 ]" g9 X/ i See also : "disabled"1 F9 I+ }) M2 M1 _! f' P
/ ^4 w, c4 H/ _" y
4 p5 y, z/ ^" ^3 ^
errorfile <code> <file>/ v' D2 m3 L% C/ }' h: J' C1 A8 d% U
Return a file contents instead of errors generated by HAProxy! N1 h5 S) T( q. t
May be used in sections : defaults | frontend | listen | backend6 L/ e( B/ K) Z% u8 `* b
yes | yes | yes | yes6 M( S( Z" J# c( F' w9 `
Arguments :8 i" U5 i$ K* p. f
<code> is the HTTP status code. Currently, HAProxy is capable of4 H6 [. o5 a0 |( c1 _- |
generating codes 200, 400, 403, 408, 500, 502, 503, and 504.
/ ?. M, ^$ f$ ]* Y4 S t# L, ^9 A& J# w( `
<file> designates a file containing the full HTTP response. It is
6 i) J9 p, L& T9 |5 P recommended to follow the common practice of appending ".http" to
0 {% f4 R% d4 q8 d+ q" Q- c" H; l the filename so that people do not confuse the response with HTML
" D$ A6 b1 I5 ~+ Z. y error pages, and to use absolute paths, since files are read% X( o& S6 V) K. k& @4 ?0 F7 D- B( V
before any chroot is performed.8 ~2 ~5 ?6 {" k) M
8 z/ z9 |6 `. `" `
It is important to understand that this keyword is not meant to rewrite
8 {* t3 z, }4 ^& ~8 ]& u* t$ c errors returned by the server, but errors detected and returned by HAProxy. b9 b5 ]- T/ p, |6 M( l; V n
This is why the list of supported errors is limited to a small set.3 B5 C/ H) {+ H4 F7 l
) I: }$ \& |2 @% I4 G Code 200 is emitted in response to requests matching a "monitor-uri" rule.
9 |1 ?; I1 t' |8 @
0 M& j/ C) C% `3 r The files are returned verbatim on the TCP socket. This allows any trick such
* A, D9 F1 n4 x4 a2 b3 V) j. b as redirections to another URL or site, as well as tricks to clean cookies,2 m; V, {* o7 T# ~; V2 {0 {
force enable or disable caching, etc... The package provides default error
+ A+ e2 v% d- u files returning the same contents as default errors.% ^- |: y9 S& E6 k
0 K# H. M+ @0 R The files should not exceed the configured buffer size (BUFSIZE), which
c* U8 a6 r9 y* |* K) u+ O generally is 8 or 16 kB, otherwise they will be truncated. It is also wise, l& X: s& E7 H# B' m
not to put any reference to local contents (eg: images) in order to avoid
+ w# c2 o. p8 r1 { loops between the client and HAProxy when all servers are down, causing an
* ^0 [# f Z8 \8 n! X& v; u error to be returned instead of an image. For better HTTP compliance, it is& w1 p7 M5 p" y! b0 b4 q& v( X) U
recommended that all header lines end with CR-LF and not LF alone.: o' y6 b8 `' | N* \6 u: e5 Y
9 ?7 q8 C& A6 C& v$ W. g7 | The files are read at the same time as the configuration and kept in memory.2 E4 {( j1 g% L; b9 o7 E$ g/ s% s0 E
For this reason, the errors continue to be returned even when the process is
( |3 q+ ?, v- U4 T1 Z$ V chrooted, and no file change is considered while the process is running. A
3 O; W. y# r" n5 q, W simple method for developing those files consists in associating them to the
" Z" X+ j' Z& Z: w3 L7 A+ I 403 status code and interrogating a blocked URL.. o# g( e7 D- o2 a
" n/ ?7 ^) m. L: m9 D4 _, [+ g1 [3 B5 H
See also : "errorloc", "errorloc302", "errorloc303"
# M* X) ` a+ x* [" _7 q) h, t4 C0 B' d0 a" [/ K. Q: N2 \
Example :9 f7 w& P' F& X$ k! M
errorfile 400 /etc/haproxy/errorfiles/400badreq.http* X# r [, R1 Q. S' E$ S6 c
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
7 T, s% q9 C6 p errorfile 503 /etc/haproxy/errorfiles/503sorry.http
( b- Z# K- ]% K% S* ~3 \8 m, b4 Y9 Y, l9 y8 Y6 {6 U3 n6 Z5 g2 [# G
, A6 l/ f7 N/ c! n( Aerrorloc <code> <url>; ^1 H: e6 \5 L8 x! I
errorloc302 <code> <url>
# F2 i" R8 G4 A$ ~ Return an HTTP redirection to a URL instead of errors generated by HAProxy8 K9 {% w% t& v. H
May be used in sections : defaults | frontend | listen | backend) M/ Q& d& l. v! N( F; }8 ?" T
yes | yes | yes | yes
- f: d4 F( T) `4 e Arguments :, Y4 M! F1 R: h8 s
<code> is the HTTP status code. Currently, HAProxy is capable of& t% ^+ ~7 p( f1 z( w) K
generating codes 200, 400, 403, 408, 500, 502, 503, and 504.2 q4 |8 x4 _8 E; u- M+ j
- }; u) ^& l( T0 T
<url> it is the exact contents of the "Location" header. It may contain# l3 v* c$ o, w, M& l+ \
either a relative URI to an error page hosted on the same site,+ }* g0 F1 l, y( D
or an absolute URI designating an error page on another site.
1 j- A5 Y7 `. |5 J Special care should be given to relative URIs to avoid redirect8 T( l' [0 K! K* z9 a( m2 G2 S/ `
loops if the URI itself may generate the same error (eg: 500).( Z- ?5 R' {) t5 X
" M+ P8 P, w4 l$ H# Y. r It is important to understand that this keyword is not meant to rewrite
" C9 J1 U! \6 q; J errors returned by the server, but errors detected and returned by HAProxy.
$ A. t% s4 I) ]2 Q This is why the list of supported errors is limited to a small set.
/ l# D1 H/ e5 o/ e, [& L8 v" R4 N* {" O; O0 w2 u0 e+ h$ k$ W
Code 200 is emitted in response to requests matching a "monitor-uri" rule.
+ D/ }9 t! J Z7 k2 X; N0 {( P8 |5 ]- U5 ^8 [1 C+ a
Note that both keyword return the HTTP 302 status code, which tells the
1 q( R% U' W% x8 I; H. X7 @ client to fetch the designated URL using the same HTTP method. This can be+ a) t7 \* @- K& f: N4 c7 ^) ]
quite problematic in case of non-GET methods such as POST, because the URL0 S7 [- V+ p1 Y+ u
sent to the client might not be allowed for something other than GET. To; U/ @* v9 r |, j6 P$ y8 y
workaround this problem, please use "errorloc303" which send the HTTP 303
& H* R+ R1 s% q) y status code, indicating to the client that the URL must be fetched with a GET
; k9 F+ y6 V# ]2 o request.
6 ~" a+ ]9 x% ^- T" ^
9 N1 `# a/ f2 a1 V+ h# z9 V See also : "errorfile", "errorloc303"
$ K. y4 v$ h/ e* ^ C% g% ], y5 C) D% e0 R
8 F% C. K- x* ]( D$ n7 ]0 nerrorloc303 <code> <url>8 I' u7 C' x7 X6 v
Return an HTTP redirection to a URL instead of errors generated by HAProxy
3 D* p8 C# m5 W) ? May be used in sections : defaults | frontend | listen | backend
2 A6 w9 H$ ~ q A: y& G+ l yes | yes | yes | yes0 \9 a4 J( L$ |0 K8 M" |7 j
Arguments :4 X! i: \9 `0 r5 M( f# n, x
<code> is the HTTP status code. Currently, HAProxy is capable of2 y. B3 A( A. s; r- m* C5 ?5 \
generating codes 400, 403, 408, 500, 502, 503, and 504.
, V8 S* S5 @+ l9 L2 h/ A8 @* [$ B; J
<url> it is the exact contents of the "Location" header. It may contain2 ^- @+ |. P2 V: i
either a relative URI to an error page hosted on the same site,
$ S% y7 A; K t: ?8 H5 ? or an absolute URI designating an error page on another site.
; W& `% S5 X3 }* [ Special care should be given to relative URIs to avoid redirect
# w) P: W p X loops if the URI itself may generate the same error (eg: 500).
! @# z# H/ x1 w' b5 z/ O L/ `3 J
It is important to understand that this keyword is not meant to rewrite* A w1 U- X% I; N
errors returned by the server, but errors detected and returned by HAProxy.
5 z) x. K9 f X5 V& X0 i This is why the list of supported errors is limited to a small set. q" P* j$ b7 D/ P8 N( t& U4 W
8 Q1 s* B: ~+ o6 m; D3 v0 g Code 200 is emitted in response to requests matching a "monitor-uri" rule.
) ?/ [0 g: O* k j) K% w( q, A O9 V) `) l8 b7 y" _
Note that both keyword return the HTTP 303 status code, which tells the* x, h0 G1 h# Z" i- |- W
client to fetch the designated URL using the same HTTP GET method. This; O7 M: W1 l6 J
solves the usual problems associated with "errorloc" and the 302 code. It is/ h1 h( C- j) Z; f+ X' V" @
possible that some very old browsers designed before HTTP/1.1 do not support; l& P: X! L; @! w' J) N
it, but no such problem has been reported till now.: }1 }9 p# {) P% C% q+ X" ~/ T! U
, G" j/ k/ G: s) y9 r0 N
See also : "errorfile", "errorloc", "errorloc302"! p7 Y+ N# ~# D3 I/ _2 e; ^0 A
2 m# r$ r3 t* z3 j
7 h: t4 O: k8 q( O) t( X& \1 _) ~5 Aforce-persist { if | unless } <condition>1 q# a" h$ `* ] _
Declare a condition to force persistence on down servers
, S2 I. L' f! p. J0 H5 y May be used in sections: defaults | frontend | listen | backend, J9 p1 x5 ]3 o9 A/ M
no | yes | yes | yes
, d" c9 W+ y6 N9 U! N
# e) n/ M9 q" h5 @5 B* B+ o( \ By default, requests are not dispatched to down servers. It is possible to3 ^0 W, l# Q6 |( S
force this using "option persist", but it is unconditional and redispatches3 k& q+ R: D2 R1 v2 Y. @! R1 a% `: b
to a valid server if "option redispatch" is set. That leaves with very little7 Q! h$ Z6 r p4 D6 _: `
possibilities to force some requests to reach a server which is artificially
; w) x& f& v; K' W# M marked down for maintenance operations.
, d* y2 V" [* B7 ]) Q! c" T
" d+ C5 w& ]1 [ n: j, c The "force-persist" statement allows one to declare various ACL-based! k7 X, i( Q' g* s: V# ?# O
conditions which, when met, will cause a request to ignore the down status of& v7 n2 N/ W( K% y% g7 h" D
a server and still try to connect to it. That makes it possible to start a; K" N0 T' J/ A) L5 p
server, still replying an error to the health checks, and run a specially" N, W0 [1 l F$ ~4 @
configured browser to test the service. Among the handy methods, one could
1 V, K2 @) @/ _! L use a specific source IP address, or a specific cookie. The cookie also has
: _; z) j _! x! O7 @3 [5 F the advantage that it can easily be added/removed on the browser from a test
1 |2 M- W% [) X6 C r% _ i page. Once the service is validated, it is then possible to open the service
0 X7 Y9 s2 d+ J" D2 c3 I to the world by returning a valid response to health checks.8 i- w1 }, I5 v- d& i) v) Y# {1 D
0 ?! ~% B2 e4 d$ K
The forced persistence is enabled when an "if" condition is met, or unless an- Z& T2 [+ K$ G/ v3 y
"unless" condition is met. The final redispatch is always disabled when this
$ {% h8 |* T) ~0 D# h, m% a is used.7 k, r( \" N& d" T
8 ?; s C0 K& a4 ~ Z See also : "option redispatch", "ignore-persist", "persist",
2 m- _5 y" I* c. p and section 7 about ACL usage. i0 \9 x d. ~; M/ ^
/ X1 e5 V B5 r: R' m5 C( k
: B8 n" c: O. Y3 e) {3 x" Rfullconn <conns>
+ ?3 D) B2 ]6 L& D Q9 Q/ Y) g' n Specify at what backend load the servers will reach their maxconn; `) w: e1 M, i! f
May be used in sections : defaults | frontend | listen | backend
" C) e/ @2 V; L yes | no | yes | yes
) X9 Y4 f1 Z2 v/ a, N Arguments :
; k% P, Q& ~% l; U <conns> is the number of connections on the backend which will make the0 f! Q; V0 {% f" A2 G
servers use the maximal number of connections.
: T: V) U: B3 ^/ ]1 b
% R* L& `' z. w% G% { b3 p' g When a server has a "maxconn" parameter specified, it means that its number
" d9 ?1 B) h2 g, ~ of concurrent connections will never go higher. Additionally, if it has a
( I$ E7 I; [+ [ "minconn" parameter, it indicates a dynamic limit following the backend's
/ s- c- X: Q. \+ W load. The server will then always accept at least <minconn> connections,6 V' _- j; p% o
never more than <maxconn>, and the limit will be on the ramp between both7 M) C: B: g2 G5 @+ t
values when the backend has less than <conns> concurrent connections. This; Q6 m6 [" y {# u* r
makes it possible to limit the load on the servers during normal loads, but( z }' x( c& H1 r: g
push it further for important loads without overloading the servers during
0 Y& y9 F" w' s3 F! u V9 t: w1 _$ z exceptional loads.
" K6 X8 |+ G" C: V7 C @' Z8 ~1 F) {- m; y9 V- r; D
Example :
. M6 [# @% X! B! w5 e; | # The servers will accept between 100 and 1000 concurrent connections each' |# D( i2 v; R$ X
# and the maximum of 1000 will be reached when the backend reaches 10000/ y. b P* L" b7 M2 `
# connections.
2 [" ]- ?6 c/ j% V& _- s q backend dynamic, R! E3 r$ r$ a$ x/ E& Y. p0 K
fullconn 10000
- j6 [. I9 x# k4 ]& U server srv1 dyn1:80 minconn 100 maxconn 10006 p& V$ k" k) S( e6 g, x1 A6 @+ ~
server srv2 dyn2:80 minconn 100 maxconn 1000
) B3 o3 h& {+ k, M( }0 p
1 N0 A1 U8 J- w5 o See also : "maxconn", "server"6 m% c/ a; L% w4 u, B2 |: t
6 e4 B+ e! b# U& v2 T& t( Y4 d: e* v4 q1 ^/ X2 u' B
grace <time>9 b( R' S& ` c5 l
Maintain a proxy operational for some time after a soft stop
0 q( C, F# K2 `3 ~( C. X8 L May be used in sections : defaults | frontend | listen | backend
" ]2 V& t1 S7 B( P yes | yes | yes | yes7 r- z, X" m1 z. } ^. H, E
Arguments :
0 B% l- J8 U- ` v <time> is the time (by default in milliseconds) for which the instance
& f3 f* B1 p P4 S will remain operational with the frontend sockets still listening/ \2 M+ d) y9 `" Z1 q# P) n
when a soft-stop is received via the SIGUSR1 signal.
, O* G2 k4 }* l, ?- }: e7 p* N9 [; ?
This may be used to ensure that the services disappear in a certain order.
$ B; c5 G6 a3 ~& m This was designed so that frontends which are dedicated to monitoring by an
! M3 Q) N6 F) v2 B- c" z external equipment fail immediately while other ones remain up for the time8 e1 b7 Z; r/ l; `7 x* d8 x
needed by the equipment to detect the failure.
" j5 |4 Q8 [7 y' J6 E
' X1 _* x6 K# t* C! w4 A' i& v+ ~ Note that currently, there is very little benefit in using this parameter,+ W/ I0 h, E$ q% i
and it may in fact complicate the soft-reconfiguration process more than
, Q8 p8 d8 |9 ]# \8 U simplify it.8 A3 u# [; |$ L6 L, ~0 f/ E
]8 o6 f& s- }6 ~* o+ Z: b
5 H! r) l: j: V- Bhash-type <method>; h0 g1 a* L9 C1 L7 A: m J+ [$ V
Specify a method to use for mapping hashes to servers6 {$ r' E9 W$ e& |
May be used in sections : defaults | frontend | listen | backend
6 `* V& v! m; y* \ O1 x- u yes | no | yes | yes
/ Z# @1 s2 \/ H- a- B. ]3 a Arguments :
$ |# \' R' |( @, j map-based the hash table is a static array containing all alive servers.. x, F Q. l( V8 u8 x9 m; D
The hashes will be very smooth, will consider weights, but will
. h0 L( G g; z8 @! h be static in that weight changes while a server is up will be3 U$ S0 ~( g" S! k% `
ignored. This means that there will be no slow start. Also,
* y: `1 t o$ q6 ?; V! G5 }7 G# g since a server is selected by its position in the array, most
7 k0 R+ Y* D# d' N/ ?1 h mappings are changed when the server count changes. This means1 ^$ H; f( n4 b7 d
that when a server goes up or down, or when a server is added0 u e. x: \# m. x+ |: b# M t
to a farm, most connections will be redistributed to different/ z- R3 Q% ]3 d1 N% j5 ^/ t
servers. This can be inconvenient with caches for instance.
% ?0 e' d) K. h, a9 h3 X# ]7 `, m. i: H1 D
consistent the hash table is a tree filled with many occurrences of each
. a) S3 M+ e% p9 f* J server. The hash key is looked up in the tree and the closest
' Z! o H/ C8 t* @% M server is chosen. This hash is dynamic, it supports changing
0 L6 `, { v: t" D weights while the servers are up, so it is compatible with the
) L6 h) ^ P( C; ~# `- {$ W- A- q slow start feature. It has the advantage that when a server
" }, O6 b5 |! N goes up or down, only its associations are moved. When a server
. m r( _ l8 R( g0 U5 c is added to the farm, only a few part of the mappings are- c# w& E; Y1 N. l
redistributed, making it an ideal algorithm for caches.
% ^0 n( K& p3 d# v1 o% m e However, due to its principle, the algorithm will never be very: v2 o d; G; S6 H* A
smooth and it may sometimes be necessary to adjust a server's
* m/ B' U$ C8 I2 R4 h weight or its ID to get a more balanced distribution. In order2 i3 T. Y+ e# W& M5 Z, J
to get the same distribution on multiple load balancers, it is" v0 B* u! F% |6 e8 `( t% `1 U
important that all servers have the same IDs.4 d4 h" \1 i! B! N$ K
J' F# m6 T1 e. U The default hash type is "map-based" and is recommended for most usages.. D8 r5 I. q/ p* e# y
* K! x4 t+ G6 E. y" s0 q See also : "balance", "server"
; D. u3 A6 f2 e8 ^% b3 I( J- z% m7 Q' }* e' T% _$ o7 s7 X( a
5 c# H8 N# \! R! X1 L' X* Ahttp-check disable-on-404
( ^, d/ f) Z9 V% r1 @ Enable a maintenance mode upon HTTP/404 response to health-checks
) M. m, Z j7 ]9 p1 o0 y May be used in sections : defaults | frontend | listen | backend. N1 g6 L* q9 `5 b: f" O1 x
yes | no | yes | yes
X, {+ Y& P: J# w1 P Arguments : none0 l2 p$ m/ N) F! R! C6 v1 [
, y( G S+ `' C9 J3 N+ P When this option is set, a server which returns an HTTP code 404 will be
' l) s) y$ \5 D7 N excluded from further load-balancing, but will still receive persistent7 ~6 F( i) c5 o: ^) F8 U8 r/ s
connections. This provides a very convenient method for Web administrators
) z0 P2 K) O( L3 Q3 t$ z; H# G to perform a graceful shutdown of their servers. It is also important to note8 ]5 T' R" p$ P7 o2 p) l) N
that a server which is detected as failed while it was in this mode will not
& Y( c* C2 b: H generate an alert, just a notice. If the server responds 2xx or 3xx again, it
q2 e' [# R* R! o will immediately be reinserted into the farm. The status on the stats page
; {9 o$ R) p! c6 W2 |0 Q& t reports "NOLB" for a server in this mode. It is important to note that this
! a* ?6 z {! z7 T option only works in conjunction with the "httpchk" option. If this option
) `( }4 P/ y/ H9 w. a1 a3 l is used with "http-check expect", then it has precedence over it so that 4049 R* t4 c* Z# {* c& } c2 E
responses will still be considered as soft-stop.
! M. D9 t5 L4 `7 B8 V% |
8 ~! q$ ?( y. B9 r9 a See also : "option httpchk", "http-check expect"
1 f, j% h: D" B0 i" b3 r; B j w# g( y
" Y1 }& T! E& g
http-check expect [!] <match> <pattern>
9 \( |7 P3 Q7 {* } [5 Q Make HTTP health checks consider reponse contents or specific status codes' @" R' N1 x( h) v1 d
May be used in sections : defaults | frontend | listen | backend
) ?0 ?( r% c% A6 N7 F1 | yes | no | yes | yes1 G+ v) _. v' R6 ^+ ^( C
Arguments :$ T; z) J) W$ t) n& J& V5 l6 E
<match> is a keyword indicating how to look for a specific pattern in the
' t, P9 R# i* ]& f response. The keyword may be one of "status", "rstatus",
" C" `7 u2 Q( D3 o/ C. Q) h/ a "string", or "rstring". The keyword may be preceeded by an
4 ~% m& v+ q8 L% |8 {" _ exclamation mark ("!") to negate the match. Spaces are allowed# K6 E9 ~+ ` ~' m+ _" p
between the exclamation mark and the keyword. See below for more5 m1 W, f/ G3 Y* h& ?
details on the supported keywords.
: \" d9 F, K/ e/ n& H* q8 b2 q& c; I3 v- q4 z9 K
<pattern> is the pattern to look for. It may be a string or a regular; c/ L5 J( O7 K5 P) n! p
expression. If the pattern contains spaces, they must be escaped4 v+ b) z, T1 d$ R' C4 }/ _( A
with the usual backslash ('\').
( G" V" K+ T9 u: f( }$ Z) W! r0 `6 K2 f" U' q3 ]: f
By default, "option httpchk" considers that response statuses 2xx and 3xx+ o8 Y g6 Z( ^+ \; `2 S: a( ~, `
are valid, and that others are invalid. When "http-check expect" is used,
- F; Y, }3 _8 f* K! p0 V it defines what is considered valid or invalid. Only one "http-check"7 P+ l3 }; q5 r6 V
statement is supported in a backend. If a server fails to respond or times1 `; s+ t$ M# |5 V
out, the check obviously fails. The available matches are :
" g* R. X6 ~* @1 E& Z
8 O0 I( U1 j0 ~; S/ a* A1 n: X4 N status <string> : test the exact string match for the HTTP status code.& Y! L+ s# o# o" k0 B9 I
A health check respose will be considered valid if the2 C! l1 n2 X4 l: L4 z5 H8 V
response's status code is exactly this string. If the
E# \: t+ X" `0 x7 c2 Y "status" keyword is prefixed with "!", then the response0 ]# @$ s0 }2 z" L4 E
will be considered invalid if the status code matches.( L6 K1 y3 q# r
# s3 G4 C& \3 _% Y6 M
rstatus <regex> : test a regular expression for the HTTP status code.5 Y K; C/ U3 H2 A
A health check respose will be considered valid if the2 l7 }. B7 S8 r+ I, X0 S; s Z; Z0 E$ L
response's status code matches the expression. If the
$ {) F- x" w3 ^) T/ H "rstatus" keyword is prefixed with "!", then the response
1 b+ [ E Y7 k will be considered invalid if the status code matches.
! _9 \- U& p) D This is mostly used to check for multiple codes.
7 j# w- I) g2 O
% T& o7 K% J. ^7 k. Z2 _/ K+ ^ string <string> : test the exact string match in the HTTP response body.
) M4 V8 l d9 j A health check respose will be considered valid if the
% d# x4 E# a. I response's body contains this exact string. If the
2 @/ N% D) e. H q! T "string" keyword is prefixed with "!", then the response
$ V; j; ^7 r/ `- g will be considered invalid if the body contains this: K9 a& v+ k( G3 h7 E7 n
string. This can be used to look for a mandatory word at d* R' A2 z* q% v: |
the end of a dynamic page, or to detect a failure when a- \% Y9 {) z1 ^
specific error appears on the check page (eg: a stack
- m! @ W, v* [1 E trace).+ x1 S$ T0 K( H3 ?
0 b5 b4 o- m/ e6 w/ M
rstring <regex> : test a regular expression on the HTTP response body.
, O* Y, ?% K$ I h- C- c4 ` A health check respose will be considered valid if the* }8 n( s$ P3 W7 D. f& D* ?* Z
response's body matches this expression. If the "rstring", i0 E3 G9 b- L
keyword is prefixed with "!", then the response will be
% \+ \; ~ N! m& j9 r considered invalid if the body matches the expression.
$ ]% q- m" Z7 c; ^; ` This can be used to look for a mandatory word at the end
( f, f6 e7 z; y9 W& ^ of a dynamic page, or to detect a failure when a specific
+ \& A+ x4 D# n0 e4 N error appears on the check page (eg: a stack trace).$ U3 y9 b% b# H" I* S# i
% x6 w) W6 l d3 W. }
It is important to note that the responses will be limited to a certain size$ e0 G9 {: v1 X. O/ U
defined by the global "tune.chksize" option, which defaults to 16384 bytes.* ` _9 V) U8 y1 T. M) O& r( n
Thus, too large responses may not contain the mandatory pattern when using
/ D6 r5 a$ V( Q3 `7 F; C "string" or "rstring". If a large response is absolutely required, it is
& }* J: V* ?0 ?$ Y8 q# t possible to change the default max size by setting the global variable.
" U% s5 f, B+ }+ F% i1 o& d0 O$ B However, it is worth keeping in mind that parsing very large responses can+ q" A! ]$ P9 A1 R# p% b b
waste some CPU cycles, especially when regular expressions are used, and that
9 p1 w' _. P* T1 d2 @+ z it is always better to focus the checks on smaller resources.+ n) D( O7 t. v
7 \* m% f* I( Y) \/ S* |
Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it
% `# {6 E5 O. R! l$ I will automatically append a "Connection: close" header, meaning that this* X+ o. C5 U5 U0 b* b7 a$ }
header should not be present in the request provided by "option httpchk".9 Q' m& b9 ?# M$ ?
6 f0 m7 R4 Z& F' k8 L Last, if "http-check expect" is combined with "http-check disable-on-404",' D# P/ E2 l; p3 w' ?) T1 c8 g# |
then this last one has precedence when the server responds with 404.
- S, Z* ~/ [ o% g
: ?' I( \! ]6 e: O V) ?" |) y( I Examples :
8 X, N# N! \) ~% p& Q4 p # only accept status 200 as valid; o5 s) z) E( V" T
http-check expect status 2003 z# W; h- S# n, h4 D, v- J
8 W& ~! N9 g$ P # consider SQL errors as errors
/ x; I0 \: O# f- J | http-check expect ! string SQL\ Error
8 j; v& y: [( ~# G+ R$ D& F2 {) C2 P* J- \9 f
# consider status 5xx only as errors( Q$ z& u) J0 ]* J* A) p$ }8 N
http-check expect ! rstatus ^5
! A/ _5 |, M1 t3 p" B4 v: ^
( s! E! T7 o+ i+ g, ] # check that we have a correct hexadecimal tag before /html
% ]* O% W$ h" N: ]$ H http-check expect rstring <!--tag:[0-9a-f]*</html>( Y$ E: M/ k5 w5 Q8 _3 {2 v% P. G
9 h/ G4 z) I1 P6 S. G& o See also : "option httpchk", "http-check disable-on-404"
( Q7 L( ?2 d/ g/ P6 W L7 S8 I2 W! h) a! I$ }5 l }5 E$ N8 m9 L) i
; H" @; e- o( E5 U" L/ W
http-check send-state
8 Z9 G& \2 x3 ~0 H0 C( h Enable emission of a state header with HTTP health checks4 e B6 O; [2 h' H6 q; l5 f" Y
May be used in sections : defaults | frontend | listen | backend4 P G( k1 b- S# Y2 Y
yes | no | yes | yes
+ O! Q* d# L2 `7 P! G$ u Arguments : none
H4 }6 v# u9 R! S2 n2 ^: s' L3 \/ D5 t8 c+ i
When this option is set, haproxy will systematically send a special header
+ h! b5 M0 \% K U% @+ y "X-Haproxy-Server-State" with a list of parameters indicating to each server
- G4 H) G( z3 L9 F# k" g2 f0 l how they are seen by haproxy. This can be used for instance when a server is
" O! v& I# n# V# y# } manipulated without access to haproxy and the operator needs to know whether
" `: B0 |* Y9 S- R$ `5 ?8 ? haproxy still sees it up or not, or if the server is the last one in a farm.
0 P Y7 S/ T/ l( x- X/ b$ ]9 O& y) V
The header is composed of fields delimited by semi-colons, the first of which
0 c. \3 g" Y$ ` is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid
$ q% @, D* r9 u checks on the total number before transition, just as appears in the stats3 l# Q5 Q3 F/ d* J
interface. Next headers are in the form "<variable>=<value>", indicating in
. F* d4 K) O9 C6 n8 q no specific order some values available in the stats interface :6 F7 Q5 T. p3 o1 i' Z$ ~
- a variable "name", containing the name of the backend followed by a slash% n9 O# G& Q4 ^5 e
("/") then the name of the server. This can be used when a server is' \, n: I$ }. i+ g1 V
checked in multiple backends., U5 ?2 P( q, k% W+ b
3 h. d; ?- f% |, X7 `5 @
- a variable "node" containing the name of the haproxy node, as set in the
' D/ n: Z, ~1 o8 o- T6 y2 f- c global "node" variable, otherwise the system's hostname if unspecified.2 B+ A1 v/ x( X4 }- r# d( {
0 v7 n: s1 }( u5 u6 v - a variable "weight" indicating the weight of the server, a slash ("/")- x8 Y) j" z$ V8 _) C
and the total weight of the farm (just counting usable servers). This
9 l5 u2 n/ J# q8 L helps to know if other servers are available to handle the load when this7 D$ B$ h k5 I i3 v3 {
one fails.
$ M6 X1 z. D- v- l( v& V. P0 a6 @) w. u+ E6 p X
- a variable "scur" indicating the current number of concurrent connections
: ^9 e/ ~5 l: b on the server, followed by a slash ("/") then the total number of) S# b" y* d; y$ g6 W. p
connections on all servers of the same backend.* G1 J! x; C: h4 X6 i6 V1 v& }1 r
2 R' x( T" q8 y! a Z( C - a variable "qcur" indicating the current number of requests in the4 K" g( W5 w# P0 b! w& }
server's queue.* v+ K" k m7 y6 k" r% k: d4 _9 j
. p& X3 L. m5 Y e) H# C Example of a header received by the application server :3 a& |* M0 k% [
>>> X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \
! x( V3 N2 Q, H& P scur=13/22; qcur=0. g- a! n/ v# V1 {" O/ q
3 t3 I; J/ n1 Y2 } j
See also : "option httpchk", "http-check disable-on-404"* l3 a& `4 K6 N3 D3 I, a/ i& b) m
' X6 `& y, Q- A1 e7 v
http-request { allow | deny | auth [realm <realm>] }
3 T2 P3 D' N! a( ]/ W [ { if | unless } <condition> ]
0 [" a$ s* |# R Access control for Layer 7 requests
! m: s8 |7 s0 a# N3 M% H
5 @$ n: M/ ]1 [+ e/ ^8 f$ L% F* Z, ~ May be used in sections: defaults | frontend | listen | backend& U! R! j% s# N; |
no | yes | yes | yes5 q: a2 Y" ?( O$ ~2 a9 I* R0 q
" h+ b$ A2 {& `! D These set of options allow to fine control access to a9 _8 S% K- p1 @6 y ]
frontend/listen/backend. Each option may be followed by if/unless and acl.9 F" ]. K& r8 V& Z* f; s1 e5 l& f
First option with matched condition (or option without condition) is final." e; `7 ]2 B. ^. G0 [+ U$ d9 b
For "deny" a 403 error will be returned, for "allow" normal processing is1 R+ C" z0 Z; W& I5 G' v- `. W
performed, for "auth" a 401/407 error code is returned so the client
E, k5 Y7 j( m should be asked to enter a username and password.1 J) s. A0 \7 s6 b4 v {) e. K
( t% W* A8 m* O3 O/ F2 ~ There is no fixed limit to the number of http-request statements per6 ?1 m0 g0 T3 j- h# L3 K
instance.3 l8 o% G% m6 d' E. D; t) U
9 x. r& K( a* G4 C Example:" `. y1 ^) {* I3 s) w3 j
acl nagios src 192.168.129.3
3 b$ @% u- L: g1 }+ P& f acl local_net src 192.168.0.0/16
; m; R3 y) c8 p acl auth_ok http_auth(L1)4 }7 ~0 _. F, M& a' O" f
3 C% u' n+ w' M9 c http-request allow if nagios% ?8 ]$ ]4 V- I3 X/ A& K d
http-request allow if local_net auth_ok
& S$ m9 V5 L3 `& U* B http-request auth realm Gimme if local_net auth_ok
S, k8 s# ^$ } g" f4 h) y6 D http-request deny
7 N* f4 R* \% r5 x% c; A# t) O( D1 P& v: K8 _) U3 M5 \
Example:$ O5 i0 F& v3 o! _2 W
acl auth_ok http_auth_group(L1) G1, z7 f7 ?2 h0 q# U' ]5 f5 k1 I
- g- m ] b' |! E http-request auth unless auth_ok% q# M$ V( T) ^+ P7 W# Y" z. P; S
' y) v) `# P) \ See also : "stats http-request", section 3.4 about userlists and section 7
: L2 ]/ ~( u1 v m3 i" E0 a/ f about ACL usage." W/ P' E( L; }4 q
- f9 |0 V! b% G' P
http-send-name-header [<header>]9 K3 ~" Y; d" M3 P: w
Add the server name to a request. Use the header string given by <header>
. Q, g/ U7 V. n& M( d; X8 Q$ c" s8 d; |- B1 g' B1 [
May be used in sections: defaults | frontend | listen | backend
7 f6 w! p) v% r: `+ t: j5 r- w yes | no | yes | yes5 j$ J7 A3 W1 G8 @/ x( x0 p. c
3 U1 \2 W, s$ O
Arguments :
. q! U- |* q0 l1 S( [; c. B" G7 g
6 Q+ l. E/ z0 y8 n/ W <header> The header string to use to send the server name
% I0 K+ Y- f' |& v- O4 a, F* Q! `& z5 e
The "http-send-name-header" statement causes the name of the target* F. [& z$ {8 ?( k8 ~+ x# H
server to be added to the headers of an HTTP request. The name
: Y# I& T7 @+ J, t7 G: W6 O5 Q, f$ M is added with the header string proved.
; t, h5 }" w Y0 b+ L/ R4 p
1 v# Z1 N# B. s0 t8 l7 s See also : "server"! G4 S! K( W' ?8 ~+ Y% c
& |) h% l5 g3 o# Y- p& j7 ]7 Eid <value>, W! K& p6 F8 z4 s- }/ y
Set a persistent ID to a proxy.! x8 f' B& ~! o, P& t* x0 G
May be used in sections : defaults | frontend | listen | backend
4 _; D& w5 o5 i7 }/ o1 V& h no | yes | yes | yes& U2 b; {$ B' S1 m( T
Arguments : none$ j+ ~, X4 \- i) X) F. d Z/ D
6 G* v B, u @& R m. Z2 e
Set a persistent ID for the proxy. This ID must be unique and positive.2 z1 H: I- g' k/ Y
An unused ID will automatically be assigned if unset. The first assigned& d6 G) x7 n" q9 h, J1 |
value will be 1. This ID is currently only returned in statistics.0 j% H; X! [) Z) N& p/ A
5 S. J$ O* w; J; B g
0 J7 w; O$ f4 l' w: Qignore-persist { if | unless } <condition>
4 U. @' @# j2 @& w4 C/ \! G0 W Declare a condition to ignore persistence
! d0 \4 @% ?& |5 w+ o8 s' F) \ May be used in sections: defaults | frontend | listen | backend
9 R! n) \, X( C7 Z( f no | yes | yes | yes
- P! v9 H4 L4 ~* o$ d- M
. X/ I9 K/ {" R& d By default, when cookie persistence is enabled, every requests containing
/ s/ q4 {4 a- b0 N the cookie are unconditionally persistent (assuming the target server is up/ y1 s m* t" \# r" b
and running).+ |8 `8 L- J+ A" a$ V
1 e( N4 X0 [: A' u
The "ignore-persist" statement allows one to declare various ACL-based8 L: p% b- C9 R6 ]2 E8 F. [
conditions which, when met, will cause a request to ignore persistence./ o$ d# q4 K- l/ {5 O
This is sometimes useful to load balance requests for static files, which. E: Z" d0 P' Y9 [- P" P" [
oftenly don't require persistence. This can also be used to fully disable+ z, g1 z. i- r1 o# L6 i' T4 Q6 g
persistence for a specific User-Agent (for example, some web crawler bots).
1 \ Y! _3 P7 ~( Z
8 V( x0 Y/ u& F, c1 d Combined with "appsession", it can also help reduce HAProxy memory usage, as
2 [& y9 s$ g3 _/ E* V6 C the appsession table won't grow if persistence is ignored.
; f, {+ l% m# g* V+ @4 [# o7 f- n+ Y0 ?0 h+ Q- l
The persistence is ignored when an "if" condition is met, or unless an. Z7 [5 L I3 \* `/ f: ^* |
"unless" condition is met.
! p F9 v( i" y1 [% |% P, y) e! G" \$ ^0 p9 b+ _
See also : "force-persist", "cookie", and section 7 about ACL usage.
# |4 N9 S% U- e7 A/ F" V4 g6 g: r6 q" D
" D# _5 |3 w* `! X0 d4 f1 P0 ilog global
7 k) M( v, s- t( D; a3 v' H: g* Klog <address> <facility> [<level> [<minlevel>]]
6 P/ ` l8 y4 P: x Enable per-instance logging of events and traffic.+ Q1 s( M/ g3 ]% A6 L; P2 q
May be used in sections : defaults | frontend | listen | backend; `( J) ~/ Q- Q+ M4 o& ~& M7 E3 X
yes | yes | yes | yes9 x/ \. Q7 Z( H' |8 R7 w! t
Arguments :4 R* ~' L5 G8 s6 q
global should be used when the instance's logging parameters are the6 F9 _! ^$ o {; r
same as the global ones. This is the most common usage. "global"1 z: x, o0 m: s( I. N9 ~/ |) m, L
replaces <address>, <facility> and <level> with those of the log
* ~4 N# ^* c# ]3 ] entries found in the "global" section. Only one "log global"- \- L1 `( H$ c0 f
statement may be used per instance, and this form takes no other$ t/ d4 k5 J d, f/ U
parameter.7 L. `$ i/ m0 \
" F! O3 e' s) m7 s
<address> indicates where to send the logs. It takes the same format as1 P; G+ [ t: l/ c2 H
for the "global" section's logs, and can be one of :1 b- ]" g. E1 L' }3 h& P
) Y9 Q# s% }0 t9 H/ T - An IPv4 address optionally followed by a colon (':') and a UDP
2 r" P5 x0 p+ Q* c' } port. If no port is specified, 514 is used by default (the
+ h/ e, T& b# H standard syslog port).. j6 h/ P1 b) W0 x. S( c
# q" P w3 \2 r% E - A filesystem path to a UNIX domain socket, keeping in mind
1 Z8 X" t. Q7 ?8 x/ K! r5 y6 j considerations for chroot (be sure the path is accessible- ?# Q# K2 { P9 r! d1 G# H: E
inside the chroot) and uid/gid (be sure the path is+ D4 n: L1 c! n' W& s4 [
appropriately writeable).
2 d9 |1 \+ @' G C6 `/ p6 K
* z7 w5 v1 t3 A% O+ M' m! ~+ F <facility> must be one of the 24 standard syslog facilities :
2 i9 M. l: E i$ x7 e( w& }/ X, a9 }% O8 M
kern user mail daemon auth syslog lpr news! K2 ?8 @! p/ E& x$ M
uucp cron auth2 ftp ntp audit alert cron2
# X$ S i+ Z! Q local0 local1 local2 local3 local4 local5 local6 local7* p8 O* A; T/ J$ _
' H w7 `) n; G( t+ c5 n
<level> is optional and can be specified to filter outgoing messages. By
! D. R& f$ e6 e, b1 h! |; p default, all messages are sent. If a level is specified, only; j% p& r8 c1 u0 N$ W1 r: C
messages with a severity at least as important as this level% s. X: P. I: g$ ~5 Y" X4 |
will be sent. An optional minimum level can be specified. If it3 o7 o, _, }& |) q+ ~8 k3 C5 `
is set, logs emitted with a more severe level than this one will* {# ~1 G& x, R) u& a% U9 L
be capped to this level. This is used to avoid sending "emerg"
/ p `+ m: W7 J! P" P+ [3 g/ S messages on all terminals on some default syslog configurations.4 k% _7 u0 Y V3 R% Q R& Z
Eight levels are known :# j3 m9 _* _* e% G- x9 M; Q
9 ^9 I4 [$ P! d
emerg alert crit err warning notice info debug# M* _ {+ A+ D" n, V2 E9 R
3 q& t! k6 [3 F8 n Note that up to two "log" entries may be specified per instance. However, if F9 ? i, W8 d9 _ [9 G0 h
"log global" is used and if the "global" section already contains 2 log7 V+ w* V; M! E9 e& L$ R. W9 J
entries, then additional log entries will be ignored.9 k# y7 t$ x0 N- U1 d9 n
; l# z8 ?9 p/ {7 J Also, it is important to keep in mind that it is the frontend which decides
: @" a m) c5 T& e" `0 g- F: ^& J what to log from a connection, and that in case of content switching, the log
6 i( ~( X; o$ q, D. M" s- |" j+ i4 s entries from the backend will be ignored. Connections are logged at level
" z( R& b; s& [4 w8 x% L8 { "info".
7 A2 p5 q$ u8 p; V) U- e' r3 l, R
: }% X! l% L% v W: ~ However, backend log declaration define how and where servers status changes. t: Z" J8 t! M; T. W: M% t
will be logged. Level "notice" will be used to indicate a server going up,& V& a3 E+ o4 }, w6 R, {
"warning" will be used for termination signals and definitive service
/ p, o5 d9 Z0 A1 [ termination, and "alert" will be used for when a server goes down.( P0 C4 Y4 ~9 _ ]- r6 G6 n
% O7 y' Y- _/ L/ O# Q. C Note : According to RFC3164, messages are truncated to 1024 bytes before
3 U! h3 b6 m- m9 l- @9 ] being emitted.! Z% z' d: K3 G/ v3 g/ v0 F
2 M) @; K8 w- P# F
Example :* K6 S+ [) t1 p3 L
log global U4 \9 Y# n. b/ B0 o2 d% \
log 127.0.0.1:514 local0 notice # only send important events; B: f4 W4 J* x! G
log 127.0.0.1:514 local0 notice notice # same but limit output level
9 e/ t4 _ C+ A' p# u' m( b$ O( H3 O
. J3 o( Q! Z7 A7 G% _* h% z, z/ C$ s. z2 }! H
maxconn <conns>, Q% g3 C8 g9 k* ]6 u0 n
Fix the maximum number of concurrent connections on a frontend7 ?! l' D- ?3 o$ D* d
May be used in sections : defaults | frontend | listen | backend
7 y0 A, J9 v9 F% S2 s5 M m yes | yes | yes | no# I. X& ~' K' D
Arguments :
h% M7 K" }, k+ F; l. t <conns> is the maximum number of concurrent connections the frontend will
1 n9 R. b1 ?/ g accept to serve. Excess connections will be queued by the system6 v3 C5 l7 c& X" g6 D7 J
in the socket's listen queue and will be served once a connection; P7 `0 Z' x; o. I. @% I0 [( u A
closes.9 ~1 j# E5 g9 \" n
, c* Z7 V5 D. I3 q$ B If the system supports it, it can be useful on big sites to raise this limit
* z/ O: J/ f0 }* X9 t( I6 M) u very high so that haproxy manages connection queues, instead of leaving the( p% O2 z2 }6 z8 |
clients with unanswered connection attempts. This value should not exceed the
8 [9 P! ]9 e' @ global maxconn. Also, keep in mind that a connection contains two buffers7 @8 N& r/ r0 w" ?
of 8kB each, as well as some other data resulting in about 17 kB of RAM being4 r; F4 s6 z$ `' u
consumed per established connection. That means that a medium system equipped4 P% T2 W* ^+ J
with 1GB of RAM can withstand around 40000-50000 concurrent connections if
9 B6 ~- s* i+ B properly tuned.
5 d, t9 [2 Y6 d0 [) q+ Y! f( l, L6 \7 _7 L' c5 s* Y1 l
Also, when <conns> is set to large values, it is possible that the servers$ w7 s, P2 |' ^# ^ x3 K
are not sized to accept such loads, and for this reason it is generally wise% ?1 r' Y: B1 W6 @) c$ H
to assign them some reasonable connection limits.1 ?# u" W# p& j) V- a
7 V9 O' F& D& @5 P$ u
By default, this value is set to 2000.
& \4 ^) _0 s; U D; a$ a: ?; ~% F5 ]- O+ H! U% W
See also : "server", global section's "maxconn", "fullconn"
7 D2 V% O% ?- ~: C( C/ O7 ^$ ^
5 x! H# W/ x8 E+ j- k3 [9 X: s: x6 b5 ^/ k" _: Q3 f1 ^# }* O+ m" a- ~
mode { tcp|http|health }
$ f+ g g4 R4 {4 u/ Z8 w Set the running mode or protocol of the instance: u J3 W1 Q3 P
May be used in sections : defaults | frontend | listen | backend
; O: m: N# a" f5 A. E! D- _ yes | yes | yes | yes
) ]7 [" _( |& P. Q4 q) ` Arguments :. n) e4 E$ H7 q* X: `2 j- K6 h
tcp The instance will work in pure TCP mode. A full-duplex connection9 G- z. b. K# {" u [
will be established between clients and servers, and no layer 73 r' u) ~+ ?0 \6 B
examination will be performed. This is the default mode. It
0 C* l/ p L8 u4 Y& F) h/ g should be used for SSL, SSH, SMTP, ...
- I6 h' j9 r' u3 `* I1 B% v; U$ ~& i% \% k
http The instance will work in HTTP mode. The client request will be& X V& J0 Q3 t: ~ V
analyzed in depth before connecting to any server. Any request7 Z/ H8 E. ^) ]
which is not RFC-compliant will be rejected. Layer 7 filtering,. ~; C, y& }: ?* ^: r+ e
processing and switching will be possible. This is the mode which6 o0 Y0 A! L9 j Y! a8 S
brings HAProxy most of its value.+ d8 [6 _, ^+ k: d
4 V3 v/ R3 Z" j2 u/ g- J health The instance will work in "health" mode. It will just reply "OK") `% f& I, d( d2 F% ]
to incoming connections and close the connection. Nothing will be
* ~$ ` t8 n0 Z/ l; y$ `; d logged. This mode is used to reply to external components health
@% P9 P* f* ~4 R* ~ checks. This mode is deprecated and should not be used anymore as
) h5 _' @. l! a: v% D2 E* H it is possible to do the same and even better by combining TCP or
6 s4 R* q! C# z1 p+ f HTTP modes with the "monitor" keyword.
- ]& Y) P( W; c& N
3 n( I/ n) n8 y. M/ x( c% H! A5 Z; u When doing content switching, it is mandatory that the frontend and the
7 n% J( W* @6 _6 n0 N, f& F! J backend are in the same mode (generally HTTP), otherwise the configuration: [% u& E% l+ {
will be refused.) v1 U+ D' c: p7 p/ L4 ?! G
" P5 q9 f, G1 m0 ?+ Q Example :
1 N( y4 \7 M0 v. S; _& \" p defaults http_instances4 R4 ^3 M I1 n, E- d7 |
mode http3 g% ~2 E$ o1 T$ _5 D* Y7 R$ C' s2 N
. G5 H, a& O) w4 ?
See also : "monitor", "monitor-net"- a* E( h" u0 |* r) j
* ^$ i9 Q. O& {2 q! d" T v; H2 x: T
* b5 W6 Y2 u: I) r) amonitor fail { if | unless } <condition>
& E3 V; }/ D4 ^! L4 {" O: K( ]+ a Add a condition to report a failure to a monitor HTTP request.
' J U5 T( y- a6 u0 J j May be used in sections : defaults | frontend | listen | backend
# [2 o% |& P8 w/ o% @ [ no | yes | yes | no
' b+ S8 u" f8 ?6 H Arguments :. J7 Q4 z9 k+ M W7 A2 r6 ^
if <cond> the monitor request will fail if the condition is satisfied,- v- I: @: U0 Y. F0 r5 ^/ v- D
and will succeed otherwise. The condition should describe a
0 l7 R* E2 |. i0 T: K6 h/ ^$ j combined test which must induce a failure if all conditions8 b; m. U1 O n7 j4 t
are met, for instance a low number of servers both in a: E7 D# V" a/ A& `
backend and its backup.
3 p5 C1 x/ W$ R j, E, O
2 l& d* M) x8 E& ^ unless <cond> the monitor request will succeed only if the condition is; O* q5 u" X! |6 W; \
satisfied, and will fail otherwise. Such a condition may be: n, I" @$ R, N# V8 z
based on a test on the presence of a minimum number of active1 ^# z1 R* N/ y/ R7 L
servers in a list of backends.7 j+ D, W9 m6 M% p# n, Q
3 `2 [3 _0 d6 ^9 v This statement adds a condition which can force the response to a monitor
@; S q& |3 R: Z n request to report a failure. By default, when an external component queries* t7 K6 D* l7 f) T- D* Q
the URI dedicated to monitoring, a 200 response is returned. When one of the0 n0 C9 x; m" Y$ `- P
conditions above is met, haproxy will return 503 instead of 200. This is( S4 y3 v2 h" H z, Z( R
very useful to report a site failure to an external component which may base* B9 z1 ^) R9 H, Y! ]! Y0 | x
routing advertisements between multiple sites on the availability reported by
# N& X4 Z$ E0 F% w6 I haproxy. In this case, one would rely on an ACL involving the "nbsrv"
( b5 R5 X f. G criterion. Note that "monitor fail" only works in HTTP mode. Both status
+ j1 K' N( x9 v1 r- o8 L messages may be tweaked using "errorfile" or "errorloc" if needed.$ g. ?0 q. F' `3 P) B. R1 |
U7 C4 L7 k% S/ o9 S
Example:
' e9 D" O I( @ frontend www; Q. g3 E$ b5 x `3 T5 v
mode http
2 u& D' o' W* [# }: N# N acl site_dead nbsrv(dynamic) lt 2% G, i7 x8 m0 E1 E' y
acl site_dead nbsrv(static) lt 2
3 |. l8 i- y& F% X, E monitor-uri /site_alive
% ]. H( v$ z% N& {4 N. c$ w: P* V monitor fail if site_dead
0 |9 h, Z: X H/ m3 P; e) D8 m0 n; Q O6 @8 ?% L7 R9 }
See also : "monitor-net", "monitor-uri", "errorfile", "errorloc"
9 @, F7 ]7 b( v B/ [9 ]/ G O0 C: ]9 c" o0 t5 y
! ?& d) I2 n0 n8 B6 _/ [) ^monitor-net <source>
; I2 R/ {8 `* A0 g3 R, e/ _' O Declare a source network which is limited to monitor requests Q4 o- H. e" b
May be used in sections : defaults | frontend | listen | backend
. B% \8 S: f x' y yes | yes | yes | no/ {1 V$ L, c" B [( `8 [6 m
Arguments :
% F3 ^# |: O, [1 h) ?6 `% ^ <source> is the source IPv4 address or network which will only be able to& @0 V- i7 {# @: B. T8 s6 ~: I3 \# u
get monitor responses to any request. It can be either an IPv4" a, A8 g" |$ v: m) k1 ] ]) x1 k
address, a host name, or an address followed by a slash ('/')
' f) I' d. x1 ` followed by a mask.
$ n) d5 Q9 e* q* u1 E5 b1 D% d" O5 z2 k& c6 u# I
In TCP mode, any connection coming from a source matching <source> will cause
5 T! J; [4 {+ Y6 \3 ^' y) q) f the connection to be immediately closed without any log. This allows another
( B* M# W' i7 a, A equipment to probe the port and verify that it is still listening, without, k, j( Y, ]2 y( F
forwarding the connection to a remote server.
! ]. N" I0 ?- g" ^8 e+ d
. j7 {# t# z, ~2 U$ W In HTTP mode, a connection coming from a source matching <source> will be
+ Y! x& A3 N7 _" V, c accepted, the following response will be sent without waiting for a request,
% ~- x. F2 Z4 C- z! C7 A then the connection will be closed : "HTTP/1.0 200 OK". This is normally
6 {7 a! r, I9 o6 [# l5 K, G3 O enough for any front-end HTTP probe to detect that the service is UP and4 X5 p9 n; j" y& i. c
running without forwarding the request to a backend server.. K& Z. A" f# E. d
$ n% V, G, a. m& ], s Monitor requests are processed very early. It is not possible to block nor
e& p: r' Q2 G& L( G divert them using ACLs. They cannot be logged either, and it is the intended {! J* m% I7 L7 Z
purpose. They are only used to report HAProxy's health to an upper component,
% ?$ Q7 z4 y! L N+ a nothing more. Right now, it is not possible to set failure conditions on
6 p$ p0 ^6 N0 r& D: z requests caught by "monitor-net".5 l8 m. v G6 |5 M" Z" z
2 o$ G* C( w; i8 u0 q/ p Last, please note that only one "monitor-net" statement can be specified in: ~6 B' I/ e1 R5 ^% J1 s: B' I; ~
a frontend. If more than one is found, only the last one will be considered.
p# y: y+ r( Q6 k$ O& {, k
" K2 h% D9 y3 o, ] Example :3 c! H9 L& D- T2 B7 c3 B' \2 Z3 ^
# addresses .252 and .253 are just probing us.
5 y4 x# j* V; e! R4 l4 G; C frontend www J$ J2 ]$ ]: j8 n6 h
monitor-net 192.168.0.252/31
: H$ R+ L3 _! S7 [: L+ k! Q" p( N. L. l8 l' j/ [" R! o
See also : "monitor fail", "monitor-uri"4 s: Q$ m4 Z4 }0 e$ ]( e' M
2 z8 _$ B# f- a0 L
; x) v# C5 @% W# ?( X
monitor-uri <uri>/ u: G' K# i( G* j( ]) B Z, J$ u
Intercept a URI used by external components' monitor requests% ]" M9 l5 O4 Y: c* V/ w% U
May be used in sections : defaults | frontend | listen | backend
$ f* k- w3 z) l3 E) m; q. V yes | yes | yes | no4 Q& [5 _" Q. C% l+ S6 C; I) e
Arguments :
% f- a) \$ S6 |# K2 U/ n <uri> is the exact URI which we want to intercept to return HAProxy's
- O% ~* D2 C* W" }3 \6 s health status instead of forwarding the request.* A1 d& ?2 @ q3 A
7 K, R6 f( i ?; |: W3 q( | When an HTTP request referencing <uri> will be received on a frontend,
- X" ^% d+ R* Y" \ HAProxy will not forward it nor log it, but instead will return either: H0 e s3 D2 E
"HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure; r* J9 o: q. R5 J# |1 [7 C
conditions defined with "monitor fail". This is normally enough for any) D( y4 `: c3 c. \' k% O
front-end HTTP probe to detect that the service is UP and running without
4 v$ |/ M- ?- V8 X4 z3 K forwarding the request to a backend server. Note that the HTTP method, the
* G& I, l- d- F version and all headers are ignored, but the request must at least be valid
* f% R. w" k' H/ B) \' l; ^# S at the HTTP level. This keyword may only be used with an HTTP-mode frontend.* y" h1 _3 \9 n) w1 X; G
3 P. W7 b+ V2 k: V Monitor requests are processed very early. It is not possible to block nor
8 B4 Y9 [6 m" G1 I# e divert them using ACLs. They cannot be logged either, and it is the intended
7 t: q+ a4 z& O3 Q, P0 }7 ` purpose. They are only used to report HAProxy's health to an upper component,; m, z# l8 B0 _
nothing more. However, it is possible to add any number of conditions using$ K. r7 [; A- |; w% u
"monitor fail" and ACLs so that the result can be adjusted to whatever check
. U1 a* [' J4 d0 m5 D can be imagined (most often the number of available servers in a backend).; E8 Z3 b4 y' r% X3 P
' a" ~4 U% y+ O% {6 F' |' {# `
Example :1 s( u f5 l0 N! f5 ~
# Use /haproxy_test to report haproxy's status: l! h( r; x5 j, \7 D* f. _: m+ d
frontend www
/ x- C \9 Y( H, E7 P mode http
/ S0 ?" v y( s' B3 n' V8 ~0 M) g monitor-uri /haproxy_test
) y& L3 z8 T& k' L
/ k2 u# |! Z5 V( S; s3 k" y; P4 h See also : "monitor fail", "monitor-net"
7 u+ A5 h% \# E& x1 c
V6 r o7 R3 C& ]) p4 r' L5 w
2 i* h6 S& U% F( x" M/ p, Y% Aoption abortonclose; k: n4 ^$ k& v& g
no option abortonclose
- |# B( a) h+ W( S0 L/ ~9 x8 x0 p% E% Y Enable or disable early dropping of aborted requests pending in queues.
7 F/ V) m! V: D+ w May be used in sections : defaults | frontend | listen | backend; Z2 j4 g$ H/ L0 C6 ~- {
yes | no | yes | yes# M8 @4 v. ^. o+ s Q
Arguments : none
& q K) a* Y/ _' U& ^
6 {; V6 g! C) S* I& @, { In presence of very high loads, the servers will take some time to respond.! V3 ]" Y- S) E3 o: p
The per-instance connection queue will inflate, and the response time will$ O" w' I( h: o
increase respective to the size of the queue times the average per-session
* o! o2 j" O y6 ] response time. When clients will wait for more than a few seconds, they will
6 ~6 F C( U) T- N$ } often hit the "STOP" button on their browser, leaving a useless request in/ n w8 B1 ]$ C/ J
the queue, and slowing down other users, and the servers as well, because the
, e+ E9 Q; X" t, \ request will eventually be served, then aborted at the first error
4 V% {0 b9 r0 u encountered while delivering the response.1 m" w$ \, P- j4 `: O' ?- w
+ U$ O1 S6 R4 t As there is no way to distinguish between a full STOP and a simple output
8 p' |% g0 y7 j close on the client side, HTTP agents should be conservative and consider; A7 j9 j5 J- f3 a. W
that the client might only have closed its output channel while waiting for! S5 }! O9 D& ? F1 S) R
the response. However, this introduces risks of congestion when lots of users5 C3 B+ A( E8 C8 L; O9 f; e
do the same, and is completely useless nowadays because probably no client at
3 ]* S: x) Z2 {* A) l all will close the session while waiting for the response. Some HTTP agents# m0 h9 E& w3 u4 u/ Z
support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most
/ a; k8 f \7 r1 X$ B9 B% ` hardware-based load balancers). So the probability for a closed input channel
7 d* z8 j; R4 ?" M to represent a user hitting the "STOP" button is close to 100%, and the risk6 S$ J( |9 z! `- i! o
of being the single component to break rare but valid traffic is extremely
5 g9 y/ d. u- D1 l0 Q+ e" o low, which adds to the temptation to be able to abort a session early while& H5 \! M; h# E* A- s: d
still not served and not pollute the servers.- k, t, D/ A% C1 x9 F
5 ?% w$ _& t$ i+ j. D: I! w# y# [ In HAProxy, the user can choose the desired behaviour using the option
" r* D2 B6 g7 m( B, y "abortonclose". By default (without the option) the behaviour is HTTP
# S- n+ d7 r+ }) D. V. L3 N compliant and aborted requests will be served. But when the option is! v5 [# F6 B B* f9 P) X
specified, a session with an incoming channel closed will be aborted while
/ N$ _+ K1 `+ \ it is still possible, either pending in the queue for a connection slot, or
* ~5 n) T. d: X* N during the connection establishment if the server has not yet acknowledged
1 K4 t+ q; q. z! g' C& ` the connection request. This considerably reduces the queue size and the load* u% N' `/ l9 L- `7 J# B
on saturated servers when users are tempted to click on STOP, which in turn
3 e0 i! l& b% W7 J- g# \" o reduces the response time for other users.% i2 v, z% h f: H% @4 b5 q
7 I& F5 h4 a& d" i: d7 F If this option has been enabled in a "defaults" section, it can be disabled6 ?9 p) C6 ?% C- L4 c
in a specific instance by prepending the "no" keyword before it.
I# x, g& A# Q7 o% q/ g" f$ N
4 i! V5 w! Y: X, V( V5 U See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters$ i' R& A' a5 C. n$ l
) r9 c( V: z: e. O! P/ I/ c0 Q* Z! j. H% h
option accept-invalid-http-request
7 i( \$ g9 h& L1 J1 [1 t! w; ?8 Ono option accept-invalid-http-request
2 c; a- x9 }! E+ H9 S |, m( Q Enable or disable relaxing of HTTP request parsing
+ J' t8 h* f. k5 N' ]% ?- I May be used in sections : defaults | frontend | listen | backend. \: a! U3 `, {/ W
yes | yes | yes | no& y" {2 h" |3 }/ U
Arguments : none1 m0 e: M H6 k9 Z | k' ^
6 A, ]4 f) \) }7 f: E0 ~ By default, HAProxy complies with RFC7230 in terms of message parsing. This
$ t* |$ i; E W. Z2 D means that invalid characters in header names are not permitted and cause an% p9 k$ n# b$ q' y- @4 ?& @
error to be returned to the client. This is the desired behaviour as such
8 U5 j& b5 b' ?/ R forbidden characters are essentially used to build attacks exploiting server
. b% O5 O: J$ q weaknesses, and bypass security filtering. Sometimes, a buggy browser or8 T9 }4 j: s2 u& R& r5 Z" e! i
server will emit invalid header names for whatever reason (configuration,
/ X* k r: C. U+ e" k% u implementation) and the issue will not be immediately fixed. In such a case,
/ ^% s9 S3 g, v/ W) ^$ B# f& b it is possible to relax HAProxy's header name parser to accept any character
" D& W4 Z! m1 D4 Q+ A even if that does not make sense, by specifying this option. This option also4 r- E6 i0 ^1 z% z0 ]- h7 M/ N2 i) Z
relaxes the test on the HTTP version format, it allows multiple digits for
1 u' {/ [* V; h, M' t9 v: |& A both the major and the minor version.
/ {' e9 u/ d" y# o9 f4 \7 W5 [6 ~, T" p* U2 G* k! D" h
This option should never be enabled by default as it hides application bugs
8 Y& k1 L8 ]% Z5 l and open security breaches. It should only be deployed after a problem has* `) H+ a- g1 Y- T
been confirmed.8 P6 q- O- y4 E% O) h
) E4 y3 H+ Y, y+ p, u
When this option is enabled, erroneous header names will still be accepted in
+ `& D% ~9 C2 [" c4 G requests, but the complete request will be captured in order to permit later, t7 O# i9 c4 ]# N4 \3 W/ g
analysis using the "show errors" request on the UNIX stats socket. Doing this7 Y3 U8 }+ m& Q2 C% ^& j! f/ k
also helps confirming that the issue has been solved.9 I7 I. k+ J) m6 n- \6 Z$ F n/ ?6 o
- {+ J4 F: s) b* B5 w If this option has been enabled in a "defaults" section, it can be disabled- }9 ]# I' `7 V" Z, [ W4 ~1 m
in a specific instance by prepending the "no" keyword before it.
: A: i' W7 q& V0 s: b% S0 V3 R0 \5 \
; v9 B! W% A! R# h9 \( L! [ See also : "option accept-invalid-http-response" and "show errors" on the
* @' ?( X8 f `7 ?' s1 ]4 o. ~; S stats socket.- ~3 L/ m, }: y8 d
$ |. S/ D1 A) ^ S: V
$ E( j/ K$ E/ ^* d7 Y: I; ^" _/ Voption accept-invalid-http-response
# y9 C' l- @' `1 D, Mno option accept-invalid-http-response
# W ^' _* [4 r( r3 X8 S/ w Enable or disable relaxing of HTTP response parsing, W% j* v" t2 u; A' j: {; |
May be used in sections : defaults | frontend | listen | backend% ?; W' ^5 M* L. d; s# W
yes | no | yes | yes2 {: u9 A- P4 i: _: G
Arguments : none
9 H9 W% R1 x$ o' v, g4 K; k
1 |( T' h$ `$ o+ _; \" \, k1 _ By default, HAProxy complies with RFC7230 in terms of message parsing. This2 S6 p3 y% x* m0 L ?* T8 ~
means that invalid characters in header names are not permitted and cause an
l" b' p1 t2 U" C9 _9 ?7 ~& N error to be returned to the client. This is the desired behaviour as such) {+ R: C+ [" |& U/ F! w% p
forbidden characters are essentially used to build attacks exploiting server& J v& Q3 y _6 M/ n3 @
weaknesses, and bypass security filtering. Sometimes, a buggy browser or
( m: X' \6 o$ c4 a1 R server will emit invalid header names for whatever reason (configuration,% T- Z+ A: z4 X5 p
implementation) and the issue will not be immediately fixed. In such a case,
; i. f1 ?0 b( Q it is possible to relax HAProxy's header name parser to accept any character& D- R4 n: P( H0 F6 r
even if that does not make sense, by specifying this option. This option also; l8 C7 [3 d1 D. V& j
relaxes the test on the HTTP version format, it allows multiple digits for- N% Z0 k" X" p4 E0 b7 f9 G
both the major and the minor version.
( d( K b# r# o7 m6 w1 |" |, W' O
) N; N0 _& K8 o# ]+ o This option should never be enabled by default as it hides application bugs
/ V0 V2 z n" @" R0 _ and open security breaches. It should only be deployed after a problem has
8 p/ u6 u2 Z$ i4 t9 X/ ?( i been confirmed.' m- u- k1 `0 X
' P: N" u( v. Q3 ?
When this option is enabled, erroneous header names will still be accepted in7 U9 k# w9 O. @
responses, but the complete response will be captured in order to permit
' _( Y& b0 ?5 H1 t5 m! B later analysis using the "show errors" request on the UNIX stats socket.0 T. d# G' T- J( J1 `
Doing this also helps confirming that the issue has been solved.* O+ p% h8 e$ R* \2 h6 v
) q% w8 C- m8 z, c If this option has been enabled in a "defaults" section, it can be disabled
2 V5 q" s& e: }8 {$ Y# O" _ in a specific instance by prepending the "no" keyword before it.9 n- P8 J/ x" D0 l' a7 E
/ H- z+ a# o/ j( L7 O' S# Z4 E See also : "option accept-invalid-http-request" and "show errors" on the- z; n$ z% P& u8 C" w
stats socket.
+ _, t3 O! f1 m: |! s
; a/ z7 R6 A, p$ r
. w F+ ^0 `2 E+ Ioption allbackups
3 s2 ^ e7 @% K. R( Rno option allbackups( I! x- ]! e7 e/ {
Use either all backup servers at a time or only the first one0 }- O6 M' d/ l8 N: a
May be used in sections : defaults | frontend | listen | backend4 J& ], ~& c" w) V/ s$ Q/ P
yes | no | yes | yes9 w& I& F8 W- I9 F6 A! k) \: ^
Arguments : none
( ^/ I" s) `8 ]* E: L; x. u4 h: W4 B. K1 P4 y G1 C+ m" ?
By default, the first operational backup server gets all traffic when normal
3 K, q+ O8 \ ?6 m. Q9 i4 @ servers are all down. Sometimes, it may be preferred to use multiple backups( R& r& W' m5 V8 N1 K
at once, because one will not be enough. When "option allbackups" is enabled,6 k) }- _( A8 H$ o7 O9 R$ U1 T
the load balancing will be performed among all backup servers when all normal7 N: A1 B; x6 ~% d
ones are unavailable. The same load balancing algorithm will be used and the' O- [1 O- D$ i% u
servers' weights will be respected. Thus, there will not be any priority! {1 f% [) h. {1 h% j) z0 H4 a9 h
order between the backup servers anymore./ j4 r* y2 n v+ d
* l' N4 ^5 k+ ]$ y This option is mostly used with static server farms dedicated to return a
4 r* \: O9 ^/ h1 x "sorry" page when an application is completely offline.1 g v" E8 N% D: H; e' D& X! z( k
+ s* \. n* h) Q* F' } If this option has been enabled in a "defaults" section, it can be disabled' u3 y7 ~% e, n4 s# W4 H1 s o
in a specific instance by prepending the "no" keyword before it.
( ~" q5 a9 v9 z) R
) C# V/ {8 W) Z+ U- g) `
1 a: k6 n' c' p6 t4 X+ moption checkcache
3 x$ z m0 x) G8 |no option checkcache
' `* M$ |0 C. P Analyze all server responses and block requests with cacheable cookies
5 ]" g6 I* U, z1 I7 o, ` May be used in sections : defaults | frontend | listen | backend
) u$ p: ~! `/ o1 M( h8 o7 ? yes | no | yes | yes
' r) {0 N+ L& c Arguments : none
0 g5 ^1 X# K2 y) C# K% ^, b7 E5 C/ E. L- m; G1 m
Some high-level frameworks set application cookies everywhere and do not) C( X0 N# h% Z3 Q# H
always let enough control to the developer to manage how the responses should
! P, x2 E* c9 L I6 ]% S be cached. When a session cookie is returned on a cacheable object, there is a
4 Y% P9 `6 f* m, o0 j. I# F% Y high risk of session crossing or stealing between users traversing the same
% Y5 q1 E& p/ |' ] caches. In some situations, it is better to block the response than to let
2 w1 r% a6 t* ~6 g some sensitive session information go in the wild.
" ~0 Z) P' y& D. U- \9 z/ e
H4 T$ ]' k% Q0 r- K' E The option "checkcache" enables deep inspection of all server responses for& [# b( `) ^- g' s+ o# p
strict compliance with HTTP specification in terms of cacheability. It
+ D9 {4 z9 e& A' H carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
7 v% J t/ ^* x2 ~' y response to check if there's a risk of caching a cookie on a client-side
7 @3 n) d. i" _* S proxy. When this option is enabled, the only responses which can be delivered- }" [+ K7 D, t" c, y% _
to the client are :
2 j' c5 m% _- ~% X# Q - all those without "Set-Cookie" header ;; j U; f' ^1 `; o' j- b9 Z f/ L" E
- all those with a return code other than 200, 203, 206, 300, 301, 410,& Y; i- l8 `4 W& c! f. a2 y/ F2 c
provided that the server has not set a "Cache-control: public" header ;
7 g0 s+ d2 @$ g: X# Q7 ]. ^5 m! H - all those that come from a POST request, provided that the server has not/ o- K. n% n" V
set a 'Cache-Control: public' header ;9 N2 ?% o* Z4 T3 X
- those with a 'Pragma: no-cache' header
' o( h% v3 s$ G2 j) f; Z - those with a 'Cache-control: private' header
3 u2 E. m, p' z1 V# Q0 \ H - those with a 'Cache-control: no-store' header- S( s( |+ a2 ? M$ i# Y0 D8 ~, A) q
- those with a 'Cache-control: max-age=0' header( \: t& e9 S+ Q ?$ Z
- those with a 'Cache-control: s-maxage=0' header, g) {- q# `) I
- those with a 'Cache-control: no-cache' header, e E' s& X9 `9 M
- those with a 'Cache-control: no-cache="set-cookie"' header
1 `& ?" p3 z0 | - those with a 'Cache-control: no-cache="set-cookie,' header
6 a/ Z, p# q R* q7 D (allowing other fields after set-cookie)0 Y! Y# ~$ g# I t, _+ h% j" c( j
?5 {9 J% G. `% G) K If a response doesn't respect these requirements, then it will be blocked
+ q4 q5 T2 D3 ~. J) m5 Y: s just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".% k. N* Y( M* n' u
The session state shows "PH--" meaning that the proxy blocked the response
( _2 Z9 U- M6 |+ M: d& S! W r [0 M) F during headers processing. Additionally, an alert will be sent in the logs so
" X+ a6 {9 O* t, c+ r0 m$ C that admins are informed that there's something to be fixed.& {/ k7 `4 `2 q- S% U* G- p
4 b9 g6 u; w; ?/ v0 ?0 o
Due to the high impact on the application, the application should be tested
/ v% U2 l1 _6 t0 z0 { in depth with the option enabled before going to production. It is also a
" m& H- O5 G- `2 ^( ^ good practice to always activate it during tests, even if it is not used in
2 I$ w: g* I# r6 ~8 l production, as it will report potentially dangerous application behaviours.9 h; l/ w! e) r4 q6 z
- X: |0 c# {3 f! k, }: [ If this option has been enabled in a "defaults" section, it can be disabled, J: b5 ~) i0 Y [: V H
in a specific instance by prepending the "no" keyword before it.
% j! G' P, _! t) y1 e5 o) T
% T+ E4 b/ w a* u. S# V
. `! B# f- n3 L) g1 z( j# i/ woption clitcpka- i- Z% R- b l; N
no option clitcpka
9 K1 l# N, H R+ {9 V/ I8 _ P Enable or disable the sending of TCP keepalive packets on the client side: g( N0 A( x3 g, c$ b
May be used in sections : defaults | frontend | listen | backend
7 Y( ~6 s7 r3 \& e. Z) h- x yes | yes | yes | no } F* E0 y3 c9 q: N
Arguments : none
; d9 |; i9 Y5 O: z
! l; e$ t0 X* n When there is a firewall or any session-aware component between a client and
d! e' Y+ a; X( Y8 e a server, and when the protocol involves very long sessions with long idle$ i$ s. i% X N4 Q9 Q3 y3 Z
periods (eg: remote desktops), there is a risk that one of the intermediate) R: R3 B; w" X, W4 c; B
components decides to expire a session which has remained idle for too long.) f: F) t: }# T, ^
4 f( g2 y3 \8 v- h9 y
Enabling socket-level TCP keep-alives makes the system regularly send packets; I4 G% X _- M1 c
to the other end of the connection, leaving it active. The delay between
! }; q) P9 F% u' s' I- E% f keep-alive probes is controlled by the system only and depends both on the6 W6 M+ t u" k. }! _' u; K" p
operating system and its tuning parameters.
$ v; z; r9 r2 }+ O7 i9 f- ]6 [, ^ O6 A: i% d
It is important to understand that keep-alive packets are neither emitted nor0 E# O4 Y& i/ v0 V6 v6 s8 k2 Y
received at the application level. It is only the network stacks which sees
. M1 }0 L' L5 h/ A them. For this reason, even if one side of the proxy already uses keep-alives
6 F2 Q6 M) t/ r, H to maintain its connection alive, those keep-alive packets will not be+ \, w* Q/ A% W4 I$ N7 b
forwarded to the other side of the proxy.
+ p+ w' [/ e( S
& Z& L1 \1 I0 ?7 h( t" W Please note that this has nothing to do with HTTP keep-alive.+ K, M! d+ m( c# \" ^0 y1 U7 \
0 j( P# K9 [, ?) o$ O Using option "clitcpka" enables the emission of TCP keep-alive probes on the
& u3 D9 u4 V+ W% F5 }, V; o4 N client side of a connection, which should help when session expirations are
, w/ z+ c( |) |" v. j! O noticed between HAProxy and a client.
1 A, j! \1 f! p3 @! E+ [& M
7 R7 T, M* H$ n6 [/ @/ V If this option has been enabled in a "defaults" section, it can be disabled5 X( O6 D, W$ x/ F) m, q% I9 D e
in a specific instance by prepending the "no" keyword before it.
* C' ~* m$ \$ _' g+ N; V3 N* E, r) i
See also : "option srvtcpka", "option tcpka"
: ^" k8 u9 K+ d- D5 Q
" v/ N, S, M4 E+ k4 d, v1 d
$ e' R, \7 F4 Qoption contstats
% |6 {0 _; o1 ~3 H. q! L9 W Enable continuous traffic statistics updates
/ z$ j" E# g" Q& ~5 \( Y y! |, ?9 j May be used in sections : defaults | frontend | listen | backend
8 D" A+ {9 e, I5 k# Y4 E yes | yes | yes | no) l/ h: L8 T- ]: s
Arguments : none
) n. Z2 C: D& n
3 z. i3 {1 O( s- p& p0 U- Z By default, counters used for statistics calculation are incremented
: G0 [* Q _, P- ^' }9 t only when a session finishes. It works quite well when serving small) A7 d* Q% S( B
objects, but with big ones (for example large images or archives) or
. ]4 V% R, G& U: e( f5 a with A/V streaming, a graph generated from haproxy counters looks like, c F# t2 H* P5 x
a hedgehog. With this option enabled counters get incremented continuously,1 B7 Q8 `" f/ x" B7 Z
during a whole session. Recounting touches a hotpath directly so# W% g: W9 G2 D3 K
it is not enabled by default, as it has small performance impact (~0.5%).
' [/ ]" n. O7 y+ o/ F3 U, Q- |1 [# y% ?" ?) t4 x1 w: s
. W. V7 K5 ]" h9 |% Eoption dontlog-normal& S( f8 A9 k5 X3 s7 C
no option dontlog-normal
B% H6 Y5 Q6 c/ J3 D" T6 \2 ~ Enable or disable logging of normal, successful connections
) F& S9 j( E! x2 }+ I3 D& T May be used in sections : defaults | frontend | listen | backend) `% T$ `: r# g" U# p
yes | yes | yes | no
, g) B: ?3 ~$ @' j- |2 Q9 v Arguments : none
5 _/ Z( ~+ ?0 S2 j' a, a; l D' ?0 V! I* b" M
There are large sites dealing with several thousand connections per second$ ^. t0 {6 A- r' ^# w; Q
and for which logging is a major pain. Some of them are even forced to turn
8 J, h0 f5 e9 ?5 E logs off and cannot debug production issues. Setting this option ensures that
7 x; k7 w% b% r4 |5 z7 B# d0 g- Q normal connections, those which experience no error, no timeout, no retry nor
H2 |; x1 N5 j: _& s redispatch, will not be logged. This leaves disk space for anomalies. In HTTP' h2 y6 F* o; t$ m& e
mode, the response status code is checked and return codes 5xx will still be! |' m/ W8 f, M& r' L8 U* }
logged.
8 x. J' i/ |- L' |1 c8 ~0 y& f# w) h/ e
) W% W. K6 J L) { It is strongly discouraged to use this option as most of the time, the key to% o E+ S! {: |6 l7 i/ u
complex issues is in the normal logs which will not be logged here. If you
1 A7 E0 r6 d3 f: B$ P need to separate logs, see the "log-separate-errors" option instead.
# J: p, s2 F% E1 Z1 O# [. z+ v2 w5 g% D& ]5 D
See also : "log", "dontlognull", "log-separate-errors" and section 8 about
) b/ c1 [( F0 {8 k, |6 F logging.
) I. i$ f2 B9 N9 ?" f; c+ K! L: N
) a$ W S) v$ C1 U# P1 ?; Hoption dontlognull j. k( j7 s) \9 j; Z4 B7 c: O. X
no option dontlognull
( j" Y! ]- l8 r Enable or disable logging of null connections
6 X! R5 N$ d+ s* v$ O7 _ May be used in sections : defaults | frontend | listen | backend
( }& s- ?, `3 y& R" v6 \ q yes | yes | yes | no
% L T( m5 ~+ p: {. R. C4 x Arguments : none
' v Y) Q7 W6 `+ e5 `/ x6 Q9 s+ N8 \4 A- P5 |& `
In certain environments, there are components which will regularly connect to
6 k! |2 w; ? j( p/ e. T various systems to ensure that they are still alive. It can be the case from
. ]+ s. L5 _0 m+ A% ]5 E another load balancer as well as from monitoring systems. By default, even a
1 {# u/ X) Y( I simple port probe or scan will produce a log. If those connections pollute
! I- W0 K& B; O the logs too much, it is possible to enable option "dontlognull" to indicate2 M; Z( \5 j" {) q5 M( R6 Y6 w
that a connection on which no data has been transferred will not be logged,
G. m7 H) s% ~ J1 d7 @ which typically corresponds to those probes.
; U/ E! N, |. ?1 D& Y) V
8 K* D$ q" Y _" ? It is generally recommended not to use this option in uncontrolled- {$ t7 V+ m, a4 [; W% ?. F2 l
environments (eg: internet), otherwise scans and other malicious activities' r! V5 g, G7 Y3 N+ f
would not be logged.1 J7 ~! |( ^. b8 f& P# w( W
( G& l+ s4 @9 d" r$ F) r- ]7 U7 w% b If this option has been enabled in a "defaults" section, it can be disabled
' k/ u8 S4 J2 p- z9 T# \+ n+ u in a specific instance by prepending the "no" keyword before it.
% J+ S) o% b" _2 k% L x; y: x+ Z. n8 p7 k2 ~: b1 m3 G8 k+ N8 F% M
See also : "log", "monitor-net", "monitor-uri" and section 8 about logging./ S0 F* Z' _4 L" ?
8 m6 _# ]1 f2 Z
7 i! V0 [; M; Q1 k
option forceclose
0 g( n- ]7 f7 p/ t3 f( Tno option forceclose7 t# G# D* z( ]( T$ A# M7 x% Q3 \
Enable or disable active connection closing after response is transferred.
5 o; a/ x: n2 Y5 j6 Z May be used in sections : defaults | frontend | listen | backend! J0 N& E. P6 Q1 s. p& e) q
yes | yes | yes | yes" y* K- p+ }* K9 Y
Arguments : none
. x# V6 @8 v; E$ ?& t, Y
9 ?# ^! I3 C+ N. e4 T; I" D, F! a, J# U Some HTTP servers do not necessarily close the connections when they receive2 z- v* ]+ ?' g
the "Connection: close" set by "option httpclose", and if the client does not3 v l' H2 |; p" u
close either, then the connection remains open till the timeout expires. This, L) Z, k- e' d
causes high number of simultaneous connections on the servers and shows high
$ z7 ^" S0 n6 S6 A* C global session times in the logs.
( a' A8 y i" d" H
1 b/ G! W) C8 R& C- `6 B When this happens, it is possible to use "option forceclose". It will
4 h* c& Y# i. A& z# k J actively close the outgoing server channel as soon as the server has finished
2 a+ I' e1 y: u* P0 F to respond. This option implicitly enables the "httpclose" option. Note that) b! {$ U* [, X1 Y3 f' `6 g u
this option also enables the parsing of the full request and response, which
; v( m. m& x" r9 f means we can close the connection to the server very quickly, releasing some
# |) U9 ~& ]" S# T7 y resources earlier than with httpclose.
" N) J: O X" V# Z" r, b6 D' \3 t' @: F7 P. q
This option may also be combined with "option http-pretend-keepalive", which# e) Y1 M+ q" u, D# z
will disable sending of the "Connection: close" header, but will still cause# @( }; Q0 _5 Z# B" @) Z8 O
the connection to be closed once the whole response is received.4 ^% c4 d5 `, _" u0 d
6 f% L0 Y) h$ E8 Y* b If this option has been enabled in a "defaults" section, it can be disabled* h( }, S1 T; ^* D9 @
in a specific instance by prepending the "no" keyword before it.0 ?! j" z6 l) ^, s# E( @9 L9 L0 z
" h% ~$ C0 y# ]0 K
See also : "option httpclose" and "option http-pretend-keepalive"8 |$ q# c5 h! ~
) m$ ~* w) s1 J i7 @- a7 x: R7 {1 A$ a0 z( l& r
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]0 K5 n# S* t1 ], A
Enable insertion of the X-Forwarded-For header to requests sent to servers# t$ ? j; S* I' c; V0 M6 t2 m
May be used in sections : defaults | frontend | listen | backend
! X2 k; i; k+ I1 K0 v+ C$ r yes | yes | yes | yes6 E" N4 J1 p& T% x3 W
Arguments :
( g5 B' \- a5 G4 g% ]. \ <network> is an optional argument used to disable this option for sources. g) {( c# r( H& F2 W# H4 t! m1 y# K! _
matching <network>' w) U8 y6 g, G! S( F) c
<name> an optional argument to specify a different "X-Forwarded-For"
% a' m0 X! X* \2 e- U) W header name.
" C }# M! j7 o/ N5 `( r( N
( Q5 a0 ]; l. ?* P) ?: ^. @; R Since HAProxy works in reverse-proxy mode, the servers see its IP address as1 o, z* c7 ^0 _0 U" @
their client address. This is sometimes annoying when the client's IP address7 e7 q' {* z# X2 `" r' ~
is expected in server logs. To solve this problem, the well-known HTTP header
+ u7 I6 [& w2 l "X-Forwarded-For" may be added by HAProxy to all requests sent to the server.
- `( w1 ]! y+ Q1 Y, r5 g- [ This header contains a value representing the client's IP address. Since this. Y9 Q) Y+ Y* S$ z+ T2 g
header is always appended at the end of the existing header list, the server, V& \: S3 d+ b$ Y
must be configured to always use the last occurrence of this header only. See
" q3 J) t% j) `; B3 Q the server's manual to find how to enable use of this standard header. Note' Q2 R) D. w8 m) r* V$ r9 \
that only the last occurrence of the header must be used, since it is really
% i6 b9 S8 b& a) i- t possible that the client has already brought one.7 \6 h1 w4 R: [0 T3 G
( L8 t+ V0 x* A0 j
The keyword "header" may be used to supply a different header name to replace
( G) X- ~2 e% D8 p7 N the default "X-Forwarded-For". This can be useful where you might already
) u" a/ O" N0 \5 D3 G0 ^! Y: W) z have a "X-Forwarded-For" header from a different application (eg: stunnel),% y: Y9 u0 g! b: n/ s& f
and you need preserve it. Also if your backend server doesn't use the7 v+ X. B2 R: m2 X0 ` z
"X-Forwarded-For" header and requires different one (eg: Zeus Web Servers: c7 U: b T0 L b5 D
require "X-Cluster-Client-IP").
# t! S' N/ U, K( l! M$ ~8 W! ^- ^7 {+ `. F
Sometimes, a same HAProxy instance may be shared between a direct client* Z/ X2 f* G' o1 x U+ M
access and a reverse-proxy access (for instance when an SSL reverse-proxy is
* v, P5 p: _7 h6 z+ I0 f used to decrypt HTTPS traffic). It is possible to disable the addition of the! g3 }# a+ X& S9 R: _
header for a known source address or network by adding the "except" keyword
l! H2 V5 }. o! S9 ? followed by the network address. In this case, any source IP matching the0 ^) H. {: e: I( g) p" o v% `& ~
network will not cause an addition of this header. Most common uses are with3 _+ g# P0 x4 k1 x3 _
private networks or 127.0.0.1.0 t& G1 {7 O y- P: O
~8 z, U; j$ n; i& X; l. ] Alternatively, the keyword "if-none" states that the header will only be& T$ ~, d) w/ \; I m7 I- a$ l$ ?
added if it is not present. This should only be used in perfectly trusted
$ a* u1 F9 c( Y' o8 X6 o! N environment, as this might cause a security issue if headers reaching haproxy8 \% v6 f, X6 l0 s, Y
are under the control of the end-user.
* x' K4 R V* B8 e1 Q7 K8 N2 b
9 z. {% H* o! Z3 h& ~ This option may be specified either in the frontend or in the backend. If at$ k6 X2 \+ A2 u r e4 _
least one of them uses it, the header will be added. Note that the backend's
% C5 u" s6 G' m; Q: \: | setting of the header subargument takes precedence over the frontend's if
9 w$ L& D( e' B both are defined. In the case of the "if-none" argument, if at least one of
. h& z/ G5 V. S4 x the frontend or the backend does not specify it, it wants the addition to be
3 E6 y, d" R. z I: \ mandatory, so it wins.1 `5 z) q) n2 t, ?
' Z( J# R, \; N* N2 ]' j7 c
It is important to note that by default, HAProxy works in tunnel mode and
~- m0 y/ g# v6 k3 j only inspects the first request of a connection, meaning that only the first6 ^: |3 i+ ?( a- t; J4 S* _' F/ E
request will have the header appended, which is certainly not what you want.
* ^) l, b k- b4 M+ A8 w In order to fix this, ensure that any of the "httpclose", "forceclose" or+ b: n$ }8 O0 N9 s
"http-server-close" options is set when using this option.
$ I5 z& h$ `: ~& [: V
1 b' u8 ]; E6 m# P Examples :
$ i8 x6 W1 V0 D8 @2 R/ i # Public HTTP address also used by stunnel on the same machine) O b1 Z0 ^9 _9 s/ o! ^' t
frontend www
8 b2 p) q) V" Z mode http
# \" {" {3 _; o6 r$ @ option forwardfor except 127.0.0.1 # stunnel already adds the header
+ F' E8 o0 Y2 t" b6 ^# f/ {# T+ n- ]. C( n/ f' M6 J/ h
# Those servers want the IP Address in X-Client- }6 p/ x3 ?4 _1 J1 B+ @
backend www
+ T q6 e$ j$ e( O& ^; g mode http
0 W, x! Y/ z+ z option forwardfor header X-Client
. B% h- o( n# g& x' C! m4 |' r8 s- X2 O
See also : "option httpclose", "option http-server-close",
" {# @. H7 o% ^0 j& p$ H8 l3 H% u+ | "option forceclose"
5 A/ _8 G# M) {6 b
+ w* e, z4 I4 Y; t, B' F9 [1 I7 d% w9 x! x
option http-no-delay; f1 F, B d) J+ y$ N& C7 ^7 E
no option http-no-delay
) P" @" d3 D+ v& g Instruct the system to favor low interactive delays over performance in HTTP
( w% ]6 e3 e: D May be used in sections : defaults | frontend | listen | backend
) f. s/ I" q$ z* r* v J- U9 ^ yes | yes | yes | yes
+ U- y, Z" }. _9 }7 o. O- t) @ Arguments : none2 I( w" ]% Y+ q+ t+ G
# }) s. x O& A7 H& f$ U8 `
In HTTP, each payload is unidirectional and has no notion of interactivity.
' H, T% _) C+ x7 w: b( o5 o. N Any agent is expected to queue data somewhat for a reasonably low delay.
& a- Z; b" H9 A: m3 o; N$ v There are some very rare server-to-server applications that abuse the HTTP
" }9 |1 I3 X6 ^: L1 } protocol and expect the payload phase to be highly interactive, with many
% N6 C; k% {1 l9 M0 W: s3 S" F interleaved data chunks in both directions within a single request. This is
. p% h+ Z* Y$ c8 O) G9 N absolutely not supported by the HTTP specification and will not work across
- v7 B1 N( T+ n most proxies or servers. When such applications attempt to do this through$ D2 n* K- U! {: X
haproxy, it works but they will experience high delays due to the network
! C- t9 I8 h& F% [1 a+ G/ Q optimizations which favor performance by instructing the system to wait for
9 j( c( w' L- m, D2 c/ N1 ^+ G6 Z, F enough data to be available in order to only send full packets. Typical
% @- A! H2 z( N delays are around 200 ms per round trip. Note that this only happens with' h! R" E; Q# V W7 s+ q" u& G
abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
& D* X* c+ S4 o, @5 r affected.
, O& K1 |* p2 O
) i6 C8 o( \7 d0 ?' x When "option http-no-delay" is present in either the frontend or the backend0 u! L" B$ \; H6 h) B, H
used by a connection, all such optimizations will be disabled in order to) w1 y a0 u4 T6 k- V- t
make the exchanges as fast as possible. Of course this offers no guarantee on
- m+ ~1 a! Q4 l6 r. z the functionality, as it may break at any other place. But if it works via
6 H- v3 v7 h6 [$ c# K4 W; O HAProxy, it will work as fast as possible. This option should never be used# ~4 V. j! i- V/ v9 m8 C
by default, and should never be used at all unless such a buggy application
0 w( Z S4 N/ w1 l8 [$ \ is discovered. The impact of using this option is an increase of bandwidth
6 y/ K0 @; k2 t( ^: D2 a' j8 S2 G usage and CPU usage, which may significantly lower performance in high. D0 u4 f/ s% e$ C* }7 S
latency environments.
) u# ]& D9 y3 f
4 I+ H; z3 ]' C3 A$ w+ p0 i6 v6 @* q0 a$ [- w1 I
option http-pretend-keepalive8 c) d) q2 y7 Z3 D2 N
no option http-pretend-keepalive$ w# v. ~. c6 k: w! ]3 u' D/ W
Define whether haproxy will announce keepalive to the server or not3 ~) _' ]# Q! {
May be used in sections : defaults | frontend | listen | backend5 [6 u8 @8 L0 {1 V
yes | yes | yes | yes
0 X1 a" J3 i; w! H g Arguments : none
* B+ u5 ^( \. k% S5 |- T; H" U6 \9 E8 ^/ o. ~4 b' f9 e/ `
When running with "option http-server-close" or "option forceclose", haproxy
3 U+ |' l6 X* z" f" z% @3 F adds a "Connection: close" header to the request forwarded to the server.! v" j$ V) N. k" [6 B+ |5 A) T( V
Unfortunately, when some servers see this header, they automatically refrain8 U% y# t. }9 X9 K' d; R
from using the chunked encoding for responses of unknown length, while this0 ]- A$ T9 X6 W0 {8 N. @
is totally unrelated. The immediate effect is that this prevents haproxy from6 y; }' G3 B- I5 D6 l; y
maintaining the client connection alive. A second effect is that a client or/ p( b) G( H2 | W1 P4 k5 v! W
a cache could receive an incomplete response without being aware of it, and
/ S7 j+ X6 f/ w consider the response complete.
7 ?0 u% O! f5 k9 a8 \: F
6 Z: @: N" A) v m; b) |5 n% c By setting "option http-pretend-keepalive", haproxy will make the server4 \! X" W# `& i6 E
believe it will keep the connection alive. The server will then not fall back
' u3 B' B' m. ]' }# n: p to the abnormal undesired above. When haproxy gets the whole response, it. `8 [5 | C& _( T: U: h
will close the connection with the server just as it would do with the
' G" T8 t# X! v4 o "forceclose" option. That way the client gets a normal response and the
% C( I2 K1 `& a6 @ connection is correctly closed on the server side.; S0 L3 s0 R, c3 ` Y; K. Y5 l- ^
. o! I& H9 V* ~7 f, z
It is recommended not to enable this option by default, because most servers
1 I. P, C- H# U! K, d, C) P will more efficiently close the connection themselves after the last packet,* `5 M* a% @' U6 y0 k
and release its buffers slightly earlier. Also, the added packet on the. P4 ?9 F: U( H0 i7 c! C$ ]3 ^2 p
network could slightly reduce the overall peak performance. However it is; R# w$ I7 O9 {" Q0 o5 F5 y
worth noting that when this option is enabled, haproxy will have slightly
' v4 {( c8 k! g1 R less work to do. So if haproxy is the bottleneck on the whole architecture,# R6 e0 R& |: f, }* U9 e* |' J
enabling this option might save a few CPU cycles.
- V! q: e/ Y$ x: H' T/ \; O& s+ }6 K* m
This option may be set both in a frontend and in a backend. It is enabled if
3 T3 J8 I% [6 P9 } at least one of the frontend or backend holding a connection has it enabled.
0 h$ q4 G$ W0 ]- G/ {4 Q3 L This option may be compbined with "option httpclose", which will cause7 S# u: |5 e' C
keepalive to be announced to the server and close to be announced to the+ v+ c+ N9 i1 R. f
client. This practice is discouraged though.
- b% C3 y' H6 B `1 I
" L: P( f) i4 k6 g1 J% z If this option has been enabled in a "defaults" section, it can be disabled: E9 n& N* K% c; |. D! B- ^% D
in a specific instance by prepending the "no" keyword before it.
- B% N# _1 a0 N7 ]4 ~- c9 A
+ j/ A: ~& A' ^1 P3 [: C See also : "option forceclose" and "option http-server-close"
2 n/ d& C4 L$ p
+ N0 Y- Z9 Z9 r" [5 \; @. X. a% D9 u+ t/ F5 u" c9 [" P
option http-server-close
$ u% @; G' U% J8 C+ ?4 M& ?4 B) zno option http-server-close8 W X4 W1 g3 E/ Y# n' B4 K, {
Enable or disable HTTP connection closing on the server side
4 U' h N1 X5 m# @8 j9 O+ Q- K* @ May be used in sections : defaults | frontend | listen | backend
3 R/ {2 A2 H9 |9 k- l) i! I yes | yes | yes | yes
& W# h( f* c" z+ d. V1 z C Arguments : none9 T5 {/ s& ^! x
5 v3 _: t. z+ N3 U By default, when a client communicates with a server, HAProxy will only( ]% L& _9 G) E. z: r. q
analyze, log, and process the first request of each connection. Setting+ l% W; j0 r9 t+ t
"option http-server-close" enables HTTP connection-close mode on the server
' y, J6 F; I+ g3 P# D3 H# V side while keeping the ability to support HTTP keep-alive and pipelining on
0 ?5 s7 w, n" z1 Q. \0 ? the client side. This provides the lowest latency on the client side (slow9 @* P, |5 r9 @/ e9 k9 |5 V
network) and the fastest session reuse on the server side to save server
, k8 k8 C6 P* e6 x( V resources, similarly to "option forceclose". It also permits non-keepalive" ^5 C8 d5 o2 M+ p
capable servers to be served in keep-alive mode to the clients if they) K8 i% m* E+ x% {
conform to the requirements of RFC2616. Please note that some servers do not0 O" H# n4 G* }
always conform to those requirements when they see "Connection: close" in the6 Q5 o$ q& Y: l4 R, l
request. The effect will be that keep-alive will never be used. A workaround9 y* V1 C$ E' a6 B$ ]* f
consists in enabling "option http-pretend-keepalive".
& i* \/ x* u2 z' |& X. Q: `2 f. h/ N0 U0 N8 v; [( x
At the moment, logs will not indicate whether requests came from the same+ n& ~0 Z3 d& z" R( Q; s
session or not. The accept date reported in the logs corresponds to the end
+ B' P8 @6 ?/ ~ of the previous request, and the request time corresponds to the time spent
% `& @7 u5 `' y G waiting for a new request. The keep-alive request time is still bound to the5 R" q. j! S# K
timeout defined by "timeout http-keep-alive" or "timeout http-request" if
9 |" X1 `) E' H not set.
+ T" T$ I. v! F5 K
- _: |/ H9 U3 ?) I& C( F' g This option may be set both in a frontend and in a backend. It is enabled if
6 r& u/ y, ?, f! k3 `6 R at least one of the frontend or backend holding a connection has it enabled.
" ^9 M2 f5 l0 N$ c$ u0 H4 G It is worth noting that "option forceclose" has precedence over "option+ L/ y6 X% M& z& C
http-server-close" and that combining "http-server-close" with "httpclose"
" A$ @2 h2 M$ m$ Y- B: ]1 L basically achieve the same result as "forceclose".
; v& ~) z5 b3 R
3 l' R2 o$ Y! A7 O If this option has been enabled in a "defaults" section, it can be disabled
: Q7 H" ^5 ?4 h& T; X# R in a specific instance by prepending the "no" keyword before it.
5 c+ F3 @/ N9 U! Z0 ^
) c2 g# F2 {% t! D( w' U See also : "option forceclose", "option http-pretend-keepalive",8 o9 w J9 O: @ P6 } h1 ~
"option httpclose" and "1.1. The HTTP transaction model".
* q/ U% h* {4 `7 g) u: [* _
- m K! W, i+ n* X2 @. d0 [' n/ O5 x$ d! K& l
option http-use-proxy-header
# ~& _ k/ n1 X2 \4 ]+ ]% ]no option http-use-proxy-header6 t t" m8 T n. D1 U0 }# t- h) j8 `
Make use of non-standard Proxy-Connection header instead of Connection; t5 P* t7 I* l+ D( O- Y
May be used in sections : defaults | frontend | listen | backend+ k$ b( |1 l1 k. R! |) @
yes | yes | yes | no* d/ ]4 t7 u9 h# _8 ]5 j7 }
Arguments : none
+ v4 S& p& p4 ]
/ p2 ~% k4 o& M% w While RFC2616 explicitly states that HTTP/1.1 agents must use the4 C4 E: v; R D* s( W( g! U
Connection header to indicate their wish of persistent or non-persistent
' c% U& n$ G( x& G connections, both browsers and proxies ignore this header for proxied7 `2 U$ d! B- |* e. ?* q4 Z
connections and make use of the undocumented, non-standard Proxy-Connection
; A. l) C1 s7 x$ A- h( ^" e header instead. The issue begins when trying to put a load balancer between
) {- n/ K: w- s( c browsers and such proxies, because there will be a difference between what2 k, p( F! @- o" M2 o; h2 b2 B
haproxy understands and what the client and the proxy agree on.: p0 c4 x* [" H" ~
6 N1 q# a5 F0 X* n
By setting this option in a frontend, haproxy can automatically switch to use1 s; E' R2 X8 b1 Z
that non-standard header if it sees proxied requests. A proxied request is- Y9 p3 Y5 u, m+ {
defined here as one where the URI begins with neither a '/' nor a '*'. The! ]' x: @9 c, l& F5 L
choice of header only affects requests passing through proxies making use of/ s" X/ P2 _; b1 z
one of the "httpclose", "forceclose" and "http-server-close" options. Note+ U3 ]/ d; w' v2 s
that this option can only be specified in a frontend and will affect the
2 Q- U2 B5 A: C- O request along its whole life.6 C* x: }! l0 o. {4 E
& [7 T# C! [, T4 O) C Also, when this option is set, a request which requires authentication will& V, r9 F' M6 o
automatically switch to use proxy authentication headers if it is itself a
9 d& w [2 t4 z; @+ C7 a8 {$ d3 B* G proxied request. That makes it possible to check or enforce authentication in
' W% R F9 \7 F# i; N. i front of an existing proxy.
1 r* n. @9 m) _: v, a; H* A
. n. i" N' {: g" u This option should normally never be used, except in front of a proxy.
* k; o: q- f. n( |4 H/ D* j
0 k5 D f5 k" u8 l See also : "option httpclose", "option forceclose" and "option
! T( Z% c6 d! S' i0 J6 y7 f http-server-close".- h% Q% Z. l t" q, ~7 C; s
* _: q; r( c" b; Y0 S
0 l: Z( B- p5 m, f3 W" m. b) ~( e+ o% |option httpchk
6 X' S1 F$ D1 v5 ^5 Soption httpchk <uri>
7 V# Y1 ?( O1 `5 w2 X* {; ?option httpchk <method> <uri>
5 g) k2 d+ U a$ U' O6 n) p2 Coption httpchk <method> <uri> <version>7 p# P1 F! l$ O" D% X
Enable HTTP protocol to check on the servers health% w6 g& R" C, r# n" V6 i& u$ U
May be used in sections : defaults | frontend | listen | backend4 k% W( _# f" R4 \* P9 x4 p
yes | no | yes | yes; `! s: U$ J( V
Arguments :6 d9 n: U- ]$ q
<method> is the optional HTTP method used with the requests. When not set,
; W! g; |+ t& K w+ g8 t( W; J- o the "OPTIONS" method is used, as it generally requires low server, [5 K7 X% H8 u
processing and is easy to filter out from the logs. Any method
+ K7 S' a/ K# |8 z/ s ~$ ~ may be used, though it is not recommended to invent non-standard
- Y6 W- O8 {* c8 H0 Z8 ? ones.7 Y1 u5 k; ]7 `& e3 J1 |
2 K/ K p, I& u& N) b' `
<uri> is the URI referenced in the HTTP requests. It defaults to " / "' t9 {; x f4 T! |) w
which is accessible by default on almost any server, but may be3 y( n" [8 n) U
changed to any other URI. Query strings are permitted.
% \" O! C* p. H2 `" M* l) T! H' I7 J. I* p6 e- S0 w( z a
<version> is the optional HTTP version string. It defaults to "HTTP/1.0"
, n# a/ ~! j: N1 a) N% O but some servers might behave incorrectly in HTTP 1.0, so turning
6 {- V$ Z5 Z+ I( ~. f0 X6 h: u6 f it to HTTP/1.1 may sometimes help. Note that the Host field is
" Q4 C0 D" i& w/ L1 N6 z mandatory in HTTP/1.1, and as a trick, it is possible to pass it( f2 }* k6 E2 X0 O* j1 h, |
after "\r\n" following the version string.! M [ K5 }3 W4 v
' a+ ^8 n/ ]/ q$ R. P" o" A By default, server health checks only consist in trying to establish a TCP5 E# z+ G" _3 ^9 \9 a6 R
connection. When "option httpchk" is specified, a complete HTTP request is: l3 ~4 j; u5 k% x& o
sent once the TCP connection is established, and responses 2xx and 3xx are
# U V! B" u* O0 ]1 P. W! C2 g considered valid, while all other ones indicate a server failure, including, a, y( A# U5 ?/ C$ |* J: O4 s' v+ y
the lack of any response.
1 s/ {, M3 G5 S# E' s5 I, u. N8 B% e. f1 T' N' \+ T8 _( M3 O1 e
The port and interval are specified in the server configuration.5 I& O8 t5 ?2 I- ]! b
1 ]) M" l$ \5 V/ c& B This option does not necessarily require an HTTP backend, it also works with
3 b) T1 |9 d/ D& } plain TCP backends. This is particularly useful to check simple scripts bound# B6 {1 U$ j- I# L# l& s2 S
to some dedicated ports using the inetd daemon.. G @: x9 U( ], J( h
5 S- @. K- n N3 O* z: s Examples :) t4 Z3 x0 H6 G
# Relay HTTPS traffic to Apache instance and check service availability
8 L4 r# b7 q V0 ?$ G # using HTTP request "OPTIONS * HTTP/1.1" on port 80.+ s4 [7 k# j' v/ ^
backend https_relay
% S h1 R1 f9 \, h# H mode tcp
5 O" v) c. D; ~2 D5 e# l option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www+ _. p2 w7 s; Z$ f
server apache1 192.168.1.1:443 check port 80
. Z8 ~3 s: o" X% T
7 o# f! `; J$ y& j* Q! [/ B See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
3 |$ C, f' }3 W6 h9 `9 u+ L "http-check" and the "check", "port" and "inter" server options.8 ]' T% u" L4 y" o
+ t) C! d1 X( u: V0 T
% I& T! n# l1 z1 M. A/ Ioption httpclose
) {! }: r# Y% pno option httpclose; d/ R( o4 B9 H- X; l. s
Enable or disable passive HTTP connection closing
* x! c, B& F1 z May be used in sections : defaults | frontend | listen | backend2 E3 @6 A: ^: q5 m- O1 A
yes | yes | yes | yes3 M @; B, ~+ ^
Arguments : none
6 J8 K# U M+ T2 a$ t7 t/ Q, Y* f6 }9 W/ Z
By default, when a client communicates with a server, HAProxy will only' J; n4 m. I$ d' X7 f$ g
analyze, log, and process the first request of each connection. If "option
6 F1 q( S3 r$ _6 { httpclose" is set, it will check if a "Connection: close" header is already
+ M! Y4 K F5 U) x x) { set in each direction, and will add one if missing. Each end should react to/ ] z; y* D: B2 `* x! Q
this by actively closing the TCP connection after each transfer, thus) W9 R4 ~* \2 l) j; U6 X9 u
resulting in a switch to the HTTP close mode. Any "Connection" header0 k1 d, v [6 @
different from "close" will also be removed.
1 y4 E% b) x; E
- q/ G: `( T+ S7 Y) p3 H It seldom happens that some servers incorrectly ignore this header and do not+ x9 S8 K5 q3 p+ f
close the connection eventhough they reply "Connection: close". For this: W: i! ~. z ?9 a4 h. P
reason, they are not compatible with older HTTP 1.0 browsers. If this happens
% f) `3 i! v- ]/ i7 Y/ N0 L3 e" W it is possible to use the "option forceclose" which actively closes the
0 G1 N1 G" R' |# Y3 D$ m4 Z request connection once the server responds. Option "forceclose" also+ J7 ^0 n$ z% o
releases the server connection earlier because it does not have to wait for4 d- D' o6 g3 j1 ]: F* X3 A' g
the client to acknowledge it.: o& A7 `1 b$ g& {
7 Q6 l# @9 `# e This option may be set both in a frontend and in a backend. It is enabled if
% W- s) l5 H/ F8 ^2 e6 K at least one of the frontend or backend holding a connection has it enabled./ u; V2 p3 u$ Q4 m& e+ e
If "option forceclose" is specified too, it has precedence over "httpclose".
9 K, k( Y: I% m) ~" Y. F If "option http-server-close" is enabled at the same time as "httpclose", it
( Y7 t, V5 H9 _- H; W7 J1 P basically achieves the same result as "option forceclose".
6 M: ^) f( g/ [2 J4 g5 t; h" D' D( g* y# l9 R
If this option has been enabled in a "defaults" section, it can be disabled/ J4 `1 T' ~( ^+ G; S& W
in a specific instance by prepending the "no" keyword before it.$ Z' V% [' m9 | n! `1 V h
, W/ {0 C) T0 A: i+ T
See also : "option forceclose", "option http-server-close" and4 {. S( E( w4 k4 d3 k! N4 o
"1.1. The HTTP transaction model".3 b8 G0 X% i/ a8 n- V; X" T
6 x3 @/ u% z' t5 }3 u/ e! i
( u% v+ B6 w1 _6 A$ i! noption httplog [ clf ]
/ h2 ]; S5 U1 U4 \ E Enable logging of HTTP request, session state and timers
2 o, u. m X$ }; } May be used in sections : defaults | frontend | listen | backend! K! p( F( _) Q B
yes | yes | yes | yes
/ ^/ J0 G) p+ }3 d Arguments :
! {! w' q+ {$ ?) c% I7 I clf if the "clf" argument is added, then the output format will be& P5 v0 D5 o9 u1 a5 t7 K$ ~! p
the CLF format instead of HAProxy's default HTTP format. You can$ b2 M; Y0 E7 h u v
use this when you need to feed HAProxy's logs through a specific, ?! Q# ~/ {4 Z$ u1 [
log analyser which only support the CLF format and which is not
" {! H( f& { Z extensible.
% T/ J }( p. y6 x; _
8 [6 G' m( Z# X By default, the log output format is very poor, as it only contains the ~0 e! X; ?8 k/ w+ P
source and destination addresses, and the instance name. By specifying& M2 x1 }) o4 j( H- L+ R
"option httplog", each log line turns into a much richer format including,
0 }) {8 `, F+ C7 T& y1 d. t! x but not limited to, the HTTP request, the connection timers, the session
' x/ Y* C j- s7 u2 Z status, the connections numbers, the captured headers and cookies, the
! `% m1 ^6 g; g frontend, backend and server name, and of course the source address and
$ s& M: V+ ^7 G7 K0 e3 i' G, m ports.9 E; H; R C V; H3 a& S/ O
* S p/ ]9 W2 m! U0 p
This option may be set either in the frontend or the backend.0 a; Z3 u% k- G6 A7 k
8 @9 R X0 Q) B
Specifying only "option httplog" will automatically clear the 'clf' mode5 t, u$ y, ], w5 P! I% ?$ D
if it was set by default.7 \. E8 C3 c7 X$ f2 Y' L' }
6 h' g- O1 D1 Z See also : section 8 about logging.. A. x ^' Q9 ?' b' n
' B: Z+ a0 r' w$ `9 ]$ ]
8 \8 P8 z3 H) r6 R: Voption http_proxy+ P; d* R6 o, J% q
no option http_proxy
, o0 e2 A! c+ Y9 i( z5 X X! n! E Enable or disable plain HTTP proxy mode
a# O( {# G- G1 d* r K) f( a- U May be used in sections : defaults | frontend | listen | backend' y6 B& X0 J/ d$ |5 O" a) o$ I
yes | yes | yes | yes8 R7 K% U8 U( Z) T a7 W
Arguments : none, s8 T# u7 h0 Q6 z/ Q2 W
, [3 Y Q$ R2 t. Y6 D+ V* {% C It sometimes happens that people need a pure HTTP proxy which understands' V* \0 b, N8 T7 W
basic proxy requests without caching nor any fancy feature. In this case,( ]$ X8 u: ^( Z- o" J
it may be worth setting up an HAProxy instance with the "option http_proxy"+ Z- a$ ]+ ?: w
set. In this mode, no server is declared, and the connection is forwarded to
0 R- \/ I; E" A. n& X3 W' f the IP address and port found in the URL after the "http://" scheme.
# v/ ]6 O9 c# ]! m' _- O7 _4 K3 g8 G8 Y4 y/ U$ ]+ b- t2 h
No host address resolution is performed, so this only works when pure IP
2 Z+ q: c/ l: @! A addresses are passed. Since this option's usage perimeter is rather limited," e$ r6 Y! B& N+ t6 i
it will probably be used only by experts who know they need exactly it. Last,
7 I# ?9 J9 ^9 d& z: a if the clients are susceptible of sending keep-alive requests, it will be: _7 L' U6 d6 m* i$ L6 z$ I
needed to add "option httpclose" to ensure that all requests will correctly
4 E1 X1 N& I5 G4 l; C6 e- } be analyzed.5 D8 H! E L* A1 N+ \' r; o8 E* }
0 v3 a5 O3 ^* m0 G: H If this option has been enabled in a "defaults" section, it can be disabled
/ W% X" x# T; _ B) k3 W5 ~ in a specific instance by prepending the "no" keyword before it.
* \+ ^- K9 g1 M
2 c7 L8 B) A B9 G- Y Example :% x! C9 u0 \/ m
# this backend understands HTTP proxy requests and forwards them directly.
0 {. L3 N9 Y( X backend direct_forward* Y$ h3 o+ N! r0 \
option httpclose
& L9 D* L' D( B' k! m( n option http_proxy
s1 V5 q7 R1 ` R! H6 m5 L) m7 V( i& H2 O" c
See also : "option httpclose"
4 ?( P- F; z* {. b
5 {9 A, \' N6 [: ~* y3 C6 D7 }) r6 O0 k9 g; A* \: W& A) j6 A
option independant-streams
+ X! m" |; A: m; ~no option independant-streams
, N, P; h: e0 _0 r( g/ r Enable or disable independant timeout processing for both directions
" X+ l* p7 B# p q$ m: j May be used in sections : defaults | frontend | listen | backend
) V- Q- a8 R, a2 n4 Q6 m4 v( ? yes | yes | yes | yes+ R8 d) p2 E5 L+ C
Arguments : none
; A) l' z3 d' G) d( U5 Z. C! @# O5 f
By default, when data is sent over a socket, both the write timeout and the
2 Q; a. j" C) O# }# g" P read timeout for that socket are refreshed, because we consider that there is
7 a& d8 ~" u% u/ k$ a5 X activity on that socket, and we have no other means of guessing if we should6 e: e( G4 Z: {2 X& x: c
receive data or not.& i% a' Q) M4 i! S! T7 ~
* Q5 n o8 c8 W
While this default behaviour is desirable for almost all applications, there) F5 c: O3 K& ]! _( `
exists a situation where it is desirable to disable it, and only refresh the
* t4 {6 D. J4 g. ~ read timeout if there are incoming data. This happens on sessions with large! ~: n7 h! `6 O/ {+ S/ d2 \
timeouts and low amounts of exchanged data such as telnet session. If the
. e3 f( D" T6 k3 ]( o* u$ N3 e3 _ server suddenly disappears, the output data accumulates in the system's6 m5 ~& y* A: K N
socket buffers, both timeouts are correctly refreshed, and there is no way
1 N- _9 p0 T+ R to know the server does not receive them, so we don't timeout. However, when
: ?9 Q6 T9 s8 Y1 w4 @( s8 Z. ] the underlying protocol always echoes sent data, it would be enough by itself3 I# I$ O- E2 [+ h( j s
to detect the issue using the read timeout. Note that this problem does not
8 ^: o/ A$ p4 F/ `$ o happen with more verbose protocols because data won't accumulate long in the
J& d2 E/ P$ Y: p) J4 G socket buffers.- r9 ]9 `- F0 M& j" i, L9 X
% U- g- t0 L1 m& c+ ^3 Q/ |+ f1 U u When this option is set on the frontend, it will disable read timeout updates$ ~- `1 y* R y
on data sent to the client. There probably is little use of this case. When
0 S! ^0 ~# x& G the option is set on the backend, it will disable read timeout updates on
X9 ]; A1 @8 r8 W data sent to the server. Doing so will typically break large HTTP posts from
b: V+ v0 ~- F slow lines, so use it with caution.
5 u) k" u0 @) W# F' @$ @$ K8 D2 f: U
See also : "timeout client" and "timeout server"
1 |0 }8 F5 A$ f$ k7 a
( c: |8 @. A3 D) i
( M& v# q1 s; R9 L) I8 Ooption ldap-check( Y" X$ n: p0 _; R# {
Use LDAPv3 health checks for server testing
5 c1 [5 r! p+ `: p- ]' W May be used in sections : defaults | frontend | listen | backend/ j( b8 s4 V1 h0 V6 s+ [
yes | no | yes | yes
9 Q0 n: b2 j) M5 a* U0 d w6 t' t Arguments : none+ M" N8 ~7 b% d. v9 R3 O$ m
1 \8 I$ y) K5 [% [8 ? It is possible to test that the server correctly talks LDAPv3 instead of just
" T5 s( `/ Y" _, H testing that it accepts the TCP connection. When this option is set, an
8 Y- u, ^% q$ T0 z5 S9 S LDAPv3 anonymous simple bind message is sent to the server, and the response5 e; @9 T9 a- w5 z$ t3 M- O
is analyzed to find an LDAPv3 bind response message.
) ~) Z$ q/ c8 w# f) R# G( J9 o# u: D- S1 g! c8 U
The server is considered valid only when the LDAP response contains success6 w% ?2 \ a. J* @+ ~; m3 G
resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).% i5 h, a( U/ c/ S# F$ k" ~( Q, i
" l# |5 J5 _* h9 v o Logging of bind requests is server dependent see your documentation how to3 R* b$ ?* R0 a& N
configure it.
" T0 O5 P; s S) I$ Z' X' c" i: Z: V7 S8 j' F& k
Example :
3 Z- N4 }. b5 U+ Y0 ?- M option ldap-check
! y" z, r, B4 _5 H! g( h: w: @% D- @% k! j! F
See also : "option httpchk"4 \& U3 D Z. H
* w$ g" T5 q- ~3 e, ^3 l) K" t+ i
8 v8 j' |+ j1 i0 p) U6 Koption log-health-checks
7 J' i: r$ X; i$ m6 | y+ D Tno option log-health-checks+ G" f/ f' f/ u) y, P* B, Q; {3 T. T* `9 M
Enable or disable logging of health checks
' @; ^# Q) E( y4 r- Y" d May be used in sections : defaults | frontend | listen | backend6 {6 Q! v* _# t% \
yes | no | yes | yes
4 {2 ]5 A3 \& y6 c Arguments : none, S1 i8 ~: L0 P7 \( }( I
0 \: P+ ]1 ^1 @% A) h8 Z. s9 y
Enable health checks logging so it possible to check for example what
2 m. k0 J. ^" n was happening before a server crash. Failed health check are logged if
. N! @. ]3 X+ w3 j4 ^" \ server is UP and succeeded health checks if server is DOWN, so the amount q" |- Q# H, B" c4 o
of additional information is limited.
7 \" ^; D+ r1 B+ O7 w3 T; @
& ^% K6 G; J% E. K2 x1 c. m% ^ If health check logging is enabled no health check status is printed, _7 }; a* F4 m
when servers is set up UP/DOWN/ENABLED/DISABLED.$ L- a# ~# ]6 g- t0 y+ u
# q, p* l7 M2 `& W See also: "log" and section 8 about logging.0 q/ |5 U0 M1 I/ p4 R
1 J9 v ^7 x# i$ _% o; x: d7 E
4 _# l4 x8 O4 @( o7 Uoption log-separate-errors2 q, g8 D( i4 B1 J( A
no option log-separate-errors: P' p( k1 ^( O
Change log level for non-completely successful connections9 |6 m. v3 h0 ~; x
May be used in sections : defaults | frontend | listen | backend
8 h, l9 d/ L+ m yes | yes | yes | no7 {0 H+ I0 l$ T! G& d" {1 {
Arguments : none
' l( l$ H1 z7 o6 Z- o. b0 M0 \5 w: A0 E4 m
Sometimes looking for errors in logs is not easy. This option makes haproxy( U* o- h2 D' F6 v+ Q" U
raise the level of logs containing potentially interesting information such# c* }, B4 _! J8 ~
as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The
0 z6 i$ g) K* X% n- \ level changes from "info" to "err". This makes it possible to log them
% O: A0 A- ~/ Z1 Q separately to a different file with most syslog daemons. Be careful not to
4 Q$ f" Q u B6 q( y remove them from the original file, otherwise you would lose ordering which# _. v1 K& t$ e" s5 w1 ?
provides very important information.
% N) a) z7 P4 e! y. y% t3 }
, {; _$ P5 h# j# U- P4 t7 D& J Using this option, large sites dealing with several thousand connections per) w! M2 k( q' K/ |. z
second may log normal traffic to a rotating buffer and only archive smaller2 n. Y/ Q: _# l/ R* @0 [* t
error logs.8 M! ?$ A G7 G) E
+ i% T! @0 v5 K; ^
See also : "log", "dontlognull", "dontlog-normal" and section 8 about }, K$ V& q- x3 b# ~, e* q7 t& r% B
logging.
; z( e7 K! L2 e x: { I R/ W* S6 J3 G" X
1 E! h. r$ c* j( `/ {3 r* g8 {7 [option logasap
2 ~6 k6 F/ H. |) zno option logasap
, W. U n; I; n0 l2 v8 w' x Enable or disable early logging of HTTP requests
8 }+ s9 R' D% K# h5 z4 J May be used in sections : defaults | frontend | listen | backend
/ h# V7 _' j8 g* r2 \3 [8 r0 P. Z yes | yes | yes | no& S! ~8 |9 y6 C r8 Y/ x
Arguments : none; P) ]3 p" o, p$ M% S
( X" j' E# X# Q4 A4 _$ T; t5 R
By default, HTTP requests are logged upon termination so that the total" B4 C. ~, k. \- Y0 [" f+ R. r/ j
transfer time and the number of bytes appear in the logs. When large objects, _, D. h0 s! k& f, r, V$ [" t
are being transferred, it may take a while before the request appears in the+ I$ r, N0 u! I4 ~
logs. Using "option logasap", the request gets logged as soon as the server+ m! _' N3 Y" p
sends the complete headers. The only missing information in the logs will be2 S+ P$ M) G- G! S
the total number of bytes which will indicate everything except the amount
7 J: b) n( p4 W: N7 `7 c of data transferred, and the total time which will not take the transfer
2 b2 x }. {6 k* v0 q time into account. In such a situation, it's a good practice to capture the
% @/ B: h. Z+ D; K) X/ J( }# K "Content-Length" response header so that the logs at least indicate how many
) z3 Z7 ~- F8 M1 {* g, @; x. y bytes are expected to be transferred.
+ r/ m9 t. o5 Y& c4 V8 e T; H* p& R* X: c5 h
Examples :
) d, f* F. F. L$ T listen http_proxy 0.0.0.0:80
' r% Q# j( g) k3 x) u mode http% A! f- ]! q b4 d6 @: A$ w1 o( U
option httplog
3 ~: Q- Q0 g/ e# I, w, _ option logasap2 N1 L4 k! G, g) m
log 192.168.2.200 local3
. v+ r1 e9 ?, Q' d6 f4 [8 p. Y# h- d3 O2 z4 c; U+ e
>>> Feb 6 12:14:14 localhost \
; H" w9 U/ a' N" J/ Y8 {. L7 s haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
" S& u4 z# V5 ]5 I9 A static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \
# t# {! K1 }2 N4 f "GET /image.iso HTTP/1.0"
( \" I7 }6 a2 n
# o3 |# F1 u- L# H See also : "option httplog", "capture response header", and section 8 about* i8 l7 _0 m8 c
logging.
6 z& ^- h$ [/ Z1 i2 Y$ b" _ t! E
' g3 s! E& {/ c, Y& y# J7 A7 h4 n
5 e3 t r" }# k& v9 \( toption mysql-check [ user <username> ]) I ^1 f0 ~+ S+ j/ @/ r" G
Use MySQL health checks for server testing& T; M3 l& R! J, k/ r
May be used in sections : defaults | frontend | listen | backend
. S6 x) f9 g: g6 A5 p$ h" b yes | no | yes | yes* h. h+ D, x" I7 i* d
Arguments :
3 w% }) w9 L, \0 d6 r <username> This is the username which will be used when connecting to MySQL/ e' \; X9 y( p0 j: L- U/ x+ N
server.
* G* K& L* w' Z
* s4 t, r+ Q# u+ h* d# }, E4 R/ y If you specify a username, the check consists of sending two MySQL packet,
5 B! F2 @) D# Z% j6 ]+ L0 h one Client Authentication packet, and one QUIT packet, to correctly close
% `0 u- R: `4 ]3 A. y$ T& R ?, y8 X MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
% O5 u; B G6 @ Error packet. It is a basic but useful test which does not produce error nor
4 M9 `0 S3 V, V7 z( o# r. k aborted connect on the server. However, it requires adding an authorization: v. e' ]/ }9 ] \$ e" o" q
in the MySQL table, like this :
3 {! v( u7 Q7 H0 i) m3 Q$ ^2 Z I( Q6 z$ l( \+ ~2 ~4 |
USE mysql;
- ^( [5 R" k3 M+ z {, M INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');8 T) G! ]+ @4 f% [, t2 N1 y3 ?. s
FLUSH PRIVILEGES;. }+ k: Y* G3 k% M
6 e& M+ E" C, Z" Z b; F( u+ l) h$ [
If you don't specify a username (it is deprecated and not recommended), the
1 ~& ]0 {$ f4 n7 e% n check only consists in parsing the Mysql Handshake Initialisation packet or g+ W9 c2 e* d4 _+ C. c+ m- @# w
Error packet, we don't send anything in this mode. It was reported that it
' c# ~: {. k) {: @4 C& p can generate lockout if check is too frequent and/or if there is not enough
2 N$ q# l8 H: Z; f4 j traffic. In fact, you need in this case to check MySQL "max_connect_errors"9 [" |: q( g- O& p( J& p
value as if a connection is established successfully within fewer than MySQL, O& q6 m! H- ?3 G: ?
"max_connect_errors" attempts after a previous connection was interrupted, q; e4 d; r8 |2 D0 ?# ?3 h. L
the error count for the host is cleared to zero. If HAProxy's server get# i- F: m! Y3 \1 x
blocked, the "FLUSH HOSTS" statement is the only way to unblock it.
c/ F$ u+ G% n) b# y" W+ n8 E, T- H: m+ k8 h3 }
Remember that this does not check database presence nor database consistency.* h" {0 C( w! q& v1 `4 Y# h
To do this, you can use an external check with xinetd for example.. j6 C; K' x$ J7 X3 I# v
1 W* c8 A8 Y9 h/ Y* b) Q The check requires MySQL >=3.22, for older version, please use TCP check.
7 N- ]1 M. C( }8 d8 [; ?8 [! |9 W# D1 [, n
Most often, an incoming MySQL server needs to see the client's IP address for
8 G9 L1 l( Q- t, d" D various purposes, including IP privilege matching and connection logging." f3 V5 v$ }- q: A
When possible, it is often wise to masquerade the client's IP address when Z+ R9 r2 u: r& ^1 i% ?8 x
connecting to the server using the "usesrc" argument of the "source" keyword,2 y* K1 ?* N2 l4 q& p
which requires the cttproxy feature to be compiled in, and the MySQL server6 L% {9 t+ Z* X% S4 O& ]3 V
to route the client via the machine hosting haproxy.
0 h5 H% o' X+ ~ I# ^( G4 B3 ?0 T" r0 ?, p2 T3 i9 e
See also: "option httpchk"
6 T6 h# u# l1 H) r0 i# `5 |, a' M
# q0 a& \- [3 t: y4 c7 _
, Q' N+ T. G! B8 W3 v1 e& }option nolinger$ M Z5 x2 v- ~5 W+ R% M
no option nolinger
9 p$ R& U3 V a) x Enable or disable immediate session resource cleaning after close+ P) a% Z t# k- U) O
May be used in sections: defaults | frontend | listen | backend
, a# a# b' s) ~ yes | yes | yes | yes
; |9 l2 O. x! v# p Arguments : none, x! v* M6 \$ A+ x7 @
4 o( e+ R+ Q9 u. w" h" c When clients or servers abort connections in a dirty way (eg: they are
# p, P7 H0 i# c6 N physically disconnected), the session timeouts triggers and the session is
C1 n# D4 P/ G) w* G( v closed. But it will remain in FIN_WAIT1 state for some time in the system,
$ H) X& Z( ^/ l" o" a/ c/ V' s+ { using some resources and possibly limiting the ability to establish newer
8 l* ]! m C9 O connections.. p6 S0 P d# j
$ ]% N8 Z1 G- h2 Y3 f+ I8 q. m When this happens, it is possible to activate "option nolinger" which forces
1 u# t/ a, y* K, g7 W2 ^ the system to immediately remove any socket's pending data on close. Thus,
( m; K6 \; e7 {6 I! D- P( j" n the session is instantly purged from the system's tables. This usually has
1 W6 c! ?6 \% R. r. S4 d side effects such as increased number of TCP resets due to old retransmits& G, q+ \/ w- y* D* W1 c! J
getting immediately rejected. Some firewalls may sometimes complain about
. P3 ]8 X3 `0 v# Y$ ]7 ]# | this too.
- o# s' y1 y, v* }7 Q! r8 u2 o
For this reason, it is not recommended to use this option when not absolutely9 u+ a7 @7 H4 T5 ] f$ A) ?1 G8 h
needed. You know that you need it when you have thousands of FIN_WAIT15 N; ~* l7 t' [
sessions on your system (TIME_WAIT ones do not count).
# V% X+ D; O6 ]9 d6 q: |4 \! f
+ C( W( h) t2 A0 |& T8 t( @ This option may be used both on frontends and backends, depending on the side
- l; |) M @- a where it is required. Use it on the frontend for clients, and on the backend4 o- b; ~4 p9 y6 N
for servers.
; a7 V) N; V: |+ `) N5 E$ v. ~# @, I& D" f' U, [5 a E
If this option has been enabled in a "defaults" section, it can be disabled
6 ?' K% O- `& Q7 g; J: v in a specific instance by prepending the "no" keyword before it.
) S, o: j) A; I" D5 e
' g. r$ ]8 |5 F$ d0 ?# D. ]5 l/ N3 V9 \
option originalto [ except <network> ] [ header <name> ]( k, u. B' E0 ~
Enable insertion of the X-Original-To header to requests sent to servers
" J0 W0 U0 B. f% X5 L May be used in sections : defaults | frontend | listen | backend1 }/ V) [8 Q0 g4 X: D' q
yes | yes | yes | yes
4 Z9 T& w. J. n' ?, D j% Q* S6 W Arguments :
6 p5 W( u: x/ L$ @* |) X <network> is an optional argument used to disable this option for sources) A3 h+ @% R" j* T1 |) C. y; H" S) E% ]
matching <network>; U3 i" S9 @& s2 s+ Q1 G) Z8 S6 H/ i
<name> an optional argument to specify a different "X-Original-To"
% r9 ~5 v g5 \6 D5 M% r# @2 w header name.
/ P: ~5 D \* ]1 {
; W, V4 Y$ w: o+ {$ f Since HAProxy can work in transparent mode, every request from a client can
. R/ L$ ]( O' y( t% F( ?0 U! T be redirected to the proxy and HAProxy itself can proxy every request to a
, B3 J) y, @& B& g! e# b, I @ complex SQUID environment and the destination host from SO_ORIGINAL_DST will% c$ h# G& ?& N, C/ c
be lost. This is annoying when you want access rules based on destination ip
; a j" e, [8 d$ g- r addresses. To solve this problem, a new HTTP header "X-Original-To" may be
. o6 S+ N+ P: w$ i- \ q" T; ? added by HAProxy to all requests sent to the server. This header contains a
" J" [' ?8 I6 [; ~: c( X value representing the original destination IP address. Since this must be0 Q! J) p4 w3 h7 U h8 l3 e) v
configured to always use the last occurrence of this header only. Note that9 u- d5 C0 L! ?; @$ x! _5 l
only the last occurrence of the header must be used, since it is really
" T8 A4 M' ^) n( ? possible that the client has already brought one./ e$ J' r7 a ]7 k
( j9 F) ]7 ]$ L7 c
The keyword "header" may be used to supply a different header name to replace
; F7 X( V; E8 _) R9 w" o the default "X-Original-To". This can be useful where you might already% f, J; C# m( o5 G' Q! B
have a "X-Original-To" header from a different application, and you need- y# p4 ^% T( O
preserve it. Also if your backend server doesn't use the "X-Original-To"& \. t. v( D. ]- a2 X
header and requires different one.( ]3 _. F. W' N
- W8 E0 o5 S: b. G
Sometimes, a same HAProxy instance may be shared between a direct client! [# {- q0 i* N, Z
access and a reverse-proxy access (for instance when an SSL reverse-proxy is
' J$ A+ v' Z5 @# m/ z used to decrypt HTTPS traffic). It is possible to disable the addition of the, l Z/ C( w. ^* m" I
header for a known source address or network by adding the "except" keyword# S0 R8 j: q6 H0 @- x
followed by the network address. In this case, any source IP matching the Y/ m9 q4 A4 U+ r7 ~5 `- ~
network will not cause an addition of this header. Most common uses are with
' q0 n! _+ u, P7 } ^3 V private networks or 127.0.0.1.
! E2 o: o, @% X0 U# T! B1 w1 ^; T+ {" j6 b! f1 P
This option may be specified either in the frontend or in the backend. If at
% ]! ]. J9 r, I) a b0 X7 C least one of them uses it, the header will be added. Note that the backend's( e: n5 x3 ]8 y( Q) g5 @* \2 z- E( X1 R
setting of the header subargument takes precedence over the frontend's if
& A! Y& W/ r: {4 c both are defined.
! F/ ^4 M J, @& U# ?* z1 v- R c0 R9 d0 x% j
It is important to note that by default, HAProxy works in tunnel mode and: h/ ]# m9 |, a- E0 Q! \' b
only inspects the first request of a connection, meaning that only the first
& M v2 H" f R& n$ I: m" r request will have the header appended, which is certainly not what you want.
& A9 w6 k, v0 d/ G- d, \- a In order to fix this, ensure that any of the "httpclose", "forceclose" or! m2 k9 }2 @& j4 h6 `$ B9 L1 f4 x
"http-server-close" options is set when using this option.
9 a+ c6 c- T2 o7 Y# ]" f& j% d) J# z; z, r5 C6 X# o5 q+ d) Y3 C4 [7 {
Examples :
& X3 E5 b) E% @ # Original Destination address% z$ j% O/ Q0 D$ p, o& [- k& J
frontend www& v3 H( O, n) k6 O+ Z
mode http
3 l4 F1 _4 K% Y3 c option originalto except 127.0.0.1
8 N' Y; H7 h. T. Y, z& R5 G J% N: l5 j2 ?# A2 H$ e* o
# Those servers want the IP Address in X-Client-Dst$ B% c: s, P) f& l8 @- r
backend www
" `4 N- z0 R7 G% ~7 ^0 P# W3 G9 { mode http, T2 o) H$ o) f" X8 p9 W
option originalto header X-Client-Dst
- P1 e/ [% ~9 }& g8 m" j
* O5 L0 S$ c& K; F4 Y- k* n" J9 c See also : "option httpclose", "option http-server-close",; W8 A# V E. x# `! {
"option forceclose"
8 |, Z) O3 t' {+ F$ m7 R ^3 b9 N0 W! Y: _. C
& L9 B7 t) u Y$ boption persist
4 {* T, [) ^4 O( z; C) K5 f6 Dno option persist
9 `% o. d4 E, }/ P Enable or disable forced persistence on down servers5 u( T1 ~# } e6 ^* n
May be used in sections: defaults | frontend | listen | backend
6 _6 O8 g6 l1 C: P+ b yes | no | yes | yes" V% W5 f) W& x6 q7 }
Arguments : none* N# r2 i) J& {( `0 n5 ~
7 ?4 u, P1 U+ H Z6 P( i' L/ ~/ ~ When an HTTP request reaches a backend with a cookie which references a dead
5 A5 h' R. O1 ]. g# X' ?, a# Y server, by default it is redispatched to another server. It is possible to) e( T5 D9 Z! b. n" _
force the request to be sent to the dead server first using "option persist"2 b$ V& C% x1 p( ?
if absolutely needed. A common use case is when servers are under extreme
8 @+ n/ c% ~( d/ N load and spend their time flapping. In this case, the users would still be$ {4 @2 o0 Q1 C" r( T% G6 ]1 u
directed to the server they opened the session on, in the hope they would be
$ G0 F0 Z! S% O3 u1 k/ R correctly served. It is recommended to use "option redispatch" in conjunction( Y% O7 ^3 h1 }% M1 D
with this option so that in the event it would not be possible to connect to
# \* e0 V8 ^, c9 @ the server at all (server definitely dead), the client would finally be C; r% q/ g: X# {+ o
redirected to another valid server.
9 M0 G. N! B6 r/ [
9 J. ^8 p# C- U$ f! N If this option has been enabled in a "defaults" section, it can be disabled
5 M5 o5 Z/ b! E: E8 c in a specific instance by prepending the "no" keyword before it.
' i6 J6 h. }7 [2 Q( U' [+ Y4 m
- ^- ~% E. G Y. T See also : "option redispatch", "retries", "force-persist"" v' B9 _7 p" m1 s: C) t' Y
' p" i. v. Y3 u/ a% q+ E9 y+ J% }
9 V) ^3 @( W7 W/ [0 ]5 s5 j! Q
option redispatch
h: H! n9 L7 y% Mno option redispatch
3 k! {8 E' o0 ` Enable or disable session redistribution in case of connection failure3 P" `' o" p" [$ D6 r) ^3 A, `
May be used in sections: defaults | frontend | listen | backend
5 W% ]* w9 e s( c yes | no | yes | yes2 ~. H" b: m, h1 n! M
Arguments : none% n" b/ q! o1 S* z/ @% |
* y* @: p' h( n0 Z+ J" F
In HTTP mode, if a server designated by a cookie is down, clients may
) G8 _; N2 A6 j6 J definitely stick to it because they cannot flush the cookie, so they will not
3 l/ d! s! E) t; h: @1 s be able to access the service anymore.
, K; y+ N# _8 y# |, Y
# V1 x5 ?. m [8 k/ M! T/ ] Specifying "option redispatch" will allow the proxy to break their
, Z- E& q) E$ G* f persistence and redistribute them to a working server.
; p9 f( o$ u7 [. m7 m8 Y
# u$ S2 u% a! Q6 C! e7 P" V7 j! k: M1 } It also allows to retry last connection to another server in case of multiple! G: [, J, _1 S4 a$ j" l
connection failures. Of course, it requires having "retries" set to a nonzero
7 y9 \1 d2 Z, b value.( F" D) J M( J L, }
f+ @* I& j. J7 u0 Z! i
This form is the preferred form, which replaces both the "redispatch" and
: w# K2 l M! _; ^+ ?$ v$ g2 r "redisp" keywords.
9 C" g1 t& y" r9 {/ |. T$ F6 ?2 p9 U4 G% ?) A/ `* b) F2 L, s! d
If this option has been enabled in a "defaults" section, it can be disabled
0 W* f/ M7 Y0 W& \& h F in a specific instance by prepending the "no" keyword before it.% c& g2 L$ R) _9 E4 `& d3 e
F2 z9 ?- G( a, k8 V: I See also : "redispatch", "retries", "force-persist"
1 P# x& R8 }0 F7 \! N: C! J6 s' E) z" p0 S) Q; X+ z$ ~
7 w8 z! J) `2 m: s" h5 Zoption smtpchk
% N+ u6 G1 s m* w8 E* t' ^option smtpchk <hello> <domain>2 n% G8 D4 Q% S/ S
Use SMTP health checks for server testing
3 C8 i& O, j) a1 c4 T* L% s& F" i May be used in sections : defaults | frontend | listen | backend
3 Z8 {% e. ^/ z; @; k yes | no | yes | yes% b$ o5 u6 r& N0 _
Arguments :& {: C- S9 y# F! k x; N
<hello> is an optional argument. It is the "hello" command to use. It can
4 V) O3 s3 [! K( w2 j. r. N. ?0 B be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other; H- r/ K h3 |2 n" |
values will be turned into the default command ("HELO").. M, V/ [( I1 Q" i, e2 `: H
- Z" @: G& W% |; i
<domain> is the domain name to present to the server. It may only be: p+ e* ^6 y: W: g& q6 W) y2 {
specified (and is mandatory) if the hello command has been
( B3 n6 x J; g8 i7 T8 h6 M specified. By default, "localhost" is used.( u! _+ _) w4 x
! W5 n- ?9 R0 u When "option smtpchk" is set, the health checks will consist in TCP% v: j2 r' s* N1 t
connections followed by an SMTP command. By default, this command is
# ^6 K+ {# O$ P3 T. N; x "HELO localhost". The server's return code is analyzed and only return codes2 [0 G4 v, x8 }
starting with a "2" will be considered as valid. All other responses,5 h0 {( g: F& I( S/ e
including a lack of response will constitute an error and will indicate a% b( Q0 c; \5 @: Y: M, p
dead server.
2 h: Z2 d+ g1 K. i; [( p* x
1 U/ E2 w. D# M- \/ r$ q This test is meant to be used with SMTP servers or relays. Depending on the
1 q! @! b: A& M request, it is possible that some servers do not log each connection attempt,
1 U% L: Z8 ]& u4 t+ C& _, t1 @( M) T so you may want to experiment to improve the behaviour. Using telnet on port
! ]# {/ e" P% N6 B; r6 A 25 is often easier than adjusting the configuration.7 r7 F g' o' c" a$ b# R
% t5 p3 d1 |( V" N8 s+ ?8 o' {, o Most often, an incoming SMTP server needs to see the client's IP address for" c' r4 ?& \+ M5 k+ n6 Y6 e
various purposes, including spam filtering, anti-spoofing and logging. When) l$ }7 s. {6 m7 s# E; B/ q; n
possible, it is often wise to masquerade the client's IP address when. Q' t6 u {+ H* q! L$ R7 v
connecting to the server using the "usesrc" argument of the "source" keyword,
y @1 l) m7 {2 Q3 o which requires the cttproxy feature to be compiled in.( F2 o; a; G0 O8 d" D& R
- V: v. g D8 f, B5 D" \ Example :
9 A2 c2 \/ A# r; x0 C1 ^" g% W% X+ S option smtpchk HELO mydomain.org3 A# ?% M- s+ S c2 B! ^. ?
. d5 ~& k: s- T) D$ M0 K See also : "option httpchk", "source"
: E, C. @& M2 t7 i. |3 k4 A7 v, h0 F; V& J$ H ^
+ |* c8 f5 M7 c: g+ Joption socket-stats
4 o1 ^, t @0 d& pno option socket-stats; ~3 ^% b3 [2 d0 \: F
& t* B, y; [9 D, A7 \
Enable or disable collecting & providing separate statistics for each socket.
. a0 L( P5 Q1 g2 i" I May be used in sections : defaults | frontend | listen | backend
u9 F' d$ b# ?# \: u5 H5 n+ o yes | yes | yes | no
- i% q" u* q5 _
$ O9 Y9 S4 O+ ?' V Arguments : none( H6 z( C7 f/ F- |( J* w
@# ]& X( W4 l6 n: u2 }; K
8 S' I/ s" S; z# F( a P& roption splice-auto
( ?+ V1 X$ W* ^no option splice-auto
4 a3 w6 E. I7 q8 w, d0 T Enable or disable automatic kernel acceleration on sockets in both directions3 c" Z3 x& L5 \* z2 k, V! Y: L, L& F# [
May be used in sections : defaults | frontend | listen | backend B$ L! [4 `, Z$ U3 ^
yes | yes | yes | yes9 d4 L) |5 G! _2 |! Z
Arguments : none
8 g: E* j- l, D6 z) A
3 I6 r5 Q7 Y4 V, Z, [/ B When this option is enabled either on a frontend or on a backend, haproxy0 z4 j' x% n9 A9 x, ]
will automatically evaluate the opportunity to use kernel tcp splicing to
/ W( J; w5 a+ b! q+ _" t2 _ forward data between the client and the server, in either direction. Haproxy
) }; B% e; j4 M: x: z, u0 }1 X: N uses heuristics to estimate if kernel splicing might improve performance or
/ P( m; H f, h8 ?6 q% h3 Z9 U4 P not. Both directions are handled independently. Note that the heuristics used% s7 V" S* b: Z: Y) @1 D
are not much aggressive in order to limit excessive use of splicing. This
7 e1 c L% @( |- q$ } option requires splicing to be enabled at compile time, and may be globally
$ r( M+ f# E) c: v# C g disabled with the global option "nosplice". Since splice uses pipes, using it
! N; u- d9 k0 Q requires that there are enough spare pipes./ {7 }) e C, R2 I6 \
) |' T+ X V; ]. R$ o4 N J Important note: kernel-based TCP splicing is a Linux-specific feature which
8 z- C' g6 v4 a* x5 ]4 m2 A, q0 a first appeared in kernel 2.6.25. It offers kernel-based acceleration to. T& H+ e% @/ i/ W4 w" W9 d$ s+ J
transfer data between sockets without copying these data to user-space, thus: [, B9 p! ?3 }) o' h* o7 X9 T% h; R! X
providing noticeable performance gains and CPU cycles savings. Since many
8 S. M4 G& \. g: Q5 w/ @: \/ e early implementations are buggy, corrupt data and/or are inefficient, this7 K- a! H) P- F
feature is not enabled by default, and it should be used with extreme care.
! T N' P2 W6 r! J0 c& z9 c While it is not possible to detect the correctness of an implementation,) H- ?* P$ B! o* ]! d
2.6.29 is the first version offering a properly working implementation. In2 }0 b4 ~- t( `1 |9 w0 b0 d0 Y
case of doubt, splicing may be globally disabled using the global "nosplice"
5 G$ |" K7 v0 N2 ` keyword.
) X1 e" o& `/ ]. x$ e/ P& g1 t' ~9 x- W1 Z3 u2 i
Example :! u+ e/ m% r. i1 @7 `* @" C& b
option splice-auto
& I9 w ?9 J6 t3 X# i4 l
7 n0 s; Q, R& i1 X If this option has been enabled in a "defaults" section, it can be disabled/ J1 b) x' B8 X: X
in a specific instance by prepending the "no" keyword before it.
1 S8 Q3 U- I- f- P9 \
$ q6 W8 p% S! ?7 z$ W9 t/ |' Q See also : "option splice-request", "option splice-response", and global
; [. _) N8 ~/ w, m0 D: ^ options "nosplice" and "maxpipes"/ K3 l0 {+ h( `+ ]
7 ^& v- ]) J7 B' ]$ z" ]
. ]9 q& n( ?/ i+ V9 Y. I4 loption splice-request7 r0 O, n; B. [
no option splice-request
7 j$ d1 i x7 `% h0 n Enable or disable automatic kernel acceleration on sockets for requests6 n x& x: U6 B: Y$ T* q
May be used in sections : defaults | frontend | listen | backend
3 s9 Y) S1 K3 k: G yes | yes | yes | yes- a5 z0 g5 ~2 y, [( g# H; }. r
Arguments : none* z6 n6 c2 b; D) h( ]9 J1 S
% Y0 d0 S9 ~) J
When this option is enabled either on a frontend or on a backend, haproxy
* ]" k; U7 d$ Z: I6 `/ Y will user kernel tcp splicing whenever possible to forward data going from l7 N c6 i o9 ~& q$ g# f
the client to the server. It might still use the recv/send scheme if there( F& I% j8 q. r) d; K- O
are no spare pipes left. This option requires splicing to be enabled at# o! j) j- Z9 a! S- c5 l
compile time, and may be globally disabled with the global option "nosplice".6 u0 c0 S+ E" t% `' ~; x6 i
Since splice uses pipes, using it requires that there are enough spare pipes.
. ` w' R! ^8 T4 ^, @3 ~" r" D8 n7 ?# P i+ p
Important note: see "option splice-auto" for usage limitations.
7 j( j, \; O8 N/ A/ B* c# x6 ~1 d0 D3 s8 G& m1 D9 P1 @
Example :6 E( s$ e% H- G. d. [. y' ~
option splice-request
/ Z" d0 }; h" _/ S" Z
# w' M T0 t+ o) x5 U9 ^ If this option has been enabled in a "defaults" section, it can be disabled
! w" B9 H4 v7 a. @9 u, \ [3 Q in a specific instance by prepending the "no" keyword before it.
V5 G& d: [: R; e! q9 }$ ^+ }) ], \! Z5 Z
See also : "option splice-auto", "option splice-response", and global options+ u. m3 ?8 \! V% f/ t+ _) X
"nosplice" and "maxpipes" X0 ~/ Z" y. w' _
2 y; @. t. Z0 O2 r# k9 h" J+ z4 K: H0 c
option splice-response
) k( h# J2 |! v8 a% hno option splice-response; y4 l: W+ `1 t. Y' _# a, ^' C
Enable or disable automatic kernel acceleration on sockets for responses
* F- F( {7 F2 E' m- M May be used in sections : defaults | frontend | listen | backend
7 P1 M3 z+ U; x# I yes | yes | yes | yes
3 i; i6 J' _% ?' j7 u8 T$ d: ? Arguments : none
4 x6 e+ M, m ^
- \4 h& I4 b6 I. A9 n) P) q" `( f When this option is enabled either on a frontend or on a backend, haproxy( S5 O B0 s1 {" j
will user kernel tcp splicing whenever possible to forward data going from
5 q/ _0 p$ o: b4 W2 `% D5 l! j4 n6 n the server to the client. It might still use the recv/send scheme if there8 _8 A# Z' c6 ]) s- j
are no spare pipes left. This option requires splicing to be enabled at' I1 |5 g1 K9 `
compile time, and may be globally disabled with the global option "nosplice".
2 y5 o# w+ O( a/ M6 B X5 ` Since splice uses pipes, using it requires that there are enough spare pipes.$ a( z+ V6 M; V$ q7 T8 r
1 i: B. b" c4 V" k
Important note: see "option splice-auto" for usage limitations.
) Z( T# N& ^9 P& x5 O- ]6 E1 F# o }' w ^7 G U) N; X2 E5 R V
Example :* j+ l5 x3 o0 i$ |" D. A# z8 a
option splice-response) P; Z" p0 t& I; `) ?1 ?5 d2 n0 I
$ A2 t5 Q8 P/ | If this option has been enabled in a "defaults" section, it can be disabled
. }9 z2 N, W& ?( ]* k- {* _ in a specific instance by prepending the "no" keyword before it.' U& T$ i* N4 G6 V! U# B# |1 a
* \" Q3 v7 @$ i q. ` See also : "option splice-auto", "option splice-request", and global options% @3 ]2 L" t4 ^" |" x+ D
"nosplice" and "maxpipes"
K" `3 I( G7 N2 H& o( G: ~9 R
0 j* }# F+ }+ u! r9 r* V, B. w
( A' w. x9 R% ^+ A0 poption srvtcpka" [6 B) R; N8 z2 e1 A+ E0 H5 b
no option srvtcpka
. {; a3 y2 M5 t0 i Enable or disable the sending of TCP keepalive packets on the server side7 @2 @1 P) G& [* h( E
May be used in sections : defaults | frontend | listen | backend
* ^. s8 c8 x( C6 B9 ^ yes | no | yes | yes0 k1 k, G& x, W
Arguments : none
p% g7 `" c1 h! C6 O' }
q( ~" j: F+ p5 Z When there is a firewall or any session-aware component between a client and' [4 W& j) ^# _, p8 b$ }
a server, and when the protocol involves very long sessions with long idle0 t! \: K# s; R6 I( d9 ~5 o
periods (eg: remote desktops), there is a risk that one of the intermediate7 F. I. |4 m+ |1 u( i I, P8 v- h
components decides to expire a session which has remained idle for too long.3 J& C& G9 M! L" A) w6 G
% t% e8 g$ [! G& {3 [9 g Enabling socket-level TCP keep-alives makes the system regularly send packets% Y, ~8 ~+ K0 u1 g; j
to the other end of the connection, leaving it active. The delay between5 m1 [3 P0 ]4 X$ C( n5 N
keep-alive probes is controlled by the system only and depends both on the
$ T2 L% [; f2 F operating system and its tuning parameters.( b, h* R# T! q2 m; C, d/ A
. Q0 c4 f$ h/ [2 W$ e8 q0 P9 W3 } It is important to understand that keep-alive packets are neither emitted nor: K8 y" h6 [$ \" I8 j9 e' K f9 d& O
received at the application level. It is only the network stacks which sees
. z+ |2 q) B+ Q them. For this reason, even if one side of the proxy already uses keep-alives
1 q& j; P9 Y9 w+ r to maintain its connection alive, those keep-alive packets will not be
1 u9 x8 [$ Q8 I forwarded to the other side of the proxy.
: w b/ ~9 u, a0 @- S3 K0 u! Z. I# t7 U" b. e$ I; J
Please note that this has nothing to do with HTTP keep-alive.: s! A6 S6 r# c9 K
; X' F& H0 o/ _
Using option "srvtcpka" enables the emission of TCP keep-alive probes on the: w8 z2 |7 h2 j4 n; l4 L9 m
server side of a connection, which should help when session expirations are1 S9 d7 O+ F7 H& A- D
noticed between HAProxy and a server.6 d8 f3 a" Z' q4 a+ U+ ~
$ @* H. v+ I9 z8 c2 Q If this option has been enabled in a "defaults" section, it can be disabled
' l" E) p" I; e* C& r' m9 } in a specific instance by prepending the "no" keyword before it.
5 X8 L; M- J( Y( m; u |4 A8 a4 N: L Z/ f3 o" h
See also : "option clitcpka", "option tcpka"2 R2 k3 u* t. d0 D
: a6 b& i: P' w, a+ j; e3 ?( ?7 C, M3 C) J& d0 @
option ssl-hello-chk3 b( S8 v2 {) B' I$ F8 a5 V- }5 ^! d
Use SSLv3 client hello health checks for server testing
6 a8 o; L6 K4 i. n/ Z! B May be used in sections : defaults | frontend | listen | backend3 ?+ Q6 p. ]$ @& |4 @3 H3 x* @( p
yes | no | yes | yes
" _# e3 V! u, Q P. U' c Arguments : none
) S! i) r4 D1 M. X0 @1 } @4 a. ^- u5 F6 ?6 s- \. X
When some SSL-based protocols are relayed in TCP mode through HAProxy, it is
* M- L/ S d% H4 P9 d( N; O P possible to test that the server correctly talks SSL instead of just testing
$ A7 [3 M( c0 Z+ g that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure
w) p3 C3 n1 m( v9 M! N$ {4 y SSLv3 client hello messages are sent once the connection is established to
$ K/ j$ v. C6 Y& N2 Z8 a) }; J6 o the server, and the response is analyzed to find an SSL server hello message.) {. D O- Q: _; Y. [% |
The server is considered valid only when the response contains this server
9 {, h1 U' L, h X0 ^3 C hello message.
+ N; F% l+ D, H; o0 W
4 C. O1 T3 L( J' a) ~ All servers tested till there correctly reply to SSLv3 client hello messages,
0 ^8 s4 u. ~/ V5 j and most servers tested do not even log the requests containing only hello
4 N' Q' ]5 \" T' m messages, which is appreciable.
4 E- A. ^7 J+ N- y5 t8 g% {! h1 w4 I
; W0 p) p$ s# W% t See also: "option httpchk"
9 `/ M; y. D- p9 ?/ L8 e% y1 A o
7 E h% G* k# Q. f0 [2 W+ B$ i( j- n" A8 i; q1 `; o# r
option tcp-smart-accept5 n2 G4 }* A' c
no option tcp-smart-accept( e& i4 R6 p; j/ }: C
Enable or disable the saving of one ACK packet during the accept sequence
& J, [. {$ p+ K9 w May be used in sections : defaults | frontend | listen | backend3 r8 j n ]1 o0 |
yes | yes | yes | no& @0 c ]( U' H. s1 h0 v
Arguments : none
; N8 R3 g; q- Y9 B5 M. D0 |: x8 [! p, A
When an HTTP connection request comes in, the system acknowledges it on4 @8 m( T" V7 q5 W2 {; y+ b
behalf of HAProxy, then the client immediately sends its request, and the
# t3 s, P0 i( |: m* n+ P& N: | system acknowledges it too while it is notifying HAProxy about the new
; v9 {' r) z) z' ]4 [- [ connection. HAProxy then reads the request and responds. This means that we
: L( m- X5 q3 | have one TCP ACK sent by the system for nothing, because the request could
+ [6 h, w9 ], V very well be acknowledged by HAProxy when it sends its response.
( U: B9 w0 V1 Z+ J+ E3 \0 `0 y) I$ a1 g m8 s5 H
For this reason, in HTTP mode, HAProxy automatically asks the system to avoid4 `$ e1 }9 C7 t# s" ]
sending this useless ACK on platforms which support it (currently at least; b+ s5 L! n$ `2 N9 J# f
Linux). It must not cause any problem, because the system will send it anyway
x- _, G" x8 [ after 40 ms if the response takes more time than expected to come.$ X% C# Q& w# |4 E5 O7 d- O a
. ^( r: \0 g7 G/ p During complex network debugging sessions, it may be desirable to disable9 ^$ C' F5 U4 b" q |
this optimization because delayed ACKs can make troubleshooting more complex& K$ `+ k$ R, L, m- u; c- S. ?
when trying to identify where packets are delayed. It is then possible to
2 o) u4 R+ m, I# i1 P: W7 k fall back to normal behaviour by specifying "no option tcp-smart-accept".
) z- q4 b! W g1 E. p H& r
: T8 a: T% {( U- U8 b: l0 k It is also possible to force it for non-HTTP proxies by simply specifying6 z! D. w+ n9 D
"option tcp-smart-accept". For instance, it can make sense with some services- C4 L" P. }9 w
such as SMTP where the server speaks first.; G2 T* r. k8 _' u7 [( x
1 w3 Y) ~+ Q+ y% F
It is recommended to avoid forcing this option in a defaults section. In case
" ~* y) K7 h5 j9 {& T( Z, i) F of doubt, consider setting it back to automatic values by prepending the
. O- A+ j- p& v( m, P# I "default" keyword before it, or disabling it using the "no" keyword.
; \0 J- }' y) J! k( L( I% b9 h
0 E- @/ ^2 | u* |' Y* _ See also : "option tcp-smart-connect"
/ F1 Z% p; t( y9 _- F' i
x1 S: {' v1 T1 c- X9 ^
; _9 i3 `+ h# s8 c5 x* xoption tcp-smart-connect
7 ~+ t. q! n w3 H( Q% j( Sno option tcp-smart-connect; \' J4 q, t( |
Enable or disable the saving of one ACK packet during the connect sequence$ u) W. [) F2 R2 m3 w- A
May be used in sections : defaults | frontend | listen | backend0 g" b. Z) z3 @$ E! E0 m4 P8 K
yes | no | yes | yes9 [9 K% ]# o/ ^3 q4 G+ |; f
Arguments : none
) ~% m6 b2 `5 V2 r* D. w; y8 {) r9 |: K& s
On certain systems (at least Linux), HAProxy can ask the kernel not to
p+ a, w6 V) P* x immediately send an empty ACK upon a connection request, but to directly4 ]" T- @8 Y% W$ I8 R
send the buffer request instead. This saves one packet on the network and# c2 x) T- [$ a2 d- e
thus boosts performance. It can also be useful for some servers, because they7 ?: Q5 K5 Z4 F$ O+ J8 }! P, i5 W
immediately get the request along with the incoming connection.
+ Z5 u6 [7 j: q4 p) ]; D
3 p% u+ G( v% r, f B This feature is enabled when "option tcp-smart-connect" is set in a backend.
# {5 Z }' H ~8 d! | It is not enabled by default because it makes network troubleshooting more e+ h- j: V; f9 u6 Z4 M
complex.: {, n) S4 g. A: T
: s G0 Q; s: L% j It only makes sense to enable it with protocols where the client speaks first9 P- A4 [' {3 ^( P( `. |
such as HTTP. In other situations, if there is no data to send in place of
2 x& S' x! S5 @1 O& L- t the ACK, a normal ACK is sent.
! I h& c; M, A$ J6 |* ~' R7 C' \
6 z+ b0 E" H) T) n2 z' n If this option has been enabled in a "defaults" section, it can be disabled& S" W5 i: @/ f6 [; }
in a specific instance by prepending the "no" keyword before it.( i% H# D( M4 f, S1 M1 B/ O
9 @; R, c2 _) Z( u& @/ D
See also : "option tcp-smart-accept"9 q1 N: ?& e( v
: @: M9 K, s7 v% Z, E
7 I" G" W/ y/ s+ |+ Coption tcpka) K& b- ]# ~9 Z4 x& n
Enable or disable the sending of TCP keepalive packets on both sides
! D: s7 |/ u: F May be used in sections : defaults | frontend | listen | backend
+ L% M5 V; D" L9 K' Z: Y yes | yes | yes | yes
9 A8 R. B4 N) o2 b% U Arguments : none
7 s+ s. M$ Q: ^+ K* H- B N$ s+ L( t$ {
When there is a firewall or any session-aware component between a client and6 p! g C, K. F z" \
a server, and when the protocol involves very long sessions with long idle
$ H% m7 I/ l: V8 p1 k& u5 D. t periods (eg: remote desktops), there is a risk that one of the intermediate
* C d7 n" s1 @ components decides to expire a session which has remained idle for too long.3 z \ @. F8 I6 L2 o
# i% o9 h: v0 {: U Enabling socket-level TCP keep-alives makes the system regularly send packets9 G3 x# T! u2 q- g
to the other end of the connection, leaving it active. The delay between
8 Y; M( ^& A' z `* _, ] keep-alive probes is controlled by the system only and depends both on the9 Q% X3 b; n7 E3 [8 X/ r
operating system and its tuning parameters.- L+ m9 ?7 ^3 B: Q3 l
& k: o0 a3 A8 N" }6 L1 v
It is important to understand that keep-alive packets are neither emitted nor
2 }) ]6 }, K: f received at the application level. It is only the network stacks which sees
* d; P. {4 l- r them. For this reason, even if one side of the proxy already uses keep-alives
- u, S* q* n! s. \" o/ A/ t to maintain its connection alive, those keep-alive packets will not be& P. W- T* [7 \( D
forwarded to the other side of the proxy.
! l4 \9 }% j9 k0 \- u1 Z$ a" A( |3 @- ?- I. F, b
Please note that this has nothing to do with HTTP keep-alive.
2 V' X7 A4 B5 J0 C# T8 k
6 {: d" K$ K" y/ |" H: E Using option "tcpka" enables the emission of TCP keep-alive probes on both# o/ `; g! n5 w: w8 n _9 x
the client and server sides of a connection. Note that this is meaningful
% j% T. R' k6 }' B: c only in "defaults" or "listen" sections. If this option is used in a
5 k- B9 J0 @0 B& F: p frontend, only the client side will get keep-alives, and if this option is( c [! n! o- N
used in a backend, only the server side will get keep-alives. For this
2 y6 P4 i1 z4 l reason, it is strongly recommended to explicitly use "option clitcpka" and
5 Z0 @% W8 R9 ]2 d$ Y3 n9 n4 @ "option srvtcpka" when the configuration is split between frontends and" k. E& {% T" s# ]
backends.
4 s% y; h9 ? ]# ]
" d, Z" a! u; [$ c) m See also : "option clitcpka", "option srvtcpka"
: K5 h5 |' U2 ]3 \" p2 E2 G- e9 r- Y# Z. @1 \( }" F
) Z0 J u ` yoption tcplog0 N% B: ?) W4 \3 N# H) ]- R# W
Enable advanced logging of TCP connections with session state and timers; ^5 i% k6 i! N, b5 X- q# D
May be used in sections : defaults | frontend | listen | backend/ P( q5 }+ O) Q6 G. w; Q5 {- r
yes | yes | yes | yes! q ~& e+ \* ?
Arguments : none
% K7 j+ S4 q& A
" E o, \ D* k, ?5 Z By default, the log output format is very poor, as it only contains the
" B) Z/ {5 b- h+ _- g% E" E source and destination addresses, and the instance name. By specifying8 O2 h# s% R+ |' C5 i
"option tcplog", each log line turns into a much richer format including, but
' z1 x7 g5 M9 J$ D, A. a not limited to, the connection timers, the session status, the connections
- \3 Y9 O, M: h( S numbers, the frontend, backend and server name, and of course the source% F+ B% Q7 [0 }' B2 A y, k' t
address and ports. This option is useful for pure TCP proxies in order to# v4 z7 a$ V! t
find which of the client or server disconnects or times out. For normal HTTP9 H/ d z r# e$ J8 |
proxies, it's better to use "option httplog" which is even more complete.
1 I z. D/ ]$ v2 V3 I9 Y, u7 h- J. ^
+ x {, v& h7 M& L1 m This option may be set either in the frontend or the backend.: R) u1 P/ L' ?9 `/ c
) d- j `, I% _. M$ W
See also : "option httplog", and section 8 about logging.
) C+ S. F N" k8 m3 S1 k
( w, X$ P1 C7 r% |2 w
7 d) ]' \* O6 N9 \; }7 ]& uoption transparent
& U& x ^# G9 kno option transparent
+ h& O9 M/ G( a0 e Enable client-side transparent proxying
2 r$ H; l" M6 E; v; L* V) x Y! a May be used in sections : defaults | frontend | listen | backend
! R" M' Y, {: o yes | no | yes | yes/ l, q7 W* \) ^
Arguments : none6 x9 i% M6 d9 J4 a9 ?/ C
" @3 ^( s. M1 C& ^ This option was introduced in order to provide layer 7 persistence to layer 31 ]# ^+ K3 D. a! D$ b, A* M4 M6 s
load balancers. The idea is to use the OS's ability to redirect an incoming
( B4 f, n2 _- S d connection for a remote address to a local process (here HAProxy), and let
: `5 R/ o1 a+ l2 R' P0 S/ m this process know what address was initially requested. When this option is
9 I& [. N9 w, ^! o2 | used, sessions without cookies will be forwarded to the original destination. a& P2 M3 |! W1 o/ ~: e
IP address of the incoming request (which should match that of another6 j! y: ~5 j) H, f
equipment), while requests with cookies will still be forwarded to the; i# U' G& Z9 p( X. O% N& d; x
appropriate server.1 [8 c m/ u" t7 ^! b
0 T! B& Q/ {+ f8 O Note that contrary to a common belief, this option does NOT make HAProxy
1 o" P6 H& `( ~* | present the client's IP to the server when establishing the connection.
+ a. o; O/ G' y7 {' D1 J9 o5 n \! w8 U! I: _% \
See also: the "usesrc" argument of the "source" keyword, and the
' ]4 b# f4 d4 r( Y3 t "transparent" option of the "bind" keyword.
& ?1 l* `( {2 k. Z2 b2 `* ]6 b% w# t+ I( E# L0 m7 [, u
, x. N }. w4 F) h) l, upersist rdp-cookie
% c0 s, E" r! E, f! dpersist rdp-cookie(name)
# o& l- |% O$ L1 {, V6 W Enable RDP cookie-based persistence
, o1 R, ~! B' |7 ]' h6 V8 i S May be used in sections : defaults | frontend | listen | backend- d( w7 a; T F% g$ G# {, [" Z
yes | no | yes | yes
" O6 s, G. k2 T) D2 h: e$ C; r; w2 a Arguments :
* s. \- q* h* L, y4 h7 s. E <name> is the optional name of the RDP cookie to check. If omitted, the& q" J( n2 D& }( O
default cookie name "msts" will be used. There currently is no
9 X" n5 w$ j7 N( N# ` valid reason to change this name.
, K8 J* o/ q; n% N. o: j0 i# S7 b' {% x) ~
This statement enables persistence based on an RDP cookie. The RDP cookie
/ B; w7 \7 k8 y0 |( E contains all information required to find the server in the list of known
* D. ~' d S/ d7 \. I9 R. x6 ?% z* Q servers. So when this option is set in the backend, the request is analysed
4 f4 ^* C+ C2 x and if an RDP cookie is found, it is decoded. If it matches a known server
8 A8 y3 V1 ~! o1 M4 K D d$ d3 c which is still UP (or if "option persist" is set), then the connection is
& d% A4 ]3 O, C# H6 S. K forwarded to this server.
2 n$ i$ p; t* A9 O
* Y A& }: @& k, e/ I Note that this only makes sense in a TCP backend, but for this to work, the" ]" U/ s/ X3 m; F
frontend must have waited long enough to ensure that an RDP cookie is present
0 y, I& b* o- E: \ in the request buffer. This is the same requirement as with the "rdp-cookie"0 K& c* ^# w: E' p6 ?, o
load-balancing method. Thus it is highly recommended to put all statements in
( j$ [; e+ {' \ a single "listen" section./ |# @0 c2 Y: m
8 @" E/ T+ n& }" H, \3 P0 B% o Also, it is important to understand that the terminal server will emit this
; @( _4 i7 s$ {, G8 K RDP cookie only if it is configured for "token redirection mode", which means. d7 a6 ^/ c2 l. C( v
that the "IP address redirection" option is disabled.
' n5 N0 }' s& v, k+ ?! y/ z \
3 Z4 Q' D9 Y p& M Example :' y) S2 h8 G3 A- ]
listen tse-farm! \2 Q8 a, w \, u
bind :33899 A7 \ f/ j) A+ P/ C# {3 k$ E
# wait up to 5s for an RDP cookie in the request( M# L- f9 Q4 b" `: ^, B6 u
tcp-request inspect-delay 5s
n# M! l7 t" ?0 t. k. l7 ? tcp-request content accept if RDP_COOKIE R; b2 J+ z3 q% u- [" p
# apply RDP cookie persistence
. L: D. c; |# x0 @ persist rdp-cookie
) I' x0 z9 ~( _# O$ m9 ? # if server is unknown, let's balance on the same cookie.
6 _9 k( N3 A7 G, f9 Z5 _7 t' c # alternatively, "balance leastconn" may be useful too.6 ^" V) P( W: v' D, Q# V
balance rdp-cookie. y2 V0 W2 j+ {# ]
server srv1 1.1.1.1:3389
5 j+ v% ?2 t N5 b8 x server srv2 1.1.1.2:3389$ e7 c P- S) ]/ G. ]0 }1 O$ D
* P6 d6 N1 B& d V3 S
See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.
& e R, |6 ~( X/ b- e2 d. z" q; `* o- \* @! h2 O
, X; y, v7 a$ d1 |
rate-limit sessions <rate>
7 W \& F+ W- K- u2 ~8 _ Set a limit on the number of new sessions accepted per second on a frontend: i) P4 N" F# s9 Y8 U
May be used in sections : defaults | frontend | listen | backend
, I* j1 J3 ?4 L" W. q% N8 ]% n' @ yes | yes | yes | no
6 j7 V' `# Q8 E- Q7 n Arguments :" c( `+ a, P- X4 ~0 h/ x
<rate> The <rate> parameter is an integer designating the maximum number& d+ r% [; D) g8 p4 M4 e0 a+ e+ @% l
of new sessions per second to accept on the frontend.
: ^) N0 Y; }9 u. o* b% Z/ n8 S3 l6 I8 _; B1 k" Z9 x
When the frontend reaches the specified number of new sessions per second, it/ Z. C, i0 L2 z, w3 n9 O/ r, l
stops accepting new connections until the rate drops below the limit again.
2 w. g n- H+ Q# T During this time, the pending sessions will be kept in the socket's backlog
9 D4 r5 M$ |( ~4 j& u (in system buffers) and haproxy will not even be aware that sessions are! g* B& m4 t0 \2 |7 e
pending. When applying very low limit on a highly loaded service, it may make; k. {, w# C9 }! w& u
sense to increase the socket's backlog using the "backlog" keyword.
% i) I! i) D! J% H) F- R
8 y ]( _, M) X& C This feature is particularly efficient at blocking connection-based attacks1 c4 i+ _, \8 V4 s
or service abuse on fragile servers. Since the session rate is measured every
( G: A. z# n" z" U millisecond, it is extremely accurate. Also, the limit applies immediately,5 q: u$ ]# o8 c; s2 z4 d
no delay is needed at all to detect the threshold.6 |7 ~! h. T5 ]! e/ `( ~
7 C: C$ u* H9 L7 [ Example : limit the connection rate on SMTP to 10 per second max
5 Q+ v' f* l' N l _4 f+ w listen smtp
3 Y1 D2 r) s3 B+ L: ^2 P9 o- S) c f mode tcp
: ^: r! O1 {) Y' M r4 }2 ?4 G bind :25
6 }7 y! M. H. l+ t; G. k rate-limit sessions 10
% N% |+ a1 U7 K7 S4 b9 p3 F server smtp1 127.0.0.1:1025
4 A, ~/ V- h8 s! Z+ Z8 Z, J2 y& a$ v3 Y
. c+ F) n6 r" f4 W) u3 _& e) o Note : when the maximum rate is reached, the frontend's status appears as
+ k* h5 B, S2 U9 a# E, F" u "FULL" in the statistics, exactly as when it is saturated.
" R0 a2 ]& Y: p3 y# v9 S8 B7 H1 Z2 F3 x7 `8 u
See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion.- f# b; z! k4 K# g
8 L1 Q1 n3 U: ^
4 X5 `' T3 ] f* W, ^
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]! Z4 p& d3 Z! G& _4 t
redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]
( w+ p6 i5 m5 P' W/ m* Y) fredirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]: {1 |) M/ w+ h
Return an HTTP redirection if/unless a condition is matched
I! r: N+ d( A7 ?: i5 K# p May be used in sections : defaults | frontend | listen | backend
: P% @9 B' h8 _; R" H' l8 j no | yes | yes | yes! K; t j! o( ~% Q6 F2 P; v+ E. ?
/ X2 n! J/ V; F, O/ _, s8 M, H
If/unless the condition is matched, the HTTP request will lead to a redirect0 @. G6 h1 K3 Q% e9 V( y2 X
response. If no condition is specified, the redirect applies unconditionally.7 s4 X0 O l, A: c& n- ], _
: u/ K, o* F* P
Arguments :# |) _1 Y9 z' ?6 v) v' A) X# ]
<loc> With "redirect location", the exact value in <loc> is placed into
& o# j6 G# T: P8 Z the HTTP "Location" header./ X$ z" {2 u# K, l, S
6 Z5 x. }# j2 E& W' B
<pfx> With "redirect prefix", the "Location" header is built from the
: P; N8 X5 ?3 N# o* e concatenation of <pfx> and the complete URI path, including the2 p* u. L5 q0 \, d
query string, unless the "drop-query" option is specified (see
' A$ q: y/ z3 D9 e4 M3 ? below). As a special case, if <pfx> equals exactly "/", then
! N2 X" \8 S+ n1 s/ @ nothing is inserted before the original URI. It allows one to$ G* ]; B6 u h9 D. w
redirect to the same URL (for instance, to insert a cookie).
3 c: M V& S& o- z1 J! _) A! Q0 Q2 ~- f5 J$ v& J
<sch> With "redirect scheme", then the "Location" header is built by
3 }5 }0 U. o( a0 {# y5 _ concatenating <sch> with "://" then the first occurrence of the
9 y1 F6 A; v+ D- o# ]0 v/ k% u6 ] "Host" header, and then the URI path, including the query string2 d2 {+ D/ X3 Z
unless the "drop-query" option is specified (see below). If no7 j6 j9 E1 c) Q' k+ ]1 Q7 }. C
path is found or if the path is "*", then "/" is used instead. If
4 h. V6 i& y8 Y no "Host" header is found, then an empty host component will be( Y0 l0 k7 b7 Y' p, w; v$ l+ u
returned, which most recent browsers interprete as redirecting to
5 x, y6 r$ T, _+ x7 n' k5 E3 ~1 U the same host. This directive is mostly used to redirect HTTP to! K: b1 F& t0 {
HTTPS.. ]% e1 a; a( i" |1 m
$ J2 j2 c: B5 H8 R) R' z <code> The code is optional. It indicates which type of HTTP redirection
0 I& P# e m' ] G4 I8 u is desired. Only codes 301, 302, 303, 307 and 308 are supported,
! Z' l) F6 Y n$ j. u: N; ?+ O with 302 used by default if no code is specified. 301 means
# Q" r5 B4 u% w& W* L/ _+ l "Moved permanently", and a browser may cache the Location. 302
0 \' z; C" y7 O e means "Moved temporarily" and means that the browser should not
5 J8 h' E6 Z7 D. ] cache the redirection. 303 is equivalent to 302 except that the1 R, f7 ^% m7 i Y' B1 d' B5 t
browser will fetch the location with a GET method. 307 is just# o. D' ~! O) B$ N# a8 G* o
like 302 but makes it clear that the same method must be reused.
0 r y. Y" N' Y" | Likewise, 308 replaces 301 if the same method must be used.1 O5 d6 G5 p) g
- x* M H, N+ J5 ?* Q( V s <option> There are several options which can be specified to adjust the) T, h1 |: m( ~4 V. K2 v
expected behaviour of a redirection :
|& i( S! Z% e) \ L( a! j Z5 I/ }$ Y- b; E
- "drop-query"2 {9 k( ^* M6 k& U9 P
When this keyword is used in a prefix-based redirection, then the% g% E7 i9 m1 e5 r
location will be set without any possible query-string, which is useful. E6 l* x4 ~# h
for directing users to a non-secure page for instance. It has no effect; x6 D( c+ v2 B4 l, ]7 f/ ^
with a location-type redirect.8 C2 }2 ]4 h2 ~
, P; t# t2 t) Z$ O5 u0 G
- "append-slash"$ G8 N. W I8 a6 L
This keyword may be used in conjunction with "drop-query" to redirect+ o: S9 n; \: B2 M [$ x9 d
users who use a URL not ending with a '/' to the same one with the '/'.1 M8 J- k/ e7 }% F* z$ w% J
It can be useful to ensure that search engines will only see one URL.6 o7 i. P1 `) @: R5 w% b e+ u
For this, a return code 301 is preferred.$ m6 r9 a( l; _0 x7 G
+ j* C9 O$ e. Y9 X1 T - "set-cookie NAME[=value]"
& V3 ^, b& ]3 e A "Set-Cookie" header will be added with NAME (and optionally "=value")
8 B1 _4 `1 X0 H' } Z: p4 }0 n to the response. This is sometimes used to indicate that a user has) Y: c- s3 `7 B( J6 N3 _
been seen, for instance to protect against some types of DoS. No other; v, r; n! v0 K$ e- T2 r9 o- F/ g( X
cookie option is added, so the cookie will be a session cookie. Note
4 G% u0 w2 l" X6 o$ J2 K that for a browser, a sole cookie name without an equal sign is
9 s' s$ j/ L/ U7 q0 x% K2 D+ I different from a cookie with an equal sign.0 Y2 W# V+ @, U0 i6 m ]- L# m
, Z# h0 K7 J( C, z: s/ i; ^" U' L* C - "clear-cookie NAME[=]", |: d. W. _4 h; R+ r
A "Set-Cookie" header will be added with NAME (and optionally "="), but" |% C6 Z! s# e3 v4 ]' n- c. _9 Z
with the "Max-Age" attribute set to zero. This will tell the browser to
0 v- q; L5 J# O' V/ g5 E delete this cookie. It is useful for instance on logout pages. It is
: v5 K" l0 I, s4 {( H4 x. w important to note that clearing the cookie "NAME" will not remove a' s/ u1 Q" m, p/ a; K! ^* @
cookie set with "NAME=value". You have to clear the cookie "NAME=" for4 B( r5 P5 J6 Y% T3 ?8 A' V
that, because the browser makes the difference./ u3 `9 B5 J7 G8 N1 \4 {8 g
. F6 O" w0 u$ S7 M$ y0 g L Example: move the login URL only to HTTPS.2 }6 ^2 l) K9 W* b9 ~0 T. k, O
acl clear dst_port 80' H1 t1 H' u/ I1 ~! \
acl secure dst_port 8080- @; @; F" ^2 Z! j6 S. v
acl login_page url_beg /login
% D |, X+ {: D2 e: T7 r5 U acl logout url_beg /logout# _; h, \" A) H
acl uid_given url_reg /login?userid=[^&]+7 E4 W8 J3 J5 M I4 {2 D
acl cookie_set hdr_sub(cookie) SEEN=1
8 ?6 @* v9 n; W3 _# C0 ~3 {& R
- x4 ~0 l0 |; w% @8 m1 O7 a redirect prefix https://mysite.com set-cookie SEEN=1 if !cookie_set `' @; ]$ h2 E9 \0 [ S
redirect prefix https://mysite.com if login_page !secure
L5 l' }7 u) K# o+ O redirect prefix http://mysite.com drop-query if login_page !uid_given
. I% v0 f& V1 e# G redirect location http://mysite.com/ if !login_page secure0 C- r' e5 R7 E* Z7 _( t2 w
redirect location / clear-cookie USERID= if logout
5 p% [# ~) p( g5 m* d9 }4 l* `$ _& ~6 k( ^; I+ v8 ^
Example: send redirects for request for articles without a '/'.
0 t M. ^. S8 C0 J* t% S acl missing_slash path_reg ^/article/[^/]*$; @: B" U2 e. ?* z. `
redirect code 301 prefix / drop-query append-slash if missing_slash
( G' N+ T7 b/ I8 O7 C# l' P! S3 J6 G, X. }; }3 {! V7 K
Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.
F' V% \' a* T- [7 G* ]3 g redirect scheme https if !{ is_ssl }8 }. N$ o0 z7 t' i% W9 F* v4 i
7 P$ V# M+ i8 q1 H! k9 ]
See section 7 about ACL usage.
3 s; k Q" W' P' j# [' w! {) X- o! ~( j8 j1 ?
- p/ T* m+ Y) ~. v$ s8 V
redisp (deprecated)
( S. O& b% k- c+ mredispatch (deprecated)
) Q3 @7 H7 d& F. W% F9 B0 R Enable or disable session redistribution in case of connection failure
! m/ u# H! M, H May be used in sections: defaults | frontend | listen | backend6 b& W9 y- Z$ e- X/ Z% D: j- Z( Y
yes | no | yes | yes
, M% s. b! u# J! \. F. U8 l1 x Arguments : none* N' C% O! S) |" ]
. K) y; v9 s' f' z8 }( E4 i3 y4 l
In HTTP mode, if a server designated by a cookie is down, clients may/ b e h$ i% k1 z3 M. A" y
definitely stick to it because they cannot flush the cookie, so they will not
]; R9 R, K: L3 Y1 U* M be able to access the service anymore., F( l' O; U+ g, K I
$ O. R% W: G8 N* S4 q! r Specifying "redispatch" will allow the proxy to break their persistence and; o& S" a) u' W( W+ w) W+ h; e
redistribute them to a working server.( H5 W$ b: S0 A6 C) t2 P7 p+ i
& S4 q4 q: R: Q- W! i
It also allows to retry last connection to another server in case of multiple
) y9 n# u7 K6 N1 v% Z connection failures. Of course, it requires having "retries" set to a nonzero
3 R+ \, p3 \9 H) P6 ^4 F4 I. p value.
$ x. l- a- J. Y' v; \2 S. U6 n- L* o
This form is deprecated, do not use it in any new configuration, use the new* E+ a2 r, e" @, |$ ^$ C" _
"option redispatch" instead.
; z* n6 V' p& f6 e% ?. e! R7 e( @3 L! a4 q" T' [8 z- A
See also : "option redispatch"
' g. N, p- Y* A" C
9 }5 k9 D7 q' q( t {! d+ |+ Y) X, N6 j& B, J
reqadd <string> [{if | unless} <cond>]! l+ H% K" |$ R& o- F' @/ F# Q
Add a header at the end of the HTTP request
: p- u/ H" j, `# I/ W May be used in sections : defaults | frontend | listen | backend
9 c+ f- e/ c* G2 B" \% `1 Q no | yes | yes | yes
" F {/ i! s' g% U( E; J, i Arguments :
: @" A) |( j* o4 ?6 |/ M" B <string> is the complete line to be added. Any space or known delimiter
( j+ j! L6 i: D must be escaped using a backslash ('\'). Please refer to section
$ m$ x% M6 u+ m% M& Y h% n 6 about HTTP header manipulation for more information.
7 H; I# }* D S# c$ T7 | I2 i2 M1 X$ x+ z: u
<cond> is an optional matching condition built from ACLs. It makes it& F* V M+ _9 b6 C7 P) V
possible to ignore this rule when other conditions are not met.) \3 e! t& k8 H/ J. @/ a8 L
3 |1 t3 W9 z3 F; v0 Z4 S% V
A new line consisting in <string> followed by a line feed will be added after( k/ ]6 d$ D) q, I9 {; Z
the last header of an HTTP request.: @4 K# N/ t; b8 h5 @9 ]6 W7 _0 f, @1 H
* O j F( @: {7 D7 E
Header transformations only apply to traffic which passes through HAProxy,
( I* \4 f+ `) q and not to traffic generated by HAProxy, such as health-checks or error
5 R- X8 z7 F3 D& v* B3 e' Q S responses.2 w8 }) G% Y7 x1 @3 ]# Q
, r1 \' I8 n" l& q* z
Example : add "X-Proto: SSL" to requests coming via port 81
* T6 v0 r9 [1 i8 a! U: y- @8 u) v acl is-ssl dst_port 818 [& C& d% a1 f$ S, Z- I
reqadd X-Proto:\ SSL if is-ssl
P u, R8 S# _8 M) ~8 K4 N
: O5 S: R- T* H' K+ _ See also: "rspadd", section 6 about HTTP header manipulation, and section 7
. L$ F& U' F1 l) X about ACLs.
) c% k _" Z) ?9 S9 m1 L, {) t
z3 ~1 _$ l2 [ D, V! O
9 i4 [7 S0 r0 Z$ Treqallow <search> [{if | unless} <cond>]2 ]9 a0 C, f5 Y' ]( \, M
reqiallow <search> [{if | unless} <cond>] (ignore case)9 S4 F. S1 t8 h" X& b- c
Definitely allow an HTTP request if a line matches a regular expression
3 l& |6 b3 u( I- Y, Z9 j May be used in sections : defaults | frontend | listen | backend
7 v( [) M" g! g no | yes | yes | yes
0 n7 S; {0 K2 D% k) E+ { Arguments :
# y6 v: Z, M3 F3 | <search> is the regular expression applied to HTTP headers and to the E" t! g. l( T7 @
request line. This is an extended regular expression. Parenthesis
4 C/ T) f) D* D6 |4 w8 B grouping is supported and no preliminary backslash is required.
% [" B+ g1 W; d; z8 Y- P Any space or known delimiter must be escaped using a backslash
* D& ~4 M1 d8 X9 i* b ('\'). The pattern applies to a full line at a time. The6 l/ R5 I* S7 A; M8 ]) B- U' E) D
"reqallow" keyword strictly matches case while "reqiallow"( g! u. j* o* n6 p1 K
ignores case.) l& ~" J% ~# d4 s* n' I' f
- c7 {/ |- v9 B: c# @0 c( i# V/ E <cond> is an optional matching condition built from ACLs. It makes it0 C* f" V; n& w7 B2 J
possible to ignore this rule when other conditions are not met.
5 j2 f7 W' p- U) R; c# U) P
" G2 ], W: {1 Z2 R* j5 I A request containing any line which matches extended regular expression
, m5 G. S/ @' l0 i0 n: C <search> will mark the request as allowed, even if any later test would- A. l6 g9 P4 R7 h6 c( D
result in a deny. The test applies both to the request line and to request
6 N. I; f2 R1 j# d* X headers. Keep in mind that URLs in request line are case-sensitive while
1 s4 l5 ]/ Z; m+ y) {% l header names are not.* v, e. |+ o, E; M) c* u
" s; c" C, k/ I/ R It is easier, faster and more powerful to use ACLs to write access policies./ q5 _) g0 U1 J. @$ g
Reqdeny, reqallow and reqpass should be avoided in new designs.( A" |) W# w, b+ z9 O3 T# H+ G6 `
+ _( b! t* W, b9 `' X. t
Example :+ A: x. \7 F; y" R( r* @; Y) B. U
# allow www.* but refuse *.local
, c/ {1 R" a" |% H% O reqiallow ^Host:\ www\.% v7 ~& Z! Q% Q9 v
reqideny ^Host:\ .*\.local" f: I) o# q, f/ @! J# _# ]
# s, K) J6 ? @& P See also: "reqdeny", "block", section 6 about HTTP header manipulation, and' G9 J; d" ?! B" [7 o
section 7 about ACLs.
: P+ w2 ^! s% s5 |+ B/ Q9 v3 V- L/ k6 C! `' @% `1 m3 ^' n- J
, S& \4 t8 | n" B) d# Q0 U# w) O" \
reqdel <search> [{if | unless} <cond>]3 g. ]% }. V3 i- B {# E5 f+ |- E; X& M
reqidel <search> [{if | unless} <cond>] (ignore case)
$ E1 D K6 c3 n* Q/ p5 y8 |4 K( l Delete all headers matching a regular expression in an HTTP request
; a4 Z$ ]# V- `0 r& Q4 K, o May be used in sections : defaults | frontend | listen | backend6 {/ a5 d0 f$ }- ^, L! k
no | yes | yes | yes
' u# e# C/ n" I$ ] T& _ Arguments :7 O: j1 Q1 v9 U9 _' Q
<search> is the regular expression applied to HTTP headers and to the1 O: ]4 w. |2 B! ^7 G
request line. This is an extended regular expression. Parenthesis5 e. Y; W/ b2 |" c$ X; z, C: Q
grouping is supported and no preliminary backslash is required.2 S5 m; y5 a- @; [
Any space or known delimiter must be escaped using a backslash; b" U0 L" Q6 {
('\'). The pattern applies to a full line at a time. The "reqdel"0 t" b, i$ D5 E) c. N! f- V K
keyword strictly matches case while "reqidel" ignores case.
3 S2 Y, O" X4 D' Q- [' H6 u9 {3 ?# s8 O
<cond> is an optional matching condition built from ACLs. It makes it$ C5 s( V% \$ D6 v+ `; S, f
possible to ignore this rule when other conditions are not met.5 \2 c* D& h* C2 J1 H2 M
& |4 l2 E# D, b- i- w* d4 n- R/ G
Any header line matching extended regular expression <search> in the request
7 D4 f3 r3 ~7 c( Z9 B will be completely deleted. Most common use of this is to remove unwanted
; d3 H7 u$ `9 i2 X* {4 u and/or dangerous headers or cookies from a request before passing it to the
9 ]7 A* }. J( d# y5 V7 ^ next servers.
( H8 I9 |& p5 H! H' C Y r% i5 W! G% {
Header transformations only apply to traffic which passes through HAProxy,/ |1 V; T1 @; @4 }
and not to traffic generated by HAProxy, such as health-checks or error
# G# z, y- O' l- ] responses. Keep in mind that header names are not case-sensitive.3 r& Y+ Q+ T! D* G. |
4 L# I) @% Z; K6 O9 T, J0 w Example :, G, x6 o% s: o4 ?
# remove X-Forwarded-For header and SERVER cookie- D% D' I5 C# l) }' Y
reqidel ^X-Forwarded-For:.*# }% M$ @/ |6 A9 L; O- {5 R3 b- A
reqidel ^Cookie:.*SERVER=
+ i7 R) Q5 k4 R/ u* p, [% d9 c3 w; G
f' T* T; d4 y9 h! {. Z6 ^ See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header. B* }3 b6 z3 Q- M- [# v7 W
manipulation, and section 7 about ACLs.
3 {4 k- R4 W& t; X2 M2 S0 I; t
: {# V8 a( |: R
* P3 O9 P, _" S1 B7 K5 ~reqdeny <search> [{if | unless} <cond>]$ n0 H* S' |- @: i7 Q" n$ J
reqideny <search> [{if | unless} <cond>] (ignore case)
5 V$ H$ ]7 |; ~" ~& d, f8 K7 k0 c/ {9 C Deny an HTTP request if a line matches a regular expression
5 B* ~/ R, l. }* o1 E* C1 g May be used in sections : defaults | frontend | listen | backend5 ~4 t# O# s% _; N
no | yes | yes | yes
6 Z* A, s. l# k% z1 s. a Arguments :
, `+ K8 b# s" Q9 ` <search> is the regular expression applied to HTTP headers and to the4 l$ R7 |/ }6 x; d, k) ^& V, Y' [
request line. This is an extended regular expression. Parenthesis6 m0 f0 J7 U# m: n
grouping is supported and no preliminary backslash is required.
4 m: l4 G; X% X% i) s3 E/ ` Any space or known delimiter must be escaped using a backslash
0 p, w4 F% q% Z/ O; |& D9 M ('\'). The pattern applies to a full line at a time. The
$ N7 D+ [1 {& T! M+ q) O! { "reqdeny" keyword strictly matches case while "reqideny" ignores
$ f& x6 p( h& S$ Q' W3 x case. h* F: w( {) ^
# W( U% p6 h9 B5 z
<cond> is an optional matching condition built from ACLs. It makes it
3 ^( q/ y6 Q' r. W5 K4 q1 x possible to ignore this rule when other conditions are not met.* @% o9 t2 C. m7 U3 G' L
: p; {& o6 X6 P+ S @) w A request containing any line which matches extended regular expression
# {9 k. Q! s* k( O <search> will mark the request as denied, even if any later test would& s2 i |0 D; ^! c; }5 a
result in an allow. The test applies both to the request line and to request
' G& E/ L; _' Z headers. Keep in mind that URLs in request line are case-sensitive while
% W- v V) ]+ o+ P2 F header names are not.! m. l$ n: h/ j( Z
9 z% D! X5 H( d) h: P A denied request will generate an "HTTP 403 forbidden" response once the$ K- M- n4 q+ ^+ m2 Z3 f& o5 R/ c
complete request has been parsed. This is consistent with what is practiced. y, e$ c8 ^; \5 D5 @' ?1 y% w' a# t
using ACLs.
0 N+ A/ x6 ]0 _8 t C3 R. ?
: [# C3 d$ I2 P: k, M7 G It is easier, faster and more powerful to use ACLs to write access policies.
% C- ~5 f8 w7 X4 O( W, r Reqdeny, reqallow and reqpass should be avoided in new designs., T$ x, M1 q4 D) R3 c. z
0 t7 k7 e0 \5 R7 J Example :
: V& p1 ?+ ~: p' O j1 | # refuse *.local, then allow www.*/ `: j; K5 v c' T+ B B: d
reqideny ^Host:\ .*\.local. n. R; u, r3 T) Q
reqiallow ^Host:\ www\.
$ v! m: T, ~5 M W0 l9 M9 O, T" i
6 l" b9 X$ ~$ b; | See also: "reqallow", "rspdeny", "block", section 6 about HTTP header; T9 G+ O2 }, n9 e7 [
manipulation, and section 7 about ACLs.
5 L; k' a% x4 J: g2 P8 H" y# g
: `6 c% ^3 z \: k
3 P2 H2 M1 L$ G/ [; Y: qreqpass <search> [{if | unless} <cond>]
" l" [, V' O1 I1 Q# D# H" A! `reqipass <search> [{if | unless} <cond>] (ignore case)
/ [* U! @' z Z; U: o0 G/ c. P6 w Ignore any HTTP request line matching a regular expression in next rules
- J3 C2 g& i( k& D2 ^4 i3 h; i4 [ May be used in sections : defaults | frontend | listen | backend
# j( `* j; W2 E, l: H7 v; M, P no | yes | yes | yes: F1 |5 |0 `8 s% V. r) |
Arguments :" K1 ^2 L4 h* n4 N5 Q# g: t s
<search> is the regular expression applied to HTTP headers and to the
- u8 j1 ^' m7 C- l$ P' S0 K' T6 F request line. This is an extended regular expression. Parenthesis
3 Z+ [9 }) ~; [, C, ^ grouping is supported and no preliminary backslash is required.+ J' q a" ~% [7 O+ p
Any space or known delimiter must be escaped using a backslash2 m6 m6 P( e6 H9 ~' b& b
('\'). The pattern applies to a full line at a time. The$ m2 N/ t" I) V( D, A
"reqpass" keyword strictly matches case while "reqipass" ignores
; D$ ]9 i4 g6 J, ]' } case.# k, s& Q3 o( Z' U E1 c) d
1 x1 W' ?: H1 H6 M8 w [& I% z7 z <cond> is an optional matching condition built from ACLs. It makes it5 n! h! U# }3 h; R, }% |8 z( K
possible to ignore this rule when other conditions are not met.( S- R$ \. V9 B7 U* N
/ I, [- V, d% `2 ~' `! \
A request containing any line which matches extended regular expression& j( ], J4 ~+ x9 x+ O
<search> will skip next rules, without assigning any deny or allow verdict.
) ?9 S4 c# m ] z- p The test applies both to the request line and to request headers. Keep in/ C! j, }( n4 a
mind that URLs in request line are case-sensitive while header names are not.2 l0 ^" @; H; S) m3 D
0 o3 Z4 j0 U3 U6 G6 x
It is easier, faster and more powerful to use ACLs to write access policies.
- H9 F0 u- e5 S8 r, y0 b Reqdeny, reqallow and reqpass should be avoided in new designs.8 [; i" [: j2 g0 A% |2 T+ |! o
& {/ J9 F# \' b& p' |$ N' }
Example :0 I% {/ b( |5 B$ s$ c8 q
# refuse *.local, then allow www.*, but ignore "www.private.local"
- z( f" K2 E; b$ N D! T. n, N1 } reqipass ^Host:\ www.private\.local9 P% D! }+ j5 d
reqideny ^Host:\ .*\.local
. G6 @- H8 l5 g reqiallow ^Host:\ www\.: u+ i( v- g' p( m( \& Z" G
' R v7 z/ o7 F y$ ~+ Z$ c See also: "reqallow", "reqdeny", "block", section 6 about HTTP header7 |$ M; T- G, E! |
manipulation, and section 7 about ACLs.
J) w3 Z. y/ |7 X# p! h
2 A* D7 d" ]: |4 v2 G- }! _1 u3 G$ R3 f" O* c( L9 i- T7 G: Z
reqrep <search> <string> [{if | unless} <cond>]8 s' A3 N ~/ i
reqirep <search> <string> [{if | unless} <cond>] (ignore case)( [" g2 c" k: k+ u+ _# V3 n/ v6 \( Z! O
Replace a regular expression with a string in an HTTP request line! i5 i* f) t) g" ^4 w( q% r
May be used in sections : defaults | frontend | listen | backend+ o! f z$ p+ C; c
no | yes | yes | yes
' @5 m% n" B3 y# v9 @% d0 H4 a Arguments :6 r- y$ u+ a+ e! B+ A Z
<search> is the regular expression applied to HTTP headers and to the; e$ [9 ]! w3 q+ B9 a$ a
request line. This is an extended regular expression. Parenthesis
# }0 X0 r* }% l. w grouping is supported and no preliminary backslash is required.
8 b V' }% c+ S" z Any space or known delimiter must be escaped using a backslash
5 H H5 q! I4 Y: C) g- E3 v- A ('\'). The pattern applies to a full line at a time. The "reqrep"" @5 o# o5 q' C
keyword strictly matches case while "reqirep" ignores case.
# }4 u# N: ]5 \5 V7 ~" r- h& B) b2 w6 K" }# ^) C! V
<string> is the complete line to be added. Any space or known delimiter3 ~2 H7 [8 y# B
must be escaped using a backslash ('\'). References to matched
P6 D. S! `( q pattern groups are possible using the common \N form, with N
8 z! |! j- Y- s7 z8 S being a single digit between 0 and 9. Please refer to section0 x, W0 j; _( |: g0 d/ Q7 J! }7 I3 q
6 about HTTP header manipulation for more information.
' z1 @4 Q1 x# ?! _) s8 p1 [6 r9 t1 U" R3 ^
<cond> is an optional matching condition built from ACLs. It makes it, E, i" d' r/ J
possible to ignore this rule when other conditions are not met.' R) R% r" M' F* s5 P! l7 ^! b
* ` h3 l h( r4 i Any line matching extended regular expression <search> in the request (both
, K! F6 {9 e! K, s# G, R the request line and header lines) will be completely replaced with <string>.
- @: ]; T: c4 T Most common use of this is to rewrite URLs or domain names in "Host" headers.
n2 w% Q+ y. O% b+ @2 E5 a* h5 `# {) u
Header transformations only apply to traffic which passes through HAProxy,
- z! {! [* d9 @/ j$ p, I and not to traffic generated by HAProxy, such as health-checks or error
" G8 P% V( Y! H8 X% | responses. Note that for increased readability, it is suggested to add enough- b8 J( w# C" Z) U6 |% v8 B( S
spaces between the request and the response. Keep in mind that URLs in- f/ J! N" M4 e" v5 ~
request line are case-sensitive while header names are not.. `4 c& U- u7 ^- Z
( u0 h4 y6 \3 |8 J0 j( |5 ~# p
Example :1 V, N1 D5 `9 y
# replace "/static/" with "/" at the beginning of any request path.
4 B0 l+ {( |9 j9 V0 l- P reqrep ^([^\ :]*)\ /static/(.*) \1\ /\2
; X8 Z* _" T: m$ a" _) N # replace "www.mydomain.com" with "www" in the host name.
3 ?" g% U; g6 ~4 e reqirep ^Host:\ www.mydomain.com Host:\ www$ L# ]0 M" {2 H$ l) V
% s) q+ F) F! ?3 k
See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header3 \' H- _# S6 I& y5 _. X3 Y
manipulation, and section 7 about ACLs.& j0 `% s/ H: d: B& G, V' o
9 j: @* u. j# h+ V. M" i* _3 F, T% i; i
reqtarpit <search> [{if | unless} <cond>]/ \& M* J1 l# V3 N
reqitarpit <search> [{if | unless} <cond>] (ignore case)
0 w: Y& |7 ]% d6 { Tarpit an HTTP request containing a line matching a regular expression8 j# Y: U0 d0 V9 T/ |+ R7 P
May be used in sections : defaults | frontend | listen | backend
) }+ R: B; F' D0 ]. `; ^2 E8 D no | yes | yes | yes" q- K$ U% k; [* i
Arguments :
% s6 ?) q2 {" x; | <search> is the regular expression applied to HTTP headers and to the
; g" P7 c2 I' C& s2 K- S2 F% ~ request line. This is an extended regular expression. Parenthesis3 M) p2 b2 Z$ Y4 Q# s4 B8 |! u& p
grouping is supported and no preliminary backslash is required.: W* A I2 c/ ^' m* G/ o, D! ]
Any space or known delimiter must be escaped using a backslash" H$ d; \1 @1 o/ ^: u
('\'). The pattern applies to a full line at a time. The( B+ t( A$ L0 T
"reqtarpit" keyword strictly matches case while "reqitarpit"; m/ S+ [/ K" s. X# o! j' j
ignores case.; u: i" C5 A+ v, @
/ g) f( q4 h6 |% w3 I# t( G <cond> is an optional matching condition built from ACLs. It makes it
( a5 c& ?7 m5 m possible to ignore this rule when other conditions are not met.
$ B1 S G) C9 t, Q
9 s: }0 N/ [' O8 \$ N2 O A request containing any line which matches extended regular expression; l8 k. ]# u1 ]9 d
<search> will be tarpitted, which means that it will connect to nowhere, will
! B' c/ Q" L" }7 t3 V: m be kept open for a pre-defined time, then will return an HTTP error 500 so
$ A% J5 v% U* n1 p$ G that the attacker does not suspect it has been tarpitted. The status 500 will
- t) b* k1 [( J, Z- ] be reported in the logs, but the completion flags will indicate "PT". The; ]* W& s% ^# F, I! S* z
delay is defined by "timeout tarpit", or "timeout connect" if the former is
* _# K& L C* D% l |9 }" h5 k not set.
, V* f& x7 V/ {" W9 \3 \
; L2 ~6 O( R0 f6 r The goal of the tarpit is to slow down robots attacking servers with$ y/ L; m; ?) A2 D) I- U K- H$ v
identifiable requests. Many robots limit their outgoing number of connections3 F: e! l6 a9 x
and stay connected waiting for a reply which can take several minutes to& ~# a! Q$ [7 C I# }4 G
come. Depending on the environment and attack, it may be particularly
5 [: c: p" P, i' U8 K efficient at reducing the load on the network and firewalls.* f" F9 I( }2 I7 g8 n9 ^6 T
~. n: C& u0 H% T
Examples :* {! T) O/ N" {& d/ N
# ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but
- ~: y3 q- m* \8 L/ V # block all others.0 O0 ~7 w, H% h$ U, V. O
reqipass ^User-Agent:\.*(Mozilla|MSIE)1 b5 B" q* @# D8 j- w0 ~
reqitarpit ^User-Agent:) ]0 S$ _( p, B) {: O$ I
! V* ]# A4 [6 |; f' N # block bad guys% ?3 \3 b- J: y9 ~
acl badguys src 10.1.0.3 172.16.13.20/28% q: K5 }' a/ H/ i& ?
reqitarpit . if badguys, n1 E6 {. h+ O( E8 C W& N
' n, O4 K. n3 G" h( X0 v4 q) l! Z See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header: A* S4 y. I; `) D6 @3 _$ @! }
manipulation, and section 7 about ACLs.4 k8 j; r9 F5 I& u$ i' S- j- ^
4 B/ p4 k, \' m. P5 a* E! {2 \5 F# ~* k% w b
retries <value>
% v: {) g1 r# D- n! T Set the number of retries to perform on a server after a connection failure- m" E. X. b3 b7 Q& J
May be used in sections: defaults | frontend | listen | backend
) b" R+ K! b. J; m$ x yes | no | yes | yes5 v2 J% v( j* h& v5 D' X
Arguments :# }6 y; l( i/ k/ f
<value> is the number of times a connection attempt should be retried on3 @% n. F% h$ s s6 ]. d. @0 C0 c( H( S
a server when a connection either is refused or times out. The
% X& T" x1 Z" O, K( g2 s- T default value is 3.4 s- F( G$ l! F( a
- u8 M; A7 p; @& Q/ N/ v# X It is important to understand that this value applies to the number of5 H( ]# P9 e1 l1 c- m3 o
connection attempts, not full requests. When a connection has effectively0 \, N* Z5 R' f/ }
been established to a server, there will be no more retry.
) K3 U* Z$ h: q; i: x( Q/ E) {: G+ }" K% W/ W+ s, ~3 C+ _( u5 c% G
In order to avoid immediate reconnections to a server which is restarting,: I( ]" ^) j' t
a turn-around timer of 1 second is applied before a retry occurs.0 U1 Z6 L4 |6 }( R( m; @. z0 i" J
7 m6 D% U- r; X. u When "option redispatch" is set, the last retry may be performed on another
; ]' \8 p k) `, j& { server even if a cookie references a different server.9 s7 u3 H& g# {$ X: Y
+ C3 J3 D( \0 z
See also : "option redispatch"
2 Q# U* ~5 |' o9 v& N2 W
$ f' ~/ U+ K2 C( F/ ^+ q: p* b& a
/ G2 K: v" Z+ o) |rspadd <string> [{if | unless} <cond>]5 {6 G4 |0 z m5 Z8 n9 [5 d4 f
Add a header at the end of the HTTP response
7 T1 l# G n4 T0 o1 ~' p May be used in sections : defaults | frontend | listen | backend
8 p* k) Q- J1 T0 d% r no | yes | yes | yes& P2 I u5 [4 X4 Y& d0 [! g8 y
Arguments :0 a7 J4 n% Y& w1 |7 r
<string> is the complete line to be added. Any space or known delimiter, u$ |7 U8 V; C9 b' O* `
must be escaped using a backslash ('\'). Please refer to section2 M$ e2 M: P! T6 b+ R0 B
6 about HTTP header manipulation for more information." K$ h1 b, Z. v6 n8 a& d: U
0 d$ N1 X" T4 u* v# ?
<cond> is an optional matching condition built from ACLs. It makes it
$ D6 m- G0 M/ U, a; _ possible to ignore this rule when other conditions are not met.
9 g! @) k/ _7 T; }
; }5 ? Y- \4 _2 x% R9 T' l K A new line consisting in <string> followed by a line feed will be added after. F: H2 ?8 b# g8 |
the last header of an HTTP response.
/ M9 P" p8 A1 C6 H; H4 `8 [- t( H% s( M) k* C- y) d: m
Header transformations only apply to traffic which passes through HAProxy,
* i$ r8 j7 A1 u) Z" v( Z and not to traffic generated by HAProxy, such as health-checks or error
! a! G+ M; p9 S; C/ |6 a responses.
& |: F+ u W, J2 M, _% Z/ p
1 O0 @! Q5 W! |5 |* h4 ~ See also: "reqadd", section 6 about HTTP header manipulation, and section 76 a' ~+ ^( g/ K" m3 h7 }. ?
about ACLs.
% z% x, a) C2 K
' {) X5 R& e* [" t# J) `9 d, u$ D1 y" J
rspdel <search> [{if | unless} <cond>]) j$ o5 d6 ]5 m, H/ \9 v. f% G
rspidel <search> [{if | unless} <cond>] (ignore case)3 b7 Q; S( K, |' [9 ~( y
Delete all headers matching a regular expression in an HTTP response
* q2 u% W- f1 y May be used in sections : defaults | frontend | listen | backend$ R+ y3 H0 B! }6 [
no | yes | yes | yes# i7 K& m# b0 ~' x- Z5 T1 E
Arguments :
" e' m! q) b" t" B <search> is the regular expression applied to HTTP headers and to the0 n) s6 V7 u2 J" `/ T E4 z
response line. This is an extended regular expression, so; i8 f; u" n% m/ f2 l1 n
parenthesis grouping is supported and no preliminary backslash
( p+ B9 X5 r4 t( i4 W7 [ is required. Any space or known delimiter must be escaped using/ |& _* J. j' N9 ` P' q& u
a backslash ('\'). The pattern applies to a full line at a time.+ B* m% d& i' B1 p+ R% }" s' N, l
The "rspdel" keyword strictly matches case while "rspidel"( p8 l: l4 e! L, N$ c
ignores case.
L9 K% h$ q& H" r' |7 D3 c- P, w2 n0 L8 z* T
<cond> is an optional matching condition built from ACLs. It makes it
# u6 ?3 t/ K9 r- D `- O possible to ignore this rule when other conditions are not met.6 Y0 P, q" i! Q# S) \
, g! j, e; [8 W z) M) t6 N4 y$ p Any header line matching extended regular expression <search> in the response
" w& n1 |, ]( b7 s- V5 u will be completely deleted. Most common use of this is to remove unwanted
7 y7 P9 Y& c0 F7 Q and/or sensitive headers or cookies from a response before passing it to the
& J1 d6 T- w2 I+ h/ @! Q, R* F. i client.6 ?1 [5 c* b6 N9 ]$ L+ z/ B
2 ]) g3 J" P8 a p z Header transformations only apply to traffic which passes through HAProxy,
: ~% b. y. F7 x2 \5 K! p& J and not to traffic generated by HAProxy, such as health-checks or error( C8 e0 Z- ~* H" k2 ?5 ^
responses. Keep in mind that header names are not case-sensitive.
+ [8 q) I* L1 q4 {0 P
3 g1 B* C# H& W. E Example :% C% K! ?1 I t. F! O
# remove the Server header from responses
. `7 N5 s. I+ g. @ reqidel ^Server:.*
. W. C/ n) O. H& m: h/ R, _/ o- B! U" N. ]
See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header
$ d. q- D* U2 Z/ Q manipulation, and section 7 about ACLs.
. K* i/ e" ?/ `9 @0 ^7 H0 ?2 k9 v, z" g
E d2 ?) S9 `& ~
rspdeny <search> [{if | unless} <cond>]$ j9 p" S# L" @* B% K
rspideny <search> [{if | unless} <cond>] (ignore case)& u5 G6 k4 i0 ]+ W1 Q
Block an HTTP response if a line matches a regular expression
, k/ i: k2 m5 k8 J+ A) _ May be used in sections : defaults | frontend | listen | backend
1 @+ @: F9 x2 t no | yes | yes | yes U& ?. f+ M+ o2 l5 i5 m
Arguments :
1 `, v; z( h5 G <search> is the regular expression applied to HTTP headers and to the9 B1 |8 {" n4 v) g, K
response line. This is an extended regular expression, so
5 m2 W; @, D9 z% X# _5 s parenthesis grouping is supported and no preliminary backslash
4 O a8 k0 v, z. F# u. l% q2 B is required. Any space or known delimiter must be escaped using
$ a8 P0 X$ g2 a# z+ S8 n+ z m a backslash ('\'). The pattern applies to a full line at a time.' p- H1 o+ b* B( R! P* \1 i
The "rspdeny" keyword strictly matches case while "rspideny"$ k$ K' H+ f) Z* q
ignores case.
% o1 k8 }" }6 i( l6 v" y9 x
7 J2 K0 W4 i( b( X5 m <cond> is an optional matching condition built from ACLs. It makes it
' @3 J+ b+ A# ~" d' n1 S possible to ignore this rule when other conditions are not met. n' W7 ^# N# [6 O
! Z6 B: Z" X: i7 { A response containing any line which matches extended regular expression0 y, Z; Q' W1 [
<search> will mark the request as denied. The test applies both to the
" D- _6 q& G* ^0 u8 [% f) d response line and to response headers. Keep in mind that header names are not8 f2 t$ D, w7 x! {: Z% D- I- v( t7 p
case-sensitive.0 ~! o+ c' n: h) o1 ~
9 T8 {+ L0 d/ V7 ^( ^8 g2 o
Main use of this keyword is to prevent sensitive information leak and to
! W: A6 l: ~& _( e block the response before it reaches the client. If a response is denied, it% M; i {7 d/ Q
will be replaced with an HTTP 502 error so that the client never retrieves
7 n: b& Z) N; i J, }4 O" x any sensitive data.; D) K' W5 V8 ~/ H
6 J! P3 h. D/ S. k It is easier, faster and more powerful to use ACLs to write access policies.
2 w. M. s6 t+ F# E7 h" m6 ~ Rspdeny should be avoided in new designs.% N0 e0 {7 J! O3 f* R) e
5 X6 X7 s3 f9 Y# w& y5 G4 R
Example :. A3 d C. W! r7 l3 F% t
# Ensure that no content type matching ms-word will leak2 j; d; S6 ^4 }1 p4 h
rspideny ^Content-type:\.*/ms-word0 v7 ~0 O1 o$ M( h
: t! {6 u" Q2 z8 L$ F' q+ R See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation
( X; ~: R$ q! { and section 7 about ACLs.
2 R ~: |& W3 ]4 `4 |% o( |9 J- `- T0 Z1 c0 T* Y. O- O7 _2 Y
3 V7 [( l1 U2 Q6 @3 orsprep <search> <string> [{if | unless} <cond>]
- W# @0 c/ `4 z/ t2 lrspirep <search> <string> [{if | unless} <cond>] (ignore case)
" @/ m( s* [% B9 ^" {* m Replace a regular expression with a string in an HTTP response line2 k% \, ?7 U$ L2 R# W5 n% _
May be used in sections : defaults | frontend | listen | backend. v. g% Z$ O1 I( s$ r: n6 U% S
no | yes | yes | yes4 m$ q' \% P( }) w5 h
Arguments :
# C1 \! ?. O1 m' \; a+ k: { B <search> is the regular expression applied to HTTP headers and to the
1 B, _8 @- d% R: H- c, G3 n: s response line. This is an extended regular expression, so
; z, q' ^$ N- y" I/ @ parenthesis grouping is supported and no preliminary backslash3 F+ T( \& o( A! W: i
is required. Any space or known delimiter must be escaped using3 M! j6 }, L6 o- n
a backslash ('\'). The pattern applies to a full line at a time.
7 O) n, J$ q3 f8 v7 y& M% z/ N0 @( a The "rsprep" keyword strictly matches case while "rspirep"2 ]7 f) G+ X# }- {
ignores case.
6 f9 N3 f4 I, U/ R, [3 X& U+ ~/ S& `% b8 ]1 r1 n9 w
<string> is the complete line to be added. Any space or known delimiter2 ?5 x6 t* n. ~, g. n+ g
must be escaped using a backslash ('\'). References to matched I, W' O+ E$ n
pattern groups are possible using the common \N form, with N
4 y4 K- ?; j! M% o! J% u being a single digit between 0 and 9. Please refer to section
. A& V! T# C s 6 about HTTP header manipulation for more information.+ N7 M o& }+ z- F
5 |* A5 ?. e. q5 c( a
<cond> is an optional matching condition built from ACLs. It makes it
6 l: T4 |+ c( k7 C; g4 b i- V possible to ignore this rule when other conditions are not met.
8 d0 J* ~4 \3 x& L1 k- f4 p/ x0 U. p/ z+ b2 u# K. w
Any line matching extended regular expression <search> in the response (both
/ ?+ l0 ]( J5 H( L# a/ d the response line and header lines) will be completely replaced with1 N1 T' o7 f; [1 ] f, T C1 a" b
<string>. Most common use of this is to rewrite Location headers.
+ I T% p3 w: A" A5 @5 ]! R. q" {1 q, Q) O9 X+ D4 |& i
Header transformations only apply to traffic which passes through HAProxy,9 K0 D+ F: o/ {6 {* A
and not to traffic generated by HAProxy, such as health-checks or error
) t9 m( [! N# d! d1 m responses. Note that for increased readability, it is suggested to add enough! |2 r2 {2 Z0 L6 R& G
spaces between the request and the response. Keep in mind that header names% `& H4 k8 x1 X- \) i/ E' w
are not case-sensitive.
" ~) f2 x( @- {1 @! t2 P0 }; D+ w% y* U# D" J
Example :
& q7 O8 A8 C. c/ }/ t( V # replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"
6 D0 Q2 T# n6 k/ \6 r! Z rspirep ^Location:\ 127.0.0.1:8080 Location:\ www.mydomain.com, @; \3 u8 X/ _4 U( u
% w8 A3 J( p) E2 z
See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header
. x3 A3 V; O1 k2 I% o4 j# h& d manipulation, and section 7 about ACLs.5 e& a) J( ^& O6 a/ Y
, Z' b/ z0 L9 L, B* F
. O( q2 b; Y' }( b# k
server <name> <address>[:port] [param*]. p5 N# F3 C9 I5 d4 a2 E( z9 L! O
Declare a server in a backend
1 L8 \% N; ~4 b( E V May be used in sections : defaults | frontend | listen | backend
+ @# s1 m' v; B- o5 k4 }; Z2 y no | no | yes | yes6 Y' E# p0 |5 V3 e! D
Arguments :% E9 ?# z8 o& c1 x7 V3 }* i
<name> is the internal name assigned to this server. This name will
{7 Y9 }2 ]1 L- }. @ appear in logs and alerts. If "http-send-server-name" is+ H$ ^/ v K H. c* V2 g/ p
set, it will be added to the request header sent to the server.
7 r- R: P' Q* @8 y! G7 u8 p; {& Y3 M1 d5 s: [# i. f0 r. u1 n2 h W
<address> is the IPv4 address of the server. Alternatively, a resolvable: z/ a( | H/ m7 L5 v2 u p
hostname is supported, but this name will be resolved during
5 I' `2 o$ R! Q5 X) V start-up. If no address is specified in front of the port, or if
: M: R, U/ D( `4 e5 V4 Y address "0.0.0.0" is specified, then the address used will be the0 G3 K; c5 s, Z9 g# z2 m" C
same as the one used by the incoming connection. This makes it
, N; }) D. R. b2 d2 g5 m possible to relay connections for many IPs on a different port or' ^- x3 F: `, M0 J" ~2 Q# H
to perform transparent forwarding with connection limitation.3 Q5 P/ x/ O4 q. J
3 j! P" Z7 ~- X1 f* \ <ports> is an optional port specification. If set, all connections will
+ k, G4 A# K4 K% | be sent to this port. If unset, the same port the client9 V, l& f8 f7 T6 y
connected to will be used. The port may also be prefixed by a "+"
4 c$ l y5 x( [ Y, y or a "-". In this case, the server's port will be determined by
( u+ v$ Z; ?) {; r" p adding this value to the client's port.# A& U' I# F1 L) U! `" A
+ z- d+ p5 C; i+ V2 Z
<param*> is a list of parameters for this server. The "server" keywords" O- M S. @1 ?6 S( V/ N: z
accepts an important number of options and has a complete section
" J1 W$ h0 k" H dedicated to it. Please refer to section 5 for more details.
7 a3 G$ k4 p5 M
( d# m1 W7 w: n# k9 g- Y: e0 C Examples :5 k$ y' [: s# L% ~
server first 10.1.1.1:1080 cookie first check inter 1000; ~7 j! p0 p. t: D( G) N
server second 10.1.1.2:1080 cookie second check inter 1000
v( c; Z$ f. V, ~1 Q" ]8 j( f, Q$ K- |/ I( v
See also: "default-server", "http-send-name-header" and section 5 about
: A z0 N+ \3 Y4 L6 _( u server options! v6 d5 t" d$ I: Z; \2 w
% x6 O% |" y" E5 ~8 W/ Q
& [2 H5 }+ }2 z' V" Dsource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]( h5 k, W3 T# c
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]( l9 |# N( R) f3 T" H5 ]2 e4 y
source <addr>[:<port>] [interface <name>]
/ @7 }6 s5 v) [ Set the source address for outgoing connections* T* P8 l1 W. P4 N# r% M
May be used in sections : defaults | frontend | listen | backend; o; c$ T1 u$ U$ y4 X* r
yes | no | yes | yes I8 o: z! H& d
Arguments :- v' W, i1 L4 B
<addr> is the IPv4 address HAProxy will bind to before connecting to a
9 ~" m- _6 _* e0 `, W( J) D" G9 E8 J) h server. This address is also used as a source for health checks.
" w: Z- N7 V$ p The default value of 0.0.0.0 means that the system will select# C! j7 `9 p' B, A) e
the most appropriate address to reach its destination.
% E1 J; J. w$ p+ \) F
( Z" o2 i* v, e* T. ?: M <port> is an optional port. It is normally not needed but may be useful
1 j, _4 P+ x' y5 t" _ in some very specific contexts. The default value of zero means3 a: V- E8 `! h3 r
the system will select a free port. Note that port ranges are not; J, K' x O; A5 G( M
supported in the backend. If you want to force port ranges, you
+ I+ W( J0 W* K* H/ z6 t have to specify them on each "server" line.& h7 w; `+ m* H5 S
) R/ X* ]1 Q& {2 B, h8 B/ T <addr2> is the IP address to present to the server when connections are1 ], B u; v6 M1 e5 d
forwarded in full transparent proxy mode. This is currently only3 l! g, F' V; y& o6 C/ Y
supported on some patched Linux kernels. When this address is
; h5 |8 h. j+ V) |0 ~6 @+ F specified, clients connecting to the server will be presented
# y/ a/ I) g2 U- X* e with this address, while health checks will still use the address6 j- J8 i9 p, O5 M' n+ s7 E2 k
<addr>.
0 |* y$ Z2 ]) p/ Y! {: Z" @: v0 O$ B7 `9 }
<port2> is the optional port to present to the server when connections
. }& _" C- l, q0 s# x4 i are forwarded in full transparent proxy mode (see <addr2> above).# z+ ^! l2 p3 \& S3 k
The default value of zero means the system will select a free
5 |- u$ f' ^5 W port.3 O+ M1 U4 x. O, q
9 k: r; }1 K& a5 p4 ^% {
<hdr> is the name of a HTTP header in which to fetch the IP to bind to.2 P- ~- A/ `) i1 L3 R' p/ P, G9 B
This is the name of a comma-separated header list which can
5 v1 W% _. _. b% l contain multiple IP addresses. By default, the last occurrence is! v0 I5 c. {! U( Q0 G
used. This is designed to work with the X-Forwarded-For header$ y2 c, l8 z4 @2 R( N# Q
and to automatically bind to the the client's IP address as seen$ L' ~) V2 {9 o9 r5 y6 S
by previous proxy, typically Stunnel. In order to use another/ N' S2 \& h! _
occurrence from the last one, please see the <occ> parameter$ F' T0 |# _. t2 \& W M7 H
below. When the header (or occurrence) is not found, no binding$ O4 A' ?* m- M- f9 T. w1 w
is performed so that the proxy's default IP address is used. Also) m1 K/ G2 P" M9 C x
keep in mind that the header name is case insensitive, as for any
3 {/ Y9 e# e# k HTTP header./ n) _3 n5 |6 _# M, K
( {+ r8 d+ M( x( b, c0 _# j" `& f <occ> is the occurrence number of a value to be used in a multi-value
' A" y% \* ], y" n header. This is to be used in conjunction with "hdr_ip(<hdr>)",
6 j1 k4 g" d1 [8 S! i! B h in order to specificy which occurrence to use for the source IP+ n. f- j( I# ]% f. o, r
address. Positive values indicate a position from the first
9 \; W; E8 J/ X6 G. f. ~ occurrence, 1 being the first one. Negative values indicate0 K9 X& K& S9 ]1 R% o
positions relative to the last one, -1 being the last one. This
{1 e4 a7 s3 ?% Q' H3 v; Q, A* R is helpful for situations where an X-Forwarded-For header is set
9 K& w) W" B- U1 L+ K at the entry point of an infrastructure and must be used several7 [& N+ r4 r% L" Z7 |+ Y$ }
proxy layers away. When this value is not specified, -1 is
) K0 ^- ?: t4 i assumed. Passing a zero here disables the feature.% Q& _ W8 n* K. L. ~$ C8 P
' m* G. q$ W6 g& @( u5 A1 A
<name> is an optional interface name to which to bind to for outgoing; r+ b4 D( }4 Z
traffic. On systems supporting this features (currently, only4 {# V# C' [8 U4 H6 C
Linux), this allows one to bind all traffic to the server to% H- z# E+ ~" m4 m- O* h) G; K
this interface even if it is not the one the system would select7 y) X* I* A U6 G( W7 H F! o
based on routing tables. This should be used with extreme care.2 u0 i. H _1 w$ b2 h
Note that using this option requires root privileges.# F1 r. g A8 y6 [
' `3 U# p& r2 G! v1 \ The "source" keyword is useful in complex environments where a specific
) b4 L+ N% J$ k6 |$ |, {6 X; E address only is allowed to connect to the servers. It may be needed when a
( N- j8 U# J @ private address must be used through a public gateway for instance, and it is
( d7 V6 n+ e, x- p5 J( @( E known that the system cannot determine the adequate source address by itself.
0 o1 H8 b. d/ j. C0 u" N0 v0 P; r1 r1 w
An extension which is available on certain patched Linux kernels may be used
I8 p4 `" Y0 w4 b+ |5 D& R! ^9 _ C( O through the "usesrc" optional keyword. It makes it possible to connect to the
$ M I! A A0 {1 {8 Y* O! | servers with an IP address which does not belong to the system itself. This( q; w+ q" [) s- p
is called "full transparent proxy mode". For this to work, the destination( [, I0 E" A3 T5 M+ V1 F( w
servers have to route their traffic back to this address through the machine
% Q2 g3 Q( p0 i" [/ T7 ~1 U, ?! R running HAProxy, and IP forwarding must generally be enabled on this machine.8 Q0 P% ~& n0 j+ l
0 O, [3 U4 T, ?( I0 U) b/ F In this "full transparent proxy" mode, it is possible to force a specific IP
/ ]/ {9 h6 X: S& w. H5 l- B address to be presented to the servers. This is not much used in fact. A more6 Q7 ?- s7 \) a+ |9 S
common use is to tell HAProxy to present the client's IP address. For this,; |- K* d4 G# ^, `# s- {) g" ^
there are two methods :, p$ R+ y0 N, S! R7 E5 `2 d h
! F4 ~8 @; ~( w! l* `+ M; P+ f" z - present the client's IP and port addresses. This is the most transparent
: a& J' F3 N1 {0 p. ?) _ mode, but it can cause problems when IP connection tracking is enabled on
. k5 t$ w, w8 i7 b- S3 P. ] the machine, because a same connection may be seen twice with different
5 F) u' O% G* W/ r+ u states. However, this solution presents the huge advantage of not2 R* m9 ^; a0 t: K7 w8 F
limiting the system to the 64k outgoing address+port couples, because all
; ^5 |0 ~5 N X$ a; [ of the client ranges may be used.
( V6 j. M8 l$ \8 K$ _/ O8 @" a) s, g }; [7 a3 ^2 N5 {
- present only the client's IP address and select a spare port. This4 u: U+ A; A# r' h; z
solution is still quite elegant but slightly less transparent (downstream5 H3 b5 A. V/ t1 |
firewalls logs will not match upstream's). It also presents the downside
y9 K7 @( U | of limiting the number of concurrent connections to the usual 64k ports.' g a }$ B8 l4 U, X. L
However, since the upstream and downstream ports are different, local IP' c) N* m$ K2 u+ u P c
connection tracking on the machine will not be upset by the reuse of the$ P% e M+ i# Z2 a8 X5 J; I
same session.
" Q% }: X9 X/ p+ K) B b$ ]+ G
Note that depending on the transparent proxy technology used, it may be* J: u# c( X7 v& J: D
required to force the source address. In fact, cttproxy version 2 requires an" T3 ]3 K! d, o7 b
IP address in <addr> above, and does not support setting of "0.0.0.0" as the& N4 m! z0 h; G3 ]- s
IP address because it creates NAT entries which much match the exact outgoing! r% i( R# v5 A3 s3 F
address. Tproxy version 4 and some other kernel patches which work in pure0 X8 s' S+ \ T' w6 f0 @
forwarding mode generally will not have this limitation.3 r- |* W# g! C
7 C4 q1 F( W: j$ F7 f& _ This option sets the default source for all servers in the backend. It may2 W/ [7 ]; q- _ d' {$ J- K) | F
also be specified in a "defaults" section. Finer source address specification0 T4 e) y" E+ P4 L; I7 s6 W: t
is possible at the server level using the "source" server option. Refer to$ T5 R4 D" i3 k4 J* r& b- ^
section 5 for more information.9 v( k) g4 ^3 G2 A* K
9 N" c/ w$ U7 D( J3 \8 @ In order to work, "usesrc" requires root privileges.
& |0 C- A) H- y( s; y$ `
+ w q5 E: P9 T9 N Examples :
/ X/ l$ H b, W+ j* s9 t8 @" d backend private7 ]& U) f/ b, d& k( w( p
# Connect to the servers using our 192.168.1.200 source address
8 K; D! P( M T; d# q: v" k4 [ source 192.168.1.200
7 B. Y; @+ t0 C6 _3 \
1 T$ `' I, Z1 n) _) I; H backend transparent_ssl14 \3 U6 Q8 I2 a) X/ T! v/ l5 A
# Connect to the SSL farm from the client's source address
. Z! V W9 }, n. j1 i source 192.168.1.200 usesrc clientip
1 ~' M! P9 c7 I0 p% z4 U( U! P. J
backend transparent_ssl2
% Z" i9 ?! r) d0 [3 K# q t # Connect to the SSL farm from the client's source address and port( d, p- h% [9 r& @$ O6 j" z" c
# not recommended if IP conntrack is present on the local machine.( B# k' m' i/ ?) [! ~- s3 [7 c
source 192.168.1.200 usesrc client
4 E+ N7 k7 n3 a$ e! m- |9 u2 i
2 E* v$ y5 b( B, f1 _% S' A backend transparent_ssl30 h$ g& x8 M; A6 Y# t) G
# Connect to the SSL farm from the client's source address. It
$ T) t8 o. \4 W: b j/ z # is more conntrack-friendly.
: I' k" g# I5 p8 i8 u# e4 _ source 192.168.1.200 usesrc clientip4 N4 D/ @6 i0 ?8 y- D3 C
: J: s' q* R/ Y7 i8 p# H
backend transparent_smtp
" h% L+ u( B- [$ _; l" z7 j1 c # Connect to the SMTP farm from the client's source address/port
+ d* \. |) r% f6 N/ t. U # with Tproxy version 4.
( m% A9 b4 Q" w- ~. K+ ]" w source 0.0.0.0 usesrc clientip
3 W( ~- j0 I L; m9 {* \/ H
4 t' ~# L8 U! z: [ backend transparent_http
+ v0 F1 x/ k* A' V) K: B$ f # Connect to the servers using the client's IP as seen by previous
' ^. ^* [) F% b # proxy.
: j f: J0 X& G. Y2 u6 O source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)8 w, ~9 q; }* _' O
9 d! E1 P8 b: t* |3 g! E5 `; y) z See also : the "source" server option in section 5, the Tproxy patches for2 _+ N* L, w' J6 \
the Linux kernel on www.balabit.com, the "bind" keyword.$ N3 K* P( m" F7 P
5 T8 Z6 \& U5 y" K+ U; j+ f2 [7 W, ?: F; q) e' Z& M* @
srvtimeout <timeout> (deprecated)
' G" p. [5 |, q! V$ F Set the maximum inactivity time on the server side.
+ c& o) j$ Z6 a' U5 n+ Y. C May be used in sections : defaults | frontend | listen | backend
; g0 g' V, t5 v* i, M, z H yes | no | yes | yes
, V8 \5 f, f! A Arguments :2 U* ^! Y' `3 ^. I. q
<timeout> is the timeout value specified in milliseconds by default, but
/ J- j" x1 ?+ z c( G can be in any other unit if the number is suffixed by the unit,
4 H3 p3 H: v9 V as explained at the top of this document.
- [, j* `3 p+ |; O$ D6 t* e
* W: b% A9 x2 {, e2 i The inactivity timeout applies when the server is expected to acknowledge or
3 S4 R0 @$ ]9 {+ r, D send data. In HTTP mode, this timeout is particularly important to consider
& X0 T7 E! ^) y% ?2 {9 _ during the first phase of the server's response, when it has to send the
4 M, K: y; t0 o) M$ s headers, as it directly represents the server's processing time for the, ?. F0 v: O B1 ]9 r
request. To find out what value to put there, it's often good to start with& [4 |2 P: N; f4 T- u6 i4 z- N
what would be considered as unacceptable response times, then check the logs
$ r0 t, _ X* i1 C& r to observe the response time distribution, and adjust the value accordingly., E( {" [0 u' I( T1 s( ~8 _ U
$ ]& E6 k4 o1 ^) d
The value is specified in milliseconds by default, but can be in any other' C( ]; ~0 o' T" t9 d& o* k
unit if the number is suffixed by the unit, as specified at the top of this' ?- }$ p3 l; I) ]6 ?2 b
document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly
% k* Z+ |7 D) d2 g4 M recommended that the client timeout remains equal to the server timeout in
0 A! p: C" W/ G+ \! Z/ W$ w3 f! _4 l4 Z9 P order to avoid complex situations to debug. Whatever the expected server9 |% d' @6 h/ X) E3 m; b& Z
response times, it is a good practice to cover at least one or several TCP
. T; s8 ?0 u+ \9 r3 m" D packet losses by specifying timeouts that are slightly above multiples of 3
* W4 y8 J* L0 D: s seconds (eg: 4 or 5 seconds minimum).
9 j* K/ q" v' I. I' o6 c
/ U; a! p. ]6 n2 h1 {' h- I This parameter is specific to backends, but can be specified once for all in G! c2 ^! [. z/ X
"defaults" sections. This is in fact one of the easiest solutions not to
9 y- B T( ~" F' E$ w8 L4 V. j3 l. e forget about it. An unspecified timeout results in an infinite timeout, which
% l5 h2 D# Z; Y, ` is not recommended. Such a usage is accepted and works but reports a warning M( |( @, e4 N' m9 I1 M: A
during startup because it may results in accumulation of expired sessions in
. I% P6 e; g9 i$ M2 G0 \/ |& Y the system if the system's timeouts are not configured either.4 ]3 _/ d5 c7 |
0 L5 j+ x* H ~3 y4 M
This parameter is provided for compatibility but is currently deprecated.
- V3 L6 S6 g% T) K7 X! k2 v Please use "timeout server" instead.5 q+ k; o8 }7 n4 u2 j# e! {" W5 D& v
1 L8 H2 a' e8 V! i _0 n+ \' D0 s See also : "timeout server", "timeout client" and "clitimeout".
6 D. A, X2 P, D1 F
Q& ]% N# }. y- y4 @. k+ G+ j% a4 N! L+ W. A$ ^
stats admin { if | unless } <cond>* ^0 J; g! \8 Z6 h1 f6 o
Enable statistics admin level if/unless a condition is matched. z. f- ^: t; C
May be used in sections : defaults | frontend | listen | backend
, P! A( D: I3 b! X' J8 m: \ no | no | yes | yes
6 N& S# F4 ~2 z7 E7 s
, ~1 T0 C. G: s# y' v' ]" C This statement enables the statistics admin level if/unless a condition is
# I& n( @8 a, x9 T matched.$ I( C7 J% G) `
0 L- V6 F1 S3 y. \. w1 }. ]* O
The admin level allows to enable/disable servers from the web interface. By
3 e4 X6 j5 g; N7 `# I G7 { default, statistics page is read-only for security reasons.4 c, z' r/ |4 \) H3 S
# L. \5 V6 G( E5 E1 k
Note : Consider not using this feature in multi-process mode (nbproc > 1)
, w( S+ ^0 {: y" _ unless you know what you do : memory is not shared between the
, B7 x3 T& V3 {' a processes, which can result in random behaviours.
) s5 J' x7 n/ A. @, y7 b9 G$ s
% B9 y0 v* \ ? Currently, the POST request is limited to the buffer size minus the reserved
3 @1 U. v/ Z; e3 [1 B1 y. a. _) @ buffer space, which means that if the list of servers is too long, the
: N1 @+ i0 }# Q$ [ request won't be processed. It is recommended to alter few servers at a! q1 ]2 }' \6 U
time.( q3 Q' ~! {6 A% [
4 b7 @! m# x2 k, v, i( ? Example :
: Z6 s& e9 `! h, L6 C # statistics admin level only for localhost
4 w; @' p. b+ A- U. z4 D- c backend stats_localhost' v- q: j$ Y3 G$ z
stats enable; w" Z$ b8 E/ o: F" u" X: Q
stats admin if LOCALHOST6 R( z) h" [6 Z0 T+ g; \
+ D$ E a3 R5 b$ V" J# O C Example :9 n1 H" ^9 \3 w+ E
# statistics admin level always enabled because of the authentication- n: M. v( [( @+ J
backend stats_auth
- ^9 X. v5 {1 v* G8 D# y W$ F stats enable# C6 [, Z, M5 a( d. A3 L9 ~
stats auth admin:AdMiN123
' F/ j3 F, y- d" ]" C- | stats admin if TRUE4 W. a2 R/ [* K/ {, p1 e4 z' [+ s
9 t7 Z, c' s% Z3 ?! B
Example :
8 g, j+ a! B3 e2 g! S # statistics admin level depends on the authenticated user
7 T/ V; w& X+ \* x6 E userlist stats-auth% b. O, U, M% D: S; Q
group admin users admin9 k; E. H H: |
user admin insecure-password AdMiN123* f+ I% T3 g2 K. q8 B# A& r; R
group readonly users haproxy; X3 H1 s8 W6 ?$ }" |( Q
user haproxy insecure-password haproxy" O# t9 C( m/ W/ g. `
, [3 [! M7 a$ F3 {) }
backend stats_auth
9 R$ {0 \9 W9 I* W; O' B stats enable+ M/ l( p3 w% ?
acl AUTH http_auth(stats-auth)
3 l0 \( o6 Z: c' \6 f acl AUTH_ADMIN http_auth_group(stats-auth) admin9 R* G9 `5 q7 O v- |: @: @* a
stats http-request auth unless AUTH% K9 |, z; h/ i% K9 O2 O
stats admin if AUTH_ADMIN
0 t, }9 w3 G: Y1 d5 z$ q, m6 W; @2 @" m7 `. L$ M; P2 Y/ e
See also : "stats enable", "stats auth", "stats http-request", "nbproc",, {) k2 N0 K3 _5 u. R- M, r
"bind-process", section 3.4 about userlists and section 7 about
2 ~% }( k$ P% }2 w$ ]( X ACL usage.
3 {; p- S" w% y0 n$ T/ C8 t6 q/ l! B# k# d1 f. C
2 q& n" ?- _; C$ @1 _
stats auth <user>:<passwd>
# R1 a8 g6 e( h Enable statistics with authentication and grant access to an account
4 o+ e; e O0 E8 \: ~ May be used in sections : defaults | frontend | listen | backend4 `" Y) A( h2 W2 s( @6 j5 n; y8 ?
yes | no | yes | yes) \7 Z/ I7 F" L- M; S
Arguments :
5 m, s' ^, L& R2 \7 O( { <user> is a user name to grant access to
% X# w; Y# H( ~5 f7 G9 |# e
! m3 h8 i' t6 r- E% p; n <passwd> is the cleartext password associated to this user
- I$ _$ ?7 E" x8 t/ s1 [; n( k1 ?% n! a! w; Q
This statement enables statistics with default settings, and restricts access8 n& s! ` k" V0 m
to declared users only. It may be repeated as many times as necessary to% a; @: o* q* R, q/ M9 o
allow as many users as desired. When a user tries to access the statistics
$ z/ }- o: i6 k0 S2 z2 W7 m! \+ o without a valid account, a "401 Forbidden" response will be returned so that
0 ~- N7 R0 h% b& @; R# h5 B" l the browser asks the user to provide a valid user and password. The real% |+ m3 T$ D7 i+ t: z4 C; I9 Z% f
which will be returned to the browser is configurable using "stats realm".
0 h% R9 s% T2 Q& T9 b
+ i& @: s" u$ x( O/ A Since the authentication method is HTTP Basic Authentication, the passwords2 v' u+ @3 @. f. x
circulate in cleartext on the network. Thus, it was decided that the
+ m- ~1 g7 T* G configuration file would also use cleartext passwords to remind the users
2 k/ H; K; ?6 c$ D5 o that those ones should not be sensitive and not shared with any other account.1 |! Y! m* {. h5 V. e: I
2 Y% k" Y: H- O It is also possible to reduce the scope of the proxies which appear in the0 I* M6 o, }: m' ?6 v5 G' B" C, j, p
report using "stats scope".' X% R" X* c5 n2 k% s, y) E Y
$ w5 b$ e! t* T
Though this statement alone is enough to enable statistics reporting, it is( B v: S# N+ n. @% \* |4 P( r/ S
recommended to set all other settings in order to avoid relying on default
+ D( F# }0 X% H7 n# w% C$ R j- ` unobvious parameters." e* P+ P$ b( J
% j0 G+ l5 T# }; E
Example :7 ~) l3 d d c: z
# public access (limited to this backend only): f/ a( V9 i6 D. @6 g
backend public_www7 x. \3 h! S. W" K& E
server srv1 192.168.0.1:80
; S# K( p% ?9 }3 {3 T stats enable
e- \6 `# Y' p. K9 n( l6 [ stats hide-version
) y! Q: U' Q" M5 B/ o! w stats scope .# O H6 L3 t6 _2 p- D$ H6 p {) V6 T
stats uri /admin?stats
! r% g* s7 w3 A stats realm Haproxy\ Statistics
5 w( v- H5 P) A: o9 {4 t& b stats auth admin1:AdMiN123
- f$ I* Q1 d4 q# S# F# p: e stats auth admin2:AdMiN321
9 `' [ K! V& n& `
: Q3 j6 T8 d* K; G/ b) y9 J6 { # internal monitoring access (unlimited)3 w$ z) m( }. ?5 G3 R5 r
backend private_monitoring
! @- p1 j3 f5 o/ O) Y' F0 W3 T6 h! n3 u stats enable
) x# z0 X4 ?+ l* t stats uri /admin?stats
8 R0 P8 J% A9 t9 {$ F- a* n0 B& {( ` stats refresh 5s; n d6 b$ Y8 i2 R9 U2 r/ M3 R3 s
( f+ h2 M3 G. K X
See also : "stats enable", "stats realm", "stats scope", "stats uri" M0 |6 \; p: C% g
/ s( U& J" l3 @" A
7 J* m3 K2 E4 U2 N! z" a$ v" Estats enable
0 \7 K7 J# x0 @ W/ U" | Enable statistics reporting with default settings
7 t, P3 |. _) }) s0 A$ W May be used in sections : defaults | frontend | listen | backend! B0 y( L' [. S$ ?: f% S
yes | no | yes | yes
- \& Z5 o6 i9 h6 w* M+ g# v# [6 p Arguments : none. t, V( C) _, {; n2 B0 T3 [
7 U7 P W) D! G) W This statement enables statistics reporting with default settings defined) E; m9 ?3 m, g
at build time. Unless stated otherwise, these settings are used :; V0 w- O) P1 @! j# M( _- q0 F
- stats uri : /haproxy?stats1 x1 b9 N/ l7 T8 S' e
- stats realm : "HAProxy Statistics": w: E% g* w6 `* F5 m# K, f
- stats auth : no authentication5 E! o+ ?, o1 M% E7 C, L
- stats scope : no restriction
( Q/ E) Y: e5 i/ N! [) E6 v5 s; D/ N( Q' m0 ] I, p/ E/ C: B
Though this statement alone is enough to enable statistics reporting, it is% F8 o3 v# N, z, Q3 z9 k/ P
recommended to set all other settings in order to avoid relying on default
4 R$ _2 s s* Y unobvious parameters.
, U! j- U0 M2 @' R/ u6 ]1 z
O! j' R: R+ x- |4 N: U Example :+ Z/ \) W. L3 z1 x8 J; N
# public access (limited to this backend only)
4 J$ i2 ^* U+ m9 ?6 b backend public_www
+ @! {4 }9 }$ T' u" e+ C server srv1 192.168.0.1:807 s* J( }+ b ?: o
stats enable% \3 h1 V# [' w9 d$ U
stats hide-version3 @) \ e# p* w) }* P
stats scope .3 u J% Q( T' r5 ^) n0 C7 V$ [
stats uri /admin?stats5 G/ ^& X4 f! i: L7 Z/ ^
stats realm Haproxy\ Statistics V: I! a6 b$ {
stats auth admin1:AdMiN1236 P; i( C- m. R- ~: E$ M, D; d5 P
stats auth admin2:AdMiN321" A7 D% B6 v9 o' m: w, r7 y
2 _8 {: H& L, N; @ # internal monitoring access (unlimited)9 c8 m) j9 @7 c' `* u2 o8 J7 K8 n
backend private_monitoring
( X" e& V- R4 v; V6 A( t3 C4 F3 @ stats enable
; ~+ X$ J7 A h: C6 n stats uri /admin?stats
0 w. t! s2 g7 _/ z( y# N stats refresh 5s& r6 J4 ~: a% j# i5 F
/ k% K- g4 O5 B2 q* @8 n; ` See also : "stats auth", "stats realm", "stats uri"& U) c1 k) ^0 q% O( S7 q& i
; q& C$ M9 k; `9 B4 X7 O* m x' w! A2 @/ T/ T7 F
stats hide-version
" ^" R6 m9 T4 i. R' [. A; c Enable statistics and hide HAProxy version reporting
# p% }9 o( C$ q May be used in sections : defaults | frontend | listen | backend
: W; s9 b9 s2 \+ h2 p; p! x8 _ yes | no | yes | yes D8 U- v. v/ z
Arguments : none) i) H% p. b0 ]4 s% C& `+ s
* {" N, d z8 Z9 k
By default, the stats page reports some useful status information along with- O! S4 f e# o- y T5 s6 O0 s
the statistics. Among them is HAProxy's version. However, it is generally# W, J( ^ R# x8 `& @ ~* j, Q
considered dangerous to report precise version to anyone, as it can help them
# D. u, [* o2 ^5 @# e8 J: i& q target known weaknesses with specific attacks. The "stats hide-version"3 @5 r5 t' M8 U" j8 f
statement removes the version from the statistics report. This is recommended2 \& V5 `; ]% K+ w! E8 r
for public sites or any site with a weak login/password.
% `6 r8 V; J$ e6 N8 b" Y7 Y
, d: e8 c7 B3 c Though this statement alone is enough to enable statistics reporting, it is
- |5 }* v) Q# a5 z! K recommended to set all other settings in order to avoid relying on default$ y+ }2 O8 I1 K) V. o
unobvious parameters.% e* n' |: [9 d* ^! \. V
8 z9 e5 `5 c: K3 V' |- c
Example :
* c# r/ v5 U0 U/ G+ u # public access (limited to this backend only)
9 I' s1 i+ }7 e8 a backend public_www- T! i( Q- h4 a. f: ]1 W) b
server srv1 192.168.0.1:80
" O5 K X( y+ o R% v6 E( a stats enable
6 ~% D/ W1 A. w9 G% O _ N; a# R stats hide-version B, t" C- X0 K+ ], F! F8 T
stats scope .2 N8 [! [4 x" S% y
stats uri /admin?stats& Y6 F0 v# W+ R3 p; {4 D
stats realm Haproxy\ Statistics
3 F9 S& P( g1 _ stats auth admin1:AdMiN123. X& j. u& w: p9 S& b$ G
stats auth admin2:AdMiN321# s! q2 P, i. h1 W
" o( H" B! V2 O( T- K
# internal monitoring access (unlimited)4 M1 S2 E; R! T, ?& E5 N
backend private_monitoring. Q: B4 d" M. a1 x& D
stats enable) u; d' j6 y( i6 L; H% R
stats uri /admin?stats+ b: O' b. J- Z6 q. {4 Z: w3 i
stats refresh 5s
6 `9 E$ `/ r% J/ Q2 L: { [( H9 o4 `- H s
See also : "stats auth", "stats enable", "stats realm", "stats uri"
" A$ K# |9 f9 F( P2 ]- `- b2 |0 r2 h I. V/ N) p
' }. J1 @) {& E6 G) V
stats http-request { allow | deny | auth [realm <realm>] }
: ?$ Q. _: `+ b8 u" w: Q: x0 t" D [ { if | unless } <condition> ]7 I; D7 k8 T: `' ~ Z6 n
Access control for statistics, g+ y+ A8 F1 T& r% H. ^
( F0 K: g, a/ ^0 m( q May be used in sections: defaults | frontend | listen | backend! b0 }5 g4 \$ v! x$ E
no | no | yes | yes5 W& C3 Z* [# X+ t9 z
4 Z+ P' b% B1 j$ d u' e As "http-request", these set of options allow to fine control access to
' M( V7 S$ Q' @. g6 h9 S; q statistics. Each option may be followed by if/unless and acl.
; P$ K! Q5 K2 `$ t; v8 O/ z7 v3 V2 X First option with matched condition (or option without condition) is final.
/ `3 T+ a& n8 Z* `! p* ~ For "deny" a 403 error will be returned, for "allow" normal processing is
* o5 o# ^% F# j3 ]! K, M performed, for "auth" a 401/407 error code is returned so the client
6 y6 K3 b0 Y5 a6 z. J0 }" w3 G should be asked to enter a username and password., h y; e# A5 Y$ N; v
+ U, x! d: |2 R There is no fixed limit to the number of http-request statements per) l% A5 r( }& c U
instance.
7 w5 {+ I+ p$ |. S* U2 t, q y# q* i% y& H1 N
See also : "http-request", section 3.4 about userlists and section 7
6 l8 W' y& b h% z( p about ACL usage.3 V+ I0 J% ?/ _ X6 U1 Z2 h# D
6 P; G! X0 I* }2 {$ f/ R
& a: n. x% ~6 b( z; `- W) h
stats realm <realm>. D4 ]; P# ?8 Z' [9 n" [: H
Enable statistics and set authentication realm
6 K; m) d/ \5 Y3 w; q May be used in sections : defaults | frontend | listen | backend% s/ ?4 I2 y1 m
yes | no | yes | yes( L: j. l- { k: \: q# Z
Arguments :% v& ]5 q$ U' S' N
<realm> is the name of the HTTP Basic Authentication realm reported to
$ m3 M, w! ]; }/ @; \0 `7 F the browser. The browser uses it to display it in the pop-up8 P1 u( @% N7 t# ]% E0 {0 p2 H. h
inviting the user to enter a valid username and password.# q! P S( c H' V) X
" D9 k$ n: g! i, s) g7 }* ?( c The realm is read as a single word, so any spaces in it should be escaped0 ]+ j( P `! S
using a backslash ('\').+ C; w1 J7 f9 t' f, h
- A$ Y) j$ H+ F6 D- a5 O! f; A This statement is useful only in conjunction with "stats auth" since it is
1 a0 ]1 K: ~* W6 R only related to authentication.& I4 }6 ]0 j! Y( @
! ?' a& r; n2 f2 O+ f; \3 j: i' R4 G Though this statement alone is enough to enable statistics reporting, it is6 Y3 ]' r6 f& U y
recommended to set all other settings in order to avoid relying on default3 [3 G- ?& {4 {/ h, Y; g
unobvious parameters.6 q, F9 n5 p3 |
# d: c$ n3 y) J# o) F$ f0 |
Example :
4 U6 [4 c* \7 W3 N! }* h! S0 X6 b # public access (limited to this backend only)
7 k# T8 k* C) Z. ` backend public_www$ I2 N* A; J) B/ n& ]; L0 @3 S0 w
server srv1 192.168.0.1:801 ]1 s" ^) J; R" \- h+ R2 _" v
stats enable
4 k3 X ~: x3 f u) O/ o stats hide-version
( M5 j& M. Q7 [6 p stats scope .
$ Z8 O3 E# ^, G1 Y, u/ u0 ` stats uri /admin?stats
" p; l; l2 t3 a0 K7 J stats realm Haproxy\ Statistics
* D+ p# \/ H, O |# k% _ I/ r stats auth admin1:AdMiN123
! P5 A+ O! Y9 G. G5 d stats auth admin2:AdMiN3218 H3 Q! K. V I; Q/ O
" w' w# `/ p1 C( R" }) |# R$ q
# internal monitoring access (unlimited)
! X" O% o% H5 v, `& C backend private_monitoring
; e& d! f) [2 b! f. ` stats enable+ c/ ^. }4 ^" y* u+ T9 b* Q
stats uri /admin?stats! l' @: `: L- m* O* p
stats refresh 5s
2 \9 J9 H* _# G. |9 `; E! z$ N$ P' z1 v* Y. h4 L; _
See also : "stats auth", "stats enable", "stats uri"
}% A' I O) e) Y- f% \0 K0 \5 i! i; k; k4 B
3 R9 T- k9 R4 y4 m+ i
stats refresh <delay> R! G! w9 A: P* f8 V! V/ K
Enable statistics with automatic refresh5 o; X3 g g- x
May be used in sections : defaults | frontend | listen | backend
3 |% \( c! r- f }7 P# m yes | no | yes | yes
! ~/ f7 U1 f' }7 a Arguments :
' P* e1 J1 S! |# U% e6 d <delay> is the suggested refresh delay, specified in seconds, which will( b! D5 w* C7 J4 W5 ]/ e# P8 l1 H
be returned to the browser consulting the report page. While the
! l- q6 G3 t+ Z' ]- W% s* F; \ browser is free to apply any delay, it will generally respect it
6 O* g6 m! ]; D! p8 ~# q# o and refresh the page this every seconds. The refresh interval may
9 J! L% x: q2 ~- ] b be specified in any other non-default time unit, by suffixing the
- `3 ~5 z' a6 h( I' s unit after the value, as explained at the top of this document.8 d- M+ c+ g. N/ e6 n
9 M6 L- w7 O) N+ P$ O
This statement is useful on monitoring displays with a permanent page N. }, b5 N$ S0 \/ V
reporting the load balancer's activity. When set, the HTML report page will, p; d6 [; ]5 L) |* }. q
include a link "refresh"/"stop refresh" so that the user can select whether
3 o! l- l2 h" k' I5 a# d he wants automatic refresh of the page or not.
6 z# e! a" a8 r$ D9 C
1 L. c$ f/ W% D" M2 b Though this statement alone is enough to enable statistics reporting, it is
. s% h9 E1 ^# g' P recommended to set all other settings in order to avoid relying on default( Q$ ^" d5 a8 F- t* K J- a: d
unobvious parameters.
+ z6 \5 ?8 b' o( y4 i- r# ]5 z
, d0 h/ B8 k1 ^ Example :
, J$ {0 g- y5 j3 l* E& }8 Q- @! u # public access (limited to this backend only)' s5 k( F+ V% |
backend public_www
8 [" |6 D7 Q. {+ c+ U: K8 A1 W3 z: q server srv1 192.168.0.1:80
N& x' H" T T8 |% y) i- m* C stats enable
8 v- ?" |# {9 M. E- p; I stats hide-version+ k6 `) J# D: l4 Y
stats scope .
9 d# f% i+ D/ Z# ~- J4 M stats uri /admin?stats$ q! Q9 i [. N6 q+ {* @
stats realm Haproxy\ Statistics. N1 c0 R- O% }9 `
stats auth admin1:AdMiN123
& f8 B) z# ]4 B3 Y5 m# j$ i% ` stats auth admin2:AdMiN321 {; m$ V$ W% L
/ X2 H5 g0 \' B" {' W) A+ R7 W # internal monitoring access (unlimited)3 f9 ?, g! ^$ d; \- S8 R2 f
backend private_monitoring& R: E* z/ }3 v' `0 d
stats enable
% @ l+ a9 }( N/ x stats uri /admin?stats
( V% u+ F4 s7 V stats refresh 5s4 o k0 t- S1 E' o) q9 {
4 s+ H: Y U o' h% R See also : "stats auth", "stats enable", "stats realm", "stats uri"9 M- X( b; X" v2 D" Y
4 T6 y- w9 v# {4 i" }% B2 Z7 T9 R+ h& Z
stats scope { <name> | "." }+ B7 ^2 R4 `( H( n1 T1 o# ^
Enable statistics and limit access scope* v: s6 f5 @. e4 D9 D% _
May be used in sections : defaults | frontend | listen | backend
* W. P# l o1 {8 w Z5 @ yes | no | yes | yes. W, |5 @: I5 D$ U7 e
Arguments :
/ w" e) B2 u; b: t& N3 T/ ?1 { <name> is the name of a listen, frontend or backend section to be
% A, [! I7 ~. M* V8 U9 j reported. The special name "." (a single dot) designates the6 Z- _( m6 t, Y; S5 g
section in which the statement appears.: X; L4 z9 o, S8 q4 A1 x
8 k) M; O3 F: W3 i& Q/ D When this statement is specified, only the sections enumerated with this" N) n! _( i8 F- [, ^
statement will appear in the report. All other ones will be hidden. This. F7 E. U2 I1 i9 \
statement may appear as many times as needed if multiple sections need to be! N4 j/ k5 C, T; I6 e# C
reported. Please note that the name checking is performed as simple string
: k# h+ B' f. x" M3 G comparisons, and that it is never checked that a give section name really S K2 I( E2 ]2 a5 K! ~
exists.
8 D4 [3 R1 Z, t+ M2 \
) k1 m6 m% u1 `5 h Though this statement alone is enough to enable statistics reporting, it is
/ F r6 ^9 X V! v recommended to set all other settings in order to avoid relying on default
" j0 u! M! l1 d. t) `( L, Y unobvious parameters., ?" d3 v) V6 {+ k
8 v- Z g# r2 ^: C; E
Example :8 l) |- r, v5 r2 D* U' W
# public access (limited to this backend only)
8 m2 l* J5 P" ]7 w5 { backend public_www) p7 D/ f' w0 j1 k6 r) G L
server srv1 192.168.0.1:80
' E; [; x: Y' ^: `% w7 D stats enable
) e9 K. s/ t0 y# n9 _3 e5 o stats hide-version- }" u' H" a& k: ~6 k
stats scope .
, G# l% Q7 L/ \6 |$ _6 Z stats uri /admin?stats
6 g9 {; ?! [5 x) v9 z stats realm Haproxy\ Statistics
4 V! }- j) y" L3 G stats auth admin1:AdMiN1230 ~7 l Y+ ` X( P5 N6 a+ O v
stats auth admin2:AdMiN321$ e3 w/ A/ }" K& K3 M( R5 A3 Z. c
4 B0 u+ x5 z' J- J& w) I6 U. `$ a
# internal monitoring access (unlimited)$ j/ c+ R: k! |" X0 k
backend private_monitoring
( h; D' S2 H2 N3 Q! z, Q stats enable7 F/ N. R5 x6 S( s9 L
stats uri /admin?stats
" K% }6 x g7 A7 Q& c# [( c* X$ v stats refresh 5s- ]7 l4 _! A6 J4 s$ Z8 B, \) e
# x; W$ ?8 ^% X: g See also : "stats auth", "stats enable", "stats realm", "stats uri"* k/ i C' c' U; H* X) \0 c
6 a; j' H. e, g* N& A7 i& c* w7 O
stats show-desc [ <description> ]
~$ N2 h+ z! Z: _* _6 r5 k, ] Enable reporting of a description on the statistics page.; N; ]) E# H I' F6 W' c9 ~2 n, q
May be used in sections : defaults | frontend | listen | backend
( r7 r$ q. w4 \$ k: h$ K% U yes | no | yes | yes
3 ~& \" i3 J& L1 z
! @0 H- X z* d& g8 k& q <name> is an optional description to be reported. If unspecified, the
* |( T7 T5 x+ ] description from global section is automatically used instead.
5 w3 n' w/ f! d% Y, B7 Z) A8 _( |$ @0 f: z. u; X6 s8 U5 N! k
This statement is useful for users that offer shared services to their+ K& F b4 `. [2 T) M* w5 ]) m
customers, where node or description should be different for each customer.
$ [) E: D, c6 ~4 z/ S) R# a) ]+ ?0 r3 e( p5 ~4 l
Though this statement alone is enough to enable statistics reporting, it is
/ Z$ e# F4 ]; L! x recommended to set all other settings in order to avoid relying on default
$ X7 n% m" D1 u' L unobvious parameters. By default description is not shown.& T2 |' N% A4 M; T# U4 L
5 F) q' ^2 P0 ~; k' L; }' D Example :
; X" J. d4 ~" c" l' n # internal monitoring access (unlimited)
8 c8 n, Q. h! { P backend private_monitoring$ m' }6 a+ Z- ^0 q8 t1 v+ B# K- N
stats enable6 U6 R8 b7 T9 ^' c
stats show-desc Master node for Europe, Asia, Africa$ K8 g5 K3 j3 Z5 W' ?/ j8 Q' w( I. M
stats uri /admin?stats. `. c& _$ d( l4 s
stats refresh 5s% V3 O' E& K3 p: G2 q) M9 L; T
* |4 X0 r9 ~$ }7 E7 X
See also: "show-node", "stats enable", "stats uri" and "description" in- m5 Q, O4 J- m0 j& j; w6 @- B
global section.
2 V6 p0 i8 t% R# H* t1 `8 b, P+ I6 [# s; ~5 ~- Z6 ~2 v
7 V7 |% i3 j" p" ]2 Jstats show-legends& j( S) J, ]) [# x2 f
Enable reporting additional informations on the statistics page :( [$ L" S7 ^% p
- cap: capabilities (proxy)1 D7 ]3 p) W# V- y
- mode: one of tcp, http or health (proxy)
6 ?+ g; E; H4 Y& u& H' j4 ~ - id: SNMP ID (proxy, socket, server)* H% L) G* F1 C: T
- IP (socket, server)1 [( K5 m8 Z* v. {# _4 Z
- cookie (backend, server)5 t. x( F- u! X7 q* {$ O5 H' j
. _1 k/ j/ X w: d$ h: \- J* r
Though this statement alone is enough to enable statistics reporting, it is2 U1 G6 E. d0 w$ r2 y2 d
recommended to set all other settings in order to avoid relying on default& Q3 K( K# c6 {$ r' E
unobvious parameters. Default behaviour is not to show this information.
4 C9 w! Z: m0 j; B
) X/ \9 J. O7 W0 S& _9 T8 V See also: "stats enable", "stats uri".
) f5 F; z1 T S0 F
9 J% o( j+ r) [6 c* J4 B
; J1 p) X1 J) r( H1 S! s5 sstats show-node [ <name> ]
- H: o" U W8 J+ ?, ` Enable reporting of a host name on the statistics page.
; m6 q9 j8 S3 r1 Y! P0 H5 D May be used in sections : defaults | frontend | listen | backend4 s0 @ ^" B m5 G9 K2 J% Y
yes | no | yes | yes
7 _4 H1 R; Q6 [; R7 s- L% f Arguments:
3 z- N! C# x5 B! K! @, x <name> is an optional name to be reported. If unspecified, the
: n0 X! P6 C3 H" d node name from global section is automatically used instead.
# V* ~$ g* r& L/ J8 a: ~0 {5 C* W3 E( q9 U5 X- d
This statement is useful for users that offer shared services to their
" y+ S: F3 z& L$ T" p5 h* j customers, where node or description might be different on a stats page
, K' r+ t% e5 Y( D& _$ q9 X/ W3 Z provided for each customer. Default behaviour is not to show host name.* K4 ]7 X# I- e5 c
: l: m, C2 |5 j1 Q Though this statement alone is enough to enable statistics reporting, it is" |5 Q4 ]( c( M* j7 N4 v& v }( ?
recommended to set all other settings in order to avoid relying on default: G5 Y3 s% d% }$ g/ A9 t
unobvious parameters.* k; ]: B L0 a5 G' ~2 T
, g2 J* A. G+ N
Example:4 A5 Q/ t( c4 {
# internal monitoring access (unlimited)( m7 e0 d- i. f9 p7 J# s
backend private_monitoring
/ \# \2 r5 N1 {" T! s stats enable
7 e7 Z$ O( M C0 k% `: E stats show-node Europe-1" C6 C$ K' C0 Z7 B
stats uri /admin?stats
: V( ]8 u [2 x4 b' G stats refresh 5s5 I/ X* `+ t+ b S7 @5 H
8 F& P; Z: f. l5 k p5 G
See also: "show-desc", "stats enable", "stats uri", and "node" in global j. b9 G: I6 L$ G% R! ?
section.
* ?& L# X l1 r; X: w
+ g# A3 H- R9 F8 Y. `" e
+ h e @. k! e |- B! i5 @+ {stats uri <prefix>: Y" f8 U& \( r; \" o& ~
Enable statistics and define the URI prefix to access them
4 N7 Q8 ~9 T2 e May be used in sections : defaults | frontend | listen | backend
2 Z) ]( d6 T7 e. j yes | no | yes | yes
( s! R8 I$ s6 S- b( Q1 D Arguments :
- U. g P Z5 y <prefix> is the prefix of any URI which will be redirected to stats. This" M+ G& V- J& E3 e2 W0 c: T+ t
prefix may contain a question mark ('?') to indicate part of a
( s$ C5 l# [% E query string.
& {6 |! o" Q& Q$ `' w
# \- H* I0 s4 S }$ T6 U) _ The statistics URI is intercepted on the relayed traffic, so it appears as a
I5 p8 Y6 {$ u B7 H page within the normal application. It is strongly advised to ensure that the
) ^9 ^( P+ B5 o7 |/ e, o, L selected URI will never appear in the application, otherwise it will never be- t$ _1 n; c9 K6 d! }1 h4 I
possible to reach it in the application.; U( B, m2 [# I( v6 O
# y( G4 {$ w, Y1 W% l
The default URI compiled in haproxy is "/haproxy?stats", but this may be4 s; O4 F1 z9 W" g$ b' e
changed at build time, so it's better to always explicitly specify it here.
1 b% ]% @. s. ?! e8 }9 I2 Y$ @& L It is generally a good idea to include a question mark in the URI so that
4 M T; G4 w5 `1 V4 S intermediate proxies refrain from caching the results. Also, since any string1 y: u* V+ w& M
beginning with the prefix will be accepted as a stats request, the question5 Z4 H# U- d3 I+ C. D3 E3 e& A
mark helps ensuring that no valid URI will begin with the same words.
$ M `% j; Y2 Q9 t' C. y! h- @3 z" ] K7 k
It is sometimes very convenient to use "/" as the URI prefix, and put that
7 p/ K$ q) N$ m a0 j statement in a "listen" instance of its own. That makes it easy to dedicate
) x3 I6 i$ E2 B) Q0 P( \+ s( L2 w an address or a port to statistics only.$ d" a4 f+ W7 M! i' H- s: I. r
$ @) N. |- q# ?5 e% |) m Though this statement alone is enough to enable statistics reporting, it is
~2 T$ ~. l& ?0 D0 h# Y recommended to set all other settings in order to avoid relying on default
0 y! k. \# ~* Y, s" s unobvious parameters.) U/ B& X1 s8 S, p5 Y( S0 a; y
" n. l7 i: i/ j4 d. e% t Example :. w- I( H, p1 r4 R( i2 ?
# public access (limited to this backend only)! R+ Q! B9 x/ C# d6 Q1 q+ u
backend public_www
& d: D4 X" q$ j1 d' [; D server srv1 192.168.0.1:80
8 V+ F5 R- f! q |4 i* x stats enable" a4 R1 w- Q( t/ I( z- I/ ]
stats hide-version* W' \3 |9 u2 Z3 Y N3 d# }
stats scope .
% E1 ~# I# s+ K% p stats uri /admin?stats/ A9 ?1 G: F8 {2 L6 u
stats realm Haproxy\ Statistics
- t4 m" x* c( s+ o" m( K# c6 Q stats auth admin1:AdMiN123+ E) a" b/ K8 @3 {
stats auth admin2:AdMiN321
H: v4 U3 {3 z% w5 Z& V4 f
* L6 `2 w: u0 v( W # internal monitoring access (unlimited)( G5 e* \5 | o$ ~
backend private_monitoring r+ y4 F: f; v' f( O
stats enable; J h* d% A" J" M3 ]: S
stats uri /admin?stats- a, ` D" q5 o" l( m
stats refresh 5s. o8 W- \, w$ D0 N
2 O/ _2 q! s W9 U
See also : "stats auth", "stats enable", "stats realm"* d0 |& Z( T$ G9 c8 s6 N
& [4 P: X1 R+ q" R9 Q- _) ~
( `$ F# K3 w' \0 q$ zstick match <pattern> [table <table>] [{if | unless} <cond>]: ?5 I+ z, x8 r+ [' k
Define a request pattern matching condition to stick a user to a server
; v, I: Q% ?$ ^0 s; h3 X May be used in sections : defaults | frontend | listen | backend
' d% w2 {. ?' a! f. l no | no | yes | yes3 V* ]' Q B {) W& x. |( L
* H. Y8 t' n5 r* C Arguments :4 Y# I, Z: X$ t$ c6 u k( O, d4 j% T
<pattern> is a pattern extraction rule as described in section 7.8. It
4 z4 n- R) g# T S8 l3 Z describes what elements of the incoming request or connection
' h, t' o1 w( ?( U+ s. y will be analysed in the hope to find a matching entry in a, H& E( ~% M% b8 d" i) F2 U
stickiness table. This rule is mandatory.; E+ S5 ]; b: K3 P
* o2 f/ c( L+ z8 j8 k8 s <table> is an optional stickiness table name. If unspecified, the same! w: p0 V0 y/ r. b% I9 b
backend's table is used. A stickiness table is declared using. Q: a& ~9 _3 m. ~$ l
the "stick-table" statement.! Y: {: U, d; f2 F8 G' U/ A
+ d; x( {; N! v1 `3 V+ [
<cond> is an optional matching condition. It makes it possible to match
& r2 l+ r: ~( C6 A+ j on a certain criterion only when other conditions are met (or: F+ P$ P2 w7 h4 z6 B5 q
not met). For instance, it could be used to match on a source IP0 H- R' ^! M4 ]- b
address except when a request passes through a known proxy, in
# O$ ? U8 n m which case we'd match on a header containing that IP address." u, U* x( y2 k4 u0 E7 I' b5 a; @
6 H$ @7 l3 d* K' i4 O# R Some protocols or applications require complex stickiness rules and cannot7 @: Z% U+ Y4 F0 K2 a
always simply rely on cookies nor hashing. The "stick match" statement: @* q. R. M% Q S
describes a rule to extract the stickiness criterion from an incoming request
$ d: T0 G! [, Q2 s& r or connection. See section 7 for a complete list of possible patterns and
7 p5 R- ~& I6 V& E' r( E0 G) ?3 G$ [ transformation rules.
6 F/ z$ {7 I3 b0 A+ [1 y L, g3 `0 `% ^) r6 c9 ~, A/ w) b
The table has to be declared using the "stick-table" statement. It must be of
1 U+ N$ C2 A6 e( |# d' L! N* I a type compatible with the pattern. By default it is the one which is present
6 _, P7 } p' @5 Z8 z in the same backend. It is possible to share a table with other backends by- a& q& {9 g4 @( `1 {
referencing it using the "table" keyword. If another table is referenced,
/ _9 N; @0 s( `+ u, l the server's ID inside the backends are used. By default, all server IDs
2 e% u6 i! t4 x1 ` start at 1 in each backend, so the server ordering is enough. But in case of
0 I' w5 ^: E: w4 [2 A5 e doubt, it is highly recommended to force server IDs using their "id" setting.. b8 E# o q* v" C3 F2 ^
. ]( n+ n0 C0 d- J& z, r It is possible to restrict the conditions where a "stick match" statement
) T; g4 L0 Z2 W8 z# g% X% H will apply, using "if" or "unless" followed by a condition. See section 7 for& g7 I+ W* M9 i x3 m1 P7 n% n% i4 E" A
ACL based conditions.& ?9 t+ u+ C+ R: z; L
: y M$ |) _5 o2 I There is no limit on the number of "stick match" statements. The first that
+ ^8 H! u$ L6 O% b5 J: Z applies and matches will cause the request to be directed to the same server" |0 V! a5 k+ E* d7 r- d
as was used for the request which created the entry. That way, multiple& X1 _' E" U5 @8 q
matches can be used as fallbacks.6 \! x2 w1 v( L7 a5 I$ E
- U- f8 @3 a( [, B1 |" Q" C The stick rules are checked after the persistence cookies, so they will not
) S& t& f, C, l# g2 N affect stickiness if a cookie has already been used to select a server. That) Q7 k6 }8 q) U
way, it becomes very easy to insert cookies and match on IP addresses in
' Z5 a- m6 Z9 N; ?" O order to maintain stickiness between HTTP and HTTPS.) }+ I5 n. @; Z. E, r0 }
# X! m" q7 N& c9 j
Note : Consider not using this feature in multi-process mode (nbproc > 1)" O7 c, N i8 Z3 D) O
unless you know what you do : memory is not shared between the
f+ I+ N m) G9 O7 j* ]8 d; F5 N processes, which can result in random behaviours.
' W- P, e' s: W) N+ h- g
: x) U# z% r. |/ N- w Example :
4 ~( H3 @/ i4 [* j # forward SMTP users to the same server they just used for POP in the' X. I/ ]/ B8 O; y9 D8 V* p
# last 30 minutes. k- Z C% F \6 F2 K
backend pop
9 }" s" v7 O! `$ r/ M mode tcp4 `: B) L3 Y& _0 W' z i* B
balance roundrobin
# F H/ U+ o8 ? stick store-request src
2 w+ X; F. ~" T$ f stick-table type ip size 200k expire 30m0 K* r' @. j! g2 _" t8 d
server s1 192.168.1.1:110* n* I! Y: \! e7 X) G
server s2 192.168.1.1:110
# L2 v. i$ z" G0 O4 K, v# t2 {! K, q: ]: Y* d! C
backend smtp6 u+ @4 z7 m2 P+ q% N; h1 B0 \
mode tcp+ b! W; \4 \( g
balance roundrobin8 }! l# N1 [/ S8 z( u
stick match src table pop( m. U2 r; w i
server s1 192.168.1.1:258 j/ p$ s+ N; i( [4 _3 l4 |) P. s
server s2 192.168.1.1:25" a1 Z) k* l# J- C' f6 w
! ^* O1 E' D$ k I8 B, v See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
3 @9 z" z" T' `: i9 A# _+ n' S about ACLs and pattern extraction.6 c* [ h* F( ^1 \) }+ c
3 k9 l6 X% J. k3 K3 Q8 S1 I# u9 q; f; c! x
stick on <pattern> [table <table>] [{if | unless} <condition>]# ~% a- `. i% F: ?
Define a request pattern to associate a user to a server
# z% U6 p. A7 b0 _" n1 r* c May be used in sections : defaults | frontend | listen | backend. e) d9 M7 _; h7 l- |
no | no | yes | yes t2 D. f, N9 u* J* c/ g
) w$ a3 T( H" _+ P& l& d Note : This form is exactly equivalent to "stick match" followed by
3 H- s' o$ m4 y* I* ~4 [! g "stick store-request", all with the same arguments. Please refer p$ f. t0 b2 O. b$ R! h; `
to both keywords for details. It is only provided as a convenience' X! x' s7 x, g/ B
for writing more maintainable configurations.
* G1 H. r: ~& Y
/ r; I8 e0 b8 j- A+ r& |3 V Note : Consider not using this feature in multi-process mode (nbproc > 1)
5 ], @' u' E9 s# H) J" X unless you know what you do : memory is not shared between the2 P5 ~8 Q- h; A" l" J5 W
processes, which can result in random behaviours., u7 [; x5 C; T1 ?: i8 x0 K
, ^) D" f& e+ b7 `1 ]' A/ U! a Examples :
. X N. D4 y2 y. w- v # The following form ...3 k t D8 r# Q' ?+ M) C
stick on src table pop if !localhost" j1 ^9 C" x* h; Q2 P) X( q
5 H" R% J: L* a) O8 s# }
# ...is strictly equivalent to this one :
' G4 ~: L6 H- U. t stick match src table pop if !localhost
! @, y5 N& i. T: ~ stick store-request src table pop if !localhost) j% k, A0 V0 H; M8 z% b3 h# l
$ @8 D. s }0 x& F% r- ~ M+ F+ h
# Use cookie persistence for HTTP, and stick on source address for HTTPS as# X9 P" Z9 f( B8 A& m& B' B- e
# well as HTTP without cookie. Share the same table between both accesses.& Z$ e) C* f: Z% }7 _6 ]# q
backend http
) T6 N' I" ?) R mode http6 m' e/ X' G0 m' }
balance roundrobin
2 G3 f( |2 d) l" p& a' T stick on src table https
! T9 o$ G$ I$ ?" l cookie SRV insert indirect nocache) o- l4 c7 f0 E9 ~5 v- _. I4 t
server s1 192.168.1.1:80 cookie s1: M' T! E0 j( a" H- S
server s2 192.168.1.1:80 cookie s2
$ @" Y, w. m, n+ l3 R* B+ j/ ~ y
+ g5 h7 c, M" P* s& o4 r backend https
8 \( T- `: R, |& ?! C$ w8 j mode tcp
$ h. R+ u" t C5 k3 d7 Z balance roundrobin" W7 }& I6 \$ J3 E8 W
stick-table type ip size 200k expire 30m& {3 {: m5 H& Q
stick on src7 q- I' p' ^% [, x2 p [3 C& }# s' H! ^2 t. H
server s1 192.168.1.1:443
( _6 D# W. q. W u server s2 192.168.1.1:443; O% U3 ~+ p9 l- S5 w6 t5 m) l
4 b& [8 V/ r" L7 K n/ A# {5 V' O
See also : "stick match", "stick store-request", "nbproc" and "bind-process".9 _" `% s J- s, e4 A, x/ s
, D$ {% r. Y, k p z v
1 {% |* \) B# ^ _ s8 e; Q% qstick store-request <pattern> [table <table>] [{if | unless} <condition>]
: V( }7 X# ~5 C; q# m2 U; w- v Define a request pattern used to create an entry in a stickiness table" {; Z M) y- g
May be used in sections : defaults | frontend | listen | backend
* X' G, ^# d6 v5 O+ D: m* R! Z no | no | yes | yes
. ^: ]$ s0 `+ _" C
8 C6 G# \3 i& [) X4 R Arguments :1 o6 @/ Q. P' t2 p% o8 ~2 r+ L: o9 v: O
<pattern> is a pattern extraction rule as described in section 7.8. It
1 O* U1 q" U/ W; |+ O+ O describes what elements of the incoming request or connection& s" D" i. O9 X# R3 c' X. u
will be analysed, extracted and stored in the table once a% o+ n& u8 ^8 l: S
server is selected.+ p8 B, n! D- ^* g1 j# @
' o2 G& S# a; @ <table> is an optional stickiness table name. If unspecified, the same
* ~; _* c O' C+ o& w% k+ ^! c8 G9 C backend's table is used. A stickiness table is declared using2 S+ X$ I3 `9 K) }* m5 a
the "stick-table" statement.0 z7 _( b% I+ {- {
) T2 a* {1 D5 j! H7 I, Z0 M
<cond> is an optional storage condition. It makes it possible to store# L9 E+ e/ Z+ v. r% v! \9 h
certain criteria only when some conditions are met (or not met).
; D9 Q4 u$ i; Y/ G, N For instance, it could be used to store the source IP address5 z8 s) ^5 c' U
except when the request passes through a known proxy, in which
: ^0 {! N- G+ b; l case we'd store a converted form of a header containing that IP
5 @; c; ]3 a4 j' r7 @+ x address.' _$ [, ]; `( g. `/ n1 A
" o/ I+ ~' F0 I1 n1 A8 @% d
Some protocols or applications require complex stickiness rules and cannot
4 P% T- M' }, \5 Y( e: [: {' e7 ] always simply rely on cookies nor hashing. The "stick store-request" statement/ V1 ?2 F& i6 s3 a! L$ Q+ X0 s1 ~) ?
describes a rule to decide what to extract from the request and when to do
* E2 x) g- m8 _: k0 P it, in order to store it into a stickiness table for further requests to
( e* w) g5 i# Q' b e5 R match it using the "stick match" statement. Obviously the extracted part must
0 S1 B' j+ l0 {; a0 e make sense and have a chance to be matched in a further request. Storing a
" P5 M5 c/ j# {- k client's IP address for instance often makes sense. Storing an ID found in a
. u D# Q! [5 l7 H URL parameter also makes sense. Storing a source port will almost never make
/ ^( ^/ B# S- b$ ?1 P any sense because it will be randomly matched. See section 7 for a complete
+ h0 J2 {) d& N list of possible patterns and transformation rules.
2 q0 m1 f5 J2 q5 V' H' o: R+ N% Q- {$ \, M* ?
The table has to be declared using the "stick-table" statement. It must be of
* b4 y s* ~! q# G a type compatible with the pattern. By default it is the one which is present" o5 F0 T; n- q7 s- [2 N2 @
in the same backend. It is possible to share a table with other backends by
* Z+ R2 z9 ]; V, H4 d referencing it using the "table" keyword. If another table is referenced,% [9 t3 r2 q4 y8 s& X
the server's ID inside the backends are used. By default, all server IDs" J8 k% |8 i9 v e7 j
start at 1 in each backend, so the server ordering is enough. But in case of
# G4 o4 p7 E0 J& W* C6 o; p- ~6 ~" O: k doubt, it is highly recommended to force server IDs using their "id" setting.
. A: ~* c- q9 I6 q# F, D& i
: ~, M/ U% d6 E" h6 o# e5 l It is possible to restrict the conditions where a "stick store-request"
( v0 q1 K! y5 N/ b) v statement will apply, using "if" or "unless" followed by a condition. This% ?" |) ^$ C, E
condition will be evaluated while parsing the request, so any criteria can be
; z! G* f2 F# c used. See section 7 for ACL based conditions.% z6 r6 B/ p+ u( _ l: U
) \" X7 j }% @0 c* M There is no limit on the number of "stick store-request" statements, but
' s/ f, P, f/ a6 R1 r+ o there is a limit of 8 simultaneous stores per request or response. This
- R5 C4 N) B2 b* Z: V makes it possible to store up to 8 criteria, all extracted from either the3 c2 h1 x1 o ^# v6 E$ u1 h+ M
request or the response, regardless of the number of rules. Only the 8 first. L: q* H& f/ i: T1 D! t" |6 _
ones which match will be kept. Using this, it is possible to feed multiple+ ^9 B" e2 M# _9 ?
tables at once in the hope to increase the chance to recognize a user on# G& B6 n8 j# S+ }+ B
another protocol or access method. Using multiple store-request rules with
8 y7 c( e# W8 Q% }. x the same table is possible and may be used to find the best criterion to rely& Y$ L2 |. ], x! t0 n
on, by arranging the rules by decreasing preference order. Only the first
+ r) \& F: [$ g1 O; t: _0 _ extracted criterion for a given table will be stored. All subsequent store-% K& o/ x2 X2 _
request rules referencing the same table will be skipped and their ACLs will
* C9 @. v. p* z not be evaluated.
0 s# Q. T* K& {; c& J p$ C9 A% p
The "store-request" rules are evaluated once the server connection has been
( ]9 W) P! T% Q$ E established, so that the table will contain the real server that processed! y% Q- z1 ? o- @' b! a6 g, T
the request.
# Z t+ R6 B9 Y: M
% h* D- h! B; D: ^1 y* P- {& D Note : Consider not using this feature in multi-process mode (nbproc > 1)
0 l' u+ p; O$ P+ ~7 y9 J unless you know what you do : memory is not shared between the
+ }4 Z8 y0 @) D9 P6 W& m! [. w$ y processes, which can result in random behaviours.7 v1 l$ S, E# \
4 ]& c: i a7 t' l
Example :8 q/ D4 |# T! D! G7 |1 A
# forward SMTP users to the same server they just used for POP in the
6 X/ k3 h* I: |/ n1 R. U # last 30 minutes
2 X# v: D0 N: ~0 g backend pop
3 D% ^( C3 \" P* Z mode tcp* M& {3 ]$ L3 T- E8 d4 c
balance roundrobin
. F: {1 d1 C/ W$ c8 \/ l1 x7 j stick store-request src4 F# k2 X: q, A, {/ T* @
stick-table type ip size 200k expire 30m
* q i( m& X |' e0 H server s1 192.168.1.1:1100 A! h/ J% i3 J: c3 |
server s2 192.168.1.1:110' ~4 m# E O$ n
: L5 Y {$ ?' f& n5 P' P" y
backend smtp0 |; F* V/ ?- ^9 s
mode tcp
* r! r* `9 Y3 T* X; z balance roundrobin
6 X5 l; q3 W I. ~ stick match src table pop; d v1 s2 f6 |0 Q1 R2 c
server s1 192.168.1.1:25' p) g6 X" a9 ?) [/ ?" H
server s2 192.168.1.1:25+ Q! i1 c" m! l0 N+ {
" x$ B- k1 V0 ?3 G* x! G4 ?$ E% I See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7, o$ s& T8 F0 p6 D- ]/ d; c
about ACLs and pattern extraction.
( n5 O* C+ L3 J0 k2 ]( u9 B1 h) ~. [5 l; Z& q
, c2 l1 c" N2 y4 c4 \, Tstick-table type {ip | integer | string [len <length>] } size <size>9 W& F5 w6 m. P5 L
[expire <expire>] [nopurge]' V: z% t) c4 v! n: Y W: K( k
Configure the stickiness table for the current backend
: y, c8 R/ S# R1 B- m! c May be used in sections : defaults | frontend | listen | backend, D, V9 M, i$ o6 z0 C) N7 y# d8 R/ H( j
no | no | yes | yes
2 [7 Z& M7 t$ e! Q4 j
" |% Q0 [4 }0 {/ I, t% t9 ] Arguments :
! ?1 f7 a$ U6 Z8 G0 Q4 C6 C$ ]9 c ip a table declared with "type ip" will only store IPv4 addresses.& Z9 X8 I! d# d$ V$ k- X
This form is very compact (about 50 bytes per entry) and allows0 G4 o# j5 U ?2 H, f5 Y7 l" R) c0 v
very fast entry lookup and stores with almost no overhead. This& i e0 Q3 {4 F% u. H
is mainly used to store client source IP addresses.; R' e$ D. j( `/ X# k4 {8 l, Z" a3 b2 o
4 ^+ W ]; E; x4 m3 Z2 K
integer a table declared with "type integer" will store 32bit integers
4 j3 M9 V0 y, m5 X# t# h; }0 R6 {! \ which can represent a client identifier found in a request for4 q0 N$ p+ p5 i% i2 X) H2 F
instance.. V) e) g" ?1 _; O5 p
% C( P3 d6 {, Y# v* v" E string a table declared with "type string" will store substrings of up- T3 ^+ ]: n' I6 m( O3 Y, D
to <len> characters. If the string provided by the pattern) h% Y" o4 u" g( Q, g# k
extractor is larger than <len>, it will be truncated before0 j) @9 a* }6 e2 p. O! _& q: |# A0 l
being stored. During matching, at most <len> characters will be5 X: d3 q6 I9 J+ i; O* z( [
compared between the string in the table and the extracted* m4 q4 ^# h) l. y7 K g" F2 B
pattern. When not specified, the string is automatically limited7 V0 H- V( b/ {/ h/ k4 [! Z
to 31 characters.
6 N2 R; l& e5 d1 O0 e0 s
' M( H7 E8 ?6 L5 H6 S; P <length> is the maximum number of characters that will be stored in a; Y" ^& P/ q5 |# a8 s
"string" type table. See type "string" above. Be careful when7 O, s. x; z3 l4 w1 ^
changing this parameter as memory usage will proportionally
% Y u( X- b& S- j increase.
7 Y7 Z% t* o* l; o& G$ o6 R9 R* r, Y" D i/ {* Z8 U
<size> is the maximum number of entries that can fit in the table. This
# x: _ c! {" H9 N value directly impacts memory usage. Count approximately
4 r" `7 v1 q0 i3 a2 V 50 bytes per entry, plus the size of a string if any. The size
; `6 M4 D4 y9 A9 a; q* @9 f, c supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
3 j) d* k7 q. z* A; q
0 |5 D6 }) y- r9 b P [nopurge] indicates that we refuse to purge older entries when the table
9 Q1 d3 \; r3 I( Z0 g is full. When not specified and the table is full when haproxy
4 f+ u* l P( M1 b wants to store an entry in it, it will flush a few of the oldest
, {0 F/ [2 X$ r: l2 V# e( ` ~ entries in order to release some space for the new ones. This is3 n ?9 s I( I2 O @( `
most often the desired behaviour. In some specific cases, it1 ]5 X$ B+ j' X3 L3 N6 z
be desirable to refuse new entries instead of purging the older5 v7 F& s5 x. H# G m
ones. That may be the case when the amount of data to store is0 o/ F0 G2 N( E- |9 I1 Z
far above the hardware limits and we prefer not to offer access! M8 E3 \0 g+ t# p! J+ {
to new clients than to reject the ones already connected. When8 U; @& A* s: z2 \
using this parameter, be sure to properly set the "expire"
+ h C, ~- v- k2 s parameter (see below).
/ z, \9 }9 ^7 {2 F7 Q/ m: z }- R$ Q
<expire> defines the maximum duration of an entry in the table since it0 q" F: }0 m9 F( {8 R
was last created, refreshed or matched. The expiration delay is4 \( c" K( S6 Q- B9 l
defined using the standard time format, similarly as the various+ v1 h; ?! g3 Q# Z3 r* d
timeouts. The maximum duration is slightly above 24 days. See
( f+ @2 Y3 p+ }% S9 ~3 u4 l section 2.2 for more information. If this delay is not specified,
0 P+ M* ~' p) q h the session won't automatically expire, but older entries will& L: O0 e; }) Y5 `/ A- f
be removed once full. Be sure not to use the "nopurge" parameter
: b# e% m6 t0 c/ j if not expiration delay is specified.# w" i, r! b7 t* p( }# m( R
7 J/ `, c6 P8 z* b
The is only one stick-table per backend. At the moment of writing this doc,1 e5 P7 U4 H" W2 T7 o
it does not seem useful to have multiple tables per backend. If this happens
" l: z5 G2 C# v; F( J to be required, simply create a dummy backend with a stick-table in it and
% q( n5 G7 H5 |* M reference it.
) t* L" T. m; Q$ s
8 H" P) Q. h' q; I4 t It is important to understand that stickiness based on learning information6 n" X$ S# e1 C! e$ e
has some limitations, including the fact that all learned associations are
- _! m4 `+ `. S \$ L7 E1 f( l lost upon restart. In general it can be good as a complement but not always4 _% a9 Q: G; i' O' k# `+ s# T
as an exclusive stickiness." c7 R- _; l/ B
* f% N# V: ]% k! w- t. f+ ?
See also : "stick match", "stick on", "stick store-request", and section 2.2
( @0 o$ T' r4 [, ^ about time format.
& I5 F: q& Q2 n" ?% \6 V! S+ `; A
' j9 s' J/ \: r4 q% T! z4 M
tcp-request content accept [{if | unless} <condition>]
@; ^6 Q' x) D& X3 `, R7 r/ S# W/ Z% i0 w Accept a connection if/unless a content inspection condition is matched3 n9 z) n4 K2 v# y# A0 q" X) i
May be used in sections : defaults | frontend | listen | backend) J' j0 c8 g) T
no | yes | yes | no
6 d. q/ y0 U, e9 L' d, Q9 S% _% W: }
During TCP content inspection, the connection is immediately validated if the3 U) V8 P, d! E
condition is true (when used with "if") or false (when used with "unless").; h" @1 j- l! l- o
Most of the time during content inspection, a condition will be in an8 U5 D5 }- y+ _) f8 B* B; t
uncertain state which is neither true nor false. The evaluation immediately! H. z8 A, \ Q( ~
stops when such a condition is encountered. It is important to understand A) i0 x7 E: X" F" v# j/ c- F
that "accept" and "reject" rules are evaluated in their exact declaration
% Z9 } a+ Z$ a# A- v7 C order, so that it is possible to build complex rules from them. There is no. H3 T0 f- C- b- `
specific limit to the number of rules which may be inserted.
) s( t! {( F% S4 j, ?7 @, i
3 k F- G4 |, _/ @* `% x& k Note that the "if/unless" condition is optional. If no condition is set on
3 b, [& h1 n$ u0 S the action, it is simply performed unconditionally., H) [; s0 o/ U
$ g5 |% ^+ M2 ^; Y3 d$ } If no "tcp-request content" rules are matched, the default action already is8 V+ V* r9 d3 F
"accept". Thus, this statement alone does not bring anything without another
9 p. ~( s6 L) z: L- p "reject" statement.
+ m& q+ o: f% }4 Y4 v3 p2 e6 B0 V) z. Q. m. N( y7 A* X. \& Q( p
See section 7 about ACL usage.
. b- {: w- |; ] q# o
( ]9 o+ T0 A% j/ D See also : "tcp-request content reject", "tcp-request inspect-delay"
7 m, q+ v' A' }- n7 e( z$ ~) T% G, V7 ?% T) O
( P& L, d# {% P3 x+ b$ u
tcp-request content reject [{if | unless} <condition>] u$ _9 o2 y1 D: n. B5 d
Reject a connection if/unless a content inspection condition is matched# s9 R1 R' R& b7 A
May be used in sections : defaults | frontend | listen | backend
6 W6 G4 i! x2 b, \4 v no | yes | yes | no7 g" T% i( n# L$ I, K
9 F! \, T: |% K4 O
During TCP content inspection, the connection is immediately rejected if the
9 j6 H" e( A5 K+ u; F0 E8 A- @4 h condition is true (when used with "if") or false (when used with "unless").
5 {& n* x/ s4 @8 O+ y Most of the time during content inspection, a condition will be in an
& E9 f! I1 B" {' b uncertain state which is neither true nor false. The evaluation immediately# S9 v" @3 H. ^' R+ r" P4 p& C* T
stops when such a condition is encountered. It is important to understand
4 V3 G5 x# O3 F& p7 ? that "accept" and "reject" rules are evaluated in their exact declaration( M7 |/ y/ P4 }- ~
order, so that it is possible to build complex rules from them. There is no1 z7 [$ @% {- f
specific limit to the number of rules which may be inserted.
" v( U0 i# X1 N8 w* D4 Y3 s! O0 @& Z. o! [7 `8 a
Note that the "if/unless" condition is optional. If no condition is set on
7 P5 K4 l" d; M1 R2 i# T the action, it is simply performed unconditionally.0 k" w7 d5 e# ]
. `3 X# l* W0 x- r) U. C If no "tcp-request content" rules are matched, the default action is set to
- e: B$ p: ?' z "accept".
. r6 r0 I: M+ F! a+ u' B, F, d5 j3 `2 f y
Example:
- t7 K2 f; R) G, b. d4 K9 C! c # reject SMTP connection if client speaks first
" i: k, f1 g1 S. m( _# [ tcp-request inspect-delay 30s
2 d5 s. F' R$ a5 o6 I% b, ` acl content_present req_len gt 0
- S( h6 O ~; H ?* e3 s tcp-request reject if content_present' t7 ^/ }- x( r+ w
; h1 \: |# p" Q$ P, g8 a # Forward HTTPS connection only if client speaks
! {$ t% y' x$ F9 R1 [* W tcp-request inspect-delay 30s
1 u5 }8 l- C* R5 t7 \ acl content_present req_len gt 0
: D4 P4 u) b; C' Z- z3 x tcp-request accept if content_present
g4 L } f7 y- C" G6 K) J1 b$ y tcp-request reject5 H* b% Y: E' Q% F) v! Q
5 x* Q8 _, g8 F See section 7 about ACL usage.6 X: x" b6 B8 j/ }+ i& J' O
6 R' D0 @: G2 j- B, K2 z9 Q See also : "tcp-request content accept", "tcp-request inspect-delay"
6 V; J$ H2 y; i& J5 G$ D( b9 _0 z6 |% _' h1 j
6 _4 o. B5 `: S! l, qtcp-request inspect-delay <timeout>
S) C) f1 n* y4 V) v9 H& i Set the maximum allowed time to wait for data during content inspection) M: X) G; `; n7 I1 k& e- e2 B
May be used in sections : defaults | frontend | listen | backend
6 ~( V W0 B# D I% T3 X( x no | yes | yes | no
+ e4 t( i7 D' S Arguments :
& j1 ?0 t9 o, x! U <timeout> is the timeout value specified in milliseconds by default, but
/ L1 K% T$ v9 J can be in any other unit if the number is suffixed by the unit,
. A6 r8 i0 x7 U: b' g as explained at the top of this document.6 q* A6 U" R' i+ a( h4 J
- k# e+ |& l5 [4 h, O
People using haproxy primarily as a TCP relay are often worried about the
6 f: W1 T8 W/ G! |( f7 n& p3 e risk of passing any type of protocol to a server without any analysis. In- r0 {+ v) K) C0 r
order to be able to analyze the request contents, we must first withhold* e! ]6 ] F5 Y2 g- N5 f1 C
the data then analyze them. This statement simply enables withholding of
# w5 m1 O9 n- d* ]3 I X! e data for at most the specified amount of time.
0 t7 A' a7 w) z( j
8 e0 F/ w1 Z) z" ^+ X Note that when performing content inspection, haproxy will evaluate the whole ~. Y' X; w6 u4 C
rules for every new chunk which gets in, taking into account the fact that3 n( w( A# J6 z' U/ Z; `
those data are partial. If no rule matches before the aforementioned delay,
$ ~$ X4 \5 R. j7 {" o* p4 X- `5 U" z a last check is performed upon expiration, this time considering that the
- ~0 C6 q% ?( V contents are definitive. If no delay is set, haproxy will not wait at all3 K, q/ }, d7 {# ]) S& n4 L* b
and will immediately apply a verdict based on the available information.5 C3 A/ `! u r2 s7 |
Obviously this is unlikely to be very useful and might even be racy, so such
1 B7 M( F' o2 k setups are not recommended.
' _4 ]' m; k# B8 l5 ?% O+ r+ O' w! T: o+ t
As soon as a rule matches, the request is released and continues as usual. If0 }" g% r3 D, L* T( {1 ^7 n0 W/ N
the timeout is reached and no rule matches, the default policy will be to let) B4 \ y! R2 @) f8 k, a
it pass through unaffected.
! `( ?0 t+ w1 s( C" {5 E2 L% t, k2 ]+ b8 i u* D1 W! n
For most protocols, it is enough to set it to a few seconds, as most clients$ g" j; m1 Y- Z) }
send the full request immediately upon connection. Add 3 or more seconds to
9 E8 D% V( a* L. i4 `' D cover TCP retransmits but that's all. For some protocols, it may make sense
% x. }$ W9 O& s1 t1 ~6 q to use large values, for instance to ensure that the client never talks. C$ H* W4 E% T! l- j( n
before the server (eg: SMTP), or to wait for a client to talk before passing* Y6 e9 e6 x% J1 [
data to the server (eg: SSL). Note that the client timeout must cover at
" R- S4 n4 E# D! m, w7 [ least the inspection delay, otherwise it will expire first. If the client1 Q5 Y" i2 C( N% I8 f$ Z$ @+ l
closes the connection or if the buffer is full, the delay immediately expires8 E. x: M. e ]& f: q
since the contents will not be able to change anymore.3 h, M/ G8 b! O; w+ H8 W2 S
' i! e& K( B3 ^ |' Q See also : "tcp-request content accept", "tcp-request content reject",0 T- l& ?% Q+ ^* @
"timeout client".: h7 O# S9 C0 ?0 |! \/ b9 Q
' h" b* \7 N9 \6 `8 i2 y
; M5 t7 k. ~- T& Z( A5 l6 M& Ytimeout check <timeout>
$ J. ~4 W O/ s2 K Set additional check timeout, but only after a connection has been already( k# p( R! x9 o: X5 ]. \4 n
established.
! {, E3 Y; N5 M
; o6 [- j$ g$ H/ a+ u May be used in sections: defaults | frontend | listen | backend
8 g& @7 J/ {! ^. ?* q( x2 H yes | no | yes | yes
1 w1 ~8 s! c! l% q: M6 O3 M$ B3 U Arguments:" k7 P. B2 G1 H
<timeout> is the timeout value specified in milliseconds by default, but
; q" g' a( w! h# s5 u J can be in any other unit if the number is suffixed by the unit,0 b/ y* g9 m' P; a9 Z
as explained at the top of this document.
r R$ X9 m1 x& G1 D4 q/ n% m# f
If set, haproxy uses min("timeout connect", "inter") as a connect timeout
5 l2 a) c' z" F for check and "timeout check" as an additional read timeout. The "min" is! [. D+ w2 }; H4 e! f7 b3 F5 ^
used so that people running with *very* long "timeout connect" (eg. those
) t* i7 i K" z3 u who needed this due to the queue or tarpit) do not slow down their checks.0 L+ y: f& O+ P- [0 V3 m8 X) \
(Please also note that there is no valid reason to have such long connect
$ }4 G% b0 g+ V: r timeouts, because "timeout queue" and "timeout tarpit" can always be used to
2 _: y0 {$ i2 d; c5 ?/ r; y& O avoid that).
1 M9 E l6 \& |/ z$ M! p; v9 |$ M! Y( ~. m6 X
If "timeout check" is not set haproxy uses "inter" for complete check5 f# x9 k6 x+ `! `, W
timeout (connect + read) exactly like all <1.3.15 version.1 Q& N# @6 g$ d+ ~
8 X# D: s, z& m3 o3 M In most cases check request is much simpler and faster to handle than normal# W7 \) n4 |" I' d/ ]0 l
requests and people may want to kick out laggy servers so this timeout should
) D" q: q, e- T6 P4 |8 |+ { be smaller than "timeout server". U, t9 F6 q. R/ Y3 T
* I$ R5 I/ G) A. F8 q/ T5 ^ This parameter is specific to backends, but can be specified once for all in
6 s, V% x5 i' H% C "defaults" sections. This is in fact one of the easiest solutions not to: K% ?9 H ]5 o, x! M( ]
forget about it.2 W; @& d0 c& s! d' A" m0 z
' O8 m9 a4 j. a. ?9 ?/ ]: \ See also: "timeout connect", "timeout queue", "timeout server",1 y- ~( ?5 I0 j- s
"timeout tarpit".
8 w' {; V( z ]& u; a
$ R9 d: O) T' n& `
3 d- P0 q9 d. |9 vtimeout client <timeout>
) \7 ?$ R% |; [% B9 o7 d l9 ?: xtimeout clitimeout <timeout> (deprecated): G3 ^ t: z, |# B
Set the maximum inactivity time on the client side.
2 L0 k w! M% q5 k; T1 m, ?& O May be used in sections : defaults | frontend | listen | backend. E- U+ E0 m; g4 J) S
yes | yes | yes | no9 Y6 n" C! @# C- @: Q
Arguments :
! y& f; m; ?7 A$ R <timeout> is the timeout value specified in milliseconds by default, but
4 u j6 Y9 n4 e0 `$ u can be in any other unit if the number is suffixed by the unit,) X. f7 m7 b# U& N1 S
as explained at the top of this document.* z! M/ A! U4 y4 a) Z
: f: M4 U" V7 D& [+ R The inactivity timeout applies when the client is expected to acknowledge or
- n2 |& H& Y9 }1 A9 `: j4 f send data. In HTTP mode, this timeout is particularly important to consider. o. b% E0 q6 |( ?: u6 N( I9 |$ z
during the first phase, when the client sends the request, and during the8 S. T/ ?* c& j2 I3 ?2 \5 @+ j2 P
response while it is reading data sent by the server. The value is specified) ]0 l; z2 Z$ Y8 p! K0 `
in milliseconds by default, but can be in any other unit if the number is; u# L- x% r2 R D
suffixed by the unit, as specified at the top of this document. In TCP mode' ^3 @, C( I# i4 I2 o
(and to a lesser extent, in HTTP mode), it is highly recommended that the
4 ^0 h6 c h( f& m client timeout remains equal to the server timeout in order to avoid complex
" h* Q% q3 j% @" [1 ^$ n$ C situations to debug. It is a good practice to cover one or several TCP packet: U0 `. ^. S3 a8 G3 L
losses by specifying timeouts that are slightly above multiples of 3 seconds
8 W4 @. ?; s4 d8 W3 U0 T2 \/ { (eg: 4 or 5 seconds)." O5 t3 `" ~( \, u! G
O9 ?7 u' f7 p) t This parameter is specific to frontends, but can be specified once for all in
4 f! ?9 J9 P% C2 X3 Q) c; e, E4 Z "defaults" sections. This is in fact one of the easiest solutions not to U* c3 R' e: q9 K# k9 k. n& d. L
forget about it. An unspecified timeout results in an infinite timeout, which( R' Y0 a! |) x
is not recommended. Such a usage is accepted and works but reports a warning
: C9 U% K& l) j, g( Q' U1 T/ _ during startup because it may results in accumulation of expired sessions in
% F1 _: x k7 q the system if the system's timeouts are not configured either.- Z% y; J$ u. X) R
% J5 {4 {0 e4 k1 k This parameter replaces the old, deprecated "clitimeout". It is recommended
: Z ^* S1 N) @+ o to use it to write new configurations. The form "timeout clitimeout" is# l# v% b2 R. k/ k3 e+ F1 b
provided only by backwards compatibility but its use is strongly discouraged.
/ N3 W" Z7 \! e' \8 {
$ o% z! f) Z# a See also : "clitimeout", "timeout server".' ~* q- p4 n8 Z: m2 ~9 d ~
* E1 i! h+ `* C: K& n5 f7 Z) [1 _$ B$ Z8 I0 @, `/ r7 t
timeout connect <timeout>
- M! i3 |+ ], z4 ?" Htimeout contimeout <timeout> (deprecated)
1 ~& i, g( ~ p* M Set the maximum time to wait for a connection attempt to a server to succeed.
8 @5 H t! ?0 ]# H6 s May be used in sections : defaults | frontend | listen | backend
; ~; \ [( u% A" \% _/ }# h yes | no | yes | yes$ K6 C; _8 d/ o* W
Arguments :7 ] @1 D( |8 f: Q7 d
<timeout> is the timeout value specified in milliseconds by default, but$ i% Z9 H5 K4 j4 K0 n0 ~. I7 A
can be in any other unit if the number is suffixed by the unit,5 Q0 P5 @8 T/ y, K+ s! l
as explained at the top of this document.
) e5 K* P5 c; O8 e, o1 d. x' x6 P3 V" w- D! C
If the server is located on the same LAN as haproxy, the connection should be3 _& V# W1 q5 e! V% r0 A3 e3 ?
immediate (less than a few milliseconds). Anyway, it is a good practice to
; U' {4 d3 M* K1 p3 D cover one or several TCP packet losses by specifying timeouts that are1 C, Y0 \/ m, \6 X
slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
+ Y" c: f6 ]+ w5 C6 Q3 Q0 u1 t connect timeout also presets both queue and tarpit timeouts to the same value: o* r0 t# c. g& U% L- q
if these have not been specified.) p r' R \' w
/ e* O% Z& O( N* }5 z7 R
This parameter is specific to backends, but can be specified once for all in
8 m6 g2 t( D6 K- u9 x# T1 Q2 y "defaults" sections. This is in fact one of the easiest solutions not to: A3 M& h3 a2 L: Z" g
forget about it. An unspecified timeout results in an infinite timeout, which
9 Q2 g, ]9 H2 p2 R3 M' v1 @ is not recommended. Such a usage is accepted and works but reports a warning
( l6 u0 Z1 e( W( M. o# Z: ^0 | during startup because it may results in accumulation of failed sessions in+ A/ @/ H' B. s6 X# k3 L
the system if the system's timeouts are not configured either.2 ?! i& |5 {& q$ v" ]' S
2 @" Q* m: R/ m" }! L8 a
This parameter replaces the old, deprecated "contimeout". It is recommended
j* R/ H9 Z' u8 \ to use it to write new configurations. The form "timeout contimeout" is
& B& d/ O) U( j provided only by backwards compatibility but its use is strongly discouraged.
4 x' f8 [$ E8 [0 H3 {/ ]3 T/ \6 c2 {, n7 V/ \; W# X
See also: "timeout check", "timeout queue", "timeout server", "contimeout",& }/ O# h) B* |7 O" z6 h/ O
"timeout tarpit".
8 Y- V6 v3 d5 h+ F4 U$ \6 ~* l# ?+ a+ j3 w" g1 h( H" y
2 H& n( Z+ W8 I1 wtimeout http-keep-alive <timeout>
1 X1 Q8 n8 u8 X5 F3 r+ c Set the maximum allowed time to wait for a new HTTP request to appear- Q; c. p7 h# V4 o0 m" w H# ^ N3 W
May be used in sections : defaults | frontend | listen | backend; Y" j/ a( m6 Z! w; U+ {( ^
yes | yes | yes | yes4 j& O6 [% c: t, h4 R
Arguments :
7 M9 T7 z& [4 L' j' w0 a2 X <timeout> is the timeout value specified in milliseconds by default, but
. J) t+ l' N& j7 ~& a& L& }' y can be in any other unit if the number is suffixed by the unit,& X5 |+ H0 f. f: c
as explained at the top of this document.* T3 C5 C f/ }
" l/ Y4 i9 g3 `# q2 M# {5 ^6 M
By default, the time to wait for a new request in case of keep-alive is set- s0 }1 X. u+ L) q( |' W8 U5 r0 y8 i
by "timeout http-request". However this is not always convenient because some
' }: f. b* p8 U# u* B. _ people want very short keep-alive timeouts in order to release connections
+ S2 D8 I" O5 B7 q faster, and others prefer to have larger ones but still have short timeouts6 ?# F9 W: j5 U7 p: K3 D
once the request has started to present itself.# Q* A/ X# e6 M' T% ]; y1 S0 q
, w4 \: r: a/ O) V% w5 R The "http-keep-alive" timeout covers these needs. It will define how long to+ |6 _ k4 x& \3 [
wait for a new HTTP request to start coming after a response was sent. Once3 b5 K+ c5 g! `
the first byte of request has been seen, the "http-request" timeout is used% n5 r9 O c0 I6 u
to wait for the complete request to come. Note that empty lines prior to a* t5 w) ~2 Z1 |7 Z2 L
new request do not refresh the timeout and are not counted as a new request.
! d& w4 r& }# _8 j% E( J5 M1 d/ B* V. f `- Q
There is also another difference between the two timeouts : when a connection
: {1 x1 A1 M. I4 a5 _; g/ @/ _ expires during timeout http-keep-alive, no error is returned, the connection
6 s( U8 K0 u, f, A just closes. If the connection expires in "http-request" while waiting for a
6 Q5 s; u& \ @! C- \7 ] connection to complete, a HTTP 408 error is returned.* S0 K2 U" M) a8 }+ z$ L; O
; o. ^: F) I9 b) W. ~# m- S
In general it is optimal to set this value to a few tens to hundreds of$ z5 {1 [. R" Q, S a/ I
milliseconds, to allow users to fetch all objects of a page at once but' \1 s W: q3 t. v _- R
without waiting for further clicks. Also, if set to a very small value (eg:
9 O. H6 {; ?) i; O. z 1 millisecond) it will probably only accept pipelined requests but not the( `& @; a4 s, T. P( l$ A1 A" `/ P
non-pipelined ones. It may be a nice trade-off for very large sites running
( i9 E( i1 E7 P7 E2 [$ U. L0 ? with tens to hundreds of thousands of clients.
/ O$ t: |" w! q% e) C9 H3 n+ t% s% ^
If this parameter is not set, the "http-request" timeout applies, and if both
% d0 [; ^' v* z3 } are not set, "timeout client" still applies at the lower level. It should be! R% ]! G" r. C4 P# L
set in the frontend to take effect, unless the frontend is in TCP mode, in
- C T( G8 G1 \$ E" _ which case the HTTP backend's timeout will be used.
% |0 h; \0 ?2 H. S: L, x$ n Z- u/ f% R" j' D2 Z0 @
See also : "timeout http-request", "timeout client".
6 Q3 `4 F! `# Q- b
: Z5 W0 G7 N/ M& Q
8 s3 U% R& [$ A+ l9 x; B6 ztimeout http-request <timeout>9 c! V6 s4 S' }) p$ D3 b* t
Set the maximum allowed time to wait for a complete HTTP request
; Q/ b9 [9 D' ?1 [ May be used in sections : defaults | frontend | listen | backend, h6 a/ b8 U" f* e7 y1 P
yes | yes | yes | yes
/ y- @/ A M2 e0 m Arguments :! n/ Z9 I& `! l! K: d7 |; L
<timeout> is the timeout value specified in milliseconds by default, but, u! d5 K R \# c! O
can be in any other unit if the number is suffixed by the unit," Z$ H4 A0 X& P/ x: \5 ~% M
as explained at the top of this document.$ Y) B9 F8 I6 g3 j4 l7 o2 G
, U" }) Q" _0 f" i* [; D2 }9 k In order to offer DoS protection, it may be required to lower the maximum8 h4 L3 v0 k: T. x
accepted time to receive a complete HTTP request without affecting the client
* t) H, t* q# F( i( c+ N3 K timeout. This helps protecting against established connections on which
3 `0 [; A! ?! I4 n, c nothing is sent. The client timeout cannot offer a good protection against z8 \- A# @6 ^7 F- p, Z
this abuse because it is an inactivity timeout, which means that if the9 f8 H' v. b8 i% }1 P) G# L$ M& ~
attacker sends one character every now and then, the timeout will not
# p4 \! b+ z; J" t5 o0 ? trigger. With the HTTP request timeout, no matter what speed the client
% H$ Y- @6 F+ a6 A# {5 ] types, the request will be aborted if it does not complete in time.( Y. _# L8 ~: C1 I1 U" h, _" I
' W& j' j/ ?4 U& {3 p Note that this timeout only applies to the header part of the request, and3 v8 E, m# s( l3 u8 E' W
not to any data. As soon as the empty line is received, this timeout is not# Y0 c b$ }6 N8 T# Q) o
used anymore. It is used again on keep-alive connections to wait for a second
1 @/ Y$ F" d% S7 S# O request if "timeout http-keep-alive" is not set.
2 L( m% }+ X4 [, f/ w8 x d! O$ d; Q7 I
Generally it is enough to set it to a few seconds, as most clients send the
1 X# F9 }; h5 t full request immediately upon connection. Add 3 or more seconds to cover TCP
) B4 Q3 v. w' l6 D retransmits but that's all. Setting it to very low values (eg: 50 ms) will
) U0 X; Q1 u. C4 b, { generally work on local networks as long as there are no packet losses. This
& f! D6 T3 F( g) z will prevent people from sending bare HTTP requests using telnet.
2 q0 d4 e' x. V% f; K
0 C9 {0 Q4 Q5 ? If this parameter is not set, the client timeout still applies between each
0 J, l4 y4 ]# G6 t chunk of the incoming request. It should be set in the frontend to take
0 s* Q9 s7 s2 H5 A& J/ J2 X( ] effect, unless the frontend is in TCP mode, in which case the HTTP backend's( L8 d2 f, x* q) M! S3 X
timeout will be used.
. N# Q" d' ^$ m+ i* c& r0 G H, d; [) n3 d
See also : "timeout http-keep-alive", "timeout client".
$ Q$ ?4 y# R4 |0 Z7 } j+ e
& D* w' L& b! J3 Y! u! l/ q; L2 J; Q s" R! c9 p0 p
timeout queue <timeout>; M# e! h/ ~- `3 V) o: a& k
Set the maximum time to wait in the queue for a connection slot to be free
# {; Z! q% |6 O! f May be used in sections : defaults | frontend | listen | backend
# M$ m$ g. ^! ]% P4 i0 O7 {6 | yes | no | yes | yes8 {* P& b# ?+ |0 C/ A4 Q# X) e! P
Arguments :
! U; w( l. N4 A" l1 x, i <timeout> is the timeout value specified in milliseconds by default, but- p* i! ~+ m3 j
can be in any other unit if the number is suffixed by the unit,
0 D9 Q* j8 ]4 A4 x, p8 S as explained at the top of this document.
: m5 h/ l' F/ a( w: T
- l( e! d; L/ i When a server's maxconn is reached, connections are left pending in a queue) d0 `/ A0 C; P& ~
which may be server-specific or global to the backend. In order not to wait
' b1 Y6 F N t T4 x indefinitely, a timeout is applied to requests pending in the queue. If the1 p/ n# U0 X# }; i
timeout is reached, it is considered that the request will almost never be/ C! H [3 K5 _# ~& R3 B: ^
served, so it is dropped and a 503 error is returned to the client.9 L! u# Q s4 V( b) \
" `1 I! `( F3 L3 q; y8 ^% f The "timeout queue" statement allows to fix the maximum time for a request to
3 w# z/ c; H, q2 v! R1 ` be left pending in a queue. If unspecified, the same value as the backend's
8 z; t- i' y) D. ]+ C& W7 S connection timeout ("timeout connect") is used, for backwards compatibility
% {7 P9 Y8 n+ Z" L- a5 P( t with older versions with no "timeout queue" parameter.; d1 e+ v$ ~5 D! h
' ~* Q* i8 p5 {1 D$ _! X' W% U See also : "timeout connect", "contimeout".
' s( h, z: h/ A8 k* L+ q
$ u! T9 q1 F" c* x6 G+ G2 h7 T- G- l1 g( V U) q! V/ G" k; A
timeout server <timeout>
l' v# E0 j3 @4 A7 R4 t: `timeout srvtimeout <timeout> (deprecated)4 n2 l, Y. u7 ~6 X& k& N' D' Q
Set the maximum inactivity time on the server side.7 B/ d! S; z3 ^1 }" N6 y3 j
May be used in sections : defaults | frontend | listen | backend; X* a; B$ f% D k
yes | no | yes | yes$ |! ?2 x5 T% i9 Y2 A- J
Arguments :
* \# O; W2 p. d; f <timeout> is the timeout value specified in milliseconds by default, but
7 D8 ~2 w7 W9 U6 w/ W, u' d can be in any other unit if the number is suffixed by the unit, z6 Q4 l: Y* T3 k
as explained at the top of this document.$ I/ b& Q0 _/ u4 W! n4 Q
) M, W. }# \3 J' V) g9 M
The inactivity timeout applies when the server is expected to acknowledge or. q$ S# h/ _: ^ q
send data. In HTTP mode, this timeout is particularly important to consider3 N/ C" o' S; s5 d8 C8 }/ d
during the first phase of the server's response, when it has to send the
+ q4 r" X4 z) |7 O+ | headers, as it directly represents the server's processing time for the1 }( A0 P7 r4 ?0 i
request. To find out what value to put there, it's often good to start with
1 f6 M8 N3 J2 J, j0 ~5 o5 e what would be considered as unacceptable response times, then check the logs
3 f4 u" A7 E# E+ n: P( V to observe the response time distribution, and adjust the value accordingly.
" |) I8 V% {7 M0 H
, G a+ ~8 z- X7 q9 U' ^ j The value is specified in milliseconds by default, but can be in any other
5 Q6 ~( V: K! @3 x1 F5 i8 y unit if the number is suffixed by the unit, as specified at the top of this
7 s% e4 s. ], O: }" ^ document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly, V4 J3 S& C; T F+ q1 ]
recommended that the client timeout remains equal to the server timeout in
3 _* W4 G& p, G/ a% F. ]* l- w+ e order to avoid complex situations to debug. Whatever the expected server
# }4 ^3 q2 g! S( b response times, it is a good practice to cover at least one or several TCP
8 F- z$ m6 e4 }( c7 X2 N; Z! A packet losses by specifying timeouts that are slightly above multiples of 3) V/ K7 E/ n2 O9 @
seconds (eg: 4 or 5 seconds minimum).# E: w: }; Y+ k
/ u8 M* H9 _; I3 y5 l$ f! Z
This parameter is specific to backends, but can be specified once for all in
" p1 Z& E) ^6 b- Q "defaults" sections. This is in fact one of the easiest solutions not to
; f M4 s% c! r u9 z forget about it. An unspecified timeout results in an infinite timeout, which
7 i8 W$ u' C4 A; y* I2 F is not recommended. Such a usage is accepted and works but reports a warning
# L2 B. y& F# v7 C4 g" n7 E6 Z during startup because it may results in accumulation of expired sessions in% ~' _/ |/ p1 r5 q
the system if the system's timeouts are not configured either./ I( c2 y- e. t$ Y- m- \
4 U1 f6 w0 C$ N/ i6 x9 \+ Y This parameter replaces the old, deprecated "srvtimeout". It is recommended/ y; E) i$ T/ ~( h" _5 `$ N
to use it to write new configurations. The form "timeout srvtimeout" is
; {7 _9 y" b6 N q* f3 ` provided only by backwards compatibility but its use is strongly discouraged.
1 P0 Y6 m! Q% h% t6 v
( O. u! J9 z/ j) H2 n) ` See also : "srvtimeout", "timeout client".
3 x. ~% p7 ?$ J- {* x2 ]" _
: f9 g7 `" I6 C0 J# @' h
. C% m, |+ o! m: I% Y9 i; ztimeout tarpit <timeout>$ e9 u% [# o, j0 ?7 w0 E8 k- s
Set the duration for which tarpitted connections will be maintained
; o) K, Y/ s& N7 n* X4 ]" O" C May be used in sections : defaults | frontend | listen | backend0 M" }9 d7 I" \
yes | yes | yes | yes2 h$ b; E6 I/ [. F' z
Arguments :
' E o% S v5 J. s1 s <timeout> is the tarpit duration specified in milliseconds by default, but. C h! L( R* N% q: F4 j* k
can be in any other unit if the number is suffixed by the unit,
( l1 D) h- Z, a h0 X& [4 T, S as explained at the top of this document.
+ K+ L- {5 ]- |! q/ b
& L! x( c1 ^* L+ {1 @8 { When a connection is tarpitted using "reqtarpit", it is maintained open with
- i0 m5 Z* p9 C7 ^6 Y7 Z" s2 s# I no activity for a certain amount of time, then closed. "timeout tarpit" r# ^8 a+ v/ k6 e; b5 S
defines how long it will be maintained open.( F5 M ~7 t# ~5 V) y
( ^* \3 d( w7 _- M0 o The value is specified in milliseconds by default, but can be in any other) z& S9 G. z; S
unit if the number is suffixed by the unit, as specified at the top of this
+ f7 L, c( v) H& x" w document. If unspecified, the same value as the backend's connection timeout. R/ Z/ ?% X" i7 T8 T
("timeout connect") is used, for backwards compatibility with older versions
& E! B! p% ]( G- c8 r with no "timeout tarpit" parameter.4 Y# b, D: v) x6 d! m+ k# P
5 B1 ]2 E5 _% C/ Z; I* i& G" e( w
See also : "timeout connect", "contimeout".
' n! E7 J" W- V
$ U( D# X; j8 m% m" c/ n6 K
) `1 f9 C4 w. @transparent (deprecated)( P! z/ r4 Q. E( E6 g q5 s! i
Enable client-side transparent proxying
: j9 a9 c: W N' U! X0 C. p7 C8 v; y May be used in sections : defaults | frontend | listen | backend
+ J k7 O) a; m% F/ |+ _ yes | no | yes | yes
: l( _3 a2 {) I0 w Arguments : none- b7 x% i" `5 a3 O. ]9 E
( V' o9 o# l* S8 O( u
This keyword was introduced in order to provide layer 7 persistence to layer" ~8 L6 |5 h+ P2 ]/ g$ x# ~
3 load balancers. The idea is to use the OS's ability to redirect an incoming4 \, Q* r: T# s b
connection for a remote address to a local process (here HAProxy), and let
; G; `0 Y5 p' v; C this process know what address was initially requested. When this option is
- I! e3 r( v* M& j. p2 p9 M used, sessions without cookies will be forwarded to the original destination
! g6 P2 @) g/ c2 } w+ M IP address of the incoming request (which should match that of another0 M7 E) ~- s3 I7 M% \
equipment), while requests with cookies will still be forwarded to the
2 V# `7 {# h8 ~( ? appropriate server." @- t |: |, @* R, Z# t3 n1 ]
, D! m; `! ^) R! q0 d ^ The "transparent" keyword is deprecated, use "option transparent" instead.* L3 P6 s% W1 G: K4 A0 I: |
! t' T0 a6 M( n$ E; P0 K/ g
Note that contrary to a common belief, this option does NOT make HAProxy
% ?; ] R4 Y+ {- F2 H. _ U present the client's IP to the server when establishing the connection.
_/ K% ^; ?& y1 ^4 [( Z' R( d3 g) ~) N
See also: "option transparent"
" U) |/ i: f2 C8 n3 \2 I, d
; m( ]: I2 q1 E0 T. }
- J$ W3 C# o. w$ Nuse_backend <backend> if <condition>
& Y: Z9 s/ ~- d$ }use_backend <backend> unless <condition>
# l2 h+ c2 l+ E3 ^ Switch to a specific backend if/unless an ACL-based condition is matched.
' ~, Y' N7 [# M1 ]4 ] May be used in sections : defaults | frontend | listen | backend: M. O( ]( v9 y% Z" M
no | yes | yes | no' k6 G6 R2 P2 @! ~( b, j& p2 ?# J
Arguments :
" T5 a9 P) H# Y" | <backend> is the name of a valid backend or "listen" section.
1 ?1 C9 m4 F7 L, ^2 L9 R3 c
/ |0 a5 ~. s" q. B <condition> is a condition composed of ACLs, as described in section 7.6 [1 s% p$ Y) O- Y _1 j& s
1 k8 M( |/ a6 l: o. m# j$ O When doing content-switching, connections arrive on a frontend and are then
" o7 N0 v9 I" ]6 n" V# B) t dispatched to various backends depending on a number of conditions. The
6 p: \2 b) K g relation between the conditions and the backends is described with the
" v& y; D8 u# k1 R* G& F0 m "use_backend" keyword. While it is normally used with HTTP processing, it can8 v7 J/ N! w6 }0 A0 |0 F# C
also be used in pure TCP, either without content using stateless ACLs (eg:2 X: o- a, A/ V, W
source address validation) or combined with a "tcp-request" rule to wait for
* r, x0 n1 z; Z- r some payload.
. c: y2 L7 h( F5 f! e9 J \
, k1 A+ c3 o- Q* D8 _7 C. I There may be as many "use_backend" rules as desired. All of these rules are
4 S/ T- u; Z( S evaluated in their declaration order, and the first one which matches will
) D& {0 @; X+ ~- Q assign the backend.
* w6 x: |, H% X) V- e
4 s0 z6 l" c& q6 l) n- U In the first form, the backend will be used if the condition is met. In the; k# z# ^, a3 c' J6 N
second form, the backend will be used if the condition is not met. If no5 L& C# G+ j6 g$ B4 s
condition is valid, the backend defined with "default_backend" will be used.( K: v* o6 l9 T+ t2 g
If no default backend is defined, either the servers in the same section are
8 E L0 H4 k" y. f l6 {& V2 L- j5 e used (in case of a "listen" section) or, in case of a frontend, no server is
% t6 E9 H# z, Q$ _3 S used and a 503 service unavailable response is returned.
- A! H6 F& w" k5 y# l: J3 Y" H/ P/ ?
Note that it is possible to switch from a TCP frontend to an HTTP backend. In
1 p- Q! f6 c+ ^2 Y this case, either the frontend has already checked that the protocol is HTTP,8 W+ P! M* v* p( Z* C
and backend processing will immediately follow, or the backend will wait for
2 ]+ n7 p$ @# h3 v2 D& \ a complete HTTP request to get in. This feature is useful when a frontend1 \& [# Y8 L7 J# M) q
must decode several protocols on a unique port, one of them being HTTP." E5 `; B- q9 \: i' K) F N0 h
3 h) k- w9 Q5 j Q% q- \
See also: "default_backend", "tcp-request", and section 7 about ACLs.* }: Z* @$ h$ {
/ [1 H6 n: v" e
0 S5 |& M: R) [5 w* e) R( B) @5. Server and default-server options
9 u0 G: Z# ?2 v' c) K/ }2 o------------------------------------
- h$ F9 B; y: R+ J8 N3 I1 r6 Y" }. l; h, z2 r Z
The "server" and "default-server" keywords support a certain number of settings2 y. M! w: N, h s. X# d
which are all passed as arguments on the server line. The order in which those' u4 p9 r% n% U+ o2 v
arguments appear does not count, and they are all optional. Some of those9 T4 J' v [4 _# p' T5 {
settings are single words (booleans) while others expect one or several values1 N) H7 m' t- r4 ?8 [$ f7 d
after them. In this case, the values must immediately follow the setting name.
: ?- S; V2 r- w, J+ n$ a hExcept default-server, all those settings must be specified after the server's
+ w$ U$ z9 V' a( f# B9 v+ saddress if they are used:1 b6 s! w" K b s
" @( p0 a, p( w& Z9 h server <name> <address>[:port] [settings ...]. l. o6 l3 d% z
default-server [settings ...]
) ~/ E `2 u9 j% s) E: ~
. c9 B' r1 k; m% F; r- l. D* {1 OThe currently supported settings are the following ones.
& v: W/ D5 H' G1 l: ^$ W+ @! r5 Q7 J+ o0 m$ ]
addr <ipv4>
1 `0 ^& W9 a; a ? Using the "addr" parameter, it becomes possible to use a different IP address
5 x4 ~+ d' d+ b2 |. d( w q( @' v: ~ to send health-checks. On some servers, it may be desirable to dedicate an IP
* n/ d7 V2 M3 U( X6 T: y address to specific component able to perform complex tests which are more
% Z7 S& f H% l8 O suitable to health-checks than the application. This parameter is ignored if2 ~- i9 r- R# i, V9 }" P8 v9 Q6 e
the "check" parameter is not set. See also the "port" parameter.2 ?/ {- J! T O5 t: R6 ~9 X
* W' Q" Y" J* @8 i8 L( _ Supported in default-server: No
4 L& I. u, i0 k% b$ H2 g
( T: M4 f6 {; y. h- P% T( U q, I8 H6 k+ n' vbackup
+ ~6 z. y- T5 {6 t) a& i U When "backup" is present on a server line, the server is only used in load* R3 H( z; w4 I9 i
balancing when all other non-backup servers are unavailable. Requests coming
/ h( {& L& h) g( H with a persistence cookie referencing the server will always be served
& ^9 i$ @- T* X# { though. By default, only the first operational backup server is used, unless
6 o0 v: [. k3 j6 o! t& D, Q the "allbackups" option is set in the backend. See also the "allbackups"+ {1 f' F: \+ X7 I" R+ P, P
option.
2 D8 J+ I* G; i; s8 w+ G
+ b" O5 L& g& t& n: z8 p: z* r0 E Supported in default-server: No+ k! R& C* G% @5 ?* U* U
- F+ ?; R% b h* q, b- C
check
+ c3 a, t6 r0 C' t This option enables health checks on the server. By default, a server is' x; ?- m6 ]# `. j7 [
always considered available. If "check" is set, the server will receive
3 a: c- l- j; F periodic health checks to ensure that it is really able to serve requests.
% w7 S5 B8 K4 [- {/ ] The default address and port to send the tests to are those of the server,
/ T& t' N/ s4 C+ t9 ~5 T and the default source is the same as the one defined in the backend. It is/ e& Z' K [1 I, C9 S7 y
possible to change the address using the "addr" parameter, the port using the
* T* K4 f0 A3 o$ P4 h, J5 F% ~ "port" parameter, the source address using the "source" address, and the/ e, O3 M8 I; U* g2 l
interval and timers using the "inter", "rise" and "fall" parameters. The5 {, Z& w# \6 ], {7 j. T
request method is define in the backend using the "httpchk", "smtpchk",, E- x2 Z4 T, O- n
"mysql-check" and "ssl-hello-chk" options. Please refer to those options and
& i4 Z) E2 _* v parameters for more information.; |" P6 F3 E1 g! s
, s$ S5 p! W5 g2 S1 I) ~. r Supported in default-server: No6 }' b0 E! C; o
: B# C" H7 A7 `0 C. C! b0 a9 @' @
cookie <value>; U! B% H `/ [9 R
The "cookie" parameter sets the cookie value assigned to the server to
8 ~- F" M! P6 C0 v% S7 H$ ^3 p <value>. This value will be checked in incoming requests, and the first
3 ]+ O4 a: \! U operational server possessing the same value will be selected. In return, in/ I4 N- J+ F0 Z; E
cookie insertion or rewrite modes, this value will be assigned to the cookie% D' F. ?4 Y/ {' ]* `
sent to the client. There is nothing wrong in having several servers sharing
* ]2 H2 V8 X7 o4 t8 k the same cookie value, and it is in fact somewhat common between normal and
/ Y2 r; E; _! d1 X/ g backup servers. See also the "cookie" keyword in backend section.
! b* f. z; p, x( Y5 x3 U# f2 E& e$ u# ]* u Y3 {7 D
Supported in default-server: No
3 A" K, @+ ?3 M7 c
' @8 u* ^! J" C2 r* O' zdisabled
6 b# e$ G, Y! [; o0 t( L The "disabled" keyword starts the server in the "disabled" state. That means! D3 Y( \, y) w# y8 A8 n$ t
that it is marked down in maintenance mode, and no connection other than the8 `' S7 ]/ A0 S2 ], @6 K& f {6 U
ones allowed by persist mode will reach it. It is very well suited to setup
8 t0 n$ w) A$ Y* Q1 v) t" d7 B new servers, because normal traffic will never reach them, while it is still, o! t- {1 `5 W3 h! ~- ~, R% ?
possible to test the service by making use of the force-persist mechanism.
! i) A1 b# p5 U% r: c
2 B) U/ Z3 l6 X- |3 B, t Supported in default-server: No1 \: p( [& @+ J b0 K8 M
/ z+ p- F5 J* }) G$ Herror-limit <count>% n: K5 P- U, L
If health observing is enabled, the "error-limit" parameter specifies the R" k3 Z% Q; }% M
number of consecutive errors that triggers event selected by the "on-error"
. O9 |6 @- Z2 w3 S8 z option. By default it is set to 10 consecutive errors.
7 E( r: b. k& J2 o' ^$ h/ Y7 n1 t& G! U& R
Supported in default-server: Yes) W/ `1 G4 K# L9 s# l
; {0 q* U7 i( P ^5 l, v7 |) ]
See also the "check", "error-limit" and "on-error".
0 l6 V: w( C. E0 J) a8 G
' ]* j7 `/ g6 x, C# g g3 Cfall <count>
) s0 t5 I5 l7 |3 a2 I. o2 } The "fall" parameter states that a server will be considered as dead after/ a" Q. ?7 T0 i
<count> consecutive unsuccessful health checks. This value defaults to 3 if8 h& F4 S4 S- G+ c" u J
unspecified. See also the "check", "inter" and "rise" parameters.
9 ?, w! } r% x9 }" k' y0 Y' R$ q
n; T, j" x4 b% P7 N* r( _ Supported in default-server: Yes
. r. x1 c9 A ^0 U$ B5 f& I/ I
1 z) p- H+ w/ R3 {id <value>
* V/ w: _$ `; {) v% K& X Set a persistent ID for the server. This ID must be positive and unique for
% V+ i2 }: g7 j) V0 e8 N6 }0 ] the proxy. An unused ID will automatically be assigned if unset. The first; l* \/ W( i4 u( F) D
assigned value will be 1. This ID is currently only returned in statistics.' I+ [4 W$ _8 q$ o1 }) a3 `
1 a! J' x& f' w0 T& Z
Supported in default-server: No. `8 d+ w! c. r, c- t
& i/ n" |8 u# W- q/ O
inter <delay>
# m* N7 r v, T6 R4 `fastinter <delay>; F( }: Q, w; o1 w+ f$ z' Q9 e. s
downinter <delay>
; q, L( d% R+ z) b; ^& U* j The "inter" parameter sets the interval between two consecutive health checks
. n# c! n, T8 I# ~' A9 n4 M$ } to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms./ |7 a8 m5 }3 E. C1 @
It is also possible to use "fastinter" and "downinter" to optimize delays* ^# U8 s& v* i, {' z0 n: h- G
between checks depending on the server state :
9 l7 `' d' u# j% g4 [, k0 E& E6 ]) i1 q1 z* s; h$ ?
Server state | Interval used
. }: e1 I$ r B/ W ---------------------------------+-----------------------------------------
5 u p6 F* b, `; q! J: j UP 100% (non-transitional) | "inter", Y; \( w- S8 A/ m( _
---------------------------------+-----------------------------------------# f. Y+ Y+ ]7 Q0 l5 [
Transitionally UP (going down), |
2 L4 a/ Y y7 w) r5 h Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise.
N: j2 x, f6 c$ O1 r- a or yet unchecked. |
) L N+ Y+ t/ E4 R1 z ---------------------------------+-----------------------------------------4 y% A5 i8 |! m7 b
DOWN 100% (non-transitional) | "downinter" if set, "inter" otherwise.
' y) T9 v$ s9 m/ _2 ?0 b, J ---------------------------------+-----------------------------------------
0 w- R J* l/ m% q& l) t, e2 M- c2 V4 H
Just as with every other time-based parameter, they can be entered in any
- \) _% x% [: g3 J- i other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also( y, D' Z0 b' `# |
serves as a timeout for health checks sent to servers if "timeout check" is3 g F( _! A; b$ l
not set. In order to reduce "resonance" effects when multiple servers are
; I: q5 V; H! A% S: T4 g hosted on the same hardware, the health-checks of all servers are started
' a8 N* f ~# @$ \" [4 |5 F with a small time offset between them. It is also possible to add some random
. ~) \% b2 n, Q% o! _ noise in the health checks interval using the global "spread-checks"
: Y& v( M5 v( v/ k( J3 J2 v; G keyword. This makes sense for instance when a lot of backends use the same2 {0 E! F. J& \- p+ H
servers.
: s* T+ S+ Z% k7 ]& D% ~2 P+ s! H0 ]0 h% I3 q
Supported in default-server: Yes0 ]6 @0 A# n2 k1 J. j
' d1 [- \( e. a1 I: X$ D, Y
maxconn <maxconn>, }0 L. Z1 S$ u% p9 P m4 S
The "maxconn" parameter specifies the maximal number of concurrent4 j5 X1 e* }3 Z6 C
connections that will be sent to this server. If the number of incoming
6 B5 ?7 s: B& g concurrent requests goes higher than this value, they will be queued, waiting
$ A. N5 A3 \& P9 z7 H3 R for a connection to be released. This parameter is very important as it can
& S! r7 Z$ E6 @; K7 ` save fragile servers from going down under extreme loads. If a "minconn"
% W! d9 k+ p: X: }- y parameter is specified, the limit becomes dynamic. The default value is "0"
, z, e( L7 F7 [7 f9 Y6 }! S which means unlimited. See also the "minconn" and "maxqueue" parameters, and
$ K; V3 o2 a+ ]5 o5 r6 b4 z the backend's "fullconn" keyword.. \% K# j) D. r9 z% s
6 d: y: ?0 l* t* {( u0 G$ L. } Supported in default-server: Yes
5 a9 ^. q2 [4 n( w; X5 k! E$ i- X, q" h5 a; N4 z
maxqueue <maxqueue>5 J* c2 b: ?# E; r# l1 d/ h4 X# J
The "maxqueue" parameter specifies the maximal number of connections which/ w' j) A3 K1 ?4 [4 z; ~7 [# C: [
will wait in the queue for this server. If this limit is reached, next
& I0 _3 Y8 J$ L8 j requests will be redispatched to other servers instead of indefinitely# n; [3 X2 [4 S0 L
waiting to be served. This will break persistence but may allow people to( M8 `4 U- T' B+ b3 `& S7 k1 Q
quickly re-log in when the server they try to connect to is dying. The7 n5 ^; d: J7 `( Q
default value is "0" which means the queue is unlimited. See also the
) E: ?3 ?" o2 P. l% F, i/ Q2 o "maxconn" and "minconn" parameters.$ Y1 Y- v8 d& D: \% z, h4 Z
8 C5 F7 i5 Z* m; \9 M' c- o Supported in default-server: Yes
$ W8 n i- j9 o, h" r1 z' d+ N% u
minconn <minconn>
: B0 m4 U1 f9 |% @# \ When the "minconn" parameter is set, the maxconn limit becomes a dynamic
: R. Y* o2 k& Q( _+ l limit following the backend's load. The server will always accept at least
% ^/ D/ l. K7 @' K! y% J" I <minconn> connections, never more than <maxconn>, and the limit will be on
5 y1 M3 u& O4 y% B' T0 {8 j the ramp between both values when the backend has less than <fullconn>! T8 ^- e0 w2 q" D/ E
concurrent connections. This makes it possible to limit the load on the% @" \9 ^, k3 p( f" m# b8 H, ^+ e
server during normal loads, but push it further for important loads without
! A5 q9 [! _( a6 C) |& L( O4 Y* I overloading the server during exceptional loads. See also the "maxconn"
V: Q5 `9 l+ r5 C and "maxqueue" parameters, as well as the "fullconn" backend keyword.
$ @" _* u: ^) C2 K: T ~# ?" `5 c! v: J G# a/ D. {& _
Supported in default-server: Yes
V0 Y0 ?! F, c r3 d2 p
) \# R: N5 S1 `" Wobserve <mode>1 v( S( i9 L0 [( f, r
This option enables health adjusting based on observing communication with- \7 X5 [* n5 j
the server. By default this functionality is disabled and enabling it also7 B# M/ |) [2 r6 Y. `/ O0 r
requires to enable health checks. There are two supported modes: "layer4" and( Y% B) p* K$ |9 d- R/ A( h( _" D
"layer7". In layer4 mode, only successful/unsuccessful tcp connections are
0 Q# ?: f& V' `9 j( {. d4 l# `8 Z significant. In layer7, which is only allowed for http proxies, responses2 ]+ D4 U9 i4 v# e9 a
received from server are verified, like valid/wrong http code, unparsable
) z1 b" G ?1 ?1 X8 u headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.: q; z2 ?3 J4 M' N! i: o
; `% L$ P( o9 U) A6 ]5 N Supported in default-server: No! ^8 X: W& A/ _- K. i" R: Z
" f- v& c3 E" g5 ~) D3 q
See also the "check", "on-error" and "error-limit".
Z: R2 k( B# D" T% b+ T# u5 P& R( M" W; f) b% O
on-error <mode>
- X- J3 O2 _1 u" P) S8 [$ L Select what should happen when enough consecutive errors are detected.
. v8 o' D! m9 @8 c" X: A Currently, four modes are available:$ b. @+ t6 J. ~/ F6 y/ J& a8 E
- fastinter: force fastinter
3 O h, W3 |* I: E( F - fail-check: simulate a failed check, also forces fastinter (default)
, F0 O! b, w8 I% F - sudden-death: simulate a pre-fatal failed health check, one more failed
; J3 `. ^- i/ y7 V check will mark a server down, forces fastinter
1 B( ]4 y4 V5 c$ D# m0 b: `' x - mark-down: mark the server immediately down and force fastinter# A; |! [2 U) W7 V
/ Q2 r/ S& A" d* s Supported in default-server: Yes
7 _+ v) p1 ?+ h: U1 I) R$ N8 s6 W1 \! n1 S) e
See also the "check", "observe" and "error-limit".; j6 O. n: u+ n$ _! X* k. j
+ I: b, a B/ j9 Q rport <port>7 \1 z& T( V7 L
Using the "port" parameter, it becomes possible to use a different port to9 Z9 R3 O1 B. Q9 F% t$ A7 r1 Q
send health-checks. On some servers, it may be desirable to dedicate a port7 p) ~; V/ q; M& H E8 h6 F
to a specific component able to perform complex tests which are more suitable
2 x X! H6 {$ q; V: m* C6 k" t to health-checks than the application. It is common to run a simple script in* t! k7 |9 V5 O q: @
inetd for instance. This parameter is ignored if the "check" parameter is not( w, ?, c" g( P; A2 y
set. See also the "addr" parameter.
4 q+ A9 B/ o1 w9 e5 @# k# m7 L8 ~- U/ S: ^; g# D2 z
Supported in default-server: Yes
! S" }* Y- @8 I( x; x( c
5 S- E, H0 z9 [* r) Predir <prefix>5 E, e5 e( s+ n) O& |% B! U2 c
The "redir" parameter enables the redirection mode for all GET and HEAD
, i# D& y$ E" P3 V; w* a requests addressing this server. This means that instead of having HAProxy
( w& K2 p( z* i7 F# b- ?" U- n! l' w$ Y forward the request to the server, it will send an "HTTP 302" response with4 G6 v! a$ l) s) X% f! t" H
the "Location" header composed of this prefix immediately followed by the/ w2 I1 r6 s0 G! Q. O9 r
requested URI beginning at the leading '/' of the path component. That means4 a" U& f3 |5 ^% N. Z* t& a2 A
that no trailing slash should be used after <prefix>. All invalid requests
$ U& M& |8 l' ]; I, M8 @ will be rejected, and all non-GET or HEAD requests will be normally served by
$ s- T% i1 W1 j2 ]; b" N the server. Note that since the response is completely forged, no header5 j, B7 Z: Q, x% y2 k; l
mangling nor cookie insertion is possible in the response. However, cookies in: g7 V& L4 f- u& G# @: U) B
requests are still analysed, making this solution completely usable to direct* ~+ V, U6 L; a4 C7 h0 C* V6 y3 T
users to a remote location in case of local disaster. Main use consists in
4 l; N: c" C, f) K/ S0 p increasing bandwidth for static servers by having the clients directly
, O) X' d; X. V( f) r% Y connect to them. Note: never use a relative location here, it would cause a
% y: ?* U P# u' I, E loop between the client and HAProxy!" u4 _5 y6 V0 {
1 `& M3 _3 ]% x4 B Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check" d& T) F& X I$ g0 l
9 d8 ?4 D5 ?) w: y' y' q Supported in default-server: No4 ~0 n" U/ D; O
, q' w; e0 {" `! A6 L, T2 irise <count># O) s/ V$ p( E" e
The "rise" parameter states that a server will be considered as operational
+ G' f# h& j5 U/ c( F after <count> consecutive successful health checks. This value defaults to 2* ^, H: U( q' m8 L9 N0 w
if unspecified. See also the "check", "inter" and "fall" parameters., h2 [" p6 u) J) @
+ }/ z, ]! k2 [) }- { u! @ Supported in default-server: Yes' y7 `$ e. W/ {6 A/ m/ c/ x L
6 ]0 L1 @' R: m+ U8 G
slowstart <start_time_in_ms>
$ @+ A, D1 j0 c, N; D The "slowstart" parameter for a server accepts a value in milliseconds which
9 l5 y0 S: A/ X) W3 r: d indicates after how long a server which has just come back up will run at
" @& e1 n- c- n$ C0 o# B full speed. Just as with every other time-based parameter, it can be entered
" I, M8 K5 d; Y; Y* q; s% [4 U6 g in any other explicit unit among { us, ms, s, m, h, d }. The speed grows
D' x. z( x/ s5 W F4 R4 x linearly from 0 to 100% during this time. The limitation applies to two
x( s5 K2 \" K+ l' C a+ V1 X parameters :- c% O" e: C8 q/ _7 D
# g7 `, Q5 F4 @1 b - maxconn: the number of connections accepted by the server will grow from 1& c8 J9 n% D& i
to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).
. H( h0 d5 `- f: O8 K$ F; p- g' b4 n2 L
- weight: when the backend uses a dynamic weighted algorithm, the weight
! N1 k) O2 e% Q* O/ G0 i grows linearly from 1 to 100%. In this case, the weight is updated at every: T2 D; P+ Q1 V# X6 r2 W- }
health-check. For this reason, it is important that the "inter" parameter
3 }+ R, |+ P W$ }" Y; j1 p is smaller than the "slowstart", in order to maximize the number of steps.5 j9 }) a+ M; Q1 ?4 K% s* R5 T7 I6 Z
2 I: ?" a% l1 s: {4 U0 Q The slowstart never applies when haproxy starts, otherwise it would cause- B; p# l. \ o* |
trouble to running servers. It only applies when a server has been previously1 F& H* G# J; @) K7 P+ I
seen as failed.6 a5 f. [$ d: M. k* s" r* @5 e
, I% g2 H0 R& I Supported in default-server: Yes( ]8 T/ v) q& o- W$ B; M
9 L( g+ p, J$ }7 Vsource <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
; r5 |" N6 W! X, \source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ] X& x F+ p* b$ T
source <addr>[:<pl>[-<ph>]] [interface <name>] ...
1 s& [/ r9 c' l2 l3 z The "source" parameter sets the source address which will be used when' Y& K, d6 ]' ?; i3 W
connecting to the server. It follows the exact same parameters and principle% |+ u; h2 i) t0 p
as the backend "source" keyword, except that it only applies to the server
( p0 I/ E. s$ j% R referencing it. Please consult the "source" keyword for details.
6 ^0 p' K; K/ `" Z7 f5 E/ M5 ?% p; R% r3 w" {
Additionally, the "source" statement on a server line allows one to specify a
; J6 j4 Y* G5 l1 V source port range by indicating the lower and higher bounds delimited by a+ e {3 y. D0 d2 r
dash ('-'). Some operating systems might require a valid IP address when a
! y7 Y! a/ r# D+ y, t source port range is specified. It is permitted to have the same IP/range for
) O. c% m6 _& b1 s+ K* z several servers. Doing so makes it possible to bypass the maximum of 64k
& G. d% z' J) q0 F @ total concurrent connections. The limit will then reach 64k connections per1 h4 o* w1 ^% t: X
server.
9 G/ y! x& h, W& ?( A& h4 b
8 w3 k: @4 u7 Y Supported in default-server: No- |: U9 U' f* a- X
/ u/ ^" K8 O- \8 G: q6 [) J) `
track [<proxy>/]<server>5 I( j( }! Z9 Z& L; y# _
This option enables ability to set the current state of the server by9 g, Q w% K2 K+ W+ F
tracking another one. Only a server with checks enabled can be tracked" S# S6 {+ J* _* x% y
so it is not possible for example to track a server that tracks another$ R0 E# G _' r, _% Q- d1 D
one. If <proxy> is omitted the current one is used. If disable-on-404 is
, T4 c( C, k* a8 L c+ a2 S used, it has to be enabled on both proxies.
7 C6 O- [4 F! ^5 H
7 Z7 y8 _& E$ w) h7 o Supported in default-server: No
6 ?, ^8 J1 v' S2 F+ \1 a( S5 V+ c) ?
weight <weight>( p7 f" @2 _$ f; I3 g
The "weight" parameter is used to adjust the server's weight relative to x! i8 s/ q) `! Y
other servers. All servers will receive a load proportional to their weight4 S- L( Y. \/ I F- g
relative to the sum of all weights, so the higher the weight, the higher the2 X5 ~7 G9 C+ c5 t5 p, H* M
load. The default weight is 1, and the maximal value is 256. A value of 01 |! \5 G0 d+ ~& L( R- q: k. e
means the server will not participate in load-balancing but will still accept
, h, _4 w( b) @! d persistent connections. If this parameter is used to distribute the load
( K" {& D" n3 _: @ according to server's capacity, it is recommended to start with values which
: e" }2 y2 H* b& `9 }' W( m1 T% F can both grow and shrink, for instance between 10 and 100 to leave enough0 e" ~. X8 E: d5 S J( b5 j
room above and below for later adjustments.
- L# A1 ?/ E7 D* m* G- c1 ?! W \9 c: _+ F% f
Supported in default-server: Yes
4 A5 S* I V1 P2 y l) j4 k0 c1 {+ |
9 K7 R& Q$ J$ S# H1 w6. HTTP header manipulation
" h# G5 g6 o5 @; ~---------------------------9 M! o# p( i# i2 W: v
! Q6 z0 R% `) U+ U' y" J" w7 e
In HTTP mode, it is possible to rewrite, add or delete some of the request and/ s( @- I3 z. L5 I* z
response headers based on regular expressions. It is also possible to block a
5 ?* G0 N0 V) d5 a% m% Nrequest or a response if a particular header matches a regular expression,$ w2 L, w" i* o. u9 l
which is enough to stop most elementary protocol attacks, and to protect
4 k' ]$ Q, X% Y4 c3 [" }( P) N! Hagainst information leak from the internal network. But there is a limitation
' P1 @. Q' U' L* Yto this : since HAProxy's HTTP engine does not support keep-alive, only headers
+ J8 d' t& @% ^passed during the first request of a TCP session will be seen. All subsequent t! O7 m' X& v" g
headers will be considered data only and not analyzed. Furthermore, HAProxy
, ?1 l# n( y" n% Unever touches data contents, it stops analysis at the end of headers.
( a) s" Z: x, c- M. n
, ?; a1 I3 }/ g9 ~# qThere is an exception though. If HAProxy encounters an "Informational Response"
6 b# [ d5 s' t7 R5 F# A" Q2 o(status code 1xx), it is able to process all rsp* rules which can allow, deny,* ]4 j7 {0 g9 i* ]5 D9 m
rewrite or delete a header, but it will refuse to add a header to any such
6 v3 E% }; t, o3 }, y3 y }. Gmessages as this is not HTTP-compliant. The reason for still processing headers5 `4 I y% N# Q- c+ v) n
in such responses is to stop and/or fix any possible information leak which may# c* Q, G5 x ~& \7 G1 m
happen, for instance because another downstream equipment would unconditionally$ n+ _4 ^% K8 l9 S3 O) ~
add a header, or if a server name appears there. When such messages are seen,1 O. S/ w1 d4 Q% e5 _! F$ M8 P0 [- G
normal processing still occurs on the next non-informational messages.( c" {) @& @4 \/ @8 D
1 J+ j Z) _. o# v# |0 tThis section covers common usage of the following keywords, described in detail4 l% `- ]7 ]2 K' T7 {' S# ~$ x
in section 4.2 :" g, t+ H( g* I( N
. @1 C4 c7 ^6 h' n' A$ | - reqadd <string>2 t& B" W5 {' C
- reqallow <search> ]4 L9 i) a; Q; D
- reqiallow <search>
5 x6 {( Q3 R: e- z - reqdel <search>
1 `5 H! s9 ?, O; z9 a. F! s# k - reqidel <search>
* G5 ?, ^( L" T& t$ c, c# l- F4 \- F - reqdeny <search>
, w2 d# V# @/ F( ]! a7 I$ l - reqideny <search>3 j1 O: L. G# n5 I; u C
- reqpass <search>& S( Y, W, C- f" Q7 h; e- i$ u+ R
- reqipass <search>' q) T* s. X. `# X
- reqrep <search> <replace>
4 {( k, B6 B! U7 Q) h - reqirep <search> <replace>
* E# i5 N: i j4 a* J - reqtarpit <search> h+ j8 e% b O) f. m5 h# j
- reqitarpit <search>
3 l9 [; g0 i& Z/ p' _ - rspadd <string>! \$ x- R9 r& A* q* u& v
- rspdel <search>+ {" |! X: {. S# A
- rspidel <search>. S7 k) z& o" Q4 p! j: x6 S
- rspdeny <search>& q% t! Z4 b; D7 j E. S
- rspideny <search>
9 @' N0 c7 @+ _- t. c; I4 I K" p; Q - rsprep <search> <replace>% ?7 X* v! L7 a" n
- rspirep <search> <replace>1 E, t) Z$ Y, e- m2 r: x _
}: G% p6 W8 n$ O
With all these keywords, the same conventions are used. The <search> parameter
# L+ {8 A' N9 Q) ~* U% dis a POSIX extended regular expression (regex) which supports grouping through
8 t* z. {& a2 n* T) g. Uparenthesis (without the backslash). Spaces and other delimiters must be
1 s0 t d3 H6 P' e v" iprefixed with a backslash ('\') to avoid confusion with a field delimiter. p6 V. b/ P, h" e$ H. [
Other characters may be prefixed with a backslash to change their meaning :' m" _" A5 _( r
* q. o1 t4 @ ?; I6 } \t for a tab
% W0 S: f/ E6 j/ A; V \r for a carriage return (CR) j# ?: E" T6 W3 I% ^* a
\n for a new line (LF)
; U# C8 ?8 z ^$ p% {1 h \ to mark a space and differentiate it from a delimiter
8 n% S9 n$ `/ \2 m7 S9 _ \# to mark a sharp and differentiate it from a comment/ i* S5 w K! U
\\ to use a backslash in a regex4 `! t" h/ }: [4 G) O$ B8 C. w, u6 F
\\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)
: _, t8 e I" d& T7 k \xXX to write the ASCII hex code XX as in the C language
8 I$ t5 N& K2 M$ Y* R: d0 w$ s+ C$ `
The <replace> parameter contains the string to be used to replace the largest& h& |% A6 x( [6 b( F
portion of text matching the regex. It can make use of the special characters
. L1 _# v5 N% {- s; y4 R/ xabove, and can reference a substring which is delimited by parenthesis in the
# I* m; Y0 ]; @4 @% S0 x: b# \) T0 @regex, by writing a backslash ('\') immediately followed by one digit from 0 to0 [! U' H1 ]# \3 p
9 indicating the group position (0 designating the entire line). This practice/ `( A* w& U: `" N+ w5 d
is very common to users of the "sed" program.: u* E' }0 Y v
1 y _$ s% U' IThe <string> parameter represents the string which will systematically be added
. o9 u& z* Z& L: v6 Zafter the last header line. It can also use special character sequences above.+ D9 i4 p* O8 z$ n, n6 U
8 p, K7 R9 [- ^Notes related to these keywords :! J, F4 y9 N* m$ s' l- F; h- ^
---------------------------------
& Y/ D3 U* Y8 J, ]/ E* j - these keywords are not always convenient to allow/deny based on header9 Q! j9 @% o7 _
contents. It is strongly recommended to use ACLs with the "block" keyword$ B. K& b- ?+ @2 |
instead, resulting in far more flexible and manageable rules.: g H/ @4 f* [+ G d/ u
" X7 i; L- \: b
- lines are always considered as a whole. It is not possible to reference' c: f, T9 m6 U9 V1 v- u
a header name only or a value only. This is important because of the way1 t: q9 e% f4 s: }& {& V+ a
headers are written (notably the number of spaces after the colon).
3 d5 R6 y. m* O y0 d
( _1 q3 h+ Y! z' i7 b5 ?5 C - the first line is always considered as a header, which makes it possible to
/ [1 C+ t( }+ I0 G5 S) ^! j rewrite or filter HTTP requests URIs or response codes, but in turn makes; [& p# R% D# M
it harder to distinguish between headers and request line. The regex prefix
2 O" U4 z/ h0 T6 l$ v ^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix9 v0 L( {. o* q0 H2 e- w
^[^ \t:]*: matches any header name followed by a colon.$ J6 |$ U, O0 ]; C# m( M8 {% k
6 V" G) { H9 s2 W2 z
- for performances reasons, the number of characters added to a request or to
& V K) Y1 Y u3 }# } a response is limited at build time to values between 1 and 4 kB. This; Z. E2 i5 W( u8 M+ o* S
should normally be far more than enough for most usages. If it is too short
2 o) `& \0 ^ T5 F4 p R) y" y1 A# u on occasional usages, it is possible to gain some space by removing some* t' ^0 y3 j6 c0 p
useless headers before adding new ones.
( u+ k4 H5 v. W$ Z4 S0 A8 N; T
, Y- s9 j& U- }5 ?7 c - keywords beginning with "reqi" and "rspi" are the same as their counterpart
8 \- {* k1 a, T; S/ u without the 'i' letter except that they ignore case when matching patterns.
$ q* d: v: u: Z+ R3 v% O g" g" ~5 y& ~% D
- when a request passes through a frontend then a backend, all req* rules
! p& D- U7 A$ v4 l. T from the frontend will be evaluated, then all req* rules from the backend
7 e' T6 n D- q will be evaluated. The reverse path is applied to responses.
9 K# F" R0 |- k8 Q0 q
% Y' k% E0 e* ?5 [( Q - req* statements are applied after "block" statements, so that "block" is
+ y p/ |/ o8 y1 W- C always the first one, but before "use_backend" in order to permit rewriting% w, d6 e% K' v5 b9 v
before switching.3 J9 ]* _ _' F! [2 G' B& Y
8 |9 t+ l0 }6 p3 @8 `5 `
; A" k# C0 W) s9 A9 ^) F/ n) J7. Using ACLs and pattern extraction5 S; n" z$ n3 ?. z; y, d
------------------------------------. J' P9 `3 U7 Y _2 q' a: ?9 z( D; n
" n C( S" Y! p% _, ~The use of Access Control Lists (ACL) provides a flexible solution to perform
3 g! p# {' H: Z( {content switching and generally to take decisions based on content extracted
" X" T5 a4 I* c1 @/ Z; g0 Nfrom the request, the response or any environmental status. The principle is( q3 o5 q, F5 v8 I
simple :
) a2 ^# j: V* Y2 H8 t' b% ^9 \" S( ]
- define test criteria with sets of values
8 L6 R7 {7 T- w1 n; B: L: ? - perform actions only if a set of tests is valid' ?, z" ]6 X* I0 D
* q7 ]3 e, m) ?4 {6 ?. ]7 N6 V' T$ K
The actions generally consist in blocking the request, or selecting a backend.
* ?6 l; i" D \0 q
* Y X' p4 f4 OIn order to define a test, the "acl" keyword is used. The syntax is :
. l! g, n* \. [/ r$ b
2 s0 Q. P5 U: u acl <aclname> <criterion> [flags] [operator] <value> ...( Z7 @" Q8 _# R, |" ?1 r
, V& g! ^* c- s2 ?+ mThis creates a new ACL <aclname> or completes an existing one with new tests.
. u( j$ U' E, b0 u( Q; E% ?Those tests apply to the portion of request/response specified in <criterion>
. i) D5 }' N7 w" zand may be adjusted with optional flags [flags]. Some criteria also support
, L/ J( h* \8 t j1 aan operator which may be specified before the set of values. The values are
# L y% w5 y8 e4 O, \3 Iof the type supported by the criterion, and are separated by spaces.
# `6 Y9 [$ o* K+ O' Z& V0 a/ m" j" I: Y7 \$ Y- |5 c
ACL names must be formed from upper and lower case letters, digits, '-' (dash),
* h, m, G7 @2 `" ?1 _'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
" f1 v3 W' H: A7 f7 |& q( N& {8 Swhich means that "my_acl" and "My_Acl" are two different ACLs.
% O& z0 h! R$ d7 x) z3 P5 ?
0 P5 g R! X3 Z5 D/ NThere is no enforced limit to the number of ACLs. The unused ones do not affect
7 F' P* j3 W. w. rperformance, they just consume a small amount of memory.' [9 I1 Z# L! b" |5 j$ y1 v3 K
; U+ A. `" Q$ P& u% H2 jThe following ACL flags are currently supported :
& ?' r" P z6 m5 K; E/ J4 K" F8 `, [# k* t% o9 Q) t! D
-i : ignore case during matching of all subsequent patterns.4 U7 g" z- F& i) `# _9 s
-f : load patterns from a file.
4 [0 h% I& l. k6 m' f5 _1 r -- : force end of flags. Useful when a string looks like one of the flags.
7 _$ p" H# h" Q5 u' v3 v( c3 i! a
1 |* o$ |5 X1 G4 C; p0 dThe "-f" flag is special as it loads all of the lines it finds in the file
) |, f: g, @4 j6 b9 Qspecified in argument and loads all of them before continuing. It is even
( K: V1 W4 u' `/ l2 i( o7 Tpossible to pass multiple "-f" arguments if the patterns are to be loaded from
+ X2 X4 L! m8 t' wmultiple files. Empty lines as well as lines beginning with a sharp ('#') will3 T) S' X3 M8 o$ p R; k
be ignored. All leading spaces and tabs will be stripped. If it is absolutely
: Y) @* F! E+ q& Z) f G0 lneeded to insert a valid pattern beginning with a sharp, just prefix it with a | N& u( w( C, o9 Y4 b
space so that it is not taken for a comment. Depending on the data type and! u: R" |3 e$ d/ b
match method, haproxy may load the lines into a binary tree, allowing very fast
3 ~, ^& ]) r) O; I& z* ulookups. This is true for IPv4 and exact string matching. In this case,
" g7 B' D1 W+ m0 U5 ?: wduplicates will automatically be removed. Also, note that the "-i" flag applies
% w0 B4 D$ B" T8 H- a/ gto subsequent entries and not to entries loaded from files preceeding it. For- x9 T8 G5 R. a8 e" M/ t
instance :
7 p% a- G$ i `+ i8 W0 t
' X u; d5 \( G3 @: K0 k7 ~ acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test; O7 i# d+ N' G# L% J
+ |/ c) x' E/ L" k% V9 R5 x9 AIn this example, each line of "exact-ua.lst" will be exactly matched against
: M) G7 p5 U, s4 Kthe "user-agent" header of the request. Then each line of "generic-ua" will be& H1 g. @) {# \, L2 X
case-insensitively matched. Then the word "test" will be insensitively matched/ h" q( b- l' q$ s( ]. v
too.
% J; l U, B( V1 J4 L
c ~" o- `; {" s. g5 w7 yNote that right now it is difficult for the ACL parsers to report errors, so if
v7 X" y7 {; n) ~2 va file is unreadable or unparsable, the most you'll get is a parse error in the9 I. L; C: ~2 v" \8 f& Q& D; W/ h
ACL. Thus, file-based ACLs should only be produced by reliable processes." K1 h, Y& o9 M! V E
, x# L8 v) m! g7 Q# Y% D& e4 c- w
Supported types of values are :
/ q4 M" ^! D$ V) X' {# v7 h$ g$ ~) z4 u7 K- c
- integers or integer ranges9 e& M" Q2 }" i8 _& W
- strings5 t9 T+ |9 A. ^5 H$ X( n% n3 s
- regular expressions
. V7 p1 l* [8 g+ h, k, [ - IP addresses and networks% @# [0 m. \4 }) h4 Y: W; @
2 t6 j( t0 F X: |& W" l/ j
* j* ~# R2 ]4 @9 b7.1. Matching integers- c- \4 V6 Z f# i
----------------------
, [! w# v! ?3 a9 e# O0 x& v
/ k# V; S0 t0 p0 z3 I4 ?Matching integers is special in that ranges and operators are permitted. Note o5 t: _2 x: E" `! i
that integer matching only applies to positive values. A range is a value0 |% ]0 W* b( w, b
expressed with a lower and an upper bound separated with a colon, both of which" C: H4 ]$ t. n1 f" X8 a0 b: v9 j5 @
may be omitted.9 Z+ l) q8 F) M' o$ _6 S. T
; S3 X8 h$ ~# X* g4 H0 w5 o
For instance, "1024:65535" is a valid range to represent a range of% z* m F7 m+ u ^
unprivileged ports, and "1024:" would also work. "0:1023" is a valid- T6 Z2 N. r0 q
representation of privileged ports, and ":1023" would also work.) g' E2 ?/ ]6 X8 ^) }: N! p2 X# r9 R
h2 W4 `4 f6 a- o1 O
As a special case, some ACL functions support decimal numbers which are in fact
$ F1 `; b0 {7 m* J" d$ atwo integers separated by a dot. This is used with some version checks for% A( r B% G; E9 ?# X
instance. All integer properties apply to those decimal numbers, including
/ U% Z3 W; p5 a- a/ Zranges and operators.) o4 ?& M# Q: |' z! p. l9 f
6 P! @9 }6 ~2 v ]: gFor an easier usage, comparison operators are also supported. Note that using
- u V; D& V8 ?% d2 a2 W4 O: roperators with ranges does not make much sense and is strongly discouraged." T# ?) n3 e: q
Similarly, it does not make much sense to perform order comparisons with a set
- c/ z, q+ T, v- _of values.
E: C8 H0 `! k: R) r) w. |2 O
: R: @$ p0 n3 \5 W& V" LAvailable operators for integer matching are :+ d) L( E4 S1 r7 j# F
' f9 x8 ?4 p7 w6 x/ y! q, ~+ F3 J7 O
eq : true if the tested value equals at least one value4 M" e9 |4 X: b# _( { x; U) C
ge : true if the tested value is greater than or equal to at least one value
0 @* B! |8 K& y1 o% \, ? gt : true if the tested value is greater than at least one value, `3 @" z2 h2 {# x7 l
le : true if the tested value is less than or equal to at least one value5 A9 @# o5 d' R7 i. r7 S2 o
lt : true if the tested value is less than at least one value
0 p6 E- @' D7 m3 j# V
5 q p9 f7 ^( |" ]3 V4 vFor instance, the following ACL matches any negative Content-Length header :
) O' j# l1 f, |; W2 X s, K8 r2 |, k$ g r
acl negative-length hdr_val(content-length) lt 0
1 p, ]6 z3 l: `! [4 I* ~1 j* I4 c
This one matches SSL versions between 3.0 and 3.1 (inclusive) :
. t4 L1 Q5 X; \+ u: q9 g
0 s4 [2 M* s/ j) O) b: E- U acl sslv3 req_ssl_ver 3:3.1( Z% K& ^2 J. }9 ^) d. M4 `. h J: @
1 G7 {' }& h! \4 U- v) |* d5 Z8 E9 ]0 e
7.2. Matching strings
" L y% N" Y$ t! s9 N/ c; f9 h1 _2 ?---------------------
; j$ X9 _& F/ n$ T( u! ~
5 k1 _' k3 x$ nString matching applies to verbatim strings as they are passed, with the6 U* Y1 A3 s1 N
exception of the backslash ("\") which makes it possible to escape some1 }6 u+ m, n! G' m5 U2 l; b6 ]
characters such as the space. If the "-i" flag is passed before the first
" u8 i) n- }3 {6 Mstring, then the matching will be performed ignoring the case. In order: y$ x9 q+ q1 ^; T/ |) T" v8 `
to match the string "-i", either set it second, or pass the "--" flag6 e" l) ^# J: V g0 F
before the first string. Same applies of course to match the string "--".
+ U0 y9 N6 Y9 j/ U" A" t; O/ q" Q# R9 n* L4 G- E* y
# l: H; g2 p. Q6 N/ F, ?
7.3. Matching regular expressions (regexes)
, }' }6 F1 P5 R: f# s/ j-------------------------------------------& @& H) h; w5 {, {; H! D
9 m# Y* N) I2 t, L/ qJust like with string matching, regex matching applies to verbatim strings as
7 g% D) G6 Z o3 z, R$ c5 [they are passed, with the exception of the backslash ("\") which makes it
* V$ Q9 F4 l8 ^/ K' \5 Y1 Opossible to escape some characters such as the space. If the "-i" flag is0 g# D1 o( e: N1 U4 n# `
passed before the first regex, then the matching will be performed ignoring
0 v' `9 ?: r- a: {# Uthe case. In order to match the string "-i", either set it second, or pass o4 W6 B. z$ ~' T* b; O
the "--" flag before the first string. Same principle applies of course to
' _! j" U# o- w! S. d( `1 \match the string "--".4 {$ M) m/ }- Q" W3 G% I+ p
5 ~! v) V5 ^" r) v, B& ^
# K5 ?& A4 a& F7.4. Matching IPv4 addresses
, f" g1 D) z7 L4 J----------------------------
9 w) I) F2 u: I, Y
, W: W% ~" W' @' c( S- kIPv4 addresses values can be specified either as plain addresses or with a8 W+ u5 O S, O: U% o
netmask appended, in which case the IPv4 address matches whenever it is
7 E, F. y. \' m" Ewithin the network. Plain addresses may also be replaced with a resolvable
$ t, v9 o+ h+ Z# h4 J. i* S( [. Thost name, but this practice is generally discouraged as it makes it more
r& ?8 x2 M* d: u3 h# `* ndifficult to read and debug configurations. If hostnames are used, you should; p( n" F. H3 s. W4 {. g; X
at least ensure that they are present in /etc/hosts so that the configuration5 M& `2 O" _) G" X Y0 ]5 q0 Y
does not depend on any random DNS match at the moment the configuration is. T6 h. Y* A1 _* R
parsed.
) w8 P( H( T* J2 |* m$ C! e4 K
' L( I! n1 a# y' x+ E* L4 I/ L8 @% [8 D7 J; ^, @! i( Q; H' {
7.5. Available matching criteria
+ z0 s- F$ P& P--------------------------------
D( p) h4 Z8 S0 s# ^$ T$ L4 |
7 i( B7 C8 Y- E( E& y2 K7.5.1. Matching at Layer 4 and below3 y" |$ c* q1 X5 s1 d
------------------------------------
- f8 a+ S d7 d3 T$ Q3 z
3 U4 V# R4 l1 ~- Q& ~2 t8 TA first set of criteria applies to information which does not require any
0 B8 k' }$ {) H+ K* }6 {analysis of the request or response contents. Those generally include TCP/IP: J. e# Q) @! M. ?- B! ?: x
addresses and ports, as well as internal values independant on the stream.
- {2 ?' c7 g/ D: s6 p4 ?6 P
! N! c! w! i5 Falways_false
0 ?$ M6 q% z* O# I6 D This one never matches. All values and flags are ignored. It may be used as
7 ^+ f# H1 V- P1 I* ?! F6 n+ w2 Y a temporary replacement for another one when adjusting configurations.& k" t @4 R) Z9 y3 v) q
6 l, x! e2 h& h; V1 `; lalways_true
& t$ b8 g" Y1 G5 C- Z This one always matches. All values and flags are ignored. It may be used as) D9 X1 \ e4 c# o4 \
a temporary replacement for another one when adjusting configurations.
6 A% L; _5 J! ?0 ~4 H" T
& f# m- f8 S) T! `9 d9 C9 Mavg_queue <integer>
1 A0 r0 ]+ t8 Y( g# C2 [avg_queue(backend) <integer>+ f7 c( Y2 A+ ^: l4 I9 A. X$ q3 u
Returns the total number of queued connections of the designated backend
( l; w0 ?5 x9 | divided by the number of active servers. This is very similar to "queue"
& ]' x: t; G2 k: c# p* P& A' U except that the size of the farm is considered, in order to give a more# r, w5 F$ s( }* J
accurate measurement of the time it may take for a new connection to be6 ?6 f) m3 C. |. w
processed. The main usage is to return a sorry page to new users when it
6 ?- }* Q+ O) }! ~8 O becomes certain they will get a degraded service. Note that in the event
; A: k3 L% |" W+ b there would not be any active server anymore, we would consider twice the
7 ?' h6 a9 |0 v4 D. x+ _3 B! ` number of queued connections as the measured value. This is a fair estimate,( _2 K3 ?, i- [0 d: k0 T- v5 q& A6 |$ |
as we expect one server to get back soon anyway, but we still prefer to send
- f+ x. g- A( V0 P9 N* Z! }8 D1 _ new traffic to another backend if in better shape. See also the "queue",4 h6 |5 N) }7 f/ {8 h% n- r* w( H
"be_conn", and "be_sess_rate" criteria.7 U2 p; P0 ~5 K. G7 s
* w" r, M- O' H* Ybe_conn <integer>8 U j# ?# a% L) w! U
be_conn(backend) <integer>
7 h/ N3 `7 _/ n- ]2 z' t0 Q4 t Applies to the number of currently established connections on the backend,
2 q3 s9 h* q0 z/ y9 z6 N0 e) B possibly including the connection being evaluated. If no backend name is8 P; I6 h* G9 C. {8 t3 p ?; G
specified, the current one is used. But it is also possible to check another ~- X: G, b4 J- K! k6 N8 c
backend. It can be used to use a specific farm when the nominal one is full.8 L9 ]4 {" P, |3 _3 K8 \0 U0 a
See also the "fe_conn", "queue" and "be_sess_rate" criteria.6 m i9 ]9 j: |3 l& u1 |
$ e- H7 Y: ^' H" u+ W c6 _be_id <integer>
; {. ~; Z( U- k$ G1 j Applies to the backend's id. Can be used in frontends to check from which% @, u" Y0 E6 v1 w& |& A% a2 a
backend it was called.
' |$ G' e. U) H- ^6 N, L7 U
& A6 M6 G/ M }) ?3 w1 Vbe_sess_rate <integer>, h6 Q( j* A2 O) C
be_sess_rate(backend) <integer>4 u% W! y* ~9 Q& T8 U
Returns true when the sessions creation rate on the backend matches the; Q8 u" N6 A( }# @' ?
specified values or ranges, in number of new sessions per second. This is' b, Y' K! d# ?
used to switch to an alternate backend when an expensive or fragile one
* H; O0 Z7 s. q reaches too high a session rate, or to limit abuse of service (eg. prevent
2 g3 B4 u" j# \* L7 t- j9 O9 a sucking of an online dictionary).9 K9 `' W, V9 k/ t4 ^! f
' F" i6 Y9 C n# w7 P, _) i Example :
l* P2 c5 |$ Z6 [, |/ S2 G1 Z q8 e # Redirect to an error page if the dictionary is requested too often
5 v! X9 M d5 {, W9 N. X7 p backend dynamic3 Q4 W: e# p. t! h% W
mode http
8 w; N# A) P$ z$ }1 |0 k6 X acl being_scanned be_sess_rate gt 1007 O! v1 z0 S( ^3 L8 n6 o
redirect location /denied.html if being_scanned
) \! P" Z( N1 |7 n- O" p! O- b" g
connslots <integer>0 _# D9 Q' B* J( z
connslots(backend) <integer>
) Y- ^. t1 i: F. b5 V- O The basic idea here is to be able to measure the number of connection "slots"
2 l: F5 a' H/ Z4 |1 e6 G/ q still available (connection + queue), so that anything beyond that (intended
2 v1 S" p- p- g% t! I usage; see "use_backend" keyword) can be redirected to a different backend.2 n$ Q7 ?8 {* D
% y; k! o- |, M% h6 { 'connslots' = number of available server connection slots, + number of; ?6 ~6 K% T( S F: e
available server queue slots.
8 i; n: K$ i' r. i7 P" B
, J$ l8 a1 D( I, \2 t4 z Note that while "fe_conn" may be used, "connslots" comes in especially8 @% s1 I/ j! ~5 J
useful when you have a case of traffic going to one single ip, splitting into
6 Y! E& r0 F5 ]0 @' L6 M5 H multiple backends (perhaps using acls to do name-based load balancing) and
; o5 Z. j- p. g. z. i# N you want to be able to differentiate between different backends, and their( E8 w4 a9 j8 A, k
available "connslots". Also, whereas "nbsrv" only measures servers that are
5 M$ e3 Y) r2 Y' H/ b) L! ? actually *down*, this acl is more fine-grained and looks into the number of
5 V2 `3 u3 r9 R3 l* R available connection slots as well. See also "queue" and "avg_queue".
; W0 R! Y2 ^! \" W# }# t3 A/ r
" e* p0 g1 H* \7 n OTHER CAVEATS AND NOTES: at this point in time, the code does not take care
# K6 K( O" t; U of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,- X Y( q6 r. ?( p" C9 y% Q$ H
then this acl clearly does not make sense, in which case the value returned% ~/ F6 c2 B9 I( u' Y
will be -1./ }5 F5 _, N6 {. Z6 c1 x
3 l* F- F3 ^0 t" m! d
dst <ip_address>
! u4 Y7 `+ h2 q$ G0 C% q4 A+ |" m3 n% E Applies to the local IPv4 address the client connected to. It can be used to& Z0 Z7 M3 |2 w6 @3 i
switch to a different backend for some alternative addresses.! I2 Y" U8 D; c _& D/ ]
- p, r+ E( r! p8 Jdst_conn <integer> w7 Y4 q: F5 M1 E5 o% c
Applies to the number of currently established connections on the same socket; g4 a& `+ L ]! w9 M1 \% @: ?7 r
including the one being evaluated. It can be used to either return a sorry4 ?5 j; ?% b3 S5 |
page before hard-blocking, or to use a specific backend to drain new requests
& [+ B7 \, u8 L$ E3 ` when the socket is considered saturated. This offers the ability to assign
/ D8 n. H8 g \, X- v# s different limits to different listening ports or addresses. See also the! ?' F$ E7 B% J7 f
"fe_conn" and "be_conn" criteria.
% a9 h+ B [0 l3 L1 O/ m9 K; ?- C2 n1 Z- Y8 T, m; ]
dst_port <integer> `7 o. ^% f( _- d' a# ?" ~- w% B
Applies to the local port the client connected to. It can be used to switch6 L9 s& M) d7 u
to a different backend for some alternative ports.4 b! r9 r; S6 i+ K( g4 g' L% `/ k6 G
7 [& K5 p& s6 Q/ ~# X) Wfe_conn <integer>4 |2 i. b( M4 f: o; D
fe_conn(frontend) <integer>
5 D& [5 l2 z. J& I" t3 D; ` Applies to the number of currently established connections on the frontend,
# H! N$ m. ?9 U6 ~. |# P possibly including the connection being evaluated. If no frontend name is" `7 P% }5 }$ ]; q
specified, the current one is used. But it is also possible to check another
+ K7 i% V3 o5 Y5 X& o1 { frontend. It can be used to either return a sorry page before hard-blocking,
5 `/ h& Y+ @5 ~' p+ W2 Y or to use a specific backend to drain new requests when the farm is1 v; c% d4 c4 l* B) a1 F( H3 n. w
considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"5 _1 }$ E2 ]5 m& x' m" o* l+ f) r
criteria.
! O/ m4 ^/ H+ ~0 I7 ?8 Z( N+ S1 h0 p; u& H: d- t q
fe_id <integer>
8 u3 J) {, E2 g! b Applies to the frontend's id. Can be used in backends to check from which2 G, V( m- [1 A& B4 ]3 Q
frontend it was called.
5 n1 k& v; p3 S$ p; M: W4 W: t$ d8 F3 N
fe_sess_rate <integer>& k5 A4 J" n" q7 h0 u, @9 T X
fe_sess_rate(frontend) <integer>
' p* {8 s% X7 J" ?' M/ Y Returns true when the session creation rate on the current or the named) q, y; a, T8 D B/ B1 g2 Z! |
frontend matches the specified values or ranges, expressed in new sessions
* ~* d( B2 y9 r) r% z- y per second. This is used to limit the connection rate to acceptable ranges in6 u. D! G+ \) \' }
order to prevent abuse of service at the earliest moment. This can be
0 u4 ^# S9 g# j% |- E combined with layer 4 ACLs in order to force the clients to wait a bit for
Q9 A. c) o$ w- a. n the rate to go down below the limit.
7 y0 p/ |" V/ ^- l' N7 B4 Q1 b7 K1 l8 \) ]$ K& L( N2 ]2 [
Example :! a5 }: b& s, b! n: q" V
# This frontend limits incoming mails to 10/s with a max of 1008 j$ W! j, _0 j+ ^5 `
# concurrent connections. We accept any connection below 10/s, and
+ H9 j- y" }, T6 Y4 }% R # force excess clients to wait for 100 ms. Since clients are limited to
: \% P8 q( v8 E/ ] # 100 max, there cannot be more than 10 incoming mails per second.
6 e# V. }5 F! h3 D7 z) K: c+ S frontend mail
! w5 O) }& ^9 }/ E: F7 @. s bind :25- T# |+ w' _+ x. w* _* A
mode tcp
T+ U% s3 i- @! E x- I! E maxconn 100' {% v O2 S0 M" W: L. ]
acl too_fast fe_sess_rate ge 10
" R6 {. J( D5 i# d/ L2 w5 C9 ~ tcp-request inspect-delay 100ms
7 M7 o9 |2 c; a1 \' i6 Z" q) X tcp-request content accept if ! too_fast
1 v2 n1 s) Y7 s% z x, c tcp-request content accept if WAIT_END
" B/ g+ X2 ]" |" X) s& u1 I- f. Y4 E# |. @
nbsrv <integer>% u) K6 a8 s. n
nbsrv(backend) <integer>; i' T5 P. _) x8 x$ C$ T
Returns true when the number of usable servers of either the current backend
% y" e' h4 d) u' q or the named backend matches the values or ranges specified. This is used to, S! H5 \; W( d: A" B. v5 j2 a
switch to an alternate backend when the number of servers is too low to
, h* W7 J' }6 h7 m to handle some load. It is useful to report a failure when combined with; G5 \6 E' V# R" t* _# ~2 C5 H
"monitor fail".9 w% f) U, p. U- T" m. z( H
, x/ M8 K f5 x% ?7 ~% [, B" {; tqueue <integer>
1 G! }# z' U. [) L0 q: equeue(backend) <integer>
1 X& s- f4 G! k: F( d. @ Returns the total number of queued connections of the designated backend,
# i/ f/ ~3 B2 {9 g3 L& B8 L$ l including all the connections in server queues. If no backend name is% }" l& W; D4 M: [
specified, the current one is used, but it is also possible to check another. X, k8 W) A* L; p9 Y6 @0 }
one. This can be used to take actions when queuing goes above a known level,
* a+ k8 E1 h1 L8 P( c+ I; H/ a# Z9 p generally indicating a surge of traffic or a massive slowdown on the servers., P2 _- l. l( y& z0 |
One possible action could be to reject new users but still accept old ones.
0 `" W- G! V. N" r See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.
6 _3 m' f" D% U6 l1 n4 b- E
, Z) T% k7 F$ u# e" Kso_id <integer>
6 n1 J3 k/ K. T, H0 V. ^ Applies to the socket's id. Useful in frontends with many bind keywords.
! b+ L/ M5 t, T- b; ~
6 Z5 h: K9 @0 y! [0 v) A# j% Vsrc <ip_address>
p4 X! h) J8 w. U7 P) f Applies to the client's IPv4 address. It is usually used to limit access to: d8 K. H1 b0 J4 A" H
certain resources such as statistics. Note that it is the TCP-level source- Z0 V1 {/ w1 ~, o$ Y
address which is used, and not the address of a client behind a proxy.
+ F& n7 {6 y- g; q4 y+ X6 t
% a* b, J5 a( r- e' v# Q: @8 @# }src_port <integer>
9 T$ _% w' q7 U* B n! W Applies to the client's TCP source port. This has a very limited usage.9 Z6 ^- z- _7 i/ q$ l$ p" ^
8 A, F4 o2 V( E: |" l: Y6 y
srv_id <integer>
4 f( z+ k. P' F, Z5 O Applies to the server's id. Can be used in frontends or backends.
: n0 {0 z; h0 u/ A9 t9 [
2 k& i" [+ L) s, V! ^) K2 |srv_is_up(<server>). J: Y. \/ l# o) {1 P& m
srv_is_up(<backend>/<server>)% t1 X: h( E# F4 [4 T' X- I) R) i/ g$ ^
Returns true when the designated server is UP, and false when it is either
8 M2 @0 g1 K" Q! p DOWN or in maintenance mode. If <backend> is omitted, then the server is
$ d! d, _* Q8 f, X looked up in the current backend. The function takes no arguments since it
: Z1 H: l3 g' I; c3 ]/ v$ W: s- Q is used as a boolean. It is mainly used to take action based on an external, W( P) n* c, N- d
status reported via a health check (eg: a geographical site's availability).
( F4 E& m, `3 _* x4 a Another possible use which is more of a hack consists in using dummy servers# a$ v' o* m5 Y0 V
as boolean variables that can be enabled or disabled from the CLI, so that; }6 U5 b$ m! P P6 y
rules depending on those ACLs can be tweaked in realtime.
& t+ b9 [4 A, G) `9 w) z+ k, l
. _# Q9 z, X; b6 t2 K& J4 j0 r2 B2 g2 p1 h; p
7.5.2. Matching contents at Layer 41 _* F, p+ X1 G7 Z0 C; C
-----------------------------------
; s) O) F9 y8 h& C4 K* y1 C5 b% B& ~8 W7 ~$ g' u5 h! @
A second set of criteria depends on data found in buffers, but which can change
" B/ X6 |" q$ k; gduring analysis. This requires that some data has been buffered, for instance
& M5 e. E8 U/ p+ d9 @8 Bthrough TCP request content inspection. Please see the "tcp-request" keyword
1 s: [1 A9 \/ `; r0 a1 W2 P4 j) K0 Gfor more detailed information on the subject.0 ?7 [- k: a; Q& Z2 Q
8 O# y! j7 Q3 T, q1 Preq_len <integer>
$ m/ M5 U* |5 G3 \8 } Returns true when the length of the data in the request buffer matches the
; y6 `$ E9 j8 C* D* m+ H specified range. It is important to understand that this test does not G' N% w/ t+ g2 R- S: ^
return false as long as the buffer is changing. This means that a check with
0 a5 j! S" s5 M4 s. `* H" P equality to zero will almost always immediately match at the beginning of the
% x7 B2 t8 V* i+ ^ session, while a test for more data will wait for that data to come in and
" U7 g2 z( r0 C5 i; x, C z return false only when haproxy is certain that no more data will come in.3 Q6 r4 S& Y$ p9 I) {+ i* l
This test was designed to be used with TCP request content inspection.
# K: X ?5 n3 ^( l
3 X1 x* x2 [$ Lreq_proto_http
; d/ I0 K }" s, R- C5 ^7 x% k1 ?) g Returns true when data in the request buffer look like HTTP and correctly; U2 V7 {: a# F) [( U
parses as such. It is the same parser as the common HTTP request parser which/ o2 A2 r4 \- m/ Y. c$ {5 I* _( i
is used so there should be no surprises. This test can be used for instance
8 ]/ T& Z3 V3 m to direct HTTP traffic to a given port and HTTPS traffic to another one
2 y2 _1 Y' W$ ~- x. a using TCP request content inspection rules.
4 ~$ L4 J/ k& H: \( g2 U! u. t; r$ E: A! Z
req_rdp_cookie <string>
! L6 Z5 }# `! Z& Xreq_rdp_cookie(name) <string>
* f* A% _" m) R( Q7 n! Y' w9 ] Returns true when data in the request buffer look like the RDP protocol, and- \" @+ a- z: J1 x) |9 m( r
a cookie is present and equal to <string>. By default, any cookie name is0 V3 Z9 B9 q; d- d& _6 J
checked, but a specific cookie name can be specified in parenthesis. The
% m7 _ A+ b$ |) h9 ? parser only checks for the first cookie, as illustrated in the RDP protocol8 L' j2 b& ]( X' U+ @1 K, r
specification. The cookie name is case insensitive. This ACL can be useful2 r4 c1 b* t; R* X
with the "MSTS" cookie, as it can contain the user name of the client" I z% F4 I7 J; s& x8 O8 l" O
connecting to the server if properly configured on the client. This can be
! g+ Z) K* s* B; I+ a0 a used to restrict access to certain servers to certain users.
& Z1 d# W! H, E2 z
* l$ ]) \8 I2 T# ^req_rdp_cookie_cnt <integer>
9 Z# b) s; A4 l; u n! Nreq_rdp_cookie_cnt(name) <integer>
: o% E* o$ l' V! q7 Z8 ~ Returns true when the data in the request buffer look like the RDP protocol+ Q" c. ?+ u' C& @2 R6 a# i8 k
and the number of RDP cookies matches the specified range (typically zero or
3 O6 z) J; d+ C2 d* ^5 \$ N( @/ Y one). Optionally a specific cookie name can be checked. This is a simple way
* ?8 K) P2 ~8 f of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH
' u6 R% k5 Y6 ?2 N6 A* C cookies.
9 T7 b* Q2 z: _$ v. ^! _0 M8 `7 u# d; A9 W! f; |* ~- G) k: y
req_ssl_ver <decimal>5 F6 P& @2 a, F* k- J- e/ N) y
Returns true when data in the request buffer look like SSL, with a protocol
" V$ ^5 H& F) m6 l version matching the specified range. Both SSLv2 hello messages and SSLv3
) M, I! W' ^" Q7 q# s. ~% Q messages are supported. The test tries to be strict enough to avoid being
1 K3 j5 A" |% i! V! Z& L easily fooled. In particular, it waits for as many bytes as announced in the
6 Y$ E* ^6 x' M/ E+ K message header if this header looks valid (bound to the buffer size). Note2 y; ?- S: L, [3 f* w. o' V
that TLSv1 is announced as SSL version 3.1. This test was designed to be used
1 |4 X; n' w. e1 d1 V, ? with TCP request content inspection.( g" r3 V9 f; L9 B- Y% h9 `0 [
7 j1 c' T: X5 k
wait_end. o4 e) m1 C# Q$ R: ^) n) a
Waits for the end of the analysis period to return true. This may be used in5 M( u1 C! W4 [* h* ^+ I
conjunction with content analysis to avoid returning a wrong verdict early.
" y" }6 D' u! e" O" H It may also be used to delay some actions, such as a delayed reject for some
# \5 k9 t! ?% U, X# N ]# D special addresses. Since it either stops the rules evaluation or immediately, w; ?9 p$ k* X1 g8 V) |
returns true, it is recommended to use this acl as the last one in a rule.
/ {7 z, I8 b% t. V! J Please note that the default ACL "WAIT_END" is always usable without prior5 W& u, o8 V$ E# T2 n
declaration. This test was designed to be used with TCP request content
6 I9 i2 H' h: q$ H% h inspection.( x6 Y/ _8 ?7 s ?& r" [
& [; p X( m4 m+ K Examples :+ L8 _+ }% Y9 E) u# J* V* _
# delay every incoming request by 2 seconds$ a8 z: Q- P$ z! x6 m, C# O! l
tcp-request inspect-delay 2s, `. G0 M# H7 ]* Z+ N( m
tcp-request content accept if WAIT_END
" A3 }$ g% w/ s+ q9 a2 x; z) m0 h% Z; Q( T, S% q# Y
# don't immediately tell bad guys they are rejected
* M% z6 y, G7 O2 K tcp-request inspect-delay 10s+ ~( S" c8 r; g: w$ X0 ^( W4 d
acl goodguys src 10.0.0.0/24/ H% F) i3 F' y! D4 e8 q6 y
acl badguys src 10.0.1.0/240 a/ p% l: G# |
tcp-request content accept if goodguys
& V! n8 u# ]4 _. n+ {4 c9 B t6 H( _ tcp-request content reject if badguys WAIT_END$ A2 f5 c1 W) M2 k
tcp-request content reject4 i: D: T9 t# g& Q1 }8 Q
8 j* J2 m- y$ G/ F$ {6 D
: B5 ?$ I2 Y+ @& c8 f3 v3 ]# x
7.5.3. Matching at Layer 76 J. N: ?) m0 K: d( Q; Z1 @( |) D
--------------------------
+ b. l7 r+ x# ^& K; y
3 m+ x# P2 J9 K+ B9 o+ W$ OA third set of criteria applies to information which can be found at the
# s4 k, m( i: q1 S9 a0 v1 ~0 @" Iapplication layer (layer 7). Those require that a full HTTP request has been
' \' V: a/ j* ~$ N' ~read, and are only evaluated then. They may require slightly more CPU resources
/ @. N% l: x+ C( Hthan the layer 4 ones, but not much since the request and response are indexed.
1 D# u' f# z9 n) R" i
2 S0 J9 w3 v% Y, Khdr <string>7 h2 ~/ O& Y- g9 v: E7 }" I
hdr(header) <string>
& j5 ^6 c0 j% v! R! U( Q Note: all the "hdr*" matching criteria either apply to all headers, or to a& [+ f& S# [" t& K$ B9 f
particular header whose name is passed between parenthesis and without any
9 b8 l0 u1 }5 q+ r' E: p* a space. The header name is not case-sensitive. The header matching complies, E3 c$ g* W5 _. E, h
with RFC2616, and treats as separate headers all values delimited by commas.3 e1 K# @, N* q: \1 j. q+ v
Use the shdr() variant for response headers sent by the server.- g5 m2 R3 d) x* N8 D
6 X0 M# c: b. J7 x2 d# u
The "hdr" criteria returns true if any of the headers matching the criteria5 F) B7 d: [% S* M8 C
match any of the strings. This can be used to check exact for values. For
7 w" x" x5 C2 _% c instance, checking that "connection: close" is set :
0 u+ p( I2 s' Z0 {
+ C% k7 \2 Z2 o% w2 K4 z8 `: ]* C hdr(Connection) -i close* G! _' C6 V% |4 U: A
6 Z3 ?5 {5 x! ~7 I5 \- d$ @
hdr_beg <string>. Y! s2 R+ a2 J
hdr_beg(header) <string>
5 e* S2 h7 B9 _! G0 C3 x Returns true when one of the headers begins with one of the strings. See
% w% M* @ w0 f7 U "hdr" for more information on header matching. Use the shdr_beg() variant for
) X: N$ [8 g; O response headers sent by the server.* V1 J! f+ h. K0 J3 J2 a$ K
/ B+ P9 o8 Q4 v1 A* I0 V" g
hdr_cnt <integer>
' r+ ^! t3 e0 d* y h: ghdr_cnt(header) <integer>
. q3 @- I+ M1 c" [ Returns true when the number of occurrence of the specified header matches
% e2 K* v v! q' o$ V+ Z2 p( {3 r the values or ranges specified. It is important to remember that one header4 V" p3 }" `" E% W0 A' o
line may count as several headers if it has several values. This is used to
6 ^' `. b N7 H: F6 j detect presence, absence or abuse of a specific header, as well as to block
7 h' h* I, I* L8 d# G0 |1 K4 w request smuggling attacks by rejecting requests which contain more than one9 k+ V. S5 W4 b: H3 p+ @
of certain headers. See "hdr" for more information on header matching. Use
7 y( R& p- i2 C7 C5 C" }/ V the shdr_cnt() variant for response headers sent by the server.
7 ^, k; }! r, P
7 |4 I) L+ Y5 thdr_dir <string>
p# ?* I% P! Zhdr_dir(header) <string>6 P+ c: X1 I# e/ `4 ?3 d
Returns true when one of the headers contains one of the strings either5 _) L7 K9 P' n/ ?* V; T
isolated or delimited by slashes. This is used to perform filename or
# j3 @1 P2 X# t l* `6 V directory name matching, and may be used with Referer. See "hdr" for more
) z L' y) w( w5 n4 h7 ] information on header matching. Use the shdr_dir() variant for response
" k7 o; V+ B$ v headers sent by the server.
: v" A/ j; f7 C# q4 h. k% r) [8 k# m" t7 e: A5 M
hdr_dom <string>
$ q# K' n! d7 ?+ y; d; ~ p2 ohdr_dom(header) <string>; s! t3 I8 C6 I* w1 e
Returns true when one of the headers contains one of the strings either
2 ?3 L+ d/ A- [/ A isolated or delimited by dots. This is used to perform domain name matching," l2 b6 Y4 K% h% N$ g
and may be used with the Host header. See "hdr" for more information on
* {7 h0 \2 B( ]- r: D( u4 Y header matching. Use the shdr_dom() variant for response headers sent by the
8 q N3 w& a" ]+ V( V" C0 ? server./ Y3 _$ _; F2 E7 X% {8 y E2 w
u9 P0 ~7 d) t+ m% {hdr_end <string>
/ W" Q( t9 F$ M. l7 Yhdr_end(header) <string>: `! a7 K |$ l5 Q' r
Returns true when one of the headers ends with one of the strings. See "hdr"
( P! D$ t3 o. Z; F" C8 F for more information on header matching. Use the shdr_end() variant for
/ L7 K& O5 `$ o2 c. \- G response headers sent by the server.
" B, I* O2 j. R0 ?+ p$ F- F% e8 u
hdr_ip <ip_address>
8 j' a. G9 [6 v1 C* C; ?5 y$ Khdr_ip(header) <ip_address>: |5 G7 D5 S9 S7 D5 i1 g
Returns true when one of the headers' values contains an IP address matching
/ @3 s0 @; O9 x) N! G <ip_address>. This is mainly used with headers such as X-Forwarded-For or6 V. }- W* z" D7 c2 z, U
X-Client-IP. See "hdr" for more information on header matching. Use the ?& A1 z- v' g3 |6 a& O- ?
shdr_ip() variant for response headers sent by the server.1 q# o+ w* w+ H( v9 B3 Y
* `2 |7 H' C& ^8 Z
hdr_len <integer>
) n# J$ |/ p% p2 @. P! ~+ Q1 z- \: uhdr_len(<header>) <integer>( s. q/ h* ?3 G, D; ?& Y( ^
Returns true when at least one of the headers has a length which matches the
( W0 j6 H6 }! |, Z! p/ R- w- a values or ranges specified. This may be used to detect empty or too large
. I2 m+ ?) Q" F1 a# l# }! E headers. See "hdr" for more information on header matching. Use the
7 [" ` k/ t( l* D. [7 ], j shdr_len() variant for response headers sent by the server.
/ U; [& P+ g" t. F3 q5 Q2 g7 Z
5 s8 m B' z6 {% M, n! r& h* Nhdr_reg <regex>
) _" T; u) x, }- p2 Jhdr_reg(header) <regex>
0 T% o3 d3 @& y9 S Returns true when one of the headers matches of the regular expressions. It( b, a- I. k6 s
can be used at any time, but it is important to remember that regex matching) z+ ^( r" C4 ?! ?2 @- i
is slower than other methods. See also other "hdr_" criteria, as well as k4 \% _. c! v6 k# R
"hdr" for more information on header matching. Use the shdr_reg() variant for) v2 f: j: z9 H2 |5 W: w* J: m7 a
response headers sent by the server.9 s7 H. s( h, ^
! i& Z8 ^0 |4 F: A% z9 n, N4 b
hdr_sub <string>6 A" k9 a% B0 W4 H# @
hdr_sub(header) <string># { \( @! o! b$ B& E- f- U
Returns true when one of the headers contains one of the strings. See "hdr"
* B, C& Z7 n% x$ B$ N. M2 x, y for more information on header matching. Use the shdr_sub() variant for. e) P, ~/ [2 G1 c8 g
response headers sent by the server.2 q/ J y' |- A. ^' z( P
" J" X ]4 q% W' C
hdr_val <integer>
9 l9 E: K" r9 U' Q2 X4 Y8 a" Yhdr_val(header) <integer>
% |2 ^5 { E) Z9 V& P Returns true when one of the headers starts with a number which matches the' ]. L0 H$ Z; z. J
values or ranges specified. This may be used to limit content-length to$ U% m" U* Z+ [
acceptable values for example. See "hdr" for more information on header4 m; [- x: ^* J; ~- J) G
matching. Use the shdr_val() variant for response headers sent by the server." U! M+ A' \' t6 D- `( v" {+ C
/ s; z7 C e7 A4 K, \http_auth(userlist)
4 |/ e9 W: s8 v7 Hhttp_auth_group(userlist) <group> [<group>]*5 V/ H) q1 e5 w4 F$ m" ?; \( [8 N1 E! H
Returns true when authentication data received from the client matches: g5 h5 s3 t. }% [0 E+ }# L
username & password stored on the userlist. It is also possible to
3 V9 X, \( e+ h6 i0 _ use http_auth_group to check if the user is assigned to at least one
* H- a6 m# `3 c" f; c of specified groups.
% W G; U9 h# c2 v9 e7 a" y' p9 l6 P3 c" M" I6 [2 M
Currently only http basic auth is supported.
( D2 x. H8 N; {" m, _7 q8 l% H) t4 |0 q* B/ h' C, @1 w1 r7 r. Q
http_first_req
, X- n% I }7 r Returns true when the request being processed is the first one of the
2 a2 {0 `/ a" j9 [# U$ {/ J$ s3 @ connection. This can be used to add or remove headers that may be missing
8 ^8 x6 _7 L: L( d) }7 \) w m4 ~1 R from some requests when a request is not the first one, or even to perform: h% W0 g" j& w- u
some specific ACL checks only on the first request.6 @( a! I& s& D/ |: ~+ o+ B
( [$ y# T) H: i9 l& imethod <string>
* B1 p- G( F) P0 U) h Applies to the method in the HTTP request, eg: "GET". Some predefined ACL
) y" V% X, x$ m% ]# k: {; A already check for most common methods./ T, V7 J2 V7 u7 ]. u4 G( M9 _
; t. f( C9 t$ C, o& l) V! S$ v6 \6 g
path <string>
; n% b* [' V( y+ Y, j Returns true when the path part of the request, which starts at the first; H) N3 h% h# T- x. }7 n' H( e; \9 C# Q
slash and ends before the question mark, equals one of the strings. It may be' n2 M4 }: ?; R
used to match known files, such as /favicon.ico.: p& G3 z2 S- R' H4 o7 u8 h P
4 f& T. d! x/ b5 }! t) Q1 e) q! Opath_beg <string>
/ K P y1 W. ]6 \0 g Returns true when the path begins with one of the strings. This can be used- t2 u& P) h9 Z. b7 D! o
to send certain directory names to alternative backends." T1 @# S: C* D4 o* X
4 Q+ t$ ~; u0 P
path_dir <string>
1 I& f2 o4 r5 r) c: F" u/ D+ E Returns true when one of the strings is found isolated or delimited with
5 t/ O, Q0 A$ ^& x slashes in the path. This is used to perform filename or directory name
- u6 L+ i- w% g; @3 Q& r& Z7 V' ^ matching without the risk of wrong match due to colliding prefixes. See also
4 ^& g. s9 C: o# m9 ? "url_dir" and "path_sub"./ j) \6 N, D" Q1 i# c7 b* ^
9 S4 d5 o8 X) g7 f- K# U
path_dom <string>
8 t' \% d1 E' F1 F- P2 V- r- Z Returns true when one of the strings is found isolated or delimited with dots
2 _% }7 d9 T5 E9 y5 _2 J% P in the path. This may be used to perform domain name matching in proxy% W1 c( z2 ]& F0 ~
requests. See also "path_sub" and "url_dom".$ \* B4 s) b) e, i8 W
1 j3 r# j2 C4 g' g9 C4 q$ c( gpath_end <string>
% A1 W, a0 V" k$ F' H$ a1 _; @ J) p Returns true when the path ends with one of the strings. This may be used to
9 S/ i# `% y& A+ w" F& q control file name extension.
& ?( F0 h# Z3 }5 n! O# g% K
! q. F/ o7 p1 C6 v+ l" q+ vpath_len <integer>
8 t h. E. p" X! u+ T; T Returns true when the path length matches the values or ranges specified.
1 F8 a6 i) R$ J' M/ F; X' h This may be used to detect abusive requests for instance.
6 t6 _8 ^5 b+ B4 n$ l2 f+ R! ?( C1 b2 O: i6 q, {$ P7 @
path_reg <regex>
3 b z2 R; o4 X! t& C Returns true when the path matches one of the regular expressions. It can be
9 R8 t8 ^3 @) \) t7 _0 j used any time, but it is important to remember that regex matching is slower
- n& Y# Y2 m3 |$ A# y+ A2 @ than other methods. See also "url_reg" and all "path_" criteria.
! o7 _" I0 Y: @% Y; \' R3 U
# R4 n. w) A1 C/ o2 m x4 q- Lpath_sub <string>
0 F8 ?: n3 H# h+ u' H) S Returns true when the path contains one of the strings. It can be used to
$ |2 M# Y( j7 a) J G# b detect particular patterns in paths, such as "../" for example. See also
1 q) e0 L$ {# k% ^: v "path_dir".
8 S. d# N/ m, Q! |$ X# d2 E: P Y3 j5 K( s2 e
req_ver <string>7 ^ t+ n. c' @4 ]
Applies to the version string in the HTTP request, eg: "1.0". Some predefined: W* F1 }/ T+ a6 J* t' _4 K
ACL already check for versions 1.0 and 1.1.* a3 _8 \4 j S' h
# F3 n! B2 G9 \! E0 ~; v' V( Cstatus <integer>
6 A3 @0 ^, ^" e! X' p Applies to the HTTP status code in the HTTP response, eg: "302". It can be' M- N, b) a+ I" l
used to act on responses depending on status ranges, for instance, remove
* b" u6 _1 r a6 F r any Location header if the response is not a 3xx.% m3 k3 D- A1 _ N
) H( f m/ m4 i" @; e
url <string>7 R M9 x) r6 z
Applies to the whole URL passed in the request. The only real use is to match
, A& V+ H. e9 ] r4 B "*", for which there already is a predefined ACL." \, Z* ]$ x: C1 v( S+ I
7 }* P: z. n4 a/ D% I5 d
url_beg <string>
6 ^, {% J9 q! D4 }" t7 T Returns true when the URL begins with one of the strings. This can be used to
2 E9 B. y" b: B: X' m! L/ E V check whether a URL begins with a slash or with a protocol scheme.
$ c- ?0 H6 T$ s% A7 X U7 s3 V/ A( S5 O0 @2 z$ d& n1 F) L0 B& _
url_dir <string>) m5 ~$ Q& |- b ?, K# e# d% y5 A
Returns true when one of the strings is found isolated or delimited with& b4 }5 c' E/ k- Y' Z- |9 D
slashes in the URL. This is used to perform filename or directory name4 J* d# x7 h& @4 ~ r% K: l
matching without the risk of wrong match due to colliding prefixes. See also! y3 o* m$ q( y( j
"path_dir" and "url_sub".$ d; ] }& Q/ M, U) ^
3 o: w3 [' T* E2 j5 t, m
url_dom <string>
7 a' `/ A# x7 J# y Returns true when one of the strings is found isolated or delimited with dots
0 T: f/ w. z' v% _ in the URL. This is used to perform domain name matching without the risk of
+ c* B9 M0 O3 C, j E ], N wrong match due to colliding prefixes. See also "url_sub".5 m5 |$ Q- D8 q$ a
4 @* M: p6 X( Z8 K/ L, p
url_end <string>
3 }2 d! O5 c% N Returns true when the URL ends with one of the strings. It has very limited
! ?' v- ^" j5 @7 ^ ~% J use. "path_end" should be used instead for filename matching.3 B5 X9 _, a8 W. |. {
$ d7 o1 W ]$ T- vurl_ip <ip_address>
( Q5 `) s b/ |% t0 j, V* v2 Y" m Applies to the IP address specified in the absolute URI in an HTTP request.+ J$ V; U p) R# H
It can be used to prevent access to certain resources such as local network.
( \$ c7 w, \( e It is useful with option "http_proxy".
7 P! D7 x% y0 m) a% f
6 i1 h$ J1 v- ^url_len <integer>0 E+ @$ @8 f, C4 z" n6 m: f" e0 i
Returns true when the url length matches the values or ranges specified. This
% h' ]$ y3 b( E9 ^/ v may be used to detect abusive requests for instance.
2 M6 W2 P: |) Z+ b7 r3 H( A5 z' ?8 d# a
url_port <integer>$ ~4 U: f( M4 P* A B1 m' ^
Applies to the port specified in the absolute URI in an HTTP request. It can
/ k8 Y* R2 X& `6 F0 S/ d% Z be used to prevent access to certain resources. It is useful with option! r" Z A m$ C& O$ f
"http_proxy". Note that if the port is not specified in the request, port 80
; ]" x3 @* z* e3 _ S6 U is assumed.- P( Z. G7 q8 h: [5 Q a6 @
2 z" T- e7 G% R+ b& h) j
url_reg <regex>
2 \ w5 z) y: Q0 i5 s8 L$ L; k5 _ Returns true when the URL matches one of the regular expressions. It can be8 w0 e+ t) z: ~6 E' P
used any time, but it is important to remember that regex matching is slower
6 Y, e h# W$ u, i than other methods. See also "path_reg" and all "url_" criteria.
- U2 W& I3 G' F
# `( j: S- G+ i* o1 {5 g/ ^. ]" aurl_sub <string>
- o5 G- P/ A) n A# s' z# m4 \! i Returns true when the URL contains one of the strings. It can be used to
7 J& n; F* [# m/ i0 r+ r detect particular patterns in query strings for example. See also "path_sub". V& b/ T3 p. j. W$ u1 w4 R
3 z) M$ b6 X7 l# |: |$ h" g9 W# l9 P
7.6. Pre-defined ACLs
1 u; {- g j9 r9 P---------------------4 a2 q: Q( u3 K# r, q" V
( s6 u9 G5 m) v8 n% \5 h( l: r: |" q
Some predefined ACLs are hard-coded so that they do not have to be declared in- z) ]! Q7 e( q
every frontend which needs them. They all have their names in upper case in
; \& |) C) _1 t6 N/ {8 ~order to avoid confusion. Their equivalence is provided below.
0 z& G+ O4 b9 Q }6 p
: ^- K5 D$ C" \1 d4 o3 Y& |" j+ VACL name Equivalent to Usage- S `- [0 V) F1 _7 }* }% l3 d" W
---------------+-----------------------------+---------------------------------
: e; U' N6 O1 x! rFALSE always_false never match; u+ ~7 `# G2 g1 X* X
HTTP req_proto_http match if protocol is valid HTTP
* X! e0 |; r$ x& }HTTP_1.0 req_ver 1.0 match HTTP version 1.0% A1 H9 m" }+ `- C# n& M' t
HTTP_1.1 req_ver 1.1 match HTTP version 1.1& s% X1 t4 B J5 r+ J) W
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length- S9 U- L6 @; R7 n" S ?/ b0 `
HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme# `$ c) K( s' ]8 Y: i
HTTP_URL_SLASH url_beg / match URL beginning with "/"; g3 ~0 r: m% _
HTTP_URL_STAR url * match URL equal to "*"
3 W& P& ~0 D4 e L+ zLOCALHOST src 127.0.0.1/8 match connection from local host
9 M1 h C ]$ ^( ^8 q# aMETH_CONNECT method CONNECT match HTTP CONNECT method
& v7 |) T, Q) wMETH_GET method GET HEAD match HTTP GET or HEAD method: `1 ?" t. ] r; M( }0 N# S
METH_HEAD method HEAD match HTTP HEAD method% d5 I, ~8 I- C& G2 Y7 j
METH_OPTIONS method OPTIONS match HTTP OPTIONS method+ D: l* y' H/ `/ e# C6 W
METH_POST method POST match HTTP POST method
, d+ q: [4 Y% H' HMETH_TRACE method TRACE match HTTP TRACE method
# D; H F$ \8 t* z' q( Q. n/ x+ zRDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie! f. O% s; s: B' U3 J
REQ_CONTENT req_len gt 0 match data in the request buffer% z& r( ~1 D$ f- g9 i U: I
TRUE always_true always match
0 ^7 d1 W# D( N6 v* c: zWAIT_END wait_end wait for end of content analysis* p/ Q# u& ~# |2 b, f
---------------+-----------------------------+---------------------------------
; X" n# v7 ?! t, r/ m& ~6 v
. u+ o" N' p. U4 A# W" i P, f k# L7 i5 I
7.7. Using ACLs to form conditions$ `/ s9 j. q) ^! F. C! D
----------------------------------
" q- H( _$ x7 a& l8 ?) k1 ?8 }0 V* E8 S; M( A
Some actions are only performed upon a valid condition. A condition is a9 F" g; L( w# B& C2 V& E
combination of ACLs with operators. 3 operators are supported :' n- s9 h9 g" a7 I: R$ f
( ^$ L8 I( T! R6 a/ |; e - AND (implicit)* A3 U" c' r2 b) d+ Y
- OR (explicit with the "or" keyword or the "||" operator)$ R0 I1 x" v" u F9 k- Z
- Negation with the exclamation mark ("!")
' t7 Q4 O* q7 @. r- J9 w4 Q& q- T/ m+ V" Y4 l
A condition is formed as a disjunctive form:, v5 b# H1 u2 t |! \' r0 M; n3 `
! [; K- z# c0 @
[!]acl1 [!]acl2 ... [!]acln { or [!]acl1 [!]acl2 ... [!]acln } ...- \7 V! o K$ V- p9 r2 ~
! b1 U5 o$ o- h" ?Such conditions are generally used after an "if" or "unless" statement,7 Y4 S* V z3 g+ P
indicating when the condition will trigger the action.
/ m( W8 q9 |: f! A( v& _( o6 P+ ]6 h4 d6 X$ s7 i
For instance, to block HTTP requests to the "*" URL with methods other than
, T) E& L, n8 h"OPTIONS", as well as POST requests without content-length, and GET or HEAD
, e- m+ p2 U, q* o" `requests with a content-length greater than 0, and finally every request which
9 |5 _ {0 F4 F& @) eis not either GET/HEAD/POST/OPTIONS !
* X* C* z+ [- l G6 R5 u& S
& L# q& b {- Y5 C/ x acl missing_cl hdr_cnt(Content-length) eq 0
! Z$ l! K- Z7 {% u: P/ E block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
6 r+ g# o% l2 R+ I, o: I' S& Q& [8 z block if METH_GET HTTP_CONTENT
0 l% e: T1 |3 v block unless METH_GET or METH_POST or METH_OPTIONS
$ B/ F3 ?+ T$ i2 {+ _: w+ X2 n: t7 s3 a4 A$ _
To select a different backend for requests to static contents on the "www" site: G& t' E6 @: X: C% F7 E
and to every request on the "img", "video", "download" and "ftp" hosts :
! X+ u0 z( `) G1 }. R. [9 k/ }$ U& u
acl url_static path_beg /static /images /img /css
, k s2 g, `* R* n. m0 Z8 R# s acl url_static path_end .gif .png .jpg .css .js
$ J9 M0 h3 }% l7 m4 y0 K acl host_www hdr_beg(host) -i www2 I+ e) e; C8 L! b
acl host_static hdr_beg(host) -i img. video. download. ftp.% S& D0 L# V& t% R
* r: K* b! ~% E k
# now use backend "static" for all static-only hosts, and for static urls
4 \: j: k/ ^4 X) b- N" G! z1 { # of host "www". Use backend "www" for the rest.
" d+ h* k, H' {% v+ J* H0 Z use_backend static if host_static or host_www url_static
~# J# \ o, m% m. G/ o$ Z use_backend www if host_www
, _9 {" a7 {6 ?1 \! `% U4 t' i' ?4 r& q+ s. n
It is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
; O S$ q4 H3 I" a/ Yexpressions that are built on the fly without needing to be declared. They must
" P1 }6 [6 W8 E) [+ p$ o1 u; ?9 ~be enclosed between braces, with a space before and after each brace (because
: ^$ z/ G! N( v% l' m1 Gthe braces must be seen as independant words). Example :
: P* S! h/ W5 R) b+ L8 V3 s& {8 z- \7 j& m& i* ~
The following rule :9 d- S# O7 _$ a+ O$ w4 g6 C1 F
& H8 r7 t! z" W) l3 x' w
acl missing_cl hdr_cnt(Content-length) eq 0
7 `: \! P% Z% B: j4 X7 B: A block if METH_POST missing_cl
# w3 T: I# L+ e" f) x5 v2 C: `' K5 b) ? D6 q# \" f
Can also be written that way :6 [! A3 L w* h" ~% k/ d/ n
! S e4 Z& s# x' ~& X' S block if METH_POST { hdr_cnt(Content-length) eq 0 }9 ?9 E3 Z( s3 J* x& o0 e, Y, A
9 X6 A8 s( L( @8 h1 ZIt is generally not recommended to use this construct because it's a lot easier1 \4 m2 M& N/ w M
to leave errors in the configuration when written that way. However, for very) z8 {! S4 W1 N8 ^2 D
simple rules matching only one source IP address for instance, it can make more
1 Q7 I: f* `* C# p; L7 xsense to use them than to declare ACLs with random names. Another example of' U9 {# v! ^2 \ z( [
good use is the following :+ E/ D+ k7 [' d6 k, `6 L2 s) U
) i9 N: U3 Q/ D& R With named ACLs :3 j( `) p5 O2 K$ `& q& k0 r
- d; x% x7 R: G4 _5 I$ E acl site_dead nbsrv(dynamic) lt 2+ |" k& [, v( _2 |) J5 \" ^" l
acl site_dead nbsrv(static) lt 2
: X4 j1 t c2 J. P! u monitor fail if site_dead1 f' N' m P5 M; h; M6 E1 k9 g
+ e& z- h! g: R2 m5 V$ i5 F& \4 g
With anonymous ACLs :* L0 V; R1 v T$ e+ j2 J" v
, l8 w" u( y- v9 h: M; m& T. m8 K monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
+ a4 d: B7 c$ ^( Z
4 B# I' r* O& {; bSee section 4.2 for detailed help on the "block" and "use_backend" keywords.( u9 b* }! I" e" M) m$ Z
% w4 H1 n C& B9 P6 ]; N4 R
( y/ l& C; z8 h* T9 W s7.8. Pattern extraction' G5 n' k) ]3 v' B+ N
-----------------------
/ `" o0 w; M, l) \3 s' | K$ c6 |* |. r9 u" c! p
The stickiness features relies on pattern extraction in the request and
7 y# H/ u% ^$ s, Mresponse. Sometimes the data needs to be converted first before being stored,
* x6 A* v0 L8 q# G8 ~- afor instance converted from ASCII to IP or upper case to lower case.. ? }* P; X, p- }, G4 H8 P8 K
: q6 s' M8 [% j) w& @
All these operations of data extraction and conversion are defined as
$ W/ W1 e5 h- N8 H ^"pattern extraction rules". A pattern rule always has the same format. It
* t) v$ r- \. m: t$ Jbegins with a single pattern fetch word, potentially followed by a list of' W+ Q% t4 _2 H5 c R- \( ~
arguments within parenthesis then an optional list of transformations. As
7 M! u! Q0 v ]8 L: ~6 Umuch as possible, the pattern fetch functions use the same name as their
! p; i5 u; I7 E. oequivalent used in ACLs.. u9 _& q2 i: n
3 V4 @9 K+ Y# x VThe list of currently supported pattern fetch functions is the following :
) v( b: h5 w2 r- n- O( l6 O
) P! M) x/ H; t) J! c: S; Z% | src This is the source IPv4 address of the client of the session.
: o# o' j: }- ~: g) k% @ It is of type IP and only works with such tables.3 y& H" i* x7 ?# ^) l; q
6 p& Z/ Z% H* Z# N4 N dst This is the destination IPv4 address of the session on the
' q) _* {" D, Q' }9 e; L/ ` client side, which is the address the client connected to.$ a' @$ S3 V) M6 @
It can be useful when running in transparent mode. It is of; t) r( M9 v8 T3 K+ W
type IP and only works with such tables.7 T: O- y2 f3 [. N3 q1 ]
$ ?" }( x& A+ @( ?
dst_port This is the destination TCP port of the session on the client
. }9 y' T2 t8 t- x, ?9 D: T* \ side, which is the port the client connected to. This might be
# q8 G- n' d5 M& v. I9 J$ k' x/ l used when running in transparent mode or when assigning dynamic
, M5 M6 e- {& @% m, ^ ports to some clients for a whole application session. It is of# X4 u2 N3 c L( \0 O
type integer and only works with such tables.6 Y+ w% }/ f% M8 h
7 N. Z9 m& d, Z8 ^ hdr(name) This extracts the last occurrence of header <name> in an HTTP
* f1 v. T* E6 E0 ~ request and converts it to an IP address. This IP address is
6 K7 f% s2 V; K! @) E& H/ z; U# q then used to match the table. A typical use is with the
2 _ a3 J3 l! t" n x-forwarded-for header.1 W, p8 `* d) d% o
1 d& V6 R r3 |. O
: u2 t2 P; N" E9 sThe currently available list of transformations include :
- x; D! P& U( l+ j. ]3 c+ E/ v
; N1 a4 e9 T" X3 t- s$ w0 {: ^ lower Convert a string pattern to lower case. This can only be placed
4 B2 P( T# Y* ]3 h after a string pattern fetch function or after a conversion
$ _# H% x# u; \; j) N: y2 X function returning a string type. The result is of type string.
" J: w3 g" o- o* z) F. C# E2 d, i4 j& o; I& O/ `
upper Convert a string pattern to upper case. This can only be placed. F. `9 q! J2 e. J# r1 S- ]) h) n
after a string pattern fetch function or after a conversion! `" W& B; f3 G: |7 W
function returning a string type. The result is of type string.
* b" T0 ]8 _, H4 F q2 l% h# l5 m8 P
- `& p. {: M; f4 ^* N ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups% p0 K: G9 W4 U. R( X& T. D" s8 \: k1 @
and storage. This can be used to make all hosts within a7 a+ u: R) x: A- W
certain mask to share the same table entries and as such use4 W' t& a$ y: Z" Z0 v
the same server. The mask can be passed in dotted form (eg:9 \, r; m7 Q2 ^- F P
255.255.255.0) or in CIDR form (eg: 24).& x" C; @4 Y, Z2 ?
) | p1 @. i5 ~; ~* y' e
u4 u% W" v* W& c( R/ D8 L
8. Logging/ c3 n4 P7 y2 K7 R5 j
----------
9 T7 k6 A1 J4 [6 W" |3 w @3 }1 B8 d/ @3 n6 ~/ k% ?. Q4 I
One of HAProxy's strong points certainly lies is its precise logs. It probably; R- X/ F4 R7 `2 H( _ W) e
provides the finest level of information available for such a product, which is
; w3 ~ {6 x+ X# Gvery important for troubleshooting complex environments. Standard information
2 l! f4 X- e" S3 Vprovided in logs include client ports, TCP/HTTP state timers, precise session( x0 M# `) K% W; z, C6 c% O& Z
state at termination and precise termination cause, information about decisions$ J# r8 y' a8 u8 P; [* G) ~
to direct traffic to a server, and of course the ability to capture arbitrary. r* j- v, {: ]9 ]3 t9 U
headers.
& Y/ d i: p, i6 b" U+ V6 K" }3 m* E4 [0 t, X4 X
In order to improve administrators reactivity, it offers a great transparency6 Z. N* _3 n9 s* n
about encountered problems, both internal and external, and it is possible to
% N* B4 t! o* g) l3 nsend logs to different sources at the same time with different level filters :! L* C4 n/ H7 K2 i# D' J
- `) O5 y$ E# f, a - global process-level logs (system errors, start/stop, etc..)
. G- ~# a! T6 j - per-instance system and internal errors (lack of resource, bugs, ...)
& L3 @! B6 K* I; T# I: I - per-instance external troubles (servers up/down, max connections)0 {; e9 k9 B* I4 K
- per-instance activity (client connections), either at the establishment or
* S* b" z- I; c( C4 D at the termination.
S' A# |( ~( t+ T$ `; S! j# i+ I5 U+ |/ P7 x) P
The ability to distribute different levels of logs to different log servers4 j8 @+ i- y8 T" |; b+ ]
allow several production teams to interact and to fix their problems as soon4 X3 j; I$ c( H4 x. Q: K- ~ I
as possible. For example, the system team might monitor system-wide errors,6 i9 o+ Y% m+ e4 W4 p
while the application team might be monitoring the up/down for their servers in7 j) ?1 x+ \: n0 F! A
real time, and the security team might analyze the activity logs with one hour
1 q( m" Q/ N. R: l% A' `, xdelay.
B/ \$ A+ ^4 P8 M" H
5 G$ Z% g' ^3 p6 a
; g, u0 u$ c% }5 e* \4 j" v. t8.1. Log levels n4 d! C- d) q
---------------5 k0 E; i2 s; a5 Z/ L! _
1 h% ]2 v, w( G& b
TCP and HTTP connections can be logged with information such as the date, time,# V! F7 J! \4 n& W1 y4 G
source IP address, destination address, connection duration, response times,
- W6 F0 H; }% ^: Z+ N0 Z4 V p$ _; I; JHTTP request, HTTP return code, number of bytes transmitted, conditions6 ?4 s x+ e6 [" v4 w
in which the session ended, and even exchanged cookies values. For example2 i& D' E+ Y, J4 S2 A
track a particular user's problems. All messages may be sent to up to two7 L; R% o$ J5 k6 q: j6 R
syslog servers. Check the "log" keyword in section 4.2 for more information, {+ x/ k) O2 t0 K @$ [) r
about log facilities.- r% P3 z1 V( u3 L0 d9 S
" u6 B7 l& d& }5 y
4 n ]# Y/ o% T5 M9 X
8.2. Log formats
, l. V' P/ v+ V( W3 X5 o4 g* r----------------
, }/ p- a+ M0 @7 O% ]
( U9 q9 C2 g1 j5 JHAProxy supports 4 log formats. Several fields are common between these formats
2 V" z* K( H) w% [% Hand will be detailed in the following sections. A few of them may vary
7 o J) E7 {1 L7 u6 e# P+ o. P/ {/ Aslightly with the configuration, due to indicators specific to certain9 A% ~" }9 L9 f$ D
options. The supported formats are as follows :
- @8 i4 |7 R* x6 }( i" O
: O2 W* P* r5 I" R6 T4 k0 S - the default format, which is very basic and very rarely used. It only
6 K. T9 v4 `7 c* T- Y provides very basic information about the incoming connection at the moment: Z; Y& w' T" V& {
it is accepted : source IP:port, destination IP:port, and frontend-name.
( D$ ~0 W" {! ]. `2 E This mode will eventually disappear so it will not be described to great
3 w6 w# T( }+ q& Z8 S- b) g. I extents.. C$ ~2 I5 n# Y6 _, z
- G! a6 x5 |) [% b1 a, ]7 E# D& K - the TCP format, which is more advanced. This format is enabled when "option
8 A; ~# |; N% M$ F tcplog" is set on the frontend. HAProxy will then usually wait for the
; N1 ^% y9 g3 m9 C- V$ c% [ connection to terminate before logging. This format provides much richer' G+ Y) b& g. i8 G q" S$ V; m
information, such as timers, connection counts, queue size, etc... This7 h# n# n6 m; D( ~+ w2 }
format is recommended for pure TCP proxies.
4 H* x4 P: `/ ^1 m
" n% S% h |% b* M% m4 K - the HTTP format, which is the most advanced for HTTP proxying. This format
# }, d$ A; D* Q8 Y; \ is enabled when "option httplog" is set on the frontend. It provides the
/ A# w% M9 a+ ?: ?" `4 Z4 R same information as the TCP format with some HTTP-specific fields such as- k7 g0 C5 U1 B' ]7 G1 ]
the request, the status code, and captures of headers and cookies. This
6 b" t% l. p* ? Z- R9 D format is recommended for HTTP proxies.
7 |# S0 H- [& @& r! M2 M, d/ {) G& r$ u4 V$ |( c0 q
- the CLF HTTP format, which is equivalent to the HTTP format, but with the* q7 v& U% N1 v* N0 R- ?8 q
fields arranged in the same order as the CLF format. In this mode, all) F0 V0 w$ G/ _" y& m, ~6 m
timers, captures, flags, etc... appear one per field after the end of the
7 v C+ j6 Y0 L common fields, in the same order they appear in the standard HTTP format.' V% f% k$ B8 Y4 y! p" y8 \/ ]/ g' K
1 q' `: j" Z: n8 f4 c% N3 x4 {
Next sections will go deeper into details for each of these formats. Format
2 b- R8 s- k# x3 I0 I/ ~specification will be performed on a "field" basis. Unless stated otherwise, a
# Q$ _- ?6 J7 s3 cfield is a portion of text delimited by any number of spaces. Since syslog( R( i4 H( j/ N0 }9 r* d7 v: F; X
servers are susceptible of inserting fields at the beginning of a line, it is
- s, U3 Y/ G9 ]; h: n% r$ e* ]$ A, aalways assumed that the first field is the one containing the process name and
9 z7 e0 r2 Q4 Kidentifier.
) [; T& F/ o M1 Y* w& R2 a. G6 Q* i1 U" z- C4 f$ W$ u' ~# q. I
Note : Since log lines may be quite long, the log examples in sections below
F- }9 W" ^$ \( j8 C% | might be broken into multiple lines. The example log lines will be+ |. F+ J {) v6 L; x. K; d* R
prefixed with 3 closing angle brackets ('>>>') and each time a log is4 O" T( S" N- k; p* Q4 W
broken into multiple lines, each non-final line will end with a+ w: ~. E& g1 k' s3 |5 }! s; y" {9 L
backslash ('\') and the next line will start indented by two characters.9 ?, R9 @, z# c1 h( y* b4 j
; q z( A: l& v( h# `1 t. A
& @9 a$ M6 R% ~, n8 T! m S8.2.1. Default log format; z/ E9 B7 f' U2 q8 b
-------------------------+ t. X0 L, ?: p4 E
1 m' t5 e+ ^4 hThis format is used when no specific option is set. The log is emitted as soon
5 T7 i0 q5 p( V1 E: Nas the connection is accepted. One should note that this currently is the only% p- {; a$ z# O% N8 l
format which logs the request's destination IP and ports.8 e8 S0 K7 w! E3 m7 x. Q* _" q1 W
9 w5 p7 u, t: F& ]+ k9 B5 |
Example :7 u0 X, S7 e' Q% A, D
listen www O8 N* k0 y4 a k0 y! o% H" `( z
mode http5 Y& d+ A1 V" |6 W- B* o
log global
& {- W! W! `$ u: j# a0 E% F server srv1 127.0.0.1:8000) S# i! w* i5 Z, E
& h. B; Y% p% P! r
>>> Feb 6 12:12:09 localhost \7 A7 {# W7 q1 g& z2 X
haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \, x' @' I1 @0 i' d: {
(www/HTTP)
: i; v$ ^ W& ?( N! [* }3 c- e) c
+ _# x3 |* B+ k8 N2 v, F% {' G Field Format Extract from the example above, }3 ^2 d/ }4 t% k( q1 P7 g
1 process_name '[' pid ']:' haproxy[14385]:
- c+ l5 W0 c5 N8 B$ O+ h2 y 2 'Connect from' Connect from
) {( {6 ]' D& S& ? 3 source_ip ':' source_port 10.0.1.2:33312# u/ [7 ^, G. @( |' [. x
4 'to' to3 m% X& |" ~! w$ g+ J3 U
5 destination_ip ':' destination_port 10.0.3.31:8012
/ W- b& }! ?. @2 n' f0 m 6 '(' frontend_name '/' mode ')' (www/HTTP)
* N6 D8 H/ f9 X3 J$ z2 b2 {/ ^% ?- d+ l. k7 n( @* k1 {
Detailed fields description :" B6 Q. X1 `* J; X9 v
- "source_ip" is the IP address of the client which initiated the connection., c, p2 I( ]& w6 |$ m6 X0 N7 ]& c
- "source_port" is the TCP port of the client which initiated the connection.# l) l9 ^. ], f- Z4 D/ a: g
- "destination_ip" is the IP address the client connected to.! M. F& W& D4 d! W
- "destination_port" is the TCP port the client connected to.
; @. q7 |, D8 R/ h# r* D( X% I/ S - "frontend_name" is the name of the frontend (or listener) which received3 c$ r8 ?0 B; @5 W5 y0 H0 g# N
and processed the connection.% X$ Y, H5 e- j1 F# j
- "mode is the mode the frontend is operating (TCP or HTTP).
3 l0 \7 g# t( C+ W! i; K/ _
; `- u+ Y" D5 e4 ]! DIt is advised not to use this deprecated format for newer installations as it
# r" Y+ d5 u- O, l2 |3 gwill eventually disappear.* `2 r i2 T K! i- P( k
" l$ H8 n3 W) G& i
0 T1 L$ `( V9 r, N2 d/ E- F8.2.2. TCP log format
( k6 i$ ^/ S! ]( t( F- P; G---------------------
! T* w, l) E- b H5 Q! y' Y; P! h" N- ^, x$ \7 U! p
The TCP format is used when "option tcplog" is specified in the frontend, and" A; W' N% b4 F/ L7 J# G. J
is the recommended format for pure TCP proxies. It provides a lot of precious
- m6 {* O$ m% @2 Ainformation for troubleshooting. Since this format includes timers and byte
% Y- w4 z+ { h! H( N9 V8 mcounts, the log is normally emitted at the end of the session. It can be1 n/ x( J" e( S0 _2 k+ p
emitted earlier if "option logasap" is specified, which makes sense in most1 {5 ]! E I$ j$ o# O1 r3 H8 w n5 Z( D
environments with long sessions such as remote terminals. Sessions which match
: P& s# P+ v; ?the "monitor" rules are never logged. It is also possible not to emit logs for9 b1 U2 X8 q* ^8 W6 F+ @
sessions for which no data were exchanged between the client and the server, by
. f, N. l! S4 Wspecifying "option dontlognull" in the frontend. Successful connections will* L# |# k* T& N
not be logged if "option dontlog-normal" is specified in the frontend. A few
" Z; d0 s% B3 p- O; G W* r o$ sfields may slightly vary depending on some configuration options, those are
* z+ l( v6 N% W" _ r& Lmarked with a star ('*') after the field name below.9 s' N7 ?* u% M! Y8 }
4 v' L" \" C8 E" e8 Y Example :# U2 R1 E, f! T
frontend fnt
$ V' x7 ]7 X9 F1 Q' j mode tcp
( \! K# V O7 ^5 g' U option tcplog
; \) L% \6 d8 X log global
: d8 M# E! x% I9 Q" s( M* k default_backend bck( ^4 }( E: S0 _! |, h' x
2 W$ z, o8 g+ h7 W5 r7 N. ^1 F
backend bck7 c* r( y9 u! ~! A0 R
server srv1 127.0.0.1:8000
% _( N6 p0 H6 `; b9 q) K' D3 p2 d9 D" S3 {% }& {5 m
>>> Feb 6 12:12:56 localhost \6 _7 b Z# h4 L% }# s
haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \$ N; {8 I3 J9 p1 y& p, M
bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0 j+ ~5 Y) L. j! G E, T
- H! k5 Z3 ~$ l
Field Format Extract from the example above
0 ^5 H# R0 |! L/ D 1 process_name '[' pid ']:' haproxy[14387]:
0 H. r$ O/ l+ M: t! d 2 client_ip ':' client_port 10.0.1.2:333134 M6 s3 s1 F+ {) C1 j {
3 '[' accept_date ']' [06/Feb/2009:12:12:51.443]1 K! o Y4 p9 b- c( M
4 frontend_name fnt# y9 T" u8 s+ I3 R P3 X6 w- k2 i1 X( B5 `
5 backend_name '/' server_name bck/srv1
$ D, p) V: V" F8 b* i5 L 6 Tw '/' Tc '/' Tt* 0/0/5007. W$ ^; }& p3 E9 D" k* E& Q
7 bytes_read* 212
$ a& I0 O# X4 v2 L* l8 r. \0 K 8 termination_state --$ ]5 N, F$ t: u' S& G0 s |
9 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 0/0/0/0/3
' ]- ~$ |" V) D& l 10 srv_queue '/' backend_queue 0/09 e# y, r7 v: V$ O( T
- [5 y& L4 K3 s% p, o0 `& y$ S+ P `
Detailed fields description :% h: w& O. g5 z2 |
- "client_ip" is the IP address of the client which initiated the TCP
8 x3 P: ?( e( [ connection to haproxy.8 r( O8 A0 c( z+ ]! Q6 V
) n8 R! R7 ^: A
- "client_port" is the TCP port of the client which initiated the connection.
5 S: _( z2 x+ Q( `+ o% T; Z+ a8 s: q: r4 [
- "accept_date" is the exact date when the connection was received by haproxy
& W8 B5 S2 }3 F" U3 G& o8 `0 N (which might be very slightly different from the date observed on the6 L% s( f6 I9 n- ^; T
network if there was some queuing in the system's backlog). This is usually% U ]$ y! x! y% d6 u9 w
the same date which may appear in any upstream firewall's log. {/ y& u. S, f$ v# [0 o
" W( R8 {4 @9 b& p+ R* C& o - "frontend_name" is the name of the frontend (or listener) which received
- u1 Z9 B$ ~2 c and processed the connection.) P5 K6 w- D9 Q; }# Y, U8 K. e( o) D, w
2 O) L( i; ^4 s! o4 N0 G) Q. D - "backend_name" is the name of the backend (or listener) which was selected
: Z5 _1 L8 @% M+ \& j" f to manage the connection to the server. This will be the same as the, J3 {2 W8 z# K; ? t
frontend if no switching rule has been applied, which is common for TCP) E4 k( e4 |" F6 B" T( x- R
applications.
! C1 Q+ Y% y4 z `
8 i- A6 T5 J4 Q( }; q2 }2 u - "server_name" is the name of the last server to which the connection was
. l( q7 S; L7 o$ X8 O sent, which might differ from the first one if there were connection errors
( F0 C+ U( G4 ^2 W" _ and a redispatch occurred. Note that this server belongs to the backend
/ W/ g" h4 w$ C4 W* W which processed the request. If the connection was aborted before reaching
8 X3 F8 L E7 c0 | a server, "<NOSRV>" is indicated instead of a server name.
1 `3 T# J/ s% m3 _2 K3 P o) M* W$ b
6 c- G! W- E4 f1 ]6 h) c - "Tw" is the total time in milliseconds spent waiting in the various queues.4 ]1 N" F8 y1 x9 i; U, C
It can be "-1" if the connection was aborted before reaching the queue.
3 D _* R/ v. ~, v4 \8 i& B4 W1 F See "Timers" below for more details.
2 O( W( p) I" N& {5 }! g; S$ w- Q
' ^1 H6 ]% f; |' [% g4 c8 w2 ^# }" t - "Tc" is the total time in milliseconds spent waiting for the connection to
+ M% r+ O, ?9 n: T( z" S establish to the final server, including retries. It can be "-1" if the5 g9 ^6 I; g* ^6 {3 g% I
connection was aborted before a connection could be established. See
" v* q6 ~0 U: M. Z y8 T "Timers" below for more details.
7 a* P4 k! V$ A+ h% e8 S3 f" J
- "Tt" is the total time in milliseconds elapsed between the accept and the# \. Y! o/ z+ W0 q( ^+ n% R
last close. It covers all possible processings. There is one exception, if
% y! r8 y% d. I' U# K! S "option logasap" was specified, then the time counting stops at the moment" d/ _' R. P9 }/ U- U W, V/ g
the log is emitted. In this case, a '+' sign is prepended before the value,
7 B7 [" M# Y) D( s indicating that the final one will be larger. See "Timers" below for more
0 {( l9 Y6 L2 q4 |2 o7 O details.7 t" t( u3 ~' y4 ~
1 I3 l5 m C: @8 \( r0 Z6 J5 L4 m
- "bytes_read" is the total number of bytes transmitted from the server to+ F* ]) Y% K7 z }* O/ Q, c7 A
the client when the log is emitted. If "option logasap" is specified, the
* \) ^2 F" [) @) a this value will be prefixed with a '+' sign indicating that the final one9 s' Q* o3 l3 \2 C, R+ c% |" p8 N
may be larger. Please note that this value is a 64-bit counter, so log
. |" b: k* ] `$ q# N: h( a analysis tools must be able to handle it without overflowing.# D: C- X1 ^1 I$ H
9 r7 V4 _9 K; f; c' a' g j - "termination_state" is the condition the session was in when the session
1 _5 ~$ u- ?, m; k4 L& r/ n. A/ J% w ended. This indicates the session state, which side caused the end of
+ w" Q5 j2 h% W6 S2 L1 I6 ]: T$ u- P session to happen, and for what reason (timeout, error, ...). The normal) X% e# R C. ~# R: z! N6 R' o
flags should be "--", indicating the session was closed by either end with/ l, i7 Y: h+ a
no data remaining in buffers. See below "Session state at disconnection"7 D6 h1 y, G5 d& b, Y" B
for more details.
7 f) j8 @: P" b
7 B7 i' [/ w9 ?, t8 A - "actconn" is the total number of concurrent connections on the process when* U$ x) W4 \) e2 k
the session was logged. It it useful to detect when some per-process system/ P8 C0 \" w' Z5 H8 F9 k- v: V
limits have been reached. For instance, if actconn is close to 512 when$ _% f" M7 N5 q9 _- }
multiple connection errors occur, chances are high that the system limits7 m" R5 d! W$ j
the process to use a maximum of 1024 file descriptors and that all of them1 X' @; W. _6 u" i& j1 I# [
are used. See section 3 "Global parameters" to find how to tune the system.
" j$ }% h" f, F( ~, O
- ]# ~8 |2 ^- Q - "feconn" is the total number of concurrent connections on the frontend when" k* ^. i9 e9 q4 n. T
the session was logged. It is useful to estimate the amount of resource ^( b- \/ Y. v
required to sustain high loads, and to detect when the frontend's "maxconn"
. W. ^* Z5 j7 K has been reached. Most often when this value increases by huge jumps, it is
7 W8 u3 r" j/ [0 H. w because there is congestion on the backend servers, but sometimes it can be) q: o2 C, p/ ^' F" t2 u
caused by a denial of service attack., }% B0 P5 @! f* X1 Y5 V
$ w1 a5 H! @) A0 g9 W: C1 x$ K3 `
- "beconn" is the total number of concurrent connections handled by the
$ t+ A3 Y+ k) I5 _9 L* n backend when the session was logged. It includes the total number of+ {+ `/ F. N, n) R5 |
concurrent connections active on servers as well as the number of
' g, [' t) D7 n3 I# e connections pending in queues. It is useful to estimate the amount of
& H8 R0 V/ b) l: ~ additional servers needed to support high loads for a given application.6 O# D; p' c# u
Most often when this value increases by huge jumps, it is because there is
' h8 c* r" M& h. d, V/ U1 S- r congestion on the backend servers, but sometimes it can be caused by a+ v* i8 n. W* k2 t! U7 n) ^
denial of service attack./ ~" y& p% r: [, H
; Y' R% ]) u$ i/ N - "srv_conn" is the total number of concurrent connections still active on
" V% n# R( P/ E+ n5 S8 k the server when the session was logged. It can never exceed the server's
0 x. P* |& h! y U configured "maxconn" parameter. If this value is very often close or equal
4 S) H1 u: J$ w to the server's "maxconn", it means that traffic regulation is involved a
" k, z5 l/ u% D7 x/ f/ u+ [- }' d lot, meaning that either the server's maxconn value is too low, or that8 V7 P) f- p0 j5 ?: S S1 c4 N
there aren't enough servers to process the load with an optimal response0 N" S$ |, r* F
time. When only one of the server's "srv_conn" is high, it usually means9 L- O7 u A8 N! T& `9 Z* c' u
that this server has some trouble causing the connections to take longer to
! E: E+ m* ?( s { be processed than on other servers.
: u O* a5 Q8 y1 T4 c& V1 ]6 ]" P6 w f
- "retries" is the number of connection retries experienced by this session, T) D# ?+ J/ B& G7 l
when trying to connect to the server. It must normally be zero, unless a0 p, W7 ]( U# Q" f
server is being stopped at the same moment the connection was attempted. v/ b! s& w9 ^: c! T. G
Frequent retries generally indicate either a network problem between
9 U" y4 ?# X1 e( N6 A+ J haproxy and the server, or a misconfigured system backlog on the server
! P0 \( j- p5 u' t1 Y preventing new connections from being queued. This field may optionally be, ~) s4 K6 u$ T2 W1 h
prefixed with a '+' sign, indicating that the session has experienced a
8 i6 Z( Y3 @, x redispatch after the maximal retry count has been reached on the initial5 _; W! e+ S/ T0 H5 T& L. [
server. In this case, the server name appearing in the log is the one the
+ P6 D+ ]0 r/ @5 ], Y: f D4 ] connection was redispatched to, and not the first one, though both may f8 P6 S: [, e
sometimes be the same in case of hashing for instance. So as a general rule
( i3 }' i, h n9 W# c- X of thumb, when a '+' is present in front of the retry count, this count
8 y `* R; p& Q" @8 c: k+ s% X; q should not be attributed to the logged server.
7 W9 t% n: B% ?. A8 q r3 G8 e0 u" l' z. C
- "srv_queue" is the total number of requests which were processed before2 l& V) K- n- I+ u* B6 V
this one in the server queue. It is zero when the request has not gone
( Q) c+ }# p. q6 n8 d$ s through the server queue. It makes it possible to estimate the approximate, e3 g4 l9 K( b
server's response time by dividing the time spent in queue by the number of- N/ z- e" N# n$ i, o: ]& f/ ~
requests in the queue. It is worth noting that if a session experiences a
, B) c5 X" j5 A! [ redispatch and passes through two server queues, their positions will be
7 c) k; h1 W! |$ ? cumulated. A request should not pass through both the server queue and the
4 z0 o1 u: D8 q backend queue unless a redispatch occurs.5 R) V4 k2 b8 k
1 }, h3 X% v2 \" ^; S# l7 m - "backend_queue" is the total number of requests which were processed before
% u# i: U6 f: D. h, N; _ this one in the backend's global queue. It is zero when the request has not3 ^5 c0 ^/ Y! O3 l. e
gone through the global queue. It makes it possible to estimate the average
# q% Y; S; J5 d @9 |. a5 ? queue length, which easily translates into a number of missing servers when
) k$ F+ \) A6 S) R6 J divided by a server's "maxconn" parameter. It is worth noting that if a9 f& s+ v0 J X( `
session experiences a redispatch, it may pass twice in the backend's queue,6 J' B1 h+ ]% }' o
and then both positions will be cumulated. A request should not pass
" Q, {9 d' I; ?& I$ H& c through both the server queue and the backend queue unless a redispatch. `; ~3 w- a1 T$ p
occurs.! [. r1 A8 a% z9 N
# A1 E" P& L5 D& E: ]
: g8 F5 f* w" }/ w x4 G T8.2.3. HTTP log format
1 z$ N/ r: r D----------------------
$ |' K9 x Y- c3 o. r2 B2 K8 f, ^8 v6 m& W3 u8 L& \* e
The HTTP format is the most complete and the best suited for HTTP proxies. It
" W' Y7 F) u9 Z1 ~8 ?' t1 His enabled by when "option httplog" is specified in the frontend. It provides
7 i/ }/ H( v1 w0 |, K0 p( s' Y/ wthe same level of information as the TCP format with additional features which/ l Q, h, d: Q. U4 e' L; r4 z; Q
are specific to the HTTP protocol. Just like the TCP format, the log is usually
( v# d7 {8 P& Oemitted at the end of the session, unless "option logasap" is specified, which5 E- w8 ^. `8 x) C, B) m$ a3 g
generally only makes sense for download sites. A session which matches the
8 J# B) ~) b4 b"monitor" rules will never logged. It is also possible not to log sessions for
; U9 ?5 M# F* \* J* [which no data were sent by the client by specifying "option dontlognull" in the
, E8 }2 U6 D! ?# e: c3 s3 w% m' h' nfrontend. Successful connections will not be logged if "option dontlog-normal"
2 m* }2 q' x: R; h# w. w: j/ {2 Pis specified in the frontend.5 d& \* F6 I5 [! C8 s' K9 f& o$ I0 y
$ }/ ?6 p& l: D$ G' m
Most fields are shared with the TCP log, some being different. A few fields may' S# `8 g' r2 q, S7 G) \
slightly vary depending on some configuration options. Those ones are marked
8 H4 u) N0 Y/ Q6 @. fwith a star ('*') after the field name below.
# `2 X9 X1 E+ z# j
+ t) d; b: c% l) X1 W: p! d" z. H Example :$ O9 Q; d9 n2 D; \: ~4 r
frontend http-in
$ {/ I4 u I/ M( ]# ~7 Y: F0 i mode http
& e/ r5 b' F! V5 C option httplog( q' o+ f) L# G. R8 W* R
log global8 j/ t( s' i9 U( C) H7 X
default_backend bck
& ]* e% s2 W) L: g) i$ c* u
$ m" P" E4 Q1 g1 } backend static
: L) D I. z ?* r* B L& ?. ` server srv1 127.0.0.1:8000
& ?# ]" R! }, S" K1 R4 m/ U D! H8 m" Q! _
>>> Feb 6 12:14:14 localhost \
: ?0 T y9 w/ Z @4 d haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
: `6 c9 P% U0 q N0 m" V. _ static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \
2 u: o- D4 Y& Q. A" G* v x6 R {} "GET /index.html HTTP/1.1"
- }+ Z" Y9 `! b7 ?# V4 {0 Y" V/ f# G2 G/ a' M) T0 J5 I- r: o- ^
Field Format Extract from the example above
) j) d1 ]$ ?5 P1 Q 1 process_name '[' pid ']:' haproxy[14389]:" V/ U4 Q0 x& D4 M/ n4 s( u) A
2 client_ip ':' client_port 10.0.1.2:33317
* z0 \" ]6 h8 u% t8 s0 V- W( g2 t; Y 3 '[' accept_date ']' [06/Feb/2009:12:14:14.655]; _1 K8 l$ z0 ]6 o6 m+ A
4 frontend_name http-in
" j) \4 J* C5 @- ~( ?' O 5 backend_name '/' server_name static/srv13 T. y: H5 W$ c4 ?* c8 {$ T$ T
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt* 10/0/30/69/109
, c& a+ w( w+ q% s 7 status_code 200
. Z; b7 I2 o0 l. l1 }; t 8 bytes_read* 2750
4 v9 q2 z# }2 d+ R( l 9 captured_request_cookie -8 R J( o" R3 R6 i
10 captured_response_cookie -
0 g1 `" B5 h0 i1 S5 R# e5 f- g/ a 11 termination_state ----: |9 b% i1 e2 N% @6 F8 W0 X
12 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 1/1/1/1/0
1 u# M8 ~! E2 \0 l4 X: Z 13 srv_queue '/' backend_queue 0/0
' ~5 n, I: S! D) n9 } 14 '{' captured_request_headers* '}' {haproxy.1wt.eu}
6 |4 o. }$ G: M$ p9 P 15 '{' captured_response_headers* '}' {}
$ F% Q8 ~7 C- d# u" l 16 '"' http_request '"' "GET /index.html HTTP/1.1"
2 p J" ]7 F/ c+ ]& I6 ?8 o2 \6 b% O
! W. |( u2 `0 p$ UDetailed fields description :' t, D, F s: y) x5 v
- "client_ip" is the IP address of the client which initiated the TCP
2 }" X$ K/ K2 t4 y connection to haproxy.
* D/ x! x$ B2 W$ Y+ S
& a* L$ b% G8 s - "client_port" is the TCP port of the client which initiated the connection.
2 {* N; c6 K5 T t) C* D1 v. E
- C4 c8 j6 ^% X0 [6 H7 r7 ~ - "accept_date" is the exact date when the TCP connection was received by4 S2 q' R! Z- @+ i
haproxy (which might be very slightly different from the date observed on
; |# o0 A, c8 p+ k5 c the network if there was some queuing in the system's backlog). This is
9 J& e- N5 ]5 K9 e2 v" F usually the same date which may appear in any upstream firewall's log. This
! ~* Q5 N r2 B; H/ ?% w3 M; c' J does not depend on the fact that the client has sent the request or not.
`, @% o. c: z# \
! ]0 j% j u' q - "frontend_name" is the name of the frontend (or listener) which received
, f& m. N% E4 C and processed the connection.7 Y( d9 d7 n" D1 f' n+ P( @
6 q( G# w9 M" z7 v: }5 i2 ? - "backend_name" is the name of the backend (or listener) which was selected
5 d0 ~4 j* a/ b to manage the connection to the server. This will be the same as the
# b- L+ H, \2 y8 Z* V frontend if no switching rule has been applied.
8 T" q! b5 G, R* C' k" d( Y1 ~' e
/ N) q! [- H# C8 y+ J* ~ - "server_name" is the name of the last server to which the connection was
9 O% v$ A9 ~6 a' x- G3 L n8 F sent, which might differ from the first one if there were connection errors
& }4 Q) J. S9 @( y+ H and a redispatch occurred. Note that this server belongs to the backend
`7 M/ l& ^3 h: W F which processed the request. If the request was aborted before reaching a
# f' p# J7 _! x' X server, "<NOSRV>" is indicated instead of a server name. If the request was5 e' l9 z7 X! i* _2 n
intercepted by the stats subsystem, "<STATS>" is indicated instead.* l3 q( B( a. T R
4 A3 a6 A5 Q1 k( C' @* o* J) _ - "Tq" is the total time in milliseconds spent waiting for the client to send0 }9 l0 o0 U$ Z7 o2 l: H
a full HTTP request, not counting data. It can be "-1" if the connection. J9 I- w) ]& y6 \- v
was aborted before a complete request could be received. It should always- v3 r) Q9 S- B g* w
be very small because a request generally fits in one single packet. Large5 X3 M9 V; q% ~( b
times here generally indicate network trouble between the client and
+ b$ [. Q1 u- D$ j8 V haproxy. See "Timers" below for more details.
; z+ I5 @ ^- J% W
8 ^' f. Q4 T) \7 z* x6 e - "Tw" is the total time in milliseconds spent waiting in the various queues.6 ~4 F8 d3 j; P: q, U! j
It can be "-1" if the connection was aborted before reaching the queue.0 x: P+ Y8 f. e" f& K$ l& d
See "Timers" below for more details.
2 m7 T3 C5 D% m8 I3 o+ F
& C. I, l: [& r - "Tc" is the total time in milliseconds spent waiting for the connection to
, G) G' c- z( e8 C establish to the final server, including retries. It can be "-1" if the
& [( A3 @; g0 s1 c( W& Z8 P5 ?, y request was aborted before a connection could be established. See "Timers"
8 a0 O7 q( h: u/ U" ? below for more details.
& F% x2 J: F/ W/ S \- {4 e1 b
: K" u7 s) {, B1 S4 h1 ` - "Tr" is the total time in milliseconds spent waiting for the server to send
' Y1 g N5 W. U& i5 }6 R, |7 I a full HTTP response, not counting data. It can be "-1" if the request was
! x3 g, y) H0 B/ }8 M w' L% M aborted before a complete response could be received. It generally matches
/ I9 ~/ m7 V4 @- l8 b4 } the server's processing time for the request, though it may be altered by
, I! ^2 h% f# |# K! U the amount of data sent by the client to the server. Large times here on- V$ J1 [& X3 Q
"GET" requests generally indicate an overloaded server. See "Timers" below# M, I5 U. i. q+ S
for more details.4 l0 I* ^8 U0 A
8 ?! G/ P+ v) o" {. H - "Tt" is the total time in milliseconds elapsed between the accept and the8 l$ K$ B3 y2 a1 T% @+ ^! k/ y6 H
last close. It covers all possible processings. There is one exception, if
: X! R$ Q n7 Y s9 A: v "option logasap" was specified, then the time counting stops at the moment
4 L4 c2 b. P9 Y* s" B- n* ^4 K the log is emitted. In this case, a '+' sign is prepended before the value,
. E+ y9 j" s0 L. o6 B) k/ a indicating that the final one will be larger. See "Timers" below for more' l! @6 @9 T9 a0 `. o$ }
details.
' [ \7 N: E* n: `7 w5 h- P, D$ ^! {6 [* M& r+ W
- "status_code" is the HTTP status code returned to the client. This status
' b! K; j b6 f is generally set by the server, but it might also be set by haproxy when+ x2 Z7 T7 J |1 e' O9 c9 c
the server cannot be reached or when its response is blocked by haproxy." G4 I+ M$ c9 h; U1 Y- Y
1 `6 [7 M/ f4 X2 v - "bytes_read" is the total number of bytes transmitted to the client when+ z/ K) e7 f+ ?8 ?9 s. G. R% F5 q
the log is emitted. This does include HTTP headers. If "option logasap" is
9 [/ g* w9 |0 ]. H$ T$ M( s: Y specified, the this value will be prefixed with a '+' sign indicating that# p9 f' ^+ ~4 K3 A. Y9 B' w
the final one may be larger. Please note that this value is a 64-bit7 x1 w0 [: o7 A0 {: \1 v0 n8 x
counter, so log analysis tools must be able to handle it without
7 w: f% M9 d( @0 n5 S1 [) w7 w overflowing.
+ H- ^ h" c/ v7 M, V; g& _5 Q2 c c
: y2 F& `- ]% A: b6 A! { - "captured_request_cookie" is an optional "name=value" entry indicating that
) P1 T6 E; R0 P: _1 `" o2 f4 { the client had this cookie in the request. The cookie name and its maximum
( B, {: \; H) a, S length are defined by the "capture cookie" statement in the frontend
0 r( ^1 H! V, c. m% V configuration. The field is a single dash ('-') when the option is not: a; A3 l t& a+ f3 i7 ?
set. Only one cookie may be captured, it is generally used to track session: R$ `2 Z- {. K9 E+ ]% r1 r ?4 Y
ID exchanges between a client and a server to detect session crossing
* r1 N% J% {3 z0 _ between clients due to application bugs. For more details, please consult
. y2 r) j/ j/ ?& k# _( ^4 M/ l the section "Capturing HTTP headers and cookies" below.3 G) h6 `) `0 ^
2 i5 M: U$ A m. G$ d- M& d: W/ R9 o) H
- "captured_response_cookie" is an optional "name=value" entry indicating$ m$ W' }* d( W/ E2 p
that the server has returned a cookie with its response. The cookie name) O1 i# [, g3 @! r7 ~3 j6 @" R
and its maximum length are defined by the "capture cookie" statement in the8 a6 d% y2 R7 k/ E2 s
frontend configuration. The field is a single dash ('-') when the option is
+ J) o, M2 l8 {' a" B+ T not set. Only one cookie may be captured, it is generally used to track$ |' s, ^7 q$ i2 C$ W, U. f
session ID exchanges between a client and a server to detect session
( `- ]9 X( u3 L1 m; f crossing between clients due to application bugs. For more details, please
0 t6 F6 ]0 U: W& g' M, q8 U consult the section "Capturing HTTP headers and cookies" below.
5 Y0 w" {3 A; J$ Q8 [, ]
5 p; a. Q+ L/ A! G8 r, u* _ - "termination_state" is the condition the session was in when the session
: c; F5 G+ [. Q! P( C- D ended. This indicates the session state, which side caused the end of
$ B6 o' m- j8 F( O/ s session to happen, for what reason (timeout, error, ...), just like in TCP
; `* D. U& A9 d" t9 r8 r logs, and information about persistence operations on cookies in the last1 q* N$ S; W8 l
two characters. The normal flags should begin with "--", indicating the
: N; \% _$ U& F1 E5 }' q9 k u! l7 ^ session was closed by either end with no data remaining in buffers. See8 Y- X4 \+ m d" [* a5 b
below "Session state at disconnection" for more details.2 r/ h6 _9 _/ f* L# t0 A* E$ b
6 W# K6 n+ {. {" l, @! p; w - "actconn" is the total number of concurrent connections on the process when* `4 U* L+ w8 X) J3 C0 ?
the session was logged. It it useful to detect when some per-process system- ?7 K& z, E6 N* Y0 b/ v
limits have been reached. For instance, if actconn is close to 512 or 10246 \2 [2 Q3 U! I+ a( Z% n8 q
when multiple connection errors occur, chances are high that the system
' a+ }9 B N* v) S$ u limits the process to use a maximum of 1024 file descriptors and that all" a' N o' s, T) `( m
of them are used. See section 3 "Global parameters" to find how to tune the
9 B6 z. x% o- Z; p; P9 Q | system.
! E# Y% p3 ~# H3 ? b; p
0 g' f( F- k9 u - "feconn" is the total number of concurrent connections on the frontend when
* P2 |1 ^- F) q: l. r the session was logged. It is useful to estimate the amount of resource, g) j1 h! j+ B( `
required to sustain high loads, and to detect when the frontend's "maxconn"# F$ f& Y ~, L7 \. `) Q4 ^; G
has been reached. Most often when this value increases by huge jumps, it is% K% r/ c% p O! V5 A
because there is congestion on the backend servers, but sometimes it can be' o* U, d, F: W
caused by a denial of service attack.1 O7 C, F8 p/ O6 Z1 i$ f
! b3 r, D4 Z3 _ _, E' V1 u0 ? - "beconn" is the total number of concurrent connections handled by the
2 A$ V" F5 \# l+ U W# z2 D backend when the session was logged. It includes the total number of
/ r7 B7 Q: Y1 Z" e concurrent connections active on servers as well as the number of. a4 R/ C7 e' x3 H' |% A
connections pending in queues. It is useful to estimate the amount of# B5 @0 l2 L* x3 d6 @. L
additional servers needed to support high loads for a given application.
6 ~$ a1 R( n5 I ^& T5 G% s7 M9 x Most often when this value increases by huge jumps, it is because there is
+ J3 {3 k% w; N$ H, x congestion on the backend servers, but sometimes it can be caused by a
, r% n- R c. L" k4 `% v& v denial of service attack.
. z! D' g0 p, u- T! x3 |
0 e, o8 T7 E4 e0 m - "srv_conn" is the total number of concurrent connections still active on; ^: Z# d M3 z2 c: n
the server when the session was logged. It can never exceed the server's
4 m5 T9 G: k* \* M1 X5 v! q7 e1 h configured "maxconn" parameter. If this value is very often close or equal
7 p: H j, j& o' w to the server's "maxconn", it means that traffic regulation is involved a, l% P& B/ b/ M) O4 B" O/ b
lot, meaning that either the server's maxconn value is too low, or that
7 j7 e9 r. Q" t0 B N% j7 v there aren't enough servers to process the load with an optimal response
+ Z4 V& {# r8 }# ?- l time. When only one of the server's "srv_conn" is high, it usually means: m- s, C4 h* ?( o6 }
that this server has some trouble causing the requests to take longer to be4 G0 h) {# }9 B, D4 J3 K- [1 V. N+ i
processed than on other servers.+ J# _9 E2 E) L7 P- D" I' p
; k' G# ?& k v |8 R3 e# o
- "retries" is the number of connection retries experienced by this session- l3 G: P' b! q0 g; u3 E
when trying to connect to the server. It must normally be zero, unless a* D7 i% Y0 l8 N7 e. e8 M
server is being stopped at the same moment the connection was attempted.; W; s9 Y+ X* ^5 d& n
Frequent retries generally indicate either a network problem between
! a" l# H' P. [+ y haproxy and the server, or a misconfigured system backlog on the server4 |$ `$ W8 K3 E, V8 B
preventing new connections from being queued. This field may optionally be
5 o; g7 h0 d2 X5 f; {6 r7 j6 f prefixed with a '+' sign, indicating that the session has experienced a
9 v: e K6 L2 ?6 ?$ ?: X. T redispatch after the maximal retry count has been reached on the initial8 t( s. B w# E* a0 N$ ]/ H
server. In this case, the server name appearing in the log is the one the2 n! V, l# [; m! A9 ^9 T& B
connection was redispatched to, and not the first one, though both may# ~; t( _- a# [: j+ H7 w% C
sometimes be the same in case of hashing for instance. So as a general rule
- w1 F a1 n; h- l: v8 o$ M of thumb, when a '+' is present in front of the retry count, this count
5 A. o1 m! y/ @# m should not be attributed to the logged server.8 d7 F( G' r0 K; `8 G( s; w" m9 W
! z3 ]1 e, W4 _9 W4 U
- "srv_queue" is the total number of requests which were processed before
( ~1 F& p1 {+ K this one in the server queue. It is zero when the request has not gone' J i8 l) P J# T8 A) K
through the server queue. It makes it possible to estimate the approximate
- T& a5 o) C" T) U5 I# D; K8 a1 _ server's response time by dividing the time spent in queue by the number of
( E/ G$ J% F* q" H9 X requests in the queue. It is worth noting that if a session experiences a
& v( U( O. q0 P1 A: @! n! P redispatch and passes through two server queues, their positions will be
8 [- j @4 e9 r& u2 c& b cumulated. A request should not pass through both the server queue and the
, d8 g3 j! `! x5 k! I backend queue unless a redispatch occurs.; u4 X4 U$ M. S
8 Z& n% b+ I, T: L D8 ]
- "backend_queue" is the total number of requests which were processed before
3 u2 f, M- Z# k x* e! y6 B this one in the backend's global queue. It is zero when the request has not
# Y5 x8 w' w; _& S' {+ p1 r gone through the global queue. It makes it possible to estimate the average" V( W' x7 W1 J t6 M6 Y! s
queue length, which easily translates into a number of missing servers when* Y3 L4 o7 T0 j0 i: N- P; Y$ L
divided by a server's "maxconn" parameter. It is worth noting that if a/ U" |$ u3 s2 [! S4 l M& F
session experiences a redispatch, it may pass twice in the backend's queue,0 d7 H; K G1 I w R; O, E1 r. X
and then both positions will be cumulated. A request should not pass) O% J; t; d, A ^5 M
through both the server queue and the backend queue unless a redispatch2 \( ^: |0 i0 b1 m5 L
occurs.
8 U( s- V4 u' m$ S5 T4 Z1 N3 m+ H: F3 N! s9 P- }3 V% A* ^
- "captured_request_headers" is a list of headers captured in the request due+ ?* Q. ]3 Z( @( W0 B
to the presence of the "capture request header" statement in the frontend.% q6 c) l) |8 [1 \7 y0 z
Multiple headers can be captured, they will be delimited by a vertical bar
8 t8 e6 U' K2 g- a. u9 g ('|'). When no capture is enabled, the braces do not appear, causing a
+ A+ l; |: }) }6 V _" T6 N. F shift of remaining fields. It is important to note that this field may
3 z1 i- r5 I) X- c8 X6 } contain spaces, and that using it requires a smarter log parser than when
- b0 t8 ?- @- n( f3 D# Q it's not used. Please consult the section "Capturing HTTP headers and
: S# z' V5 p3 N$ X cookies" below for more details.
0 j8 h- ]& J9 l- o j& v2 o( h: ?% J, a l! Q+ c: k, n
- "captured_response_headers" is a list of headers captured in the response- L' [; d) {: q, t3 ?( V
due to the presence of the "capture response header" statement in the" @/ e! V G- m1 U" R' O1 B
frontend. Multiple headers can be captured, they will be delimited by a7 a7 c/ u7 ~9 N- [2 Z- G' N% g
vertical bar ('|'). When no capture is enabled, the braces do not appear,
( y7 k6 x& s3 H+ [8 ^( y7 A causing a shift of remaining fields. It is important to note that this
2 v3 h+ R1 x- }& n( p9 o1 Z field may contain spaces, and that using it requires a smarter log parser1 q( p& v: S7 I% D( \2 A
than when it's not used. Please consult the section "Capturing HTTP headers- r7 i3 _" k6 g5 K' z; j$ o
and cookies" below for more details.
8 D1 k T, W1 V# p0 D
4 I% A7 w# l; O$ {* I6 H( b - "http_request" is the complete HTTP request line, including the method,
! u; w/ L$ M/ f+ ^4 h# B request and HTTP version string. Non-printable characters are encoded (see
W# M' @' c0 a* Y& N below the section "Non-printable characters"). This is always the last( c/ U3 c+ i, p# `6 S4 Y& j `8 W
field, and it is always delimited by quotes and is the only one which can
6 G1 |- g8 x! L) a contain quotes. If new fields are added to the log format, they will be
% J7 h& N! A/ N4 S' Z added before this field. This field might be truncated if the request is1 \# z8 \& _% M! e
huge and does not fit in the standard syslog buffer (1024 characters). This
' d' o1 b, c8 s: P is the reason why this field must always remain the last one.5 y# Q. b8 G- h, U! k7 ~
8 q& S4 R" O( |
- I% T5 {: d3 J- e' q$ P- q8.3. Advanced logging options5 ~6 S& N! S4 N6 ?; v
-----------------------------
+ u" a( a( V% f" V/ W8 B. ~3 _& j, D& y
Some advanced logging options are often looked for but are not easy to find out
- |. W5 i( M1 K7 Jjust by looking at the various options. Here is an entry point for the few; g' ~& X) g# W g3 S6 \
options which can enable better logging. Please refer to the keywords reference e+ h' S+ V& |8 W% I# T
for more information about their usage.
3 n* s- E6 w$ [# u) g, C6 ?3 K, P7 {# ]9 \# B( @! p
0 b3 N- e: ~1 [6 ~, R% A: O8.3.1. Disabling logging of external tests
+ i; c3 s' W8 |- ?/ I; X------------------------------------------
: v5 t; C9 s$ J4 p+ P7 A% |
8 |4 F! T9 y! t5 _$ q! WIt is quite common to have some monitoring tools perform health checks on7 c' t( O1 m, W( {
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any
: O$ l7 v, `0 l5 K" l1 qcommercial load-balancer, and sometimes it will simply be a more complete
0 T; h% L: D2 o1 xmonitoring system such as Nagios. When the tests are very frequent, users often* e, L+ T6 n' y8 g
ask how to disable logging for those checks. There are three possibilities :
2 F; W- T- V( N3 i: j+ J' a" _* F% p( |% n8 y% U
- if connections come from everywhere and are just TCP probes, it is often5 L4 G: ]& s5 }# @: E: m
desired to simply disable logging of connections without data exchange, by! A" }2 X! }3 M4 L% d
setting "option dontlognull" in the frontend. It also disables logging of: { c- n2 q# J* g% n6 {; X5 t$ T
port scans, which may or may not be desired.5 {+ N7 y2 B6 c6 |/ r* M( j1 R6 i; c
" Q8 V5 b/ D: F; _7 P - if the connection come from a known source network, use "monitor-net" to
; D" z1 l1 j* L: p3 F declare this network as monitoring only. Any host in this network will then
6 k8 R. ~0 }- E0 ~) `$ b$ Y only be able to perform health checks, and their requests will not be6 U1 v" m8 j _0 z7 L
logged. This is generally appropriate to designate a list of equipments
* x- b; `% o) [- @/ K9 Z+ |) x. } such as other load-balancers.
' M3 A8 Q% j- V1 [# v$ C5 |4 j
) n6 G2 Y0 I: P( r - if the tests are performed on a known URI, use "monitor-uri" to declare
) R' X; c9 S9 m' f( { this URI as dedicated to monitoring. Any host sending this request will
- Z5 `& T6 @+ D% o) h" K only get the result of a health-check, and the request will not be logged. ^ d/ b0 ]% F0 g/ a% {
7 b& P ?! K1 E! H, S) ~
2 R: c& z0 X/ @+ h) v/ L1 I6 }1 {
8.3.2. Logging before waiting for the session to terminate
9 C. f/ b7 S8 h2 I+ B3 u----------------------------------------------------------
+ b; V0 ]8 H- T6 o! P+ p# |. n- u4 u" c
The problem with logging at end of connection is that you have no clue about2 k, N1 X0 S8 P# F
what is happening during very long sessions, such as remote terminal sessions
6 o, T/ b9 \1 x7 B# Wor large file downloads. This problem can be worked around by specifying
* _7 z3 l1 u) [/ O/ V& y"option logasap" in the frontend. Haproxy will then log as soon as possible,
, k' R0 k8 E: b: jjust before data transfer begins. This means that in case of TCP, it will still, K4 j1 \3 |: r' p# P! }
log the connection status to the server, and in case of HTTP, it will log just
2 d% A: Y* K) iafter processing the server headers. In this case, the number of bytes reported7 Z8 Y' p* Y/ d
is the number of header bytes sent to the client. In order to avoid confusion# b6 ?1 h3 g8 C' }$ i% t
with normal logs, the total time field and the number of bytes are prefixed9 C6 U! a' N2 k* c; b9 x
with a '+' sign which means that real numbers are certainly larger.
. @; A% F3 a, L! c) T* D' P) x" Y6 h2 [1 ^! S$ D6 c7 { w
3 k" i. K: N. i) ]9 n+ l$ j8.3.3. Raising log level upon errors
# x: X- x3 R! g& N9 `5 g" e2 O------------------------------------
. U. \) O2 a7 l; L
$ B! p0 ^% P4 SSometimes it is more convenient to separate normal traffic from errors logs,
3 O, O4 d/ [+ @% u' Bfor instance in order to ease error monitoring from log files. When the option
. [; P# H# i7 j0 ~" K+ T; ?"log-separate-errors" is used, connections which experience errors, timeouts,6 [- l0 Z: i9 X* C/ M5 c
retries, redispatches or HTTP status codes 5xx will see their syslog level
/ I* ?4 Y8 ]7 A( {raised from "info" to "err". This will help a syslog daemon store the log in$ r! j/ Y/ f+ T, h" J( }
a separate file. It is very important to keep the errors in the normal traffic
; J2 a8 } x! J8 Ffile too, so that log ordering is not altered. You should also be careful if
" U+ i1 k2 a$ Q% pyou already have configured your syslog daemon to store all logs higher than
; {4 C+ I8 n- O8 e"notice" in an "admin" file, because the "err" level is higher than "notice". a: a$ S! V1 r) w9 _2 T! X
8 N3 `( t6 f. w7 p
+ k! T4 L3 O+ p* V8 d$ b# I8.3.4. Disabling logging of successful connections# f! S1 v9 n3 w# Z3 O( Y5 ~
--------------------------------------------------* l6 x( X- C! U1 j1 S
8 E; D' Z$ Y! r) {8 qAlthough this may sound strange at first, some large sites have to deal with
- l. J" z/ M6 G8 |: k! s2 P# Kmultiple thousands of logs per second and are experiencing difficulties keeping
0 h2 O% [9 x& l3 u# [2 N$ |them intact for a long time or detecting errors within them. If the option, s: B0 o: {. W" ~1 H3 h
"dontlog-normal" is set on the frontend, all normal connections will not be
8 B4 {( C! K# k0 A% |logged. In this regard, a normal connection is defined as one without any- O; T( `5 j m% d
error, timeout, retry nor redispatch. In HTTP, the status code is checked too,
5 X" F2 H! E, B) Rand a response with a status 5xx is not considered normal and will be logged
8 m" j- u3 a! e. S' V+ ]too. Of course, doing is is really discouraged as it will remove most of the
+ ]" P2 d9 p' Ruseful information from the logs. Do this only if you have no other
7 a& B) P& {% D9 qalternative.5 Y! L3 p2 e' \: L+ z L# `3 q
" Q& s; Z7 e+ V# t* K2 E3 O2 e" M# N8 I7 h& y) X# V7 A. H
8.4. Timing events1 ?" ^' ]: u; O
------------------* }7 P/ T7 g% t- u
4 N V# L1 S: g: h( z* J! gTimers provide a great help in troubleshooting network problems. All values are
' d& Z; H K+ Z5 Y$ Z7 g$ r8 Areported in milliseconds (ms). These timers should be used in conjunction with
7 d6 k8 P/ k: t9 D2 S1 Mthe session termination flags. In TCP mode with "option tcplog" set on the1 B$ i: }4 }/ ?5 o
frontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP
, q0 T8 i# h% ?' Y0 gmode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :' M& R+ o& ]/ S$ n. }$ G
|$ d- v' V* d/ F: A
- Tq: total time to get the client request (HTTP mode only). It's the time
; D4 X8 h' _3 C9 o; E7 |$ {, v elapsed between the moment the client connection was accepted and the6 _0 E, b' w1 h6 G
moment the proxy received the last HTTP header. The value "-1" indicates: l# Q: i; r. M0 f7 r
that the end of headers (empty line) has never been seen. This happens when9 K, X0 `9 M8 M5 N0 J
the client closes prematurely or times out.% v8 y6 v+ | G1 {( o* }
! B2 j( I' Z9 g. {: Z
- Tw: total time spent in the queues waiting for a connection slot. It4 G( |) h0 n. G1 N0 X0 D
accounts for backend queue as well as the server queues, and depends on the. W# Q; f) u; E% \2 `
queue size, and the time needed for the server to complete previous
/ {4 U9 Y+ Z5 D) W: L6 ] requests. The value "-1" means that the request was killed before reaching' k7 {0 a# U; J" K& v/ E
the queue, which is generally what happens with invalid or denied requests.* q, q O: s6 ], c
/ }0 ~3 \2 r5 T$ J7 N2 l
- Tc: total time to establish the TCP connection to the server. It's the time, v4 \- }' m* k: N
elapsed between the moment the proxy sent the connection request, and the) h4 A0 c* p4 O7 V& N! j+ d) x2 T: R
moment it was acknowledged by the server, or between the TCP SYN packet and( U$ k- A$ N: }3 r, i: {; `
the matching SYN/ACK packet in return. The value "-1" means that the
: J: X$ j6 ~- h3 g connection never established.
* K3 }" q7 H5 B+ A# G( L K1 q' @4 `3 g" R
- Tr: server response time (HTTP mode only). It's the time elapsed between
7 E# o) r6 K3 ^8 \) r1 E$ |, Y the moment the TCP connection was established to the server and the moment! o4 d0 D s( p1 C4 d% r
the server sent its complete response headers. It purely shows its request
: a% a5 E' s6 N5 Z7 a" ~- n processing time, without the network overhead due to the data transmission.! i8 @5 i) j6 E1 {
It is worth noting that when the client has data to send to the server, for+ f. o+ X5 H p% `% {: r* n+ S5 W
instance during a POST request, the time already runs, and this can distort
/ }: U$ r9 u& l( O apparent response time. For this reason, it's generally wise not to trust7 X! r& e) u0 C# O9 t0 G
too much this field for POST requests initiated from clients behind an
; t5 s4 a0 c1 B7 } X untrusted network. A value of "-1" here means that the last the response
0 ?/ B4 [1 e2 R header (empty line) was never seen, most likely because the server timeout G: `" M, X; P; h& @
stroke before the server managed to process the request.
0 J6 v; ~7 Q e+ t
4 ], R) G" h, C Q0 {& R9 N+ h - Tt: total session duration time, between the moment the proxy accepted it
9 @& t. D8 y: O8 X. ], ~- W6 a and the moment both ends were closed. The exception is when the "logasap"
# k! y$ @9 ~1 Y( d; o) N- r option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
3 l! K; T6 t- o prefixed with a '+' sign. From this field, we can deduce "Td", the data5 L# @8 M9 q6 W- l1 |4 g5 {
transmission time, by substracting other timers when valid :
: }5 g2 n; [9 Z; X+ e; U! H- B$ [+ a5 M& x
Td = Tt - (Tq + Tw + Tc + Tr)
6 w: {& w3 B3 @& E8 f- a+ H, O! d8 E
Timers with "-1" values have to be excluded from this equation. In TCP) [' m$ i7 d! @- w$ C8 Z
mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be( ~4 @- U* s1 \7 d% e5 g+ A3 S: L
negative.- b- x* |! \+ ]+ B
4 i# Q! T7 S: V% R' I
These timers provide precious indications on trouble causes. Since the TCP
' ~$ o4 j7 u# M% n7 E* ]protocol defines retransmit delays of 3, 6, 12... seconds, we know for sure
/ K# Q! F+ ]9 s6 t! I1 P/ ithat timers close to multiples of 3s are nearly always related to lost packets0 ?+ j7 J- Q+ |' l9 ~- k4 j
due to network problems (wires, negotiation, congestion). Moreover, if "Tt" is! ]& t8 H% t9 l$ M. N
close to a timeout value specified in the configuration, it often means that a& U- v6 |1 G7 j
session has been aborted on timeout., u1 m1 i1 N p/ v
0 F) ?5 B8 t0 u! X8 ]Most common cases :
& B6 \2 u# `7 K) }; ~- R
% x2 k9 P4 O$ K/ m6 O - If "Tq" is close to 3000, a packet has probably been lost between the; ]" `2 L8 `/ d* B7 S3 m( K+ T1 v( [9 Q* S
client and the proxy. This is very rare on local networks but might happen
. o5 f7 p0 P1 y8 A( V# n' M when clients are on far remote networks and send large requests. It may# t5 {3 N) X% d: M+ i# u5 S
happen that values larger than usual appear here without any network cause.
" k7 r$ ^: v5 E" P Sometimes, during an attack or just after a resource starvation has ended,
7 T, B& k2 Q4 R( J6 F4 m6 l( [3 M5 E haproxy may accept thousands of connections in a few milliseconds. The time
* `8 H' w! K _7 n spent accepting these connections will inevitably slightly delay processing. z* N- @* v8 \# y; ^) B4 ^5 r x
of other connections, and it can happen that request times in the order of
; s* H( m8 I& P3 v3 d a few tens of milliseconds are measured after a few thousands of new1 F: P! d7 H- ~8 J; R
connections have been accepted at once. Setting "option http-server-close"7 N2 L9 @7 |( E) k
may display larger request times since "Tq" also measures the time spent
# D# o/ L' x0 |0 B) ~" l9 J0 p waiting for additional requests.2 i1 B! a+ ?9 L9 K+ D% A. ?
6 r, |( |0 R- F1 g' N1 k- g. v - If "Tc" is close to 3000, a packet has probably been lost between the
: Z- H3 ?4 v% [ server and the proxy during the server connection phase. This value should7 r. p6 \( e; y7 t* _7 H
always be very low, such as 1 ms on local networks and less than a few tens3 X, z- g$ c6 }, A. Z" x
of ms on remote networks.- f8 P" O- K. ?' z+ p
' `- A% g+ g/ D& d5 L
- If "Tr" is nearly always lower than 3000 except some rare values which seem6 e# ?5 k; h8 q, q4 u
to be the average majored by 3000, there are probably some packets lost
) H, P( t; v0 X, h8 N9 N between the proxy and the server.- a. F) T t6 @* j
5 E6 o$ y1 O6 w) J" w* Y& m - If "Tt" is large even for small byte counts, it generally is because& {* H& ^% T% C: ]; M
neither the client nor the server decides to close the connection, for {; X% J4 c- q
instance because both have agreed on a keep-alive connection mode. In order4 j: l+ o: k$ H
to solve this issue, it will be needed to specify "option httpclose" on0 }2 f) ^! F, C, C4 s( \& a' E* w# E/ `
either the frontend or the backend. If the problem persists, it means that8 G4 A5 r2 x$ r* X& M
the server ignores the "close" connection mode and expects the client to! n9 `, j& n/ Z4 }1 u
close. Then it will be required to use "option forceclose". Having the; e( p4 L# a$ V/ A$ P6 D9 r; l2 H
smallest possible 'Tt' is important when connection regulation is used with+ G' y, [. {* Z: u, T( K% ^
the "maxconn" option on the servers, since no new connection will be sent: T, x; [ r+ _0 c+ r( A! A
to the server until another one is released.6 c7 y( `: j7 c" n4 n: K
f* O1 w" Q6 H& G1 u
Other noticeable HTTP log cases ('xx' means any value to be ignored) :8 ?! t2 ?: f" A E& ^" ^0 T4 Z: B
- U" o( i- K! c0 I8 |; M Tq/Tw/Tc/Tr/+Tt The "option logasap" is present on the frontend and the log
* u! o& B- R8 w, }; U$ L was emitted before the data phase. All the timers are valid. B3 }; W! \9 y9 d) N8 P
except "Tt" which is shorter than reality.) d, Y% P$ @ q; H& K1 w. e/ \: n8 u
/ K) b7 t. s) l9 q -1/xx/xx/xx/Tt The client was not able to send a complete request in time2 U, m# D' ]7 |( j# s5 X0 i
or it aborted too early. Check the session termination flags' I) u8 v$ b/ I
then "timeout http-request" and "timeout client" settings.' ~6 X0 U J _' [
1 `- Q( S# e5 [ Tq/-1/xx/xx/Tt It was not possible to process the request, maybe because5 O8 I. U5 p" {3 U
servers were out of order, because the request was invalid" {9 B q5 s9 t, k4 R
or forbidden by ACL rules. Check the session termination
# M7 a% ~) d' r& Y( j flags.2 p3 g) `" o P. h
: T8 J% w7 B& U5 Q( `
Tq/Tw/-1/xx/Tt The connection could not establish on the server. Either it' t3 D( y. P$ |6 Z" \2 ^
actively refused it or it timed out after Tt-(Tq+Tw) ms.
, V) c w) X1 V Check the session termination flags, then check the% i/ L1 z# v4 ?$ n8 R" b4 V5 _7 X7 l
"timeout connect" setting. Note that the tarpit action might
; ~5 x5 M3 @5 C) d5 D. E return similar-looking patterns, with "Tw" equal to the time, W9 J( W% l+ X" Z) E
the client connection was maintained open.) G: Y0 a" b: \+ h; s
9 ]$ P: I) R: v& B7 D5 l
Tq/Tw/Tc/-1/Tt The server has accepted the connection but did not return' f, j6 ?5 b" f& T1 x3 F4 b% N$ n
a complete response in time, or it closed its connexion$ P& M8 k; [. O0 h% V" z1 _. b
unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session
, w% G) G( \1 d+ U' _* n! [2 D6 ~ termination flags, then check the "timeout server" setting.
& g$ j6 ?0 e. W' w6 p O J- @, \0 O. g/ V" L: Q1 ^- F2 k
% m/ z. `* n6 \* A8.5. Session state at disconnection' f, e" A+ R" w: `1 ^# `
-----------------------------------$ y: d4 ]: P0 O h( `- l
3 s ?3 u+ x2 a, R& s
TCP and HTTP logs provide a session termination indicator in the# c; }+ F. c3 R/ g! m
"termination_state" field, just before the number of active connections. It is2 I: l7 Y' n' c* C% I/ H
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,8 E* J+ N. `( u( r
each of which has a special meaning :
5 \( ~ R" b1 Y) Y' d5 m8 a: Q
- On the first character, a code reporting the first event which caused the
" F% N- J! P' u$ c! e session to terminate :
+ ?& _; Q! ? A) y
1 i* @; u- v" F C : the TCP session was unexpectedly aborted by the client.& C5 p! D# f; y. P/ w
$ I7 ? O5 Y& q# G; I- B
S : the TCP session was unexpectedly aborted by the server, or the
3 J( r* V* [7 a: Z9 f server explicitly refused it.
. Q/ `% C! h0 ~6 N6 X( ]! M1 k2 q4 j+ l$ f; e: ]2 G
P : the session was prematurely aborted by the proxy, because of a
( c1 ~1 R4 P1 z; [9 j3 { connection limit enforcement, because a DENY filter was matched,
9 e [# N I+ t4 { because of a security check which detected and blocked a dangerous
1 L |( X2 W. `" v error in server response which might have caused information leak
+ a2 \1 `9 Q- P4 y (eg: cacheable cookie), or because the response was processed by
W8 C+ \ |( A& d: I) }- I3 Z the proxy (redirect, stats, etc...).7 b& H+ E/ [- m' Z8 c/ u* d- j
- ^7 h$ x" c$ o, _
R : a resource on the proxy has been exhausted (memory, sockets, source
0 Y5 s1 K5 b% N! D) P ports, ...). Usually, this appears during the connection phase, and
/ m& r) g( Y. F2 K system logs should contain a copy of the precise error. If this
' K+ _4 s' p" C; N" i6 Q j happens, it must be considered as a very serious anomaly which, d& C. t7 W/ v) b2 S) W
should be fixed as soon as possible by any means.
' A) C ^+ R0 A0 ]; G8 L
d; _$ m5 F4 G" m/ u V* i I : an internal error was identified by the proxy during a self-check.
. y. C+ P, Q& l6 \% W1 R This should NEVER happen, and you are encouraged to report any log
; d& F* y! Y0 [, J containing this, because this would almost certainly be a bug. It7 x0 D% j+ b2 |7 C% |
would be wise to preventively restart the process after such an
) I0 f6 U; I/ I' c event too, in case it would be caused by memory corruption.
y6 C2 R7 E8 g4 n! G' Y! c- s! Q, v0 W" z* E+ O/ r5 `
c : the client-side timeout expired while waiting for the client to
% { m# \' Y* b& d' Y- r/ k send or receive data.% E3 E/ ^4 n; b8 K
. ]9 E/ a {% s4 L. T8 a s : the server-side timeout expired while waiting for the server to
/ @* Y" _# A4 ` send or receive data.4 H! A/ y: j+ G* R
; n$ @; P) m0 m3 j8 R
- : normal session completion, both the client and the server closed
& L [: {+ \8 y( ]4 v$ F. ^6 D with nothing left in the buffers.5 v, e& b1 ?+ h% Q
1 Y+ x7 J. u. g# P' M
- on the second character, the TCP or HTTP session state when it was closed :
3 ` P* k9 C, A8 A6 B0 G3 e) l% X. d$ t( v6 R6 g2 Z! }. L
R : the proxy was waiting for a complete, valid REQUEST from the client
9 ~$ [. F2 ^% ^ (HTTP mode only). Nothing was sent to any server.
4 p, D. y# C7 _% `7 e$ R, b0 Y$ \
/ B+ D# C/ q* k: r8 I Q : the proxy was waiting in the QUEUE for a connection slot. This can
9 y% R4 u3 h ~& n- w+ @* h only happen when servers have a 'maxconn' parameter set. It can6 E! ]; z H, {$ t# ^
also happen in the global queue after a redispatch consecutive to! t) j: z: W1 D+ \. }! R
a failed attempt to connect to a dying server. If no redispatch is
6 T4 ]; b6 ^( W' x' ^( C A reported, then no connection attempt was made to any server.
3 a$ t# O& ~! ?* H; @
- E( ~+ ?4 x4 T- g! P C : the proxy was waiting for the CONNECTION to establish on the
. j* r2 z) s l server. The server might at most have noticed a connection attempt.# h) A5 ` j$ O
1 H2 }+ k: { _/ h* A3 |
H : the proxy was waiting for complete, valid response HEADERS from the
, q R5 n* b& S V server (HTTP only).
5 J+ a( n" \3 N" a$ u+ u6 Y# N% P7 }9 u% U) k
D : the session was in the DATA phase.$ y8 A: E# d4 C( J
) a- h$ L! E, r5 c L : the proxy was still transmitting LAST data to the client while the# B: M+ B, B* ~
server had already finished. This one is very rare as it can only0 F+ Z- u! o( ]
happen when the client dies while receiving the last packets.+ x" S" W6 ?0 t. |& }2 w
4 R6 g' T* d9 L
T : the request was tarpitted. It has been held open with the client- l7 x* y% D+ J4 W8 A
during the whole "timeout tarpit" duration or until the client
6 h4 H! x! M! H closed, both of which will be reported in the "Tw" timer.6 R* ~, X9 W: r( K' a
' R+ o4 b, n1 w5 }* c0 a4 P
- : normal session completion after end of data transfer.
! j0 U2 D1 ~8 L
! J2 m( ^3 S. K: m5 F4 E$ X - the third character tells whether the persistence cookie was provided by) p1 `# u& M' |# R+ e0 f
the client (only in HTTP mode) :9 b- [5 {0 {9 s, x# [
' }% D6 i4 ]7 r( S/ [ N : the client provided NO cookie. This is usually the case for new8 _/ R1 m5 H8 A' u* v
visitors, so counting the number of occurrences of this flag in the
- G# \9 I0 N! F ~ logs generally indicate a valid trend for the site frequentation.1 B+ x0 e6 J: @" o( H
; a2 ^# N* Y* I8 ^/ G: J- h I : the client provided an INVALID cookie matching no known server.& [; Z8 F; I! P H
This might be caused by a recent configuration change, mixed: ~% e! K. T5 q/ ]+ _
cookies between HTTP/HTTPS sites, persistence conditionally- T! g; B" Y6 U( v' B9 B4 w$ p
ignored, or an attack.& u* J( K. E4 e3 d6 f s3 Q- `* o
# F( U- H) w5 I; A3 d' L4 i+ Z D : the client provided a cookie designating a server which was DOWN,9 t) z7 r* E7 M2 ~. p, q5 A7 X/ @: a/ y
so either "option persist" was used and the client was sent to
/ d2 o' ?! c& W, H+ o" c/ w this server, or it was not set and the client was redispatched to
/ y* U$ J% F% N7 B0 w another server.* J- k" `1 b, Z
' r# ^) P4 I$ `
V : the client provided a VALID cookie, and was sent to the associated
( F+ y. ~* k0 d. h server.
) D3 n) N6 j6 i# e5 ^; i. b3 F+ Y3 k$ j3 T" @) Y% H) ~" `
E : the client provided a valid cookie, but with a last date which was
$ Q' i2 {' c/ ?' P7 U9 D6 e% d* j older than what is allowed by the "maxidle" cookie parameter, so
- h, A% o+ q8 |1 \ the cookie is consider EXPIRED and is ignored. The request will be3 {4 [& x0 D( _% D5 D9 Q
redispatched just as if there was no cookie.6 t& }- k4 T. p+ O6 \9 ^5 [ E) j
8 ~' G9 n3 O7 k
O : the client provided a valid cookie, but with a first date which was2 _' Y: g( @. I; y
older than what is allowed by the "maxlife" cookie parameter, so, l3 } S$ \: k5 j3 |, i# U
the cookie is consider too OLD and is ignored. The request will be
; \2 J o" j' L, {" C redispatched just as if there was no cookie.
$ d7 z6 b- t( u$ l" h! c3 _- u: D7 k& g1 y, ~8 c
- : does not apply (no cookie set in configuration).
" k N0 P" V. _2 u! A- y/ q; S, f' }
- the last character reports what operations were performed on the persistence& A* g3 t* v4 @
cookie returned by the server (only in HTTP mode) :
2 U8 T0 B0 v# Y' A6 j- ]" P
! \/ q1 D- m; o6 J N : NO cookie was provided by the server, and none was inserted either.* h0 U5 d: g; I; M/ n+ |" o$ p/ W
( z j' a* k* z) l9 M! e! }
I : no cookie was provided by the server, and the proxy INSERTED one.
5 B7 H G1 m7 W8 i" [! I' B Note that in "cookie insert" mode, if the server provides a cookie,
4 t$ ^7 k W* m- T Y- v- _; b# M it will still be overwritten and reported as "I" here.
1 l9 w( O; ~3 [3 V) m( k) K4 P Z* n* B& z
U : the proxy UPDATED the last date in the cookie that was presented by# B* U" w- Q( u- l1 }1 ^
the client. This can only happen in insert mode with "maxidle". It
! I: z: z0 [2 I happens everytime there is activity at a different date than the/ B' |0 J# c8 J/ v2 ?
date indicated in the cookie. If any other change happens, such as
+ p: C! U* Q, O A" n) N/ v a redispatch, then the cookie will be marked as inserted instead.
( P" Y$ Z: T; ?3 v3 o5 D
3 D2 H* S% K" H: x P : a cookie was PROVIDED by the server and transmitted as-is.6 z* [' f" X8 m; n( w' Q+ a- F
; A$ R+ {4 f: F# q
R : the cookie provided by the server was REWRITTEN by the proxy, which
- w" _ q1 ]% [ happens in "cookie rewrite" or "cookie prefix" modes.% m, q8 z6 d2 x" D& x; k/ b2 W
1 U- h& w& c6 Z$ l/ n
D : the cookie provided by the server was DELETED by the proxy.( y9 t) u' p# b1 V9 b
2 e( \" p5 v! A5 Q( ~
- : does not apply (no cookie set in configuration).1 [; M: T3 \. o+ }; n3 ?$ g
$ E" U' B" z, {) m* @The combination of the two first flags gives a lot of information about what. ?# f9 X4 H: U1 @
was happening when the session terminated, and why it did terminate. It can be0 w6 C3 ^6 X, R0 O& j3 E$ ^3 ?+ M; W
helpful to detect server saturation, network troubles, local system resource
# h. [- Y) d; y/ i5 L" l! }" {starvation, attacks, etc...2 R% ?" k4 v( i0 I6 D [
1 U- u. J' d5 N+ gThe most common termination flags combinations are indicated below. They are$ t+ v! }$ e# f7 h1 ]1 A& v
alphabetically sorted, with the lowercase set just after the upper case for
4 v$ t% k' Y. Q8 [8 i/ ?8 [easier finding and understanding./ Q: Z8 L% N. ^
, w6 y$ q; l' C; w Flags Reason, L$ q# l8 ^7 x# K6 K# u h: P
, J% x! [, M- t' l
-- Normal termination.8 C. X3 d; P9 H
5 ^ f" q( a# |/ d6 F3 [
CC The client aborted before the connection could be established to the& _* O4 k' C9 [. x1 V
server. This can happen when haproxy tries to connect to a recently4 [/ e/ ~) x1 v. ?/ _. Y! y
dead (or unchecked) server, and the client aborts while haproxy is n' w7 b: G# S4 ]3 f
waiting for the server to respond or for "timeout connect" to expire.# F2 i$ |3 M6 E. |
8 y( j- ?0 M' ^: X8 _/ V/ g, N
CD The client unexpectedly aborted during data transfer. This can be$ Y; b5 n0 _8 a0 a: O" `5 d
caused by a browser crash, by an intermediate equipment between the6 N. t3 F/ r- w$ h9 C3 V
client and haproxy which decided to actively break the connection,
0 J/ i; C$ V0 G. i* p3 Z% ~ by network routing issues between the client and haproxy, or by a A2 {7 `; C1 P$ ^4 k1 b
keep-alive session between the server and the client terminated first
# T# _* @+ c" o by the client.
G& D5 t" p6 z3 _" K& \
+ N& G7 a) ^* M* U3 p cD The client did not send nor acknowledge any data for as long as the3 }- a, Q6 ]9 g! n5 ?; |3 c& q" b
"timeout client" delay. This is often caused by network failures on
$ w7 d6 H* B ~% Z) o4 \; D) t7 Q the client side, or the client simply leaving the net uncleanly." I# C1 ~, z$ k* G: u
8 x4 s$ t' n7 i$ [- W CH The client aborted while waiting for the server to start responding.
" h5 L( i K% q: {4 B# f# E It might be the server taking too long to respond or the client
8 c+ {1 a; U; W+ R9 E/ H9 x, { clicking the 'Stop' button too fast.. M+ [) j1 D7 Y A2 C' D
- J- m) x7 b5 f9 d+ h i cH The "timeout client" stroke while waiting for client data during a9 a" ^/ ?2 a" z$ {# |9 c8 K
POST request. This is sometimes caused by too large TCP MSS values
$ X* `# j, i x% G/ O for PPPoE networks which cannot transport full-sized packets. It can
' ~, r8 w9 ?: y, b, s' s } also happen when client timeout is smaller than server timeout and# Z2 T! Y. }, r1 D; Q8 c; U
the server takes too long to respond.
3 Q8 _8 s* } ]. L! t* {& ?+ `( R2 A, F0 q% W/ B! ]! }( n
CQ The client aborted while its session was queued, waiting for a server* v8 j8 E2 A4 c3 m
with enough empty slots to accept it. It might be that either all the' S/ g) y2 O7 z9 z
servers were saturated or that the assigned server was taking too/ U7 a2 u1 Q0 o9 z" [6 l; W9 l8 W. c
long a time to respond.
% L T% J& _1 _& C F, ]) r& r! d0 j. ~# L$ o: F
CR The client aborted before sending a full HTTP request. Most likely
+ P: P# F% V. a/ n$ q the request was typed by hand using a telnet client, and aborted: N3 r* ^& D7 n0 l* k0 b
too early. The HTTP status code is likely a 400 here. Sometimes this/ @* n# l$ Y3 _3 Y/ y1 p8 a- w1 `- W
might also be caused by an IDS killing the connection between haproxy* H1 |3 e; O; M9 P1 x
and the client.
) Q# w! V x- e" Y) r
! H, e/ E7 b& ^4 L cR The "timeout http-request" stroke before the client sent a full HTTP
9 E7 `' R+ f/ w; a6 K request. This is sometimes caused by too large TCP MSS values on the/ @& A5 s8 ]. M9 z, H* h3 h' P
client side for PPPoE networks which cannot transport full-sized' }# `, \9 z4 F. s0 Z
packets, or by clients sending requests by hand and not typing fast; j" R3 M0 ]" D K& P: ^: G, S: u
enough, or forgetting to enter the empty line at the end of the
$ C, s4 {" g( \. Q! \: Y h" d1 P request. The HTTP status code is likely a 408 here.& I8 }/ Q4 T* ?9 l0 V5 ?6 w
* T1 w4 K. U% V1 ` a- }6 W( N
CT The client aborted while its session was tarpitted. It is important to, h$ c8 I- a4 L. C% R9 B, Q2 ]8 |
check if this happens on valid requests, in order to be sure that no! v8 C3 o1 d8 ^" a! {
wrong tarpit rules have been written. If a lot of them happen, it0 a! }1 G, M" s4 K4 X( O2 ^! u
might make sense to lower the "timeout tarpit" value to something
6 \1 S" O2 k$ W6 j9 ` closer to the average reported "Tw" timer, in order not to consume
/ W$ D' p- R: c+ j7 T6 m( W resources for just a few attackers.
; ~/ E8 W: C& _* ?* J) Y3 B$ n7 z% K% E: o; t9 X
SC The server or an equipment between it and haproxy explicitly refused
0 K6 {4 g) j: [( Y% G the TCP connection (the proxy received a TCP RST or an ICMP message
0 S( g. `9 A6 O9 L( v in return). Under some circumstances, it can also be the network, g8 _* g/ X+ v1 o
stack telling the proxy that the server is unreachable (eg: no route,- ?9 z5 ?: V' |" J9 i
or no ARP response on local network). When this happens in HTTP mode,
1 X0 C, V) H! X7 N the status code is likely a 502 or 503 here.
( N1 W- \7 H6 i- a) U% W2 `
4 e @! [. I" r! z& b1 d! U sC The "timeout connect" stroke before a connection to the server could. u1 U' @% ~) _0 s6 E4 f# I
complete. When this happens in HTTP mode, the status code is likely a. P3 q, l9 V3 y- L! m
503 or 504 here.
, ]0 R8 a' Y6 l; D4 V' E2 F* C7 i0 S4 Q9 Y2 O$ p
SD The connection to the server died with an error during the data4 n# W) M/ K e) e t$ {
transfer. This usually means that haproxy has received an RST from3 Q2 K. G$ }0 S+ S6 i
the server or an ICMP message from an intermediate equipment while' G: x/ i3 d4 ]% K, o) p
exchanging data with the server. This can be caused by a server crash) L5 D, l, H: q/ n7 N# P) G
or by a network issue on an intermediate equipment.# u O: A* H2 l' ~$ w% W$ a4 b) s
, d* |9 B+ q6 V' ]) S8 a sD The server did not send nor acknowledge any data for as long as the# w6 V m/ Z* q! v. @% g' u
"timeout server" setting during the data phase. This is often caused3 w& d$ @) }( l
by too short timeouts on L4 equipments before the server (firewalls,
! N, U! }4 o+ R% ^ load-balancers, ...), as well as keep-alive sessions maintained
- Z, d3 Z2 i) [+ a between the client and the server expiring first on haproxy.
. s4 z! J5 o+ @
; m4 y+ R5 M- t SH The server aborted before sending its full HTTP response headers, or( k4 F- j3 x4 X/ N$ e% v
it crashed while processing the request. Since a server aborting at& y" S, T" b* p1 c9 Z! B4 B
this moment is very rare, it would be wise to inspect its logs to; O3 M ~8 w9 w, K
control whether it crashed and why. The logged request may indicate a
; o, M/ r" o( ]+ r* v# N small set of faulty requests, demonstrating bugs in the application.* }4 H2 ~; A/ C1 I8 {
Sometimes this might also be caused by an IDS killing the connection z8 f7 f% P1 u: z8 K, U. \# a
between haproxy and the server.
5 P- p6 P* Q+ x1 G" V) ?
8 q9 x/ B# z* z5 G" ? sH The "timeout server" stroke before the server could return its
' k l+ n4 m9 T' n2 F% d: o response headers. This is the most common anomaly, indicating too
7 p0 D" M+ e% B: h2 u long transactions, probably caused by server or database saturation.: Y. \3 U, X5 K$ B9 y( O; n
The immediate workaround consists in increasing the "timeout server"
* z& E) z, R6 W6 g setting, but it is important to keep in mind that the user experience. Y1 f, r9 v+ e7 J" w; @
will suffer from these long response times. The only long term* I5 R/ v3 Y# ]
solution is to fix the application.' W( E: R+ e5 I% _0 X b5 o$ b3 ?
' e* m( y& N# ]6 x7 y9 `0 Y, j$ ] sQ The session spent too much time in queue and has been expired. See
0 t. G* Q1 A5 `' F ?0 [ the "timeout queue" and "timeout connect" settings to find out how to! g' G+ b) v( Q4 I) S
fix this if it happens too often. If it often happens massively in5 A5 o' ^0 L0 |! z3 l8 f) O
short periods, it may indicate general problems on the affected& c# Z. p$ c: S- y
servers due to I/O or database congestion, or saturation caused by
4 G' X, Y' V! X. ? external attacks./ j' h' V; F" P# {. L6 F2 U
' v: M1 G( F' C
PC The proxy refused to establish a connection to the server because the }0 F# E D& ?/ K" M% q
process' socket limit has been reached while attempting to connect., X" y. S4 l ^: w
The global "maxconn" parameter may be increased in the configuration( e: C) Q' G; b, S9 [2 f, n4 z6 Z
so that it does not happen anymore. This status is very rare and/ F: E% \2 d. V' l1 A
might happen when the global "ulimit-n" parameter is forced by hand.! ]( x# ]/ z3 J& u* ]
: [- [* k. f# F" o% H& k
PD The proxy blocked an incorrectly formatted chunked encoded message in4 i# ]4 J; ]- g- d( t% e Q
a request or a response, after the server has emitted its headers. In3 f9 K' r4 B% r+ r, }& Q
most cases, this will indicate an invalid message from the server to& W6 i$ l$ U& F/ H; h5 q
the client. Haproxy supports chunk sizes of up to 2GB - 1 (21474836472 \% s" O& A- z {. r, L+ I
bytes). Any larger size will be considered as an error.
" _, S1 x# t) z/ F0 s- y* q0 L* n4 _
7 d/ w4 x: Q3 ]6 _4 z PH The proxy blocked the server's response, because it was invalid,
+ ], |. h" g7 r1 L incomplete, dangerous (cache control), or matched a security filter.
/ H1 @$ m: T+ X8 Z: i In any case, an HTTP 502 error is sent to the client. One possible
2 r# z5 f$ M" K+ X+ s/ _8 [ cause for this error is an invalid syntax in an HTTP header name
$ c; k7 ?* m+ ~9 _: w$ u containing unauthorized characters. It is also possible but quite5 R5 D. C5 B# ]0 Q K! c3 c" Q1 b
rare, that the proxy blocked a chunked-encoding request from the
( e: V3 c! @* O/ Y1 y1 h l/ x- F client due to an invalid syntax, before the server responded. In this( h l& c4 O# ^( \/ }0 Z
case, an HTTP 400 error is sent to the client and reported in the" f2 W- ~# _; A) x7 i7 r: j2 O4 M
logs.
' v: k7 U1 a1 S4 g- C
8 q1 F! |, y% }; k/ x PR The proxy blocked the client's HTTP request, either because of an" F6 p9 m: v1 }( Z0 b
invalid HTTP syntax, in which case it returned an HTTP 400 error to
0 ?, Y P" n0 i: q: b the client, or because a deny filter matched, in which case it
& \1 S- t( i# D# F7 \ returned an HTTP 403 error.2 O1 D! E4 y, N$ ^: N
& y2 a3 K! X8 ~* E* V
PT The proxy blocked the client's request and has tarpitted its
* J4 a+ Z! V: c1 }# ? connection before returning it a 500 server error. Nothing was sent
: \; P# d- R+ a' K to the server. The connection was maintained open for as long as
" D8 _, ~! o' e( [ reported by the "Tw" timer field.
1 X/ R: C# x4 T# f
6 p1 ]4 ^7 y9 V1 L9 i7 d, I) L/ [ RC A local resource has been exhausted (memory, sockets, source ports)
1 W. ^9 |5 d0 I0 O( n w5 d) w: @ preventing the connection to the server from establishing. The error
0 ]# G( Y+ s: v! Y2 [2 J9 b* { logs will tell precisely what was missing. This is very rare and can! s: K' O! ^3 v) c0 O S$ w- }
only be solved by proper system tuning.
4 g- O' p+ ?0 J9 `( x: z# a
1 m- M j+ ^* M P1 nThe combination of the two last flags gives a lot of information about how
& Q S! ~9 K; W8 l; H& opersistence was handled by the client, the server and by haproxy. This is very
4 K1 v5 }6 r1 M3 ]& C4 [important to troubleshoot disconnections, when users complain they have to
/ Z5 j% [- w# t" R1 k. l; z: `re-authenticate. The commonly encountered flags are :
4 D0 i, F5 |) X! @, _5 G% G) K: j* o. l7 o7 f; n
-- Persistence cookie is not enabled.6 R7 ?! p* l% z ?
. `: |, v* q9 [5 _9 e0 w* s
NN No cookie was provided by the client, none was inserted in the
2 j2 L0 a N2 m9 y+ n, k! h response. For instance, this can be in insert mode with "postonly"$ X9 P1 K. i* f% p- D; u" M
set on a GET request.. Z* Z# q$ `8 o: {. b6 N4 m
' _: I1 l# d7 P4 q$ v2 F
II A cookie designating an invalid server was provided by the client,
3 m' x4 L, `$ @1 X' @/ { a valid one was inserted in the response. This typically happens when
, V/ E A# \& C3 C- |' T9 h a "server" entry is removed from the configuraton, since its cookie
- `/ [7 e5 T3 L G. c value can be presented by a client when no other server knows it.
0 |9 A) l0 ^! ?& m& ~5 p3 S5 W; {# q: w
NI No cookie was provided by the client, one was inserted in the
% u2 f3 Y/ Q# V6 [+ m$ b response. This typically happens for first requests from every user
0 a* s1 |! z: l& e# x in "insert" mode, which makes it an easy way to count real users., u5 u/ ^! D* K/ \$ [* z" z
! E s: K8 Z- f) [3 T/ q
VN A cookie was provided by the client, none was inserted in the
& `6 @! _ h& U( W" z9 `+ | Y. @ response. This happens for most responses for which the client has! N' }% _8 `& B3 O, _- y
already got a cookie.
M0 R3 L; D H" S) m& L1 v3 ~- s$ f& H2 Y5 F5 Z8 ~
VU A cookie was provided by the client, with a last visit date which is
' d- z" t, }- a; X, ` not completely up-to-date, so an updated cookie was provided in
9 M4 I5 t( Y7 K- b9 j response. This can also happen if there was no date at all, or if I0 {0 y* p. e. J, ?- I. G
there was a date but the "maxidle" parameter was not set, so that the
. g# ^/ P$ p. F cookie can be switched to unlimited time.
1 R y+ n& D' e
+ e+ F* M+ ^7 M0 }) I* d9 [ EI A cookie was provided by the client, with a last visit date which is4 _4 _/ ^- H8 A7 _3 N' p) _
too old for the "maxidle" parameter, so the cookie was ignored and a& b4 [* e+ i& K
new cookie was inserted in the response.
3 R2 _/ p* H Z1 D. |: `% e s8 r* a& B; R
OI A cookie was provided by the client, with a first visit date which is
/ i5 Y6 [7 N+ p/ K4 S too old for the "maxlife" parameter, so the cookie was ignored and a; @# |7 y9 j3 f4 U1 }: c8 W
new cookie was inserted in the response.
6 c% \' @: Q! J5 G! O) P k5 A3 z! z! C
DI The server designated by the cookie was down, a new server was u7 J( Y1 u9 {
selected and a new cookie was emitted in the response.- p, \6 \: l! Y2 p
% k' Y3 J) A3 \$ u& C4 W
VI The server designated by the cookie was not marked dead but could not) M0 T$ X- a' I: ]) ?
be reached. A redispatch happened and selected another one, which was! I0 i# S, r% g3 R
then advertised in the response.
0 a/ u, X& { S, q/ g
( P) Z. `) l w, U' l
& r# g, I% O! h# h, W$ @* K8.6. Non-printable characters+ D1 @, ~5 R: e# {$ \. Z0 [$ ?0 V
-----------------------------# b' l1 S# D* J' A2 p9 J. u0 y
! F. L) U( Y7 J3 f
In order not to cause trouble to log analysis tools or terminals during log
W! C! [' M/ A( ?7 o# v" Pconsulting, non-printable characters are not sent as-is into log files, but are( b6 f0 Z _' d7 _6 d5 i+ b0 p
converted to the two-digits hexadecimal representation of their ASCII code, y7 u4 m( k r
prefixed by the character '#'. The only characters that can be logged without. O, w9 m" o/ [8 @3 U
being escaped are comprised between 32 and 126 (inclusive). Obviously, the0 n' S1 K3 D. O
escape character '#' itself is also encoded to avoid any ambiguity ("#23"). It
! X3 k7 `! n7 f1 E( dis the same for the character '"' which becomes "#22", as well as '{', '|' and y* U; c# r& a
'}' when logging headers.# i/ j0 f' V/ ?, A, |
/ C+ k4 e5 \) i& I' K/ p1 TNote that the space character (' ') is not encoded in headers, which can cause
2 y8 y$ t3 l# e4 ~' @+ Y& _* Cissues for tools relying on space count to locate fields. A typical header: [3 s& x! l; y4 |( r, Z4 E
containing spaces is "User-Agent".
+ H+ Z) F- Z- ?+ b! j8 A" {* p9 K, g) B' L% P; |# c
Last, it has been observed that some syslog daemons such as syslog-ng escape
" Y' Z& L; A& q3 xthe quote ('"') with a backslash ('\'). The reverse operation can safely be& ^/ N* L( _2 \ G# f# y: J
performed since no quote may appear anywhere else in the logs.
3 f" G- i5 T/ D8 G9 f3 A
4 q9 `, k# V. Y4 @- D- t/ Z' h( _, o. m
8.7. Capturing HTTP cookies+ C- L/ M- q7 O% d) x
---------------------------* a* V* q6 H Y: k
+ u! A+ w- }1 T! SCookie capture simplifies the tracking a complete user session. This can be4 j; ]6 b1 A. [+ ?; R" ^2 p
achieved using the "capture cookie" statement in the frontend. Please refer to, B; _8 O0 z6 ?0 A6 W
section 4.2 for more details. Only one cookie can be captured, and the same% D8 l! \/ G! K1 s& N8 Y
cookie will simultaneously be checked in the request ("Cookie:" header) and in, n) W$ Q: y1 ~/ g/ A! C1 x; ?
the response ("Set-Cookie:" header). The respective values will be reported in
" _0 F6 Q4 V2 j# Qthe HTTP logs at the "captured_request_cookie" and "captured_response_cookie"8 I' ~8 e4 _ ^# l( Z5 s" N
locations (see section 8.2.3 about HTTP log format). When either cookie is
; ^1 G: S7 N4 D0 @, \# P8 `not seen, a dash ('-') replaces the value. This way, it's easy to detect when a, w+ T; o8 h5 w) N
user switches to a new session for example, because the server will reassign it
7 e+ b( P3 V d0 ga new cookie. It is also possible to detect if a server unexpectedly sets a
; z% |% s+ U5 i" d3 T, o! l: |wrong cookie to a client, leading to session crossing.
/ _. L6 x. n1 Y3 m0 G) x/ S4 e5 w6 b. W
Examples :8 r5 i* B$ v5 k! [, d$ ^
# capture the first cookie whose name starts with "ASPSESSION"; y2 E/ _( Y; l/ w
capture cookie ASPSESSION len 32
" y, j, Y- f! y `3 ]7 O2 Q
( I" ?, {; ]# R; c2 U2 k3 ] # capture the first cookie whose name is exactly "vgnvisitor": h @ B, L( M+ `+ o, q% R1 N
capture cookie vgnvisitor= len 32
& u+ q) x1 \8 b! `
: P+ N `$ g6 V" I3 p/ T; ^6 S2 z6 }& t- c' K3 s* j% a- b( C
8.8. Capturing HTTP headers
, U3 ?4 z" Z5 c6 D( h& r" Y---------------------------4 j3 p2 f- I0 w. e1 i* z
5 z6 ^* E! _# Q, W! c' `! _& H( E
Header captures are useful to track unique request identifiers set by an upper
+ ^1 X. D+ ]- S6 bproxy, virtual host names, user-agents, POST content-length, referrers, etc. In) K! ]5 X$ |# f! K; d8 _
the response, one can search for information about the response length, how the3 R" t( m1 [# @' r1 x- ]; W) ?
server asked the cache to behave, or an object location during a redirection.
& v5 w2 F6 k3 ]/ K0 p; `0 i, _4 D% s
9 _) h6 a0 A9 m/ x3 S9 r" NHeader captures are performed using the "capture request header" and "capture; O# f1 X, F" M" Z& J
response header" statements in the frontend. Please consult their definition in
( f6 n8 B) K6 @0 m+ Jsection 4.2 for more details.
( n. j' H3 E$ q& }/ r' ?" n+ n0 I# H" X5 [ r( t
It is possible to include both request headers and response headers at the same9 J( o7 L2 {4 e8 H* B/ z
time. Non-existent headers are logged as empty strings, and if one header- g1 ?1 {6 M4 S
appears more than once, only its last occurrence will be logged. Request headers
/ R) H, g4 C7 |! ?" G5 ware grouped within braces '{' and '}' in the same order as they were declared,& O+ Y6 X: e' n4 m
and delimited with a vertical bar '|' without any space. Response headers9 a- x/ o0 }6 ~9 i* Z! M" l
follow the same representation, but are displayed after a space following the1 N- ^2 `9 A5 P
request headers block. These blocks are displayed just before the HTTP request
7 @. v" ]% R: Ein the logs.
7 `: x7 r$ A& C0 P3 r8 @* ]; O/ I4 @$ l m1 V
Example :9 l: G9 }* `- E
# This instance chains to the outgoing proxy3 p2 Y1 T6 G- _! a
listen proxy-out0 k u4 t5 i0 n3 o. z
mode http
1 O; [- p$ w" Y, Z1 ?# f; U) s option httplog
$ T, D0 d( C9 {* ^# b2 ~ option logasap0 `3 J1 I# u ~
log global5 W0 S0 D- V# o! r1 y
server cache1 192.168.1.1:3128/ q3 e! G; b T7 n8 p
$ c! X9 }3 Z4 H6 c t) V, P
# log the name of the virtual server* N, R, Q# |! O4 p4 n, v' s/ o" f: I
capture request header Host len 20- v! m/ Q. x3 w8 T/ I
$ Y4 g5 G9 k+ }' }0 R # log the amount of data uploaded during a POST }" ^1 p% X0 t
capture request header Content-Length len 10. T m: h3 u$ r/ @
, l2 C3 z$ L4 ?" h
# log the beginning of the referrer
; @! [2 Z. B" t' z; d capture request header Referer len 20
. s" m3 k9 Z0 W2 \& H
* [0 N* `; e! `) s0 A& Y( A# W # server name (useful for outgoing proxies only)
2 W4 O$ g# [) P. ?2 `0 X1 i% t capture response header Server len 20
3 x+ B) Z' z# M# X
. g) @/ p+ L$ Q. y # logging the content-length is useful with "option logasap"7 W9 M9 S+ j( s$ O% r. w
capture response header Content-Length len 10/ B2 M$ x Z9 e. D- R7 i
5 V M! G3 J4 D# G
# log the expected cache behaviour on the response
* W. D- [# G( _& K capture response header Cache-Control len 84 H) Z! Z# Q0 p' W, c+ W
& e( E( Y+ J1 {, ^1 V# i' r1 ]7 y6 l # the Via header will report the next proxy's name+ Q4 l$ m2 w2 u/ v% [/ A2 z: M6 L
capture response header Via len 20
* B5 a) a% ` _* s( t: v3 h% G' h. v9 C- m8 G/ s
# log the URL location during a redirection# c4 ]+ Z4 |# ]6 `; {$ U" g
capture response header Location len 20 M8 U3 Q+ O5 U8 `8 u$ [2 H
' `8 v# F4 |/ h+ ^: V5 D >>> Aug 9 20:26:09 localhost \+ Q* w% K0 N* O- ^% L
haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \: ^3 J$ z' m9 l
proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \! f$ _ d" O$ X
{fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \
! d& L1 a. x _, N "GET http://fr.adserver.yahoo.com/", s( d7 {4 \' W: @2 u
7 f Z( Z% q$ R2 V0 ~( {
>>> Aug 9 20:30:46 localhost \# H$ N2 N8 D/ }( ~+ J( r1 ]5 i
haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \2 J4 D+ B9 [7 Z! ]8 d) x! _7 A% e
proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \( _& J& k0 `. q% a
{w.ods.org||} {Formilux/0.1.8|3495|||} \
$ Y/ u! R9 G) c: w, ? "GET http://trafic.1wt.eu/ HTTP/1.1"
; t; g& Y3 S* @! g, M
% F, ^; _; s9 O/ }& |6 X8 g, x7 K >>> Aug 9 20:30:46 localhost \# K+ F; x9 ]3 M z8 c
haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \; v! X7 A4 A3 I6 x$ I
proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \
& m4 h+ e: a d# i, F {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \9 t2 ^! o' R; |3 X- l- H1 r
{Apache|230|||http://www.sytadin.} \0 s4 _" w3 O M' Q3 f
"GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
6 h& m) o% R3 B i
7 P$ j& n3 X) G6 X) ]) v
1 e! `( [! y9 O3 T" P8.9. Examples of logs
4 l! Y% q4 I6 p. |: ~5 I1 D---------------------, T4 S; a; ]6 K2 Z: P" r
) |; s& O" L# E+ }0 j' rThese are real-world examples of logs accompanied with an explanation. Some of
5 D1 h2 j; s& ]& N- a' ithem have been made up by hand. The syslog part has been removed for better0 @- f& j, ?3 e; e/ H ~: N5 k
reading. Their sole purpose is to explain how to decipher them.' i) o& B5 V! G8 A9 Y* N4 ~. u- V4 [
1 o" {5 L" j5 v/ O; \ >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \
1 f f/ f; A2 r* F! V px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \' a" W# I& x0 j* E4 S# |
"HEAD / HTTP/1.0"
6 N/ s4 x0 P; R4 ~: i, ^! n! D" ~4 h3 Z! s. P, H5 O
=> long request (6.5s) entered by hand through 'telnet'. The server replied
; g8 t5 s9 |% p; Y, ^% M in 147 ms, and the session ended normally ('----')
; W3 O7 m s6 ^5 [* }5 x& l" C5 R/ q/ n* E, r' C* ?* _* t6 {
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \
2 ?; M8 j9 x8 V& ~! u2 c- d+ s$ \ px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \) J# X N- o' I2 E, F7 k' A" T
0/9 "HEAD / HTTP/1.0"5 f1 ?2 ]" `0 ?3 C3 x6 \0 ]. G
$ ]- ]0 ^: P8 V! h
=> Idem, but the request was queued in the global queue behind 9 other
; Q- r. r) U. N1 E requests, and waited there for 1230 ms.
- E' |7 O, O) g& P1 O
1 @/ w8 a. `& v6 C+ h( J# a1 K' Q- l( U >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \
2 h* k( K3 a) L6 D& I4 L px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \
( ]6 w3 l. N& H0 H9 B1 F2 J- M1 ] "GET /image.iso HTTP/1.0"2 ]' e" l% x* h! v7 [8 ^0 w
P6 P* I$ V2 V0 y' j9 W* l => request for a long data transfer. The "logasap" option was specified, so
! z5 m9 P' u4 J3 | the log was produced just before transferring data. The server replied in' w% j \1 R8 T {) C4 r6 n7 t& P
14 ms, 243 bytes of headers were sent to the client, and total time from
2 b1 o! p% f) V8 g* A7 A accept to first data byte is 30 ms.
& n# k$ ^: [9 D: v- q4 O6 n/ ]( x6 T8 e+ J- l$ d
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
# ]. ]" k* O' k8 W8 Y px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \
& ~) N/ i0 q) P( g6 n! C "GET /cgi-bin/bug.cgi? HTTP/1.0"
t4 f9 a" l0 @. \
0 s. n3 s- {8 s" f$ ^+ O! v; Q => the proxy blocked a server response either because of an "rspdeny" or
" f( ^& y- }5 Q# k4 T2 |) r/ [ "rspideny" filter, or because the response was improperly formatted and
/ o& j2 z1 P" e/ Q not HTTP-compliant, or because it blocked sensitive information which. H$ N: {: \6 y$ L/ s6 v
risked being cached. In this case, the response is replaced with a "502
# Q. Y# t' b1 L! j+ o bad gateway". The flags ("PH--") tell us that it was haproxy who decided
4 P. H( c" Y9 k- d$ f to return the 502 and not the server.; l. Q0 P4 D/ H! [( g- I9 ]
1 r3 T' c8 _: B
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \" U$ N- L! Z, v- i8 _) x5 v H( T
px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""9 w) `+ r) K! M2 U F
$ O$ g1 B7 M% Z& u. a9 r; K3 _
=> the client never completed its request and aborted itself ("C---") after
, _) S5 C; B+ {1 j 8.5s, while the proxy was waiting for the request headers ("-R--").% z) w2 a% }# x8 Q3 L
Nothing was sent to any server.
" R) D8 [" h( p" @. |: @8 e. ]" X4 G4 @" N9 N$ u# M; f4 \4 g
>>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
3 X: p% k! n# g- g px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""; _1 {1 g# ^5 H* r+ ?8 e3 R7 Y
& e% V2 d9 N; D6 ]6 R4 I/ o => The client never completed its request, which was aborted by the: Y' t) `! s( i# r$ M; p
time-out ("c---") after 50s, while the proxy was waiting for the request
1 q S9 y$ w! S3 H2 E9 k2 r) k$ m/ p headers ("-R--"). Nothing was sent to any server, but the proxy could
5 w6 `; X/ K: G" Y1 K0 J send a 408 return code to the client.
3 F4 d' N( u9 I
& u a' j5 N k6 j( K1 Y: B >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \% c' ?8 n& g3 A& | ~
px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
1 y+ J: p6 d: \+ I# q R9 U
! F. p- O& ?4 |0 l* i0 E, ]4 w/ M => This log was produced with "option tcplog". The client timed out after
* c% l8 o9 C0 E+ h; r8 E 5 seconds ("c----").
) |5 H( [$ F5 ]' d* l0 m$ T1 ~: W" k- e" m) E5 A. {/ V
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \! L5 w x, B+ o; c0 i0 {6 Q
px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \: e+ q: I5 `% ?: f* e+ |' ~
0/0 "HEAD / HTTP/1.0"- B& J4 {; X' N9 A3 l$ }5 V; T
* u0 k# x& a8 Y! B: x& v
=> The request took 3s to complete (probably a network problem), and the
$ b/ i! [ _( X! C* B, D( L- g' p8 z connection to the server failed ('SC--') after 4 attempts of 2 seconds
5 n; e" o9 o/ p+ X (config says 'retries 3'), and no redispatch (otherwise we would have4 N b- h9 W$ M; O1 k) E' c6 c$ I2 ?
seen "/+3"). Status code 503 was returned to the client. There were 1152 K& H1 B, g2 R* e& i
connections on this server, 202 connections on this proxy, and 205 on l3 H' _2 x0 l. {$ s
the global process. It is possible that the server refused the& h, `- R+ s% r6 P3 _0 W1 ~& }
connection because of too many already established.7 |7 ?0 `2 F: ]$ Q/ m- o6 N
5 e$ r& N% t* W$ b5 K
/ E8 n# V- X0 J! F9. Statistics and monitoring
p1 I. `& b( {% C+ ~9 K c----------------------------
% C" K6 @! H& [# ^6 K) r+ E- e) u+ P W) G, E, U3 X* k
It is possible to query HAProxy about its status. The most commonly used
- s* p1 E0 Q+ p3 C) G7 P7 _4 }! x/ R1 }mechanism is the HTTP statistics page. This page also exposes an alternative
5 M9 D' y, B" ]. G. xCSV output format for monitoring tools. The same format is provided on the8 ~0 @3 ~# v( I6 ?* Z! b2 {
Unix socket.
8 P' E0 u- u$ G7 ~
7 J8 v! |0 C2 w9 @% W& I% S* ]# X! |0 {' N
9.1. CSV format
6 d8 G! g% E: D- j& v+ q: O---------------* b9 N, @* I6 o! U! K7 z/ t* O
" I$ j6 r# e* u1 \& ^0 _' f n
The statistics may be consulted either from the unix socket or from the HTTP0 x) b+ c" Z+ z( _) j3 t
page. Both means provide a CSV format whose fields follow.
) |* y' d) A5 v' M7 M2 d2 v2 }. K: D8 z
0. pxname: proxy name
( i( ?( h, s# g 1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name- q/ O2 O. C" C5 T: Q* u) H
for server)! L2 K9 a/ I5 R c, x
2. qcur: current queued requests8 v9 ^( u% A# R* g
3. qmax: max queued requests
" h$ u3 N- x1 |9 J, K2 [8 t 4. scur: current sessions- o8 h# s% j7 h* S
5. smax: max sessions
( v# V" `- }3 N* ^ 6. slim: sessions limit
5 s/ |8 x5 S. O9 E& G 7. stot: total sessions9 J- w- q: k! N) `+ r, P
8. bin: bytes in2 w) C `3 L# o1 P, a* A Q5 k, [( }
9. bout: bytes out; c5 y" H2 U) Z! j
10. dreq: denied requests0 g: ^7 U- ]) `* j) F: O$ A6 [
11. dresp: denied responses
/ f* A; \: e# r8 c I+ p# C6 y" x* ^ 12. ereq: request errors
0 Q7 N" j+ X5 d; q) i 13. econ: connection errors
( y8 q- d8 E- n. n 14. eresp: response errors (among which srv_abrt)
- i! k i3 D. W/ G 15. wretr: retries (warning)
& S5 x+ f$ B& { 16. wredis: redispatches (warning)4 w. S/ w ]( w) E/ g+ V
17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)5 G* F/ w8 ^7 m! C
18. weight: server weight (server), total weight (backend): ~* o' B! w6 s: M
19. act: server is active (server), number of active servers (backend)7 u9 ?" r( A( S& ]- O) C& Y
20. bck: server is backup (server), number of backup servers (backend)
: X& a, W6 G4 e m1 R [ 21. chkfail: number of failed checks
9 ~+ R% p" k3 j: Y" H 22. chkdown: number of UP->DOWN transitions
. {* o7 x. C/ K 23. lastchg: last status change (in seconds). }; ]- ?5 L* n' F
24. downtime: total downtime (in seconds) g, _, k0 I" u3 f9 z" u9 ?+ n
25. qlimit: queue limit
8 G2 [7 k7 ~ C8 d. \$ }! d 26. pid: process id (0 for first instance, 1 for second, ...)" D; o! y4 L8 k5 ~+ G( p
27. iid: unique proxy id
6 x7 `; H' s1 w- M$ ?) r0 V* D 28. sid: service id (unique inside a proxy)
3 e0 f# D3 S" P+ A1 U- B$ z 29. throttle: warm up status
4 N% [% x0 e1 p: S1 V1 r1 H# k! v M# ` 30. lbtot: total number of times a server was selected" s* n3 \7 A: a& s- B. |
31. tracked: id of proxy/server if tracking is enabled
$ L2 w0 s- N( L- M4 J( r+ ]' h 32. type (0=frontend, 1=backend, 2=server, 3=socket)
5 K& e1 D. p! }; ?2 k2 V 33. rate: number of sessions per second over last elapsed second
# n: E1 I" |4 ?6 e: I" f( ? 34. rate_lim: limit on new sessions per second
" Z5 C4 b# w, o# E3 X/ ~ 35. rate_max: max number of new sessions per second2 Y' x, ^* e- t$ l% C- [, U$ F7 v
36. check_status: status of last health check, one of:
$ o" B- P9 U+ [, X UNK -> unknown* G H; \; u/ M+ F
INI -> initializing5 m( T- W- n ~# H9 H& ^
SOCKERR -> socket error0 u+ }$ J0 t7 b& P- h- t- H
L4OK -> check passed on layer 4, no upper layers testing enabled A9 ]& h. i) k2 w
L4TOUT -> layer 1-4 timeout
: Y5 H& N) `" [+ T+ r, k! b9 _ L4CON -> layer 1-4 connection problem, for example y2 t) e; `5 O- y
"Connection refused" (tcp rst) or "No route to host" (icmp)0 ^' ~- y9 t) }0 c5 a v5 C
L6OK -> check passed on layer 64 j0 G4 u' `: U
L6TOUT -> layer 6 (SSL) timeout, b( g/ d. ~$ v! l3 r
L6RSP -> layer 6 invalid response - protocol error
- [, Q& F5 t) `2 x% `; D$ H L7OK -> check passed on layer 7% n" N# P' L% ^5 {5 N4 g
L7OKC -> check conditionally passed on layer 7, for example 404 with
( p3 ?" g4 Z, f disable-on-404) i t) ?0 m$ ?: z# s* K
L7TOUT -> layer 7 (HTTP/SMTP) timeout: q8 g- T: v9 }/ V% R) n1 M' L f
L7RSP -> layer 7 invalid response - protocol error
$ p {6 Q& }7 o3 g& n L7STS -> layer 7 response error, for example HTTP 5xx
. L( G' V- e' p _4 c9 X 37. check_code: layer5-7 code, if available
8 F% K/ Y1 V, H3 ^0 o 38. check_duration: time in ms took to finish last health check4 D* P; B( k/ }# h" k4 d ], L
39. hrsp_1xx: http responses with 1xx code; T; \. Y) F ~! p* y
40. hrsp_2xx: http responses with 2xx code
: N- c2 D, l: V5 E x1 B 41. hrsp_3xx: http responses with 3xx code& ]7 V) w/ q& _# G5 t' c& K( x
42. hrsp_4xx: http responses with 4xx code% B* t3 t: } I8 a: }
43. hrsp_5xx: http responses with 5xx code7 S: c. h1 Y$ R
44. hrsp_other: http responses with other codes (protocol error)& s$ X) G/ A9 U9 [( h9 g0 S
45. hanafail: failed health checks details- A6 w) r I9 N; ^" e, c. r
46. req_rate: HTTP requests per second over last elapsed second, r* B& E' u( D9 u* m7 G, a
47. req_rate_max: max number of HTTP requests per second observed
2 \' z7 z: u- j+ C0 g& N' q1 `* R 48. req_tot: total number of HTTP requests received
9 _3 @# A1 {( n% l5 r/ V* e7 t 49. cli_abrt: number of data transfers aborted by the client5 [, V; B' u5 D" X4 L/ i
50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)" r' U: \7 g) z7 R5 ^" T
$ n: g$ B, d; ?2 H/ X& e* z6 n, w! ~. `4 {2 i5 k! `
9.2. Unix Socket commands" M0 d2 M! f. B6 @' \
-------------------------0 M. l1 i: v0 B$ U7 U# U3 D
1 g& X7 m' t8 M& [' n
The following commands are supported on the UNIX stats socket ; all of them
4 b8 N4 G0 `; L' F5 D* ?- gmust be terminated by a line feed. The socket supports pipelining, so that it, A% |& J6 i' V$ @
is possible to chain multiple commands at once provided they are delimited by6 g9 `; j8 ?# W- v2 ~3 Q; I
a semi-colon or a line feed, although the former is more reliable as it has no0 u; ?$ B0 v9 i& k- g3 {
risk of being truncated over the network. The responses themselves will each be
0 F: a2 Y* ?4 P1 i+ f* i9 }followed by an empty line, so it will be easy for an external script to match a
9 ~; c$ e- Z ?6 B) Ggiven response with a given request. By default one command line is processed7 Z4 S! G* L+ z9 s
then the connection closes, but there is an interactive allowing multiple lines
; ? q' A6 C4 h* R lto be issued one at a time.
6 A, F# |2 R9 z' x3 J
- \" W% S" @4 kIt is important to understand that when multiple haproxy processes are started
( c4 ?. W# u6 J; T8 s! a: ?on the same sockets, any process may pick up the request and will output its
' K* v2 h7 m; S( d; f1 u4 \own stats.1 j$ V: n1 S a L, n- c, {
2 e W( G* V% F& b' R- M" gclear counters
P- Q, M) z7 ^& H3 i7 b Clear the max values of the statistics counters in each proxy (frontend &
9 C' `4 G0 [9 d0 p( ^3 k# h backend) and in each server. The cumulated counters are not affected. This- J7 w- a' t( O, R9 s* a. L
can be used to get clean counters after an incident, without having to# g9 k) h/ D, U/ q: B7 I
restart nor to clear traffic counters. This command is restricted and can) H0 Z" {: o5 S) W1 b7 w# [. @: L
only be issued on sockets configured for levels "operator" or "admin".7 Q5 w% t0 h) S
$ Q' B8 ]" B0 Q+ w* g+ ]' I/ R2 w
clear counters all
7 G' R; I: G! x$ N6 }& Y/ ] Clear all statistics counters in each proxy (frontend & backend) and in each: K2 l3 R: o% [, s9 F. I( t
server. This has the same effect as restarting. This command is restricted
- {, q) o0 q S5 N. o. o and can only be issued on sockets configured for level "admin".
6 {/ i0 C7 C: Z2 D9 ?0 ^0 U9 X. F
, j" ]) i v9 y0 {* Udisable server <backend>/<server>
: B8 ]( ], O4 A; M( i, b' h Mark the server DOWN for maintenance. In this mode, no more checks will be7 [0 r, s2 Y. p$ f0 m0 F9 j
performed on the server until it leaves maintenance.
' c. Q/ A" b5 Y! E3 G If the server is tracked by other servers, those servers will be set to DOWN9 `1 w/ I# \8 i/ D( b4 h: e% d- L( R
during the maintenance.
- w0 A9 a1 s7 ?. F9 [5 B* d( d/ B2 _- j/ h
In the statistics page, a server DOWN for maintenance will appear with a1 ~" K3 b7 }9 {2 m! S4 M# [1 p0 _( O
"MAINT" status, its tracking servers with the "MAINT(via)" one.
4 \) q! w3 U. y7 J! k2 i" m. {# J6 j
Both the backend and the server may be specified either by their name or by
2 ^. Q3 J3 \( n! g0 P their numeric ID, prefixed with a sharp ('#').
& w9 P& x9 N# K4 w# t7 |1 E. N* y8 R6 n5 z! B$ P- L) O
This command is restricted and can only be issued on sockets configured for
# {0 V4 S& w& p P0 v0 I- n, U7 Z5 W level "admin".
4 Y3 Q: s; R" B9 W3 [
( B( ~3 f3 [3 O" s* c) B' |8 A7 Oenable server <backend>/<server>
U* i: @% \2 p/ S) J5 l" j6 p If the server was previously marked as DOWN for maintenance, this marks the
; Q: \ b1 N2 J6 x server UP and checks are re-enabled., F" \5 i( r, Y$ j
8 }3 l/ R) @, ~9 @3 k
Both the backend and the server may be specified either by their name or by5 o* M0 {( h/ |8 l3 N% Q
their numeric ID, prefixed with a sharp ('#').
& ~3 }4 q |, a* e* P
- H5 R A4 p( }# k9 f This command is restricted and can only be issued on sockets configured for m5 Z2 ^: M8 r; O; n* [$ I2 u( n
level "admin".
7 j% [: h& @) _( Z
- N- a* H& I7 j* o. e" x# ^) Kget weight <backend>/<server>- E4 \. _" {$ N, ?, X
Report the current weight and the initial weight of server <server> in
* j0 S, {# H! F7 u/ q8 S: ` backend <backend> or an error if either doesn't exist. The initial weight is8 C' y2 a( c _4 p
the one that appears in the configuration file. Both are normally equal* O$ r- P# i! @+ Y
unless the current weight has been changed. Both the backend and the server/ T, a6 W* Y5 V" E& ~- j; [$ x
may be specified either by their name or by their numeric ID, prefixed with a8 J# Z% W) t7 }- J
sharp ('#').9 O. P7 }+ K& i( l0 T: ]6 U* I" n
) h& f0 D+ \& H' b( E+ k0 xhelp
* K5 t( v: ^6 h4 F Print the list of known keywords and their basic usage. The same help screen
% J% D4 N- @1 `$ t is also displayed for unknown commands.9 I& C8 E' P, t# s1 A
+ H0 J/ c5 q2 D& n. F* pprompt0 i, I: f* `$ p( c! Z$ I
Toggle the prompt at the beginning of the line and enter or leave interactive: p, o A7 p& u) I0 U
mode. In interactive mode, the connection is not closed after a command
" S! T% A2 n9 C2 Z& T completes. Instead, the prompt will appear again, indicating the user that% `6 ~% ?( }; a& ]' b, N8 b
the interpreter is waiting for a new command. The prompt consists in a right
, y" C3 ~( g+ L1 f4 ~ k" O+ {2 _) e0 \2 d angle bracket followed by a space "> ". This mode is particularly convenient2 g+ l, s/ W6 j* d9 T
when one wants to periodically check information such as stats or errors.: T8 j, W+ W3 _
It is also a good idea to enter interactive mode before issuing a "help"
5 D0 a7 O0 o# C& A& @) B5 M0 _ command.
7 d1 I, Q" G6 v1 ~! i5 B2 f( ?4 ]
quit8 \5 M, J( @9 S
Close the connection when in interactive mode.
4 [' V. ~6 d; @# f3 p' _' n( y9 _
9 ~. s" W z+ Q4 |) d" U* Bset timeout cli <delay>" V. a( P4 e* ?* h& R
Change the CLI interface timeout for current connection. This can be useful3 C( t4 t5 g9 }0 I! k
during long debugging sessions where the user needs to constantly inspect, F# r/ E) j( g* X/ x
some indicators without being disconnected. The delay is passed in seconds./ h( X e8 V/ o" c) j
( Z* ^( M+ y* E: Q! z m
set weight <backend>/<server> <weight>[%]0 X& ~: w/ L# ~* I
Change a server's weight to the value passed in argument. If the value ends
6 ?$ u: |6 }$ Z0 f0 z with the '%' sign, then the new weight will be relative to the initially
, \0 i1 {& f$ ]8 c, ]: Y configured weight. Relative weights are only permitted between 0 and 100%,: x, B: ?9 z0 q% ~
and absolute weights are permitted between 0 and 256. Servers which are part4 q* O5 F* e7 o1 n v/ H
of a farm running a static load-balancing algorithm have stricter limitations
& Z% o! g- u5 l+ v* B# C because the weight cannot change once set. Thus for these servers, the only( R7 |' P" h) `3 ]4 H6 q C, S
accepted values are 0 and 100% (or 0 and the initial weight). Changes take
- w; O# L% E- K; W effect immediately, though certain LB algorithms require a certain amount of! v! Q! W, O' \5 X
requests to consider changes. A typical usage of this command is to disable7 \( \. w9 j1 O4 @" c' ^
a server during an update by setting its weight to zero, then to enable it0 y5 `9 V* Z- [) u. A" N
again after the update by setting it back to 100%. This command is restricted6 [8 S0 D& l1 m# a7 n1 A9 n
and can only be issued on sockets configured for level "admin". Both the6 Q6 y& {" f* O1 M$ e `1 E
backend and the server may be specified either by their name or by their9 p1 A3 ?. C4 E2 {
numeric ID, prefixed with a sharp ('#').4 w! C& |7 D4 C3 ?6 }! d1 @
' Y& z% x" ]$ {show errors [<iid>]9 K) z" e8 F7 Z1 x/ X
Dump last known request and response errors collected by frontends and
7 K8 k, T4 J) o backends. If <iid> is specified, the limit the dump to errors concerning
2 H5 Z N$ j0 F( S4 Q4 ?0 B$ l L either frontend or backend whose ID is <iid>. This command is restricted
3 W# l& I& T9 n4 X6 w) y and can only be issued on sockets configured for levels "operator" or
3 L5 \( g( f( N "admin".
! |8 P7 F$ H$ e# ]; _
$ v8 h% b- {2 D% } The errors which may be collected are the last request and response errors: u! l) k. ?3 Y0 j: D! p; H
caused by protocol violations, often due to invalid characters in header
8 A8 y( u- B: x( o names. The report precisely indicates what exact character violated the
/ R( I* {, \. ], C' z/ p protocol. Other important information such as the exact date the error was
4 ^* D0 t0 p. Q( T detected, frontend and backend names, the server name (when known), the# J z( Q* `# H8 z% k) u
internal session ID and the source address which has initiated the session& w$ s$ o% |2 O
are reported too.
( U* D8 } D& P: P p; b4 V4 P3 N; h, W. O
All characters are returned, and non-printable characters are encoded. The
8 N: b' E2 b& P+ Z; r1 ?) e% S5 C most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one
) j( V& Y$ j% g0 _7 \1 f letter following a backslash. The backslash itself is encoded as '\\' to+ N X8 Z J; \1 r+ `# h* Q
avoid confusion. Other non-printable characters are encoded '\xNN' where
I1 u u& v4 y' u# a9 U; p NN is the two-digits hexadecimal representation of the character's ASCII6 N* Y x7 q$ _7 A; A
code.: J" G! [# }6 H3 ?) ^/ E8 ~1 w+ \
- M* P- D5 f2 m6 w9 Q Lines are prefixed with the position of their first character, starting at 0/ ^8 g r6 M, y, ^3 k5 t9 o
for the beginning of the buffer. At most one input line is printed per line,
6 _( l+ C$ T: Z and large lines will be broken into multiple consecutive output lines so that: T! l M: f/ C
the output never goes beyond 79 characters wide. It is easy to detect if a% M( K# b6 k+ i7 s
line was broken, because it will not end with '\n' and the next line's offset4 Y& b$ U7 Y" q
will be followed by a '+' sign, indicating it is a continuation of previous4 K. N" K Z& h5 J
line.+ Z) N8 j$ W" F# T" e) P: J
4 k* f" W: U$ ^ o1 m- S0 @! A Example :2 i- }& J( g/ x
>>> $ echo "show errors" | socat stdio /tmp/sock1
+ ^- d! b& ~, ?% ?+ [5 s [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response
6 w. }( k8 y/ H! \: k src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)+ f2 A0 u/ p! ?
response length 213 bytes, error at position 23:
7 B4 Y1 T& A$ R; G( ? s0 P0 i* w; }/ ]5 f9 z1 V
00000 HTTP/1.0 200 OK\r\n
& ^) h3 {1 r$ M3 @+ P 00017 header/bizarre:blah\r\n
* S- S* {4 a4 }* T! i9 y3 l" B3 C 00038 Location: blah\r\n
* a# s n& q& [/ G 00054 Long-line: this is a very long line which should b* t1 w" H& I) N. \8 n8 i$ S8 D# b
00104+ e broken into multiple lines on the output buffer,3 j: v$ @5 h4 o4 L( h. u+ M( f
00154+ otherwise it would be too large to print in a ter; [7 q9 G* K+ I; M+ z" Y" [
00204+ minal\r\n. e* I1 U" c- v# V# R% j- x$ ~0 E
00211 \r\n" L: {0 d7 P; X6 j* f# v
7 L5 U, p7 j$ V In the example above, we see that the backend "http-in" which has internal: i9 o+ c1 |+ I; i4 L
ID 2 has blocked an invalid response from its server s2 which has internal- g; b) L& T9 \* p
ID 1. The request was on session 54 initiated by source 127.0.0.1 and+ g i4 e- M4 n' t- h4 Y
received by frontend fe-eth0 whose ID is 1. The total response length was
6 d# o0 b# r0 u, e/ m. x 213 bytes when the error was detected, and the error was at byte 23. This- \. u* J7 W% H; G
is the slash ('/') in header name "header/bizarre", which is not a valid h0 O5 Z# x. c
HTTP character for a header name.% \8 H- z3 B$ e& h8 d4 ]
4 f( L( w) ^& e8 `$ sshow info" v6 r5 i( T: Y$ [8 K
Dump info about haproxy status on current process.. L# d; Q" M! D j8 m) F
& S r% {1 S' U9 Lshow sess
, K; e2 n9 P% e4 W2 L! \ Dump all known sessions. Avoid doing this on slow connections as this can' s* E+ T3 J( ?# S" ^/ {
be huge. This command is restricted and can only be issued on sockets7 ]+ d2 e6 s0 F; ^& s
configured for levels "operator" or "admin".7 v% F4 o% h' ~: j* \2 S9 q
% _% P9 ]. E4 O( Q% l3 Z
show sess <id>/ |% ^& u0 i$ f" r7 T5 P1 @2 r
Display a lot of internal information about the specified session identifier.& ^! C: e1 W, e0 r8 E5 `% k" S
This identifier is the first field at the beginning of the lines in the dumps* o6 z1 \5 P t+ U* Y
of "show sess" (it corresponds to the session pointer). Those information are) }2 z6 r7 W" v: o; _
useless to most users but may be used by haproxy developers to troubleshoot a2 E8 ~. Z0 _4 N6 M* D
complex bug. The output format is intentionally not documented so that it can, e9 N$ Q5 J7 n
freely evolve depending on demands.
- P W1 R7 `. J# ` r" ?$ i) U4 o1 Q3 n3 x+ _0 _
show stat [<iid> <type> <sid>]
' |8 Q& t- o( v7 Y% Y3 C+ r* Q+ x Z Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
a; O0 ~1 q- p! D$ c possible to dump only selected items :
. [2 U0 F1 O- a7 Q - <iid> is a proxy ID, -1 to dump everything. W8 E8 O. \2 x; W( u
- <type> selects the type of dumpable objects : 1 for frontends, 2 for* z" ^# f* X7 o' t7 w
backends, 4 for servers, -1 for everything. These values can be ORed,
9 o+ ?( a; m; x- U( l. K T for example:/ S1 S. p' h% Y, R9 y
1 + 2 = 3 -> frontend + backend.
* Y; T+ t& l# t7 `+ o' D 1 + 2 + 4 = 7 -> frontend + backend + server.
& Q* d! f- t) u* S) ?' a - <sid> is a server ID, -1 to dump everything from the selected proxy.
0 w3 d+ w% N5 t3 _' `9 w [2 c' X$ m, t3 S5 ~/ l: n
Example :
8 H1 [/ F" _1 C8 @* g/ ` >>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock1, a2 H/ p) P9 r# s; ]- w3 I3 Q
Name: HAProxy B2 f5 ` @! k" T; H% t* Z
Version: 1.4-dev2-49/ w4 C7 l) t: O
Release_date: 2009/09/23
# {" B( \4 a& P p Nbproc: 1
; P' @0 A, K4 Q# E/ j2 c Process_num: 1
$ }; {8 D$ `5 Q0 i' d6 O2 K( P (...). S* s. }% f; j" W. k+ }& _
$ c$ ?5 T4 L3 \6 T e! D
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq, (...)! o9 R4 R$ k$ g4 P" R
stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
: m9 n8 J% f8 @+ g7 @+ g1 A stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...). I8 n) o& q, t9 q+ K- }# {& X
(...)
" A/ n; N* f9 ` www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)
/ n2 c- p( Y! Q, N+ Y3 w/ i# l! g3 ~% V3 ?8 l
$' d+ I- I- f: P( v, I
/ @) Z3 f( l% Z2 q& V9 c A2 \ Here, two commands have been issued at once. That way it's easy to find
9 ~! z% ` M! e6 F which process the stats apply to in multi-process mode. Notice the empty/ b; b4 h4 n. k. x
line after the information output which marks the end of the first block.
1 k; O. s* t0 y- |" b! m0 } A similar empty line appears at the end of the second block (stats) so that
8 t$ m0 \# }7 w7 i# f. B the reader knows the output has not been truncated.) n. E' L' b% x9 L( u" V
8 a, F$ b8 U2 I/ l8 r% X
b, j. N- l9 c1 F) J5 |/*
) b5 \8 u) ^# d; Y) m } * Local variables:
5 p% f }9 E8 C5 C# g6 V * fill-column: 79' ~' @( s& O5 S* h
* End:( }! C( G9 M: U( J6 C& q9 ]5 h
*/7 J! E$ q7 S# s# u1 @
1 d3 h/ @6 o/ a. h9 Q
& p$ ^4 `% ~% k |
|