|
|
----------------------
- D `! X. V% l* F1 Y5 _ HAProxy
$ r/ ?& v9 p0 M2 S* Q! H$ D Configuration Manual
! g! N4 J' O4 }! Q' u) U. @ ----------------------
$ i9 U( q0 g7 E+ f+ l) k' D; {; e2 c# o version 1.4.273 O6 |' Q' h" M( ^
willy tarreau
" u$ z6 C! i+ m+ u6 V: X 2016/03/13
- ?9 {& R0 N4 x5 e2 \
& m. P) m7 c& b$ v4 L/ X' S1 e
4 E- a' V* I8 M* }( y/ d/ L G2 RThis document covers the configuration language as implemented in the version+ ]; P1 r' }, M+ b0 k2 w% ^
specified above. It does not provide any hint, example or advice. For such
+ F3 T, ^3 q7 l% r8 kdocumentation, please refer to the Reference Manual or the Architecture Manual.+ O2 E! ?2 Z9 M, l" q, [9 i) a. [ ]( Q
The summary below is meant to help you search sections by name and navigate3 e# M1 U/ Y" m* ~4 R5 v% p
through the document., |2 c0 {( O$ E1 l
/ o; M8 B: @) x# O# r/ P
Note to documentation contributors :% t4 x; P! c1 F9 E
This document is formated with 80 columns per line, with even number of
5 j0 N5 M# F' b1 a' S spaces for indentation and without tabs. Please follow these rules strictly& @1 }5 } G |8 j, x3 a( Q0 d v/ ?3 o
so that it remains easily printable everywhere. If a line needs to be
+ S2 \! B0 ^ C; Q: o printed verbatim and does not fit, please end each line with a backslash
/ U" i% j! P1 l" _( X) p ('\') and continue on next line. If you add sections, please update the, ^& I2 c2 j8 {
summary below for easier searching.
% b8 j8 B w1 |4 k
l- Q- e- S& W0 `. G7 @" @
: h' F) I" r# W5 @1 \# LSummary
0 ?0 V) G4 {- |' N. B! E, c-------. q' t" q2 o) Z4 |+ D
- K! K* S- _, A. y. @' C
1. Quick reminder about HTTP" ^) W# A2 e+ T4 t
1.1. The HTTP transaction model5 X2 [* [1 k! t4 a9 t* w n
1.2. HTTP request
- H6 V# A: ]; o2 W9 u1.2.1. The Request line
. |) c' L0 ~( D) Y1.2.2. The request headers
- u) f, g7 A& I' a1.3. HTTP response# {# g' f4 q9 d }
1.3.1. The Response line
4 ?; Y- u0 {) W$ Q) C* v0 f* H1 E1.3.2. The response headers
- [/ O7 [6 R) O' R- e- |" U
3 \( L8 W% G. H3 O: P. X2. Configuring HAProxy
0 y9 p; y1 v% b2.1. Configuration file format1 ?+ z% m% j# s5 e5 {
2.2. Time format
5 c( o0 j: f, B7 k9 e/ ?2.3. Examples
5 D; v7 A+ p6 E' o
" ?) k' v' W# m: l" w) f3. Global parameters! ~8 C" W; r9 Z
3.1. Process management and security
- z, Z5 v) w) T3.2. Performance tuning1 M, G% H7 N! _! i
3.3. Debugging8 M n4 h$ G" s
3.4. Userlists
! L; I- I. E2 ]; f' ]+ o( {$ n" F$ q" ?2 R% B8 u4 I
4. Proxies) |! r. r' H3 Q4 C7 S9 u" V p
4.1. Proxy keywords matrix
) l1 U) m4 V+ s) |/ ~4.2. Alphabetically sorted keywords reference4 H9 [0 H' b) B2 ^9 G$ d( z
) D- P; d: P3 s- t$ l3 S7 L5. Server and default-server options- y; \" E- j+ }% c) G, G
9 z2 n% e l: }/ D B. V% p1 }2 n6. HTTP header manipulation
8 \/ q% Z& H9 q, F* Q; y. F5 `- S( C. I+ S5 t
7. Using ACLs and pattern extraction( n- x1 ?& _4 ?
7.1. Matching integers
. s* ~- w9 G2 n1 X- R" i7 p7.2. Matching strings
: k$ g8 Y' K3 e) i" b1 l7.3. Matching regular expressions (regexes)" w e, P0 ?2 v6 q
7.4. Matching IPv4 addresses2 N! ` S4 O! Y- _7 s6 |3 \
7.5. Available matching criteria3 F. A/ x" Y. V1 c( ?
7.5.1. Matching at Layer 4 and below0 F3 d) x: R" Z0 U+ ~6 I9 z2 Z$ ~
7.5.2. Matching contents at Layer 4* w; X Q4 C. K3 {
7.5.3. Matching at Layer 7
2 g, D% }: _' i$ z1 _+ m7.6. Pre-defined ACLs: Q- E9 V6 c3 W; i
7.7. Using ACLs to form conditions
" z' F5 j. \' x! ~9 {1 \( a; H6 g7.8. Pattern extraction0 W/ t- _! F E! P7 @* `2 M
- p% _4 t8 m5 T7 ~' B& v1 z
8. Logging. m. D1 f/ ~% O
8.1. Log levels
% ~/ ]5 @, y8 F" t8.2. Log formats, F& E# x/ j6 E2 x: X2 `& r8 ^; m
8.2.1. Default log format
4 w2 R& M- l- p7 ]. d# N" ]8.2.2. TCP log format
( [1 C: l- L6 W/ _# J0 m8.2.3. HTTP log format
9 Q3 O9 R* h- q* h, Y. K9 X$ A2 u8.3. Advanced logging options8 a |6 E0 X! a1 I; _( [
8.3.1. Disabling logging of external tests
7 {3 ]2 T$ l4 l+ q! J5 ~8.3.2. Logging before waiting for the session to terminate
! J3 i0 {' f) n* G8 Z8.3.3. Raising log level upon errors
. r z- w$ t8 o5 c0 p8.3.4. Disabling logging of successful connections9 s" m2 n c" M; ^5 m" o+ H
8.4. Timing events# F2 X, |3 o7 n" K9 w9 m
8.5. Session state at disconnection$ O) ^' t! ?/ l+ J/ }9 [' N# C! n
8.6. Non-printable characters6 o: j$ X% O6 T9 {
8.7. Capturing HTTP cookies
, u1 V5 n& ?- n3 z/ b d8.8. Capturing HTTP headers2 r1 C& y! T0 Y3 q* o! N
8.9. Examples of logs
) D4 T$ d; C4 ^6 u
. d- T) q% j/ m9. Statistics and monitoring
0 J! F( [* I5 m* ]. x5 _4 H9.1. CSV format
. I/ f5 p' d }$ C4 B( P( v; o9.2. Unix Socket commands
; S; l4 E+ v) J7 x; L! H" M1 G; L$ z& U) a
' @6 ^9 b0 Z, u* E/ V. E9 Z1. Quick reminder about HTTP* S+ c0 S+ V5 ?, o! y
----------------------------1 k+ A: @- N6 @! m! F) L5 G
) F# r# L# o$ C7 H4 q0 |When haproxy is running in HTTP mode, both the request and the response are
$ k! d* L2 C( e+ vfully analyzed and indexed, thus it becomes possible to build matching criteria! S) K' M1 B; Q" ]6 s
on almost anything found in the contents." D. F3 r" Q0 u
0 Z' i% r/ m* L8 M. V6 ~ x
However, it is important to understand how HTTP requests and responses are+ [2 _0 y$ s& ?
formed, and how HAProxy decomposes them. It will then become easier to write
& R4 S4 F2 z1 Ncorrect rules and to debug existing configurations.1 c `! h# i! g4 E9 \' s# B8 B; f
: }% \7 A1 J8 E9 T& v4 Y
5 V+ Y6 S. V) a% l: a
1.1. The HTTP transaction model+ {2 a, D- I: Y
-------------------------------
. |* }. t1 ~: Z- o5 |$ g0 a
) D, ]! N8 i5 sThe HTTP protocol is transaction-driven. This means that each request will lead) k+ n, _7 \' U7 D' s; @6 i
to one and only one response. Traditionally, a TCP connection is established
8 x- V3 a* p6 L8 h/ [from the client to the server, a request is sent by the client on the; y7 N$ g1 `- H, ^) E: I2 N9 F
connection, the server responds and the connection is closed. A new request
( w! W# K1 D5 {( ~$ t w5 q) Kwill involve a new connection :
$ n' y) f8 c! U8 r8 [) D+ U' D: @2 X/ X0 t- F3 A& [
[CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ...
. k! i+ U9 v' k& ?
) J. Z# g9 Z% W' ^/ A- i& o7 AIn this mode, called the "HTTP close" mode, there are as many connection
7 Y, B/ a" {! r u4 Festablishments as there are HTTP transactions. Since the connection is closed
2 D% P( i/ n/ s% g2 s! g1 H* g# u! Wby the server after the response, the client does not need to know the content* N# h5 w+ S# f# ]2 I* m. t/ ^
length.; h, ?% g2 X; g' E- D3 ?. m
1 Y0 w0 H' K0 m% m( z- }+ l
Due to the transactional nature of the protocol, it was possible to improve it
* J- e- l' ?7 i( ?6 u& U) j% Yto avoid closing a connection between two subsequent transactions. In this mode
i* f R6 h; A' H9 ihowever, it is mandatory that the server indicates the content length for each+ p& O y. r' A
response so that the client does not wait indefinitely. For this, a special
5 n. W ]: k$ Sheader is used: "Content-length". This mode is called the "keep-alive" mode :/ O8 K2 s8 u( T; X( I3 C7 E
h* d5 ?6 G; i6 N7 c' J/ b- {* n [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ... z# g* t/ v5 Y @! B" |' k
' S" ~# U+ w4 {) R: V8 iIts advantages are a reduced latency between transactions, and less processing
4 I7 A) [2 J0 S% }+ Vpower required on the server side. It is generally better than the close mode,, r* k' E% x I, A# s
but not always because the clients often limit their concurrent connections to
3 V5 R) V, |' J7 V4 d3 C, ta smaller value.
. u& i" T& S8 ~
4 Y. f7 O$ V6 Z" S9 YA last improvement in the communications is the pipelining mode. It still uses
- D8 h( r; ~" i# t# n* x( ]keep-alive, but the client does not wait for the first response to send the
/ |1 g# [9 k9 y3 dsecond request. This is useful for fetching large number of images composing a% u6 ?( v. I M1 c7 S, U$ T% _/ T
page :, T* a( E+ s$ p
# U: f/ f) O1 u5 v1 ]( \ [CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ...9 O; n; c4 j7 [1 m2 v9 W. v# A
. e7 ?1 N/ d+ N
This can obviously have a tremendous benefit on performance because the network
1 {* E: ~* X/ R! t, ylatency is eliminated between subsequent requests. Many HTTP agents do not# |5 k$ C( l+ I
correctly support pipelining since there is no way to associate a response with7 R5 T$ B- ~+ Z X
the corresponding request in HTTP. For this reason, it is mandatory for the
4 Q8 z( Q; M" _+ x! pserver to reply in the exact same order as the requests were received.
& G/ b9 p% e" z& R# |; a" d$ p, f1 N+ @' h
By default HAProxy operates in a tunnel-like mode with regards to persistent: Z! M" z, I( G) g+ M
connections: for each connection it processes the first request and forwards6 q) R8 {/ @9 q
everything else (including additional requests) to selected server. Once
( f* u% A) y2 Z' I0 M4 Hestablished, the connection is persisted both on the client and server
$ L B! A, z; ]$ N+ x6 X( csides. Use "option http-server-close" to preserve client persistent connections4 b$ [# Q8 b7 Z, @+ k7 E) s; s
while handling every incoming request individually, dispatching them one after
3 ]0 N' w" H; ~another to servers, in HTTP close mode. Use "option httpclose" to switch both3 \8 G( o) H$ g7 S; B( ^& ~
sides to HTTP close mode. "option forceclose" and "option
& e9 @- g7 c+ chttp-pretend-keepalive" help working around servers misbehaving in HTTP close8 o1 S8 s# [, `7 X3 U! Q
mode.
" z9 Q6 O+ E1 v# [2 f9 M3 u9 ^4 I$ ?8 u# A( ^
& s# T6 z S# I# C! v8 K1.2. HTTP request8 U6 [# R3 u% f* y/ K3 k2 a
-----------------
/ j+ u, Q9 N' `9 H$ _# v- ~8 M8 f, i1 ~0 d) }
First, let's consider this HTTP request :
z: B8 ~2 O: r; Z: @+ ~& _+ E! }4 _$ b- ^: s' b
Line Contents. l' c" f$ f& ?6 U* g3 ^ T
number
( M7 x9 e& ]1 S6 i$ v. Y6 |" b 1 GET /serv/login.php?lang=en&profile=2 HTTP/1.11 U! A' G1 }# {( `
2 Host: www.mydomain.com
: W; X/ w: x9 k8 f( f 3 User-agent: my small browser3 Q7 W8 y# j& O: l
4 Accept: image/jpeg, image/gif. v# M \5 Y, ]4 b4 N4 b! T7 h
5 Accept: image/png6 M( U. B/ u1 h. |% v2 z4 i* R2 q1 Q
% v* H; o; _$ U" a O# G6 I) d) C* K @" n
1.2.1. The Request line
W5 P r* s+ l8 V" i6 \-----------------------
' J6 T# M' `6 {% K% D# M5 k5 s1 o5 I6 q2 d
Line 1 is the "request line". It is always composed of 3 fields :9 }& f( N3 A( p/ e2 O9 U- [
, O* |( r4 V. N6 `; U/ _" p
- a METHOD : GET
7 k& s" j, y6 R# b) N - a URI : /serv/login.php?lang=en&profile=2 R O+ G% b: H$ E" r/ d
- a version tag : HTTP/1.1
. t8 D: ^% q" Z
* S2 u* i+ S; ~% ^2 d( yAll of them are delimited by what the standard calls LWS (linear white spaces),7 ?) H3 f2 ?, S& ]7 }4 J
which are commonly spaces, but can also be tabs or line feeds/carriage returns/ e% h. V! R+ i( t2 e7 Z. o3 O2 N
followed by spaces/tabs. The method itself cannot contain any colon (':') and
9 p* k, _% N1 I) w* d- Qis limited to alphabetic letters. All those various combinations make it) ^" t& k" r8 }2 i# r
desirable that HAProxy performs the splitting itself rather than leaving it to
# V) g! r& n/ A& f$ ?: A% Wthe user to write a complex or inaccurate regular expression.+ Z/ b/ P" ?/ V% t
, P1 Z9 e$ ]2 HThe URI itself can have several forms :
2 ` V$ T4 A5 P+ M3 k% v6 r
( \( z: ^0 }* D% ` - A "relative URI" :0 i) U' H1 e! o1 W/ R! Z
3 C2 Q5 {* b% W1 X3 l /serv/login.php?lang=en&profile=21 e; k- y0 L* @' o# w, E( r' C
0 ]" u+ t% ~' a, o% G1 U1 w
It is a complete URL without the host part. This is generally what is
. p ~4 U' ]! G! L received by servers, reverse proxies and transparent proxies.
& M) `0 y1 G- H' Q1 ]% w) \
' W4 m: B( L1 e/ C3 [6 n! e! Y - An "absolute URI", also called a "URL" :9 H, v: _) W' X/ p
# V* G% [. L0 o A4 Y! g: W
http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
* ~' q0 W3 `5 y0 d# t) T3 h+ Z) B+ o3 [/ G
It is composed of a "scheme" (the protocol name followed by '://'), a host! m0 C9 t* X# Q0 f
name or address, optionally a colon (':') followed by a port number, then
9 |. ~ w- D# |& a' j a relative URI beginning at the first slash ('/') after the address part.4 Q# `( i4 v4 B! u* O) E
This is generally what proxies receive, but a server supporting HTTP/1.11 b# f9 U; ~2 ~; U3 A" Q
must accept this form too.
' n F+ l, @7 q. s& D: N& @( [
8 |# g7 m4 d, l, U7 k1 p - a star ('*') : this form is only accepted in association with the OPTIONS
, N: K4 V7 L$ R6 A9 w! t- H6 x method and is not relayable. It is used to inquiry a next hop's% R, z! @7 `2 t' {2 D
capabilities.
8 y4 ?" b: G- S, Z0 E K( X# U3 n) @
4 E1 i6 N: \) D# A& |% e9 h. Q/ { - an address:port combination : 192.168.0.12:80! a f y l8 J$ J4 ?
This is used with the CONNECT method, which is used to establish TCP
n* ]+ k8 @/ {9 D6 \, l! { tunnels through HTTP proxies, generally for HTTPS, but sometimes for, j5 J! x/ r/ b, H" G; S% M
other protocols too.
! n1 p" O4 w$ q. C. L/ ^" J. t* c2 d+ ?7 O8 t+ h* N4 G* }8 _
In a relative URI, two sub-parts are identified. The part before the question
0 x& X/ U5 F) `9 }: nmark is called the "path". It is typically the relative path to static objects
J7 r# A1 T9 }& zon the server. The part after the question mark is called the "query string".# v/ f' O( e# _2 |; ~1 } a1 D: ]
It is mostly used with GET requests sent to dynamic scripts and is very. O; c! `# h, @' a$ G
specific to the language, framework or application in use.9 t, d& U( \& X
$ A0 e! V. m/ z
. Q, t H7 R2 {; x h4 I1.2.2. The request headers
! G& n/ O& L: R- Q+ z3 b& h--------------------------
: ~; [6 Z0 V8 ?5 m: J' G8 w2 R1 H% c4 a* ]
The headers start at the second line. They are composed of a name at the% O. Y- _9 r* W
beginning of the line, immediately followed by a colon (':'). Traditionally,
4 c( k6 R/ z! r# C# A/ yan LWS is added after the colon but that's not required. Then come the values.
) r2 E# ~) {$ h! mMultiple identical headers may be folded into one single line, delimiting the
- b7 C& i' n3 G$ `# h0 i; Hvalues with commas, provided that their order is respected. This is commonly
# L& X7 L7 _2 ^" |+ `encountered in the "Cookie:" field. A header may span over multiple lines if
: X- W3 _) {' \2 |& |4 n; \2 jthe subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5
9 l% W8 I0 q- E9 p* \0 M/ u" qdefine a total of 3 values for the "Accept:" header.8 X8 x4 {8 ~( M2 C# j
' V: _8 U3 k! ]2 F& \
Contrary to a common mis-conception, header names are not case-sensitive, and _; c* j! w8 e* \. O7 T# r
their values are not either if they refer to other header names (such as the
4 D B6 t% p" L t9 k h5 }. |"Connection:" header).+ S* B! l. W; l, k% S* ]
/ D5 e9 x8 ?# p7 v
The end of the headers is indicated by the first empty line. People often say
, R% b6 I5 D, m+ w7 G6 qthat it's a double line feed, which is not exact, even if a double line feed
9 s0 n& E. a& q; t( F0 j$ O. a1 dis one valid form of empty line.: Y8 p. ]# t$ [# G
; \3 `5 k9 p) \Fortunately, HAProxy takes care of all these complex combinations when indexing. B$ P2 {. `4 O! y; g& Q7 [
headers, checking values and counting them, so there is no reason to worry6 G1 Y* u0 G9 G6 ~, [2 p; z
about the way they could be written, but it is important not to accuse an, h# s/ S1 T) {3 G& {* [# Z8 F" k
application of being buggy if it does unusual, valid things.7 N5 z: r- e+ R! S
; g j, n8 B; m* I7 A. _
Important note:9 V# }; x( e/ h; M; @( ?
As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks# d0 \4 j& K' @: Q, c7 T# v
in the middle of headers by LWS in order to join multi-line headers. This: h9 X6 y. m7 q( S& c
is necessary for proper analysis and helps less capable HTTP parsers to work/ \ M. w; H- g# r7 }
correctly and not to be fooled by such complex constructs.4 u+ r! I! s4 s3 T, P+ o
4 Q+ b3 p. B: z3 j4 V: i
8 t8 h$ Q2 t! d1.3. HTTP response* ~4 u3 n m1 [( ]* F; ?! ^( Y
------------------' [0 F$ M. ]- E$ _- B
( d/ A6 a' p; p2 e4 [5 K) k) F
An HTTP response looks very much like an HTTP request. Both are called HTTP
+ ?0 R0 R' I- Omessages. Let's consider this HTTP response :$ a* o+ F9 c% H2 r' X
4 ~8 F* q. F1 f
Line Contents
$ |3 Q: e1 g- `' x9 @- H' D8 v4 X number' I! D9 [% _( W
1 HTTP/1.1 200 OK" S% I* X/ Q8 n: @+ w% [* s
2 Content-length: 350! S0 r+ L- w9 N5 t7 Z8 L
3 Content-Type: text/html
+ Y, b2 n& @* q" Q
- A! m5 s5 N! x" t2 DAs a special case, HTTP supports so called "Informational responses" as status/ S: w" b$ `: b; b& T/ u! v
codes 1xx. These messages are special in that they don't convey any part of the
1 [8 {: B# ?4 D3 y* }9 r" ?' d7 Sresponse, they're just used as sort of a signaling message to ask a client to( |1 j C: w) x# Y
continue to post its request for instance. In the case of a status 100 response- S/ L6 ^( h; P# o& @+ z
the requested information will be carried by the next non-100 response message4 [, e9 n: c3 }# ?8 r8 _% y
following the informational one. This implies that multiple responses may be; T- p5 ?* i F
sent to a single request, and that this only works when keep-alive is enabled
, r" c8 T8 s' C4 f7 J(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to
6 d/ u2 i) O S1 L: ~$ e3 w t9 wcorrectly forward and skip them, and only process the next non-100 response. As
$ g) b0 w! P. w/ t) T# zsuch, these messages are neither logged nor transformed, unless explicitly& R! }' `7 Q4 w( B
state otherwise. Status 101 messages indicate that the protocol is changing
* r5 p( F( ~ A" T! Pover the same connection and that haproxy must switch to tunnel mode, just as1 z) z5 W! [' P @" w
if a CONNECT had occurred. Then the Upgrade header would contain additional' H8 p& v4 m9 h# V( J/ t
information about the type of protocol the connection is switching to.
' z/ C: U% W7 m' n o8 c# {7 q; ?; K* c
! N' n9 q2 k4 U: F
1.3.1. The Response line. Q" Q* }4 Z% ?- C8 `
------------------------
$ t0 [9 [1 Z% @: v, O( _
6 G0 R0 i" A) `" zLine 1 is the "response line". It is always composed of 3 fields :( g6 G2 `$ L9 s" j) x5 j) V) u
/ w& `: p) r3 \, j7 \" i
- a version tag : HTTP/1.1
$ M% d+ k& u: b9 R2 D- @3 f6 C! @' [ - a status code : 200
, ~/ [5 f% l! _9 r - a reason : OK# r- Y9 Y" b8 w) N
M, b9 o: G K9 n7 Z5 c! yThe status code is always 3-digit. The first digit indicates a general status :9 R8 _: O+ b8 p% |1 Q) }7 F
- 1xx = informational message to be skipped (eg: 100, 101)) Y- D$ G [8 n
- 2xx = OK, content is following (eg: 200, 206)
! S% N9 Z" p$ E! L0 y" O - 3xx = OK, no content following (eg: 302, 304)% e6 p' i: i- h: M/ X
- 4xx = error caused by the client (eg: 401, 403, 404)
1 b. T3 l. G* M* D1 J - 5xx = error caused by the server (eg: 500, 502, 503)/ `0 |$ M# u7 B; b6 t+ M/ D
. w& h3 y3 A9 [8 H0 p. zPlease refer to RFC2616 for the detailed meaning of all such codes. The H! T7 p- ~' b& U0 a
"reason" field is just a hint, but is not parsed by clients. Anything can be
3 M3 j1 L; ^1 Y# G1 B- x: R. Dfound there, but it's a common practice to respect the well-established5 K" N9 ]! }8 ^
messages. It can be composed of one or multiple words, such as "OK", "Found",) E+ [8 ~( ]: |# h% Z% b
or "Authentication Required".' V% m# ~0 \5 [6 F/ v
$ K" {: B3 @( [$ X9 Q5 T. q
Haproxy may emit the following status codes by itself :8 D7 g) L: O( y3 Y
. z" I+ H) y5 q! H ~2 O Code When / reason
, c' U# `8 N* m# Z7 B( P3 m 200 access to stats page, and when replying to monitoring requests$ t* i/ E! ]+ e& a- v" r, @ q! H
301 when performing a redirection, depending on the configured code
B6 Q% A# a* K& j" I( c, A 302 when performing a redirection, depending on the configured code
, x; A* o d9 ? 303 when performing a redirection, depending on the configured code
1 V4 z/ Z! ?- z3 j8 T3 w 307 when performing a redirection, depending on the configured code6 j% W5 u. u# ?$ v* I& k
308 when performing a redirection, depending on the configured code
% p' c0 M% L5 N3 `! Y% I z 400 for an invalid or too large request
9 M: D' g* y* R, J 401 when an authentication is required to perform the action (when
( V! A! q% H$ M' Z3 H; e4 ? accessing the stats page)1 d8 S/ I3 {- n3 a! I
403 when a request is forbidden by a "block" ACL or "reqdeny" filter% t6 V- W& c0 }2 X
408 when the request timeout strikes before the request is complete
4 k+ c' Z4 G' c# o: j 500 when haproxy encounters an unrecoverable internal error, such as a
1 h5 e6 v+ N+ m memory allocation failure, which should never happen
3 Z& D& M0 t! h/ o- D 502 when the server returns an empty, invalid or incomplete response, or. n) {9 X% Q, r K0 s6 q
when an "rspdeny" filter blocks the response.+ a1 b2 g, g) H
503 when no server was available to handle the request, or in response to. W( k+ Z: a7 f7 ]; v2 w) `# N
monitoring requests which match the "monitor fail" condition
. ]( ]/ _5 } l# _( k7 M 504 when the response timeout strikes before the server responds9 f, C: i2 y# [( W- _
9 L: y |, c; l9 V7 j9 HThe error 4xx and 5xx codes above may be customized (see "errorloc" in section* L4 i2 v, j4 o+ D% N5 K9 R
4.2).8 X5 ^* H# ?: X9 ~. F+ T
6 F& i. A; A6 y% V- g; h' B
# K. Z( C0 v& Q9 a1.3.2. The response headers) |) P5 {5 z c
---------------------------
# O1 m" O o$ }0 T: h
$ ^5 l J. B. b4 v. `6 i0 N0 MResponse headers work exactly like request headers, and as such, HAProxy uses
) m/ S' k6 w8 E% r+ Sthe same parsing function for both. Please refer to paragraph 1.2.2 for more
0 t4 E4 b" g) n V9 D6 d7 qdetails.
8 f8 a! C6 w1 a: M0 r6 B. H K
" s+ ]& F4 V; w5 p" r' Z3 [+ l7 _1 ^$ X7 v9 R4 @; _8 a3 l
2. Configuring HAProxy0 S( d3 t" s( i8 e8 E
----------------------7 i' f8 e, D: P
6 j! \2 }# K0 i* P! w
2.1. Configuration file format
' G" j, K9 j3 v% i6 d& k------------------------------3 G2 u3 d$ k/ f8 o2 Q, u
; S6 [1 p$ I* f
HAProxy's configuration process involves 3 major sources of parameters :
4 y7 P$ {( {, |$ c9 I- p, b8 K9 B3 w% Y. Y3 c: U% D* H* s
- the arguments from the command-line, which always take precedence2 i5 Y, s9 ^9 h: c' a
- the "global" section, which sets process-wide parameters
6 b! | U" V9 H$ ?" `5 n0 Y - the proxies sections which can take form of "defaults", "listen",, x" M% {6 L& j' _7 t$ ?' N
"frontend" and "backend".. k; T. }& z4 v9 k- M$ k
^7 e* b# m5 `& j' L
The configuration file syntax consists in lines beginning with a keyword/ s O% R. @6 u. ~1 l I- j. N
referenced in this manual, optionally followed by one or several parameters } i {9 K9 C& b
delimited by spaces. If spaces have to be entered in strings, then they must be% ~: u6 |- T* j6 e) m
preceded by a backslash ('\') to be escaped. Backslashes also have to be$ ?% M; h$ R8 O6 R+ M5 N2 b
escaped by doubling them.
7 u @# U o9 C, Y2 c9 o, d) S' Z2 f
2 K+ J9 \, f3 `
2.2. Time format! A5 `% H/ o" d# J) V
----------------2 U' B' J4 K9 r$ v1 U( `2 `
. A2 {9 n }: B& cSome parameters involve values representing time, such as timeouts. These
1 }0 n! ]. |/ g& gvalues are generally expressed in milliseconds (unless explicitly stated, W0 \6 U7 H/ }: k4 k2 R! }4 v
otherwise) but may be expressed in any other unit by suffixing the unit to the) R' G% J( F6 y/ X, L& C6 `! B
numeric value. It is important to consider this because it will not be repeated- y- T x; @7 U2 D
for every keyword. Supported units are :
! G# w& Q3 Y ~5 j, l4 S
! g' B5 U0 Z6 ?* Q2 D% a - us : microseconds. 1 microsecond = 1/1000000 second7 V4 k0 V7 [- z# N* W) ]
- ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.2 |+ G/ j4 W- S f1 N' ^5 t, D4 G* [9 ?, T
- s : seconds. 1s = 1000ms
! a4 Y- B& p9 r( V - m : minutes. 1m = 60s = 60000ms; ?2 n8 p. o' s7 b
- h : hours. 1h = 60m = 3600s = 3600000ms
; f7 o% E. a0 U - d : days. 1d = 24h = 1440m = 86400s = 86400000ms
" Z( b/ M$ u, `6 K/ q& v4 R/ N) t6 W' `. K: M T
8 M- Z8 b2 [8 x# N( L, I2.3. Examples
+ Z* U* Y$ O+ t/ j4 z-------------, F6 q3 A9 N5 p
9 E# q! a* N M- g c # Simple configuration for an HTTP proxy listening on port 80 on all
% m0 _$ G, F0 D% _7 G4 f # interfaces and forwarding requests to a single backend "servers" with a! A, t5 }3 Z7 g1 B- _5 ]% x: b
# single server "server1" listening on 127.0.0.1:8000
0 ~$ ~5 t6 l' r8 p$ x: e, [1 P global
- w6 A" s9 ?8 E2 N# F+ B daemon
% V$ j6 m; g0 Z% h& F maxconn 256
" q F# ^9 @ L3 t/ t- y" H" Z" t* [' f
defaults2 k& x7 {. G' ?3 [- \
mode http
% H8 U- x( T- z) n5 e+ J3 {; x9 O. p3 b timeout connect 5000ms
0 U1 k* Y. l4 W& m) x& D; l timeout client 50000ms
+ x+ H- |. S. K timeout server 50000ms# d# C' y8 r, j! C& P
7 E( y" [6 L; _% y4 b" v frontend http-in
9 V+ T" S g3 P; ] bind *:80
1 r3 \0 d8 ~6 K9 {8 D5 D default_backend servers
3 s* [9 P6 l* S5 C; L) |
" x; m2 Q( |) [5 d- m8 w backend servers
+ \! ^. f% e/ q! H9 [ v% ? server server1 127.0.0.1:8000 maxconn 32
5 X. d4 A6 I; x" M. \7 Q9 j
3 F9 [) O, }% @, Q% @+ M, B! U+ I
' W8 R, U' Q% v3 Q" O # The same configuration defined with a single listen block. Shorter but
, k, j. r+ L, @/ F' I: [ # less expressive, especially in HTTP mode.
8 Y4 L4 K/ ~! p) \: N global
" o$ z! v; e2 U" n daemon7 D( ?/ O# }: L" p- S
maxconn 2563 M, a0 Z7 b& K/ X
7 D) L$ \8 w6 N defaults
* k" h) g" n) W) r mode http
: Q0 \* u6 R0 T: d" [ timeout connect 5000ms) z+ I5 V# O G& v
timeout client 50000ms$ ~1 s8 @7 {. n) c1 ^* g
timeout server 50000ms
# w/ [0 t' k/ ^2 q' ~5 N' ^' Z& }* F2 P
listen http-in v5 V/ ^) l& t/ V
bind *:80
0 N/ ^7 R: P& I server server1 127.0.0.1:8000 maxconn 32
* V I$ Q: Y* m4 x/ ]& ~- |) s
) d$ Y$ K1 i+ g* y
+ I A& B3 W" b9 |Assuming haproxy is in $PATH, test these configurations in a shell with:
1 I2 y0 k: Z8 {; P7 }' a9 c
( X3 F4 h" e. S. [ $ sudo haproxy -f configuration.conf -c& w q- O( k' s2 w& r! A1 i
7 ?/ |, d* u+ C" Q3 t* Y# e$ ~
3. Global parameters
. Q6 w6 c: D, g8 I9 E, @- E--------------------
+ ~ ~+ F" y3 J7 d% u% C7 y8 S6 @3 A* q. \, R- i4 ]) r% I- @) D
Parameters in the "global" section are process-wide and often OS-specific. They/ G( [+ C* D- o$ l2 F
are generally set once for all and do not need being changed once correct. Some
]4 Q/ |/ b u4 Bof them have command-line equivalents.
& [8 I5 A( Z+ @6 X+ R0 L9 j1 r" d$ h- y. W! x- j' X5 U& L/ i
The following keywords are supported in the "global" section :
+ g# F+ Q2 } Z3 e2 G! k& Y: c. @' r' y
* Process management and security
J( Y, e+ X2 s7 q, c - chroot, o5 { h, m. b: T! t
- daemon* B0 p, P9 V2 K/ J( U9 q! n
- gid; @- Y" r$ u1 a7 v3 X$ [
- group: D" U& f+ b9 {
- log
* v( z' D' o; f, L0 w - log-send-hostname# F2 B& H2 m- i8 P3 ~0 P' R$ ]& _
- nbproc
3 J6 |. ?) e6 X5 ~" @' } - pidfile6 R4 w5 a q* ?# f/ l$ F% v3 x
- uid
6 D4 J ^) n& ?5 D2 c7 k: \5 O - ulimit-n
, n: V6 C& }- s9 p8 B - user) S; ~( ~- e# z5 L9 e- |
- stats
, {" m' B' x0 G+ B1 Q" m - node
$ d e2 f& `! E i) | - description
) z: D2 }& E6 J$ G2 ^' v* I* P. o
. ^- j) R3 h# P& e * Performance tuning
: L: W) E3 v. D$ \4 [6 U - maxconn6 S5 w1 m5 J, t" e: H7 w( o
- maxpipes
v" I# \1 J0 x9 L; K$ l - noepoll- |5 v9 x9 ?0 B/ w" |' k. D
- nokqueue
W+ a# e+ m) O# E4 N: p% Z - nopoll; q1 [4 N2 h& X* I j
- nosepoll
3 u0 Y9 F; O; R# d: P4 L4 s - nosplice
7 @' j# R/ l, k3 r, X1 W - spread-checks$ l! I0 r& @, J5 j
- tune.bufsize
- ]" q/ ]5 [. ^: D, r9 J" m$ j0 Z& I - tune.chksize* w( U, s! a6 V: Z
- tune.maxaccept6 T' p; Z4 C( }" e* ~( q6 |( i
- tune.maxpollevents
( @1 N8 f) U( v7 j/ j- I& Z8 @ - tune.maxrewrite
, R4 z( O* E/ i4 ^ - tune.rcvbuf.client
+ w8 l6 J, f& L/ V. B3 y4 @3 L - tune.rcvbuf.server9 w! ^* r! _5 d6 U. f
- tune.sndbuf.client- Q: o7 [; v ]* c: Q
- tune.sndbuf.server
8 q: e [8 `4 y( t+ n0 K! z9 [& V! `* ~* _
* Debugging6 w- J( ?- a3 M+ E
- debug
8 o% h6 d- @& ?: h4 f - quiet1 q) n8 G7 i# C
e( S" q( x+ D' c' N" G7 I; }* L6 [8 y4 Q
3.1. Process management and security
- o) u/ a7 x$ t5 S U* k3 G------------------------------------+ r3 l" A' H/ |- S- K' S0 t
( J. I0 ^8 [* O b, L
chroot <jail dir># Q) m/ ]- Y' O6 y
Changes current directory to <jail dir> and performs a chroot() there before
/ ~! d$ M/ }" d2 n, N7 m3 U dropping privileges. This increases the security level in case an unknown
- p3 {$ ^" ?9 R3 P, R* s vulnerability would be exploited, since it would make it very hard for the
' |# M4 j7 w0 r attacker to exploit the system. This only works when the process is started/ e4 d: ^" N: c9 U
with superuser privileges. It is important to ensure that <jail_dir> is both
( s! J7 D5 `2 y# ` D) E empty and unwritable to anyone.
6 n% g- a% [" |2 |2 i6 l) G D6 A5 s9 }7 ], m& j
daemon
" J; k8 x5 b9 V6 K) x Makes the process fork into background. This is the recommended mode of
$ [! x z7 J- A* U) y) }7 [ operation. It is equivalent to the command line "-D" argument. It can be) J! D! G. z. O. ?
disabled by the command line "-db" argument.
1 _1 E& r( B( B( u! J5 E8 N3 r' L% _$ n1 U2 m& ?
gid <number>0 R' `: l! e9 j% T4 C
Changes the process' group ID to <number>. It is recommended that the group) O( C, W' e. p0 _+ p
ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must: U& w5 j9 a- I) B8 y3 M& o
be started with a user belonging to this group, or with superuser privileges.
! h {5 A% ~* m- b0 s Note that if haproxy is started from a user having supplementary groups, it
; F5 H: H' o( l. G% p3 `- q0 [ will only be able to drop these groups if started with superuser privileges.
/ {: u# b E6 Q8 H# @1 \$ u See also "group" and "uid".
2 K' U/ J. @" Y! b& Z6 f
$ K1 `5 j3 j* h7 ~! w' Y2 Fgroup <group name>6 G/ t4 a: l: n* R3 l) U& p7 K* _
Similar to "gid" but uses the GID of group name <group name> from /etc/group.
: C5 l- ~4 ]! s See also "gid" and "user"." ~5 d% o: {& l& f& g' d- m, a
3 O9 |8 ]2 R- D; g6 I4 g2 Slog <address> <facility> [max level [min level]]5 q* d5 h8 ]/ V; ]' e! v& O$ s B7 [
Adds a global syslog server. Up to two global servers can be defined. They
. W7 B$ @9 |5 Z5 d5 K+ }& c, h will receive logs for startups and exits, as well as all logs from proxies) v+ h7 x L1 l
configured with "log global".
) B' E" ^) r, C! Q: S+ K: I. Z# O$ C: p: g+ `
<address> can be one of:
" `' _% L! d9 R) O; k8 V8 A+ c/ F- `, V0 @4 H Q# a+ w
- An IPv4 address optionally followed by a colon and a UDP port. If
, T. N# D& k" P no port is specified, 514 is used by default (the standard syslog0 d( t' e+ e* J \5 e* \ F
port).
% o5 I; m( F" e; @& m, Y9 ^
" M) U+ ^/ n% F9 P/ u: V' O - A filesystem path to a UNIX domain socket, keeping in mind6 K0 L1 d" _; s9 w: u
considerations for chroot (be sure the path is accessible inside
; p2 K( A' r* x E the chroot) and uid/gid (be sure the path is appropriately
6 E/ g- ], g" F8 d0 b) P0 | writeable).7 a ]+ }4 w0 w w: K
8 u/ t5 y; C. W! V
<facility> must be one of the 24 standard syslog facilities :) u$ r7 r% q) {
: l" D4 }: y* {# C; Z' k: }4 |+ R kern user mail daemon auth syslog lpr news
5 S! S& R5 ^0 {9 R. f$ }3 W. U uucp cron auth2 ftp ntp audit alert cron2
! R% X3 X1 {6 w local0 local1 local2 local3 local4 local5 local6 local7
. s& F4 y3 c6 w; U+ _) o
: Y5 @2 |3 l+ U: M- g/ `! z An optional level can be specified to filter outgoing messages. By default,4 N' A7 \: r# w- M
all messages are sent. If a maximum level is specified, only messages with a
) F0 V6 N" a% B+ u6 W" E severity at least as important as this level will be sent. An optional minimum
! w- M m4 W& M H9 c7 D level can be specified. If it is set, logs emitted with a more severe level1 e6 D p/ F- u/ q7 k( {6 Q. z5 T
than this one will be capped to this level. This is used to avoid sending
$ f# z$ N" f* ? "emerg" messages on all terminals on some default syslog configurations.
' A* L, Y0 ?4 H) c: P/ ]: _ Eight levels are known :
- a2 m: s) o b8 m: E* a6 z2 X! W8 q, Z8 y+ r9 p' R% x
emerg alert crit err warning notice info debug1 w; u7 G- U8 T) m
1 }3 I5 B2 y% y) w
log-send-hostname [<string>]/ n& }: [* w9 S, O- F
Sets the hostname field in the syslog header. If optional "string" parameter6 \- q x7 U/ n) r9 P
is set the header is set to the string contents, otherwise uses the hostname, e: w" ]3 f9 y
of the system. Generally used if one is not relaying logs through an' p( D( F$ ]' h" K! T J
intermediate syslog server or for simply customizing the hostname printed in
4 G, F+ Z( v N. S; E6 {" }2 a the logs.
$ E: j7 b, Z9 g
7 [) m9 q6 y6 n8 }4 |4 V$ Jlog-tag <string>, ?; F8 W7 x. e4 q
Sets the tag field in the syslog header to this string. It defaults to the
% u) P8 c0 O8 a+ E& q7 L$ H program name as launched from the command line, which usually is "haproxy".
X6 T, y" D/ \ Sometimes it can be useful to differentiate between multiple processes0 j; f$ P( Q" h( a+ f2 ~3 Y) k0 ]; y' N
running on the same host.
% r2 ]( C* a& B" }4 B1 l' J1 `1 L+ R4 `0 Q2 z
nbproc <number>6 W/ q+ o/ P2 U
Creates <number> processes when going daemon. This requires the "daemon"
{0 N# X! q! ^ mode. By default, only one process is created, which is the recommended mode
. f3 |. R: x5 ?( B7 t5 F of operation. For systems limited to small sets of file descriptors per
& a0 U0 T# r) W. B' }% c process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES
6 `4 T ~8 }/ ]# k- \ IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".% ~1 }4 @ I+ l6 k8 ~6 s5 ?" ~
$ [- ~$ y7 g/ S" H& t. N8 q
pidfile <pidfile>
- k$ W/ G, S( P7 r$ S; R, v7 H Writes pids of all daemons into file <pidfile>. This option is equivalent to
6 F" x* ~: H$ t# ^+ ]8 R- ]+ O/ h the "-p" command line argument. The file must be accessible to the user. k Z/ G6 C; w. p! J6 [
starting the process. See also "daemon".
; ?, u7 ]- _$ c8 j X8 t; S6 f0 E& y: l- b
stats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]/ D- ^+ B2 y, X( z% s3 W" g
[level <level>]
/ o% E3 S7 n* O6 u
, u* C# ^% ?) `4 c2 R: s$ o Creates a UNIX socket in stream mode at location <path>. Any previously$ l% M' D H' a$ ^
existing socket will be backed up then replaced. Connections to this socket
: {5 T- f$ y& u( | L will return various statistics outputs and even allow some commands to be
) ~0 V) K6 {9 |: s9 I issued. Please consult section 9.2 "Unix Socket commands" for more details.' O- S7 D7 `' p" J" K5 a& P8 k
! ?$ B7 D/ b2 _
An optional "level" parameter can be specified to restrict the nature of
7 A# O1 c8 e5 R) |, k1 s1 f- u the commands that can be issued on the socket :6 K: B" \1 e# o+ ^, G
- "user" is the least privileged level ; only non-sensitive stats can be1 e& u/ D3 ?, o; g8 {; O
read, and no change is allowed. It would make sense on systems where it
9 D+ j+ U0 [, v( W' |! y is not easy to restrict access to the socket.
J7 o( B% A7 f+ E/ T5 Q0 `0 ?! [8 C
- "operator" is the default level and fits most common uses. All data can
& g" Z! U0 Y6 }) |; Z1 B be read, and only non-sensitive changes are permitted (eg: clear max
( d' Z! {3 o# {; J @5 K counters).# a0 A: A# M5 Y0 A& o9 h* y
: F# q$ A3 R; Q1 n. z; k- ~ - "admin" should be used with care, as everything is permitted (eg: clear
: ^+ F/ d& @# k0 ^& h- Y all counters).4 q+ @( {5 u" i9 K' a3 T
" |) s0 S/ y* p" I, G On platforms which support it, it is possible to restrict access to this/ g' J, t" p% N+ W w- i! N
socket by specifying numerical IDs after "uid" and "gid", or valid user and
. q6 m7 [* ~! D2 Y5 o) I4 x group names after the "user" and "group" keywords. It is also possible to
0 m6 o/ M$ ]' f6 k* j restrict permissions on the socket by passing an octal value after the "mode"- J; c, G4 x- }$ }5 {" X
keyword (same syntax as chmod). Depending on the platform, the permissions on
! K" ^. U- c' b the socket will be inherited from the directory which hosts it, or from the* }3 z$ U+ R' Y9 M: V
user the process is started with.
; P& z+ }" o8 t
9 n7 l' E; N" U# h9 B3 hstats timeout <timeout, in milliseconds>/ w- |# }, {8 P9 s0 O/ j
The default timeout on the stats socket is set to 10 seconds. It is possible
3 z+ x6 a; ]# Z4 p$ k7 X/ i8 _' a to change this value with "stats timeout". The value must be passed in6 s5 ?% w$ H8 j) ]
milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }.7 N1 o# w& t w& @$ S
3 X& b/ d! u. x O* F8 j9 _) C4 Jstats maxconn <connections>
, b7 q! }9 B) g" p By default, the stats socket is limited to 10 concurrent connections. It is
, V7 o8 f0 g, j7 e- a possible to change this value with "stats maxconn".
+ k7 T# c% e3 q, j4 _0 f* j8 V9 L6 x8 q. U+ w% [
uid <number>
1 p( V2 H ], N! O7 t" v" d Changes the process' user ID to <number>. It is recommended that the user ID
1 U# ]' X( l0 H" C# ^- e# Z5 V is dedicated to HAProxy or to a small set of similar daemons. HAProxy must7 c. D8 e9 l2 l! W# c& W+ y
be started with superuser privileges in order to be able to switch to another
% T. Z3 P" a4 N one. See also "gid" and "user".8 M7 _* O% g3 _8 [/ t. v
3 I& p" U8 a$ l( _3 Q4 F; \6 y2 i* E+ culimit-n <number>3 r1 }3 k( D: x- j* M
Sets the maximum number of per-process file-descriptors to <number>. By
4 m3 ]1 H5 h/ \ E8 Z7 z- g default, it is automatically computed, so it is recommended not to use this% k$ P6 W' v: _2 Y
option.
8 j3 j. H3 {: Z2 C4 |# y1 m" N8 X, @; U( r1 m G8 I
user <user name>
( S& j6 V0 C% G; b! }6 C3 S Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.
: p. I" x ~# T7 w2 O; E w5 Y See also "uid" and "group".
% ]8 g f9 Z9 q7 ]7 t. Q
- A- s$ W' j3 e N$ \% H3 @$ Wnode <name>8 j8 Y; d" H. @. I) u
Only letters, digits, hyphen and underscore are allowed, like in DNS names.
1 _3 U( l! p7 g$ i' ?* E1 g1 }& X. U% s! |' I. m0 C
This statement is useful in HA configurations where two or more processes or2 z# Y; Y/ O0 `9 ^0 E
servers share the same IP address. By setting a different node-name on all
1 d3 u7 `- B$ Z& V; s nodes, it becomes easy to immediately spot what server is handling the
. Q% l8 i/ s: M: T+ m traffic.. q5 b9 L5 C4 W2 b9 \
I# H8 ^# d0 n) Ydescription <text>
$ M- v4 K0 T8 r' H3 c Add a text that describes the instance.0 m$ m! d( ?; s+ U; U
: k8 w# A. ?2 [3 }$ a, C
Please note that it is required to escape certain characters (# for example)
/ e( ^9 w7 r& p; c and this text is inserted into a html page so you should avoid using
0 H) \% K. D$ B! W8 d6 E8 e "<" and ">" characters.7 Y4 c, x8 ~1 ?8 \
* J9 M9 d2 t1 @) f8 M' H/ r: m
- k5 K7 d( R5 V0 \+ o3.2. Performance tuning
2 ^* p" c w) g+ K, Z' m-----------------------
$ R4 k$ E! F3 r1 H- N+ A4 k ^1 P8 n" k7 L Q8 E
maxconn <number>
2 o9 N' r4 p2 x" N$ }1 R5 @! d/ i Sets the maximum per-process number of concurrent connections to <number>. It2 S$ d q" H7 T* P4 E: n3 N# n8 t
is equivalent to the command-line argument "-n". Proxies will stop accepting
/ p, h0 f8 A" k. A# U connections when this limit is reached. The "ulimit-n" parameter is
& \% Z# v" j# E: z9 t. x automatically adjusted according to this value. See also "ulimit-n".
3 f4 e; t9 c$ z, v6 a( x9 ~+ v' K) \" o8 Y1 J4 p( u
maxpipes <number>! c @8 `+ V# Q) K b8 x/ S
Sets the maximum per-process number of pipes to <number>. Currently, pipes! }+ ~, y8 x4 W" F9 E2 i
are only used by kernel-based tcp splicing. Since a pipe contains two file
; }# m; x6 I+ ^4 k/ [% ^1 M. A descriptors, the "ulimit-n" value will be increased accordingly. The default6 A6 G. }) m6 t. d- ]$ A+ l# m
value is maxconn/4, which seems to be more than enough for most heavy usages.
, A1 k1 v# I1 a8 n" B5 V$ \/ y The splice code dynamically allocates and releases pipes, and can fall back
F6 d0 W+ E% p' ` to standard copy, so setting this value too low may only impact performance.( J7 C2 X3 a* b# M& r
% S3 R0 v. `2 [9 {5 \noepoll
& b8 ]$ e& G4 M2 \ Disables the use of the "epoll" event polling system on Linux. It is4 P9 y9 E- d: k# T# v/ Y/ ~/ x
equivalent to the command-line argument "-de". The next polling system+ W+ H) T% y+ J# B# \
used will generally be "poll". See also "nosepoll", and "nopoll"." j/ q' W! h; _+ g2 [3 B8 n3 z' H
. Q7 i k E; d8 F# D
nokqueue
* U6 c* Q! Z/ i1 m5 O+ } Disables the use of the "kqueue" event polling system on BSD. It is& U! {- @" E3 y* E, S" a
equivalent to the command-line argument "-dk". The next polling system$ r& t3 U0 \/ [, J) _& F& H! H
used will generally be "poll". See also "nopoll".9 y% e, X5 l: z" o
' D; _& e1 x1 x$ p$ o% t
nopoll- w+ R0 s D+ t
Disables the use of the "poll" event polling system. It is equivalent to the; z( _& K9 o* {8 D" W+ ?: c
command-line argument "-dp". The next polling system used will be "select".
9 E% u* k& R: J9 w& { It should never be needed to disable "poll" since it's available on all
1 O" I$ A- X' O' i- O, Q/ G$ }8 T( y platforms supported by HAProxy. See also "nosepoll", and "nopoll" and
! i- [. u9 N, R4 ` "nokqueue". I) k2 j, l7 e/ U/ J. P% B& ?6 a
' b: Y, H3 K6 r' q1 Q8 c; f
nosepoll. \5 T: D, _/ _9 [% M, O0 X
Disables the use of the "speculative epoll" event polling system on Linux. It& t; e+ K+ W4 E1 @
is equivalent to the command-line argument "-ds". The next polling system! @' q& S' h/ h! H L. y2 p2 F
used will generally be "epoll". See also "noepoll", and "nopoll".3 S- T- [, d, [: ]
3 o( J) Q3 F4 inosplice3 C/ t! L0 n9 v
Disables the use of kernel tcp splicing between sockets on Linux. It is
. Q) l0 D% b* R; L equivalent to the command line argument "-dS". Data will then be copied
( i" O8 @7 B7 w! d7 z2 b* f4 D using conventional and more portable recv/send calls. Kernel tcp splicing is
& v8 J1 N6 H* p1 p. Q limited to some very recent instances of kernel 2.6. Most versions between0 s* p" X' {, D g" f
2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not! ]; v, i( M+ Q) v3 p
be used. This option makes it easier to globally disable kernel splicing in
5 u! C: p* K0 Z# g& t case of doubt. See also "option splice-auto", "option splice-request" and
! y/ Q( o) v, z: }9 e "option splice-response".
" b5 k+ p& w0 o% y8 {# F: [& L' i, k8 T+ t* ^ o9 ^' H" [
spread-checks <0..50, in percent>! P4 n2 F5 D4 E" W( R
Sometimes it is desirable to avoid sending health checks to servers at exact5 w: j; F E) C# b2 f
intervals, for instance when many logical servers are located on the same
* o) Z6 M2 [# Z0 s7 T- I3 [ physical server. With the help of this parameter, it becomes possible to add
6 @7 G/ s" q3 S some randomness in the check interval between 0 and +/- 50%. A value between4 D" A$ m% ]& t* B
2 and 5 seems to show good results. The default value remains at 0.
* u4 I' a6 r4 X' M1 w; R
6 w$ f, U3 K# @) }8 M1 u$ vtune.bufsize <number># w1 I9 I( Q7 J# x" G9 U0 `% ~
Sets the buffer size to this size (in bytes). Lower values allow more
% b3 p j$ B3 P- S$ p- L+ o% M& M sessions to coexist in the same amount of RAM, and higher values allow some
4 y q8 W) C5 e: O+ m applications with very large cookies to work. The default value is 16384 and
7 v$ h0 l2 n' z0 u can be changed at build time. It is strongly recommended not to change this2 E ^0 S& ?2 F; H9 M7 h
from the default value, as very low values will break some services such as
; @ h$ [' Q6 M statistics, and values larger than default size will increase memory usage,
a7 A; K- G$ M# `$ g3 H possibly causing the system to run out of memory. At least the global maxconn
7 e9 ~! e8 l8 Q- a parameter should be decreased by the same factor as this one is increased.
j" F! Q) {4 Y/ R, ?8 ?$ p/ n( P+ B
+ {0 B, {' v6 T. Qtune.chksize <number>; h" B( |5 a2 G( H, V
Sets the check buffer size to this size (in bytes). Higher values may help8 Z7 w0 g+ j2 w- j
find string or regex patterns in very large pages, though doing so may imply* m$ J8 `0 L H% E) L3 q
more memory and CPU usage. The default value is 16384 and can be changed at
2 v! `( K: U( q* Z9 t build time. It is not recommended to change this value, but to use better: _1 K$ O& ^/ j! e
checks whenever possible.! P3 o. o8 i" {
/ U% s0 E" w" P$ ?
tune.maxaccept <number>/ {" y5 k; G! l4 P
Sets the maximum number of consecutive accepts that a process may perform on
+ ~. B% Y \, o* v3 k a single wake up. High values give higher priority to high connection rates,# r1 J. d- p6 K5 u2 ?
while lower values give higher priority to already established connections.
+ L. E1 r) ~" s This value is limited to 100 by default in single process mode. However, in+ e' u/ B5 Z! P
multi-process mode (nbproc > 1), it defaults to 8 so that when one process
! M4 v( y* E+ j wakes up, it does not take all incoming connections for itself and leaves a9 |! } H }$ X: L# b3 R1 t
part of them to other processes. Setting this value to -1 completely disables- ~ N% H. r) m3 B7 c
the limitation. It should normally not be needed to tweak this value.
9 x9 ]( x% O o3 @( o9 I; m7 p; i( N; ] r; O3 N
tune.maxpollevents <number>
+ O4 B, Z v; q- J Sets the maximum amount of events that can be processed at once in a call to
' @3 n) P* z5 F4 g( Q the polling system. The default value is adapted to the operating system. It
6 t, G% p! G7 v ?. C has been noticed that reducing it below 200 tends to slightly decrease9 n; _5 P" D ^# |* Z% D
latency at the expense of network bandwidth, and increasing it above 200
) l( d K& ]- }* S9 y: }# X tends to trade latency for slightly increased bandwidth.( A6 x6 D. J3 d; ?& L$ j
, R$ R% D, `8 M9 {$ D" X9 i# T" xtune.maxrewrite <number>0 ~% m: e4 [2 }0 J: M
Sets the reserved buffer space to this size in bytes. The reserved space is$ q$ ~2 {% v+ O: Q6 L
used for header rewriting or appending. The first reads on sockets will never
9 s" i8 B; u/ I% [" u4 | fill more than bufsize-maxrewrite. Historically it has defaulted to half of& s9 x7 A M0 v4 s
bufsize, though that does not make much sense since there are rarely large
7 a! I. M3 N. _) O/ \/ q# q numbers of headers to add. Setting it too high prevents processing of large' S$ i) F" _% k
requests or responses. Setting it too low prevents addition of new headers# [4 b7 S% w$ f) A. m. \/ u
to already large requests or to POST requests. It is generally wise to set it
) h: M' v$ b! e8 I; c0 K' | b$ \# B to about 1024. It is automatically readjusted to half of bufsize if it is* @5 \9 P/ R+ G3 {6 @ t
larger than that. This means you don't have to worry about it when changing4 T& @& T" Q6 v5 F3 z, O; l
bufsize.' n3 R8 H( U7 h( r0 K
7 L% q" Z* @0 O4 Etune.rcvbuf.client <number>
$ s* x9 n! i4 n$ }7 Gtune.rcvbuf.server <number>
) B9 [' K* D6 D Forces the kernel socket receive buffer size on the client or the server side {4 O5 ~: m/ `% h d
to the specified value in bytes. This value applies to all TCP/HTTP frontends
' w' i( N' U- i! f/ q0 k2 ^; q% N and backends. It should normally never be set, and the default size (0) lets0 X+ E* ^$ a; M& a% a$ ]) C
the kernel autotune this value depending on the amount of available memory.
3 Z! S" t0 Z4 b5 _6 x8 O0 @ However it can sometimes help to set it to very low values (eg: 4096) in
9 @, A8 L8 W, D; {4 a5 y4 A order to save kernel memory by preventing it from buffering too large amounts
* T* {9 ]. E; u" E: N( v of received data. Lower values will significantly increase CPU usage though. ?2 b/ \/ [( X
. C2 ~# Y: y, d- }6 M! O
tune.sndbuf.client <number>
; y% Y# h7 t% g1 b7 A/ y [tune.sndbuf.server <number>
& H* ] y R7 ~" _; d# o Forces the kernel socket send buffer size on the client or the server side to
4 D2 u7 |, c5 ?- N4 w the specified value in bytes. This value applies to all TCP/HTTP frontends
+ S" W2 ^/ w) [ and backends. It should normally never be set, and the default size (0) lets
, K% a/ z: l, {/ ^4 v" u1 G7 K the kernel autotune this value depending on the amount of available memory.% r; ` Y1 V7 ?- R& s( g
However it can sometimes help to set it to very low values (eg: 4096) in
, K5 a, \8 ~5 M0 h: L! n. u' O order to save kernel memory by preventing it from buffering too large amounts
; E" W- `! B1 q8 Z of received data. Lower values will significantly increase CPU usage though.
) V8 }7 t, g, |9 S/ r6 r% x, ~2 z Another use case is to prevent write timeouts with extremely slow clients due- `8 {7 L! v* J# P) g/ W
to the kernel waiting for a large part of the buffer to be read before, t4 W" ~, K4 M4 [
notifying haproxy again.7 t" ^; v; w+ Z# y4 N
8 u* D$ I* E H P0 r( c* ~
0 ?' w) w. k7 y. t' t3.3. Debugging
& o9 S$ U) v3 r3 |* f$ R--------------& u$ }3 V' C( N- s& _! Q
1 @+ j4 ^- O8 v! W. u
debug
) _+ a3 Q i% P, {2 j6 ]) E# m Enables debug mode which dumps to stdout all exchanges, and disables forking
5 h0 O, k2 s# N9 v4 x! d0 w into background. It is the equivalent of the command-line argument "-d". It. R& h* i& O7 `% y' D
should never be used in a production configuration since it may prevent full9 s& b1 }' H0 K$ E
system startup.
1 G9 `6 V! p E4 k- n; d7 t# ^- r. t A: U3 i6 a) h
quiet* ~# G: j: {( x# U% P7 V5 z
Do not display any message during startup. It is equivalent to the command-
& D% ?) s( @/ I* [ line argument "-q".4 |1 G4 {1 a# i: f0 ^
5 g* w: f8 l J" \3 _4 O
3.4. Userlists! I$ M9 l2 b4 l; w+ ?4 P1 Q f
--------------3 @0 v! J, @/ _! l% P! }# g" C
It is possible to control access to frontend/backend/listen sections or to1 ?& I7 C8 |1 g. d
http stats by allowing only authenticated and authorized users. To do this,+ l/ ? e/ m5 P/ l2 w( k+ |0 f
it is required to create at least one userlist and to define users.
8 b( m: j0 }# ]6 C* M @) E- m
$ p0 A0 F, \! `3 Z" c! H3 R0 N' H# A: Suserlist <listname>
: S' L5 s4 ~: u" i' F( L" |5 U Creates new userlist with name <listname>. Many independent userlists can be
$ \5 M/ I; a0 b- a+ m( j used to store authentication & authorization data for independent customers.' J6 x3 S( K, \7 D! t
/ _2 |# D' h* `) e/ z
group <groupname> [users <user>,<user>,(...)]
% {- F% a& s. t: {, r4 s7 r2 W5 a$ `) q8 } Adds group <groupname> to the current userlist. It is also possible to8 x4 g. L F* K
attach users to this group by using a comma separated list of names
* U+ Z1 w7 F. u proceeded by "users" keyword.
8 z9 d9 t8 h, } u$ a- q4 x ?0 i1 d+ l% a! I9 o( J
user <username> [password|insecure-password <password>]
, u; @3 X, j, c0 X8 U1 O" S [groups <group>,<group>,(...)]
4 ? o2 t% ?9 d/ e6 J6 z- | Adds user <username> to the current userlist. Both secure (encrypted) and" H. O7 e/ n7 k3 Z" \
insecure (unencrypted) passwords can be used. Encrypted passwords are5 r# ~( n0 A, g
evaluated using the crypt(3) function so depending of the system's |$ m3 [1 l' h& I6 q
capabilities, different algorithms are supported. For example modern Glibc7 U/ L% i# T- C/ [- g
based Linux system supports MD5, SHA-256, SHA-512 and of course classic,5 G7 D$ ^" R c
DES-based method of crypting passwords.4 F4 I5 L) f, s5 p0 Y
0 N- t; v: b+ T! g
* Y# Y6 s- P3 X9 p Example:
! R; ?$ }4 ?' T q1 h4 Q userlist L1' _0 a- W6 @6 W! G2 N
group G1 users tiger,scott, @6 U" M% l$ V" ?) V7 x4 J3 m. A/ H
group G2 users xdb,scott; { h; W7 q4 O; f& a% ~
& g0 P4 t S" L; I& a& u: S4 s user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91) }4 Z9 E* O9 Q/ n8 z
user scott insecure-password elgato
# n9 T4 d7 _) k0 p$ |8 f9 S4 ~ user xdb insecure-password hello F" t. z' Q c, T3 b# t
! i2 r& K0 j& p
userlist L2
2 L- T7 |* v. L( e7 G6 a group G1" \7 z9 Z5 D1 p G
group G2$ J7 R8 [, x/ b
, B4 S/ {- W: a. m$ q1 \
user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
9 s! m+ i3 H( x( ?" k* C" Z user scott insecure-password elgato groups G1,G2- Q% C g; Y7 e8 f) M5 b9 p
user xdb insecure-password hello groups G2/ x3 }$ v! O f$ [# ?6 t
" g0 {/ w8 |" r( n9 G0 ]- a
Please note that both lists are functionally identical.
7 V3 Z' ?# A4 W
9 k# [" Q6 \( g2 m3 m5 V4. Proxies
) n$ ]* M* l3 P2 g6 P----------
. f6 X/ a0 q1 J6 x6 `3 Z9 w
4 ^; B3 U$ B1 e/ A' X# m' v3 jProxy configuration can be located in a set of sections :
: O8 e" s. [3 {) x. u4 P: s - defaults <name>
/ U. e# m$ |& E1 V0 g# E - frontend <name>
+ W0 E4 G9 }# H - backend <name>" T9 F! O. W1 H+ w9 x5 @
- listen <name>1 e V+ \# z- E
1 ]- h1 r; q4 W# N
A "defaults" section sets default parameters for all other sections following. c" |' }! ^0 B H- w7 d
its declaration. Those default parameters are reset by the next "defaults"+ o: D% o# k% d" m
section. See below for the list of parameters which can be set in a "defaults"
8 y. g7 ^- w$ C5 ?# g- H2 R- ~section. The name is optional but its use is encouraged for better readability." z" ^4 W: I; I* ^# t" b4 k/ T
$ x v" ~+ K. ^: O& E9 [A "frontend" section describes a set of listening sockets accepting client# A$ V6 P; \; x* A$ Q9 t" z7 I
connections.& w7 G2 b' {6 J- j! b* g- G- a2 ^
8 x) W U" S1 a1 [0 X" U' Y( L
A "backend" section describes a set of servers to which the proxy will connect
! g5 h6 w. i7 c7 B0 lto forward incoming connections.
" A. P, x3 b& @5 b
4 H, s- S, k: ]A "listen" section defines a complete proxy with its frontend and backend
! D0 }5 c5 s4 c+ F% x; Z# Rparts combined in one section. It is generally useful for TCP-only traffic.0 q$ u, R* M0 s4 a% P* d' @
2 z, w7 y& r0 Z) W
All proxy names must be formed from upper and lower case letters, digits,/ {' s* h9 l; m: c7 l1 K/ {
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are8 s4 L; D4 @: |% l
case-sensitive, which means that "www" and "WWW" are two different proxies./ }# F2 c3 i, i5 L- {
8 q/ z( l5 \% N" {8 n
Historically, all proxy names could overlap, it just caused troubles in the2 g& b# t9 I; T6 u
logs. Since the introduction of content switching, it is mandatory that two
+ s' v {; k3 S5 Qproxies with overlapping capabilities (frontend/backend) have different names.
% I' f4 ]/ e( j5 E( F0 y' _% VHowever, it is still permitted that a frontend and a backend share the same% f( O5 j o- Q2 ~
name, as this configuration seems to be commonly encountered.& X* r4 c: i' g# j& V
! }% C2 G: O# o$ s4 A# QRight now, two major proxy modes are supported : "tcp", also known as layer 4,
6 d! N9 o! A" F% Nand "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards; Z4 _* X+ \* a7 m, r! j8 Q: n. j
bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the: z3 F, V7 k5 s. ?. z9 a
protocol, and can interact with it by allowing, blocking, switching, adding,
& }& X$ E+ C7 Z. H3 g& Qmodifying, or removing arbitrary contents in requests or responses, based on
3 g& p) _2 ~8 O3 Tarbitrary criteria.
3 E A+ E' X4 D9 e+ k8 [ K B
$ x$ |+ c- O0 n, }7 L& Q0 ]) t' r# h$ t0 z; n1 P x
4.1. Proxy keywords matrix
9 m8 ^) N- l$ X- K9 f g" G1 u--------------------------9 T% H0 X i- \6 Z
$ F" P. m( y! _5 r* w
The following list of keywords is supported. Most of them may only be used in a
( D' e- E6 @; i1 \0 ?( P. climited set of section types. Some of them are marked as "deprecated" because
2 U& y9 y% b$ o8 g( Uthey are inherited from an old syntax which may be confusing or functionally8 K3 M0 k9 `- _, r8 `2 R5 b L
limited, and there are new recommended keywords to replace them. Keywords/ X" }8 }3 s; y* f" d q7 K
marked with "(*)" can be optionally inverted using the "no" prefix, eg. "no/ e+ i! [% s9 g* s2 E
option contstats". This makes sense when the option has been enabled by default# B1 i) H3 m5 B( w: A4 z/ q4 K* I
and must be disabled for a specific instance. Such options may also be prefixed
* D2 H7 V2 p5 s. ~9 swith "default" in order to restore default settings regardless of what has been
: k, V9 ]; Q S( {specified in a previous "defaults" section.) d% N3 g6 ^7 x, ^
4 S* h) B( A6 _1 { l* L
! y$ `4 K# b9 Y( U7 U
keyword defaults frontend listen backend
& n* U$ h' L: o/ ~ C, ]------------------------------------+----------+----------+---------+---------
( n4 C5 m" a1 M- _" F# n! d; Lacl - X X X
D! l$ Z/ |! D$ b4 F2 dappsession - - X X
. ?# ^$ O6 W) r) f, Q- E1 J! Ebacklog X X X -
; K9 r1 G0 T5 a8 p7 W1 }! hbalance X - X X/ l' t# b; s! v
bind - X X -& t5 y7 L5 x% @1 P9 q! p, q
bind-process X X X X! }/ O9 C- d; u* [$ l: n& c. Q
block - X X X
; J0 U; O* F1 O4 acapture cookie - X X -% t5 i9 | V, T* U0 [
capture request header - X X -
* i" |+ | p/ ~0 I' h& p& Pcapture response header - X X -2 v0 J# g. S7 _4 }" G" Y
clitimeout (deprecated) X X X -( c8 q0 ~: ?% X
contimeout (deprecated) X - X X
' d6 y: z7 a- L( N0 I; K' bcookie X - X X; C$ y1 z' V0 F" L) |
default-server X - X X
% n* M: u1 J! I3 o2 Ndefault_backend X X X -
: l( D2 U: c; t0 Y) U1 sdescription - X X X
4 Q. g: _; L. W4 r& ndisabled X X X X
0 \% m1 i/ V1 F8 l3 H9 {2 tdispatch - - X X W) B# k! M4 y" i& e
enabled X X X X
+ _& o( I u$ P, c! ~errorfile X X X X8 q, I& K9 e/ h2 G, M, g) g
errorloc X X X X
" \. G# F" f: Uerrorloc302 X X X X
/ P( k( l3 u+ ~/ j! R; k; ^1 T-- keyword -------------------------- defaults - frontend - listen -- backend -6 h+ `3 g$ i b$ U4 g
errorloc303 X X X X
0 b5 I' e/ K; p$ Q6 @force-persist - X X X
0 @ E3 R8 _" G% @" r0 nfullconn X - X X
3 Y$ f% H+ q5 y# h' @grace X X X X
# x6 |. S. C: ~4 F- b; {3 X. h% mhash-type X - X X
V" t7 c! {/ f0 R0 ~; Bhttp-check disable-on-404 X - X X
5 Z, i* `+ J5 w! yhttp-check expect - - X X
1 f- c1 F& a& W$ v0 Yhttp-check send-state X - X X4 {& g! b7 v, X* ]5 W" J- j8 y
http-request - X X X
: ~$ v0 F% |. t$ Oid - X X X
M: h' f j0 A$ p* G: m7 Jignore-persist - X X X# u5 R! @: e5 W" M
log X X X X
# }2 K: i7 r( b4 H! A" V/ l: Pmaxconn X X X -8 ~: m \) t# T, M) o
mode X X X X
5 x. F5 H2 w+ v& B) e) ]monitor fail - X X -
/ Y: z! A# g! E5 @7 z& r6 n7 Smonitor-net X X X -
, {6 Z7 E* o1 y2 ?" m/ D/ B/ Amonitor-uri X X X -, b) k: y" K2 ~6 z, b& O
option abortonclose (*) X - X X
, s3 M+ o4 Q% C! A8 g( u# Koption accept-invalid-http-request (*) X X X -
9 D" \" U& H% S0 Goption accept-invalid-http-response (*) X - X X( P; K- M: a$ I+ B/ _
option allbackups (*) X - X X
$ t. Z$ D: W/ P% [9 b/ Foption checkcache (*) X - X X4 E) c d. j; A D
option clitcpka (*) X X X -
! U& ]) g0 d& N4 Noption contstats (*) X X X -
) ~2 ~9 m R7 @/ G# eoption dontlog-normal (*) X X X -
1 g9 b4 M) G& l; c" H& K8 Y1 t: Z! ?option dontlognull (*) X X X -) d* v0 m. j% r6 F2 ?1 @" i- x
option forceclose (*) X X X X
0 B' |! }/ T Z8 Z: M7 E) x3 y3 v-- keyword -------------------------- defaults - frontend - listen -- backend -
. L1 f% v% ? {& E5 Foption forwardfor X X X X
" o) b- P; v& i; t6 B d4 Woption http-no-delay (*) X X X X
! b( Y) e- P5 X& |6 ^5 \& Boption http-pretend-keepalive (*) X X X X
& s, {9 H/ g R% x! ooption http-server-close (*) X X X X9 y- @: r" l. e$ a7 y; ^1 o6 `$ l4 z
option http-use-proxy-header (*) X X X -' H( M O! v X) p9 R( y7 W+ N
option httpchk X - X X/ l/ d1 }) G+ w7 F0 S
option httpclose (*) X X X X7 f8 }% s2 a8 H
option httplog X X X X
3 f& [9 e) e& Toption http_proxy (*) X X X X
# F$ u0 }: w4 `option independant-streams (*) X X X X
) E! f$ r) \) z9 g. xoption ldap-check X - X X$ Y8 }/ d& J& A: g9 U
option log-health-checks (*) X - X X$ G4 X) h, H1 s
option log-separate-errors (*) X X X -
8 H6 ?& O9 U, f& h& o6 koption logasap (*) X X X -
$ ?2 Y( G! q) o5 D& c! E' Moption mysql-check X - X X b$ |7 H0 }) [* F X& T
option nolinger (*) X X X X
0 T$ R$ x' L) Z: \8 Z6 ^" Goption originalto X X X X$ b) H; i& [0 ~5 n* F
option persist (*) X - X X: d5 ?* A4 o- \+ `
option redispatch (*) X - X X/ Z( i( Z% F' k( ?- w
option smtpchk X - X X
6 \# l6 ~ o: ]option socket-stats (*) X X X -
& n6 ^2 u+ F0 X% j3 V2 H4 noption splice-auto (*) X X X X, V, d8 \, Z' T* `
option splice-request (*) X X X X
. U! y* c5 ?4 J6 R; G7 F& voption splice-response (*) X X X X
# c3 s, n" |6 x+ \# c8 n! ^# yoption srvtcpka (*) X - X X/ K* I1 z. o& T& d" z3 w# v/ S
option ssl-hello-chk X - X X
7 J; Z6 p2 W! C! n-- keyword -------------------------- defaults - frontend - listen -- backend -
& W9 X) r1 h- r0 s: N. q* zoption tcp-smart-accept (*) X X X -2 S% f2 c' j1 h' q, ~
option tcp-smart-connect (*) X - X X0 x5 M* T* w8 H( k: {
option tcpka X X X X! j' H: n1 h+ i/ l/ @2 f8 b* Z
option tcplog X X X X
, L, [+ p& ^7 Q* K9 A" Koption transparent (*) X - X X
/ {3 A P7 E T, spersist rdp-cookie X - X X" G# h% `5 z7 u$ B" y, J. w; G
rate-limit sessions X X X -' _: [6 q: N* H
redirect - X X X* W: h W# C1 b# ?! q& _2 I0 m
redisp (deprecated) X - X X+ I( v: p& J5 U' i O3 a
redispatch (deprecated) X - X X
9 I' F. r/ y0 a1 F/ ?7 w. Nreqadd - X X X" [2 I+ X- Z* d
reqallow - X X X
5 ]2 ^) b# W' K8 e& wreqdel - X X X) ^) i. j7 d/ u
reqdeny - X X X, {- X' K( m& {8 V, e
reqiallow - X X X) s) y# Z$ c9 `/ w& k ~, v
reqidel - X X X# [: ?$ |+ ]( N1 U
reqideny - X X X3 I, f9 y/ J/ D' f9 r5 c0 t
reqipass - X X X$ ~ b7 f B' V& E4 W) n- \2 n8 X
reqirep - X X X
. k0 m: `- e8 _& }9 f# areqisetbe - X X X
5 Y% v1 M- k4 C. Q1 l3 d; e0 Qreqitarpit - X X X
2 T2 x$ B* |) D* r6 Z8 Areqpass - X X X
: \/ R8 e$ Y* U5 L/ y' ireqrep - X X X
" m3 ?8 s+ C: k. w. R; h/ }-- keyword -------------------------- defaults - frontend - listen -- backend -$ Y6 m! C8 q4 Q- j8 T7 ?
reqsetbe - X X X
, g! g) T% [$ W8 V" n& C" @3 rreqtarpit - X X X' I% K7 s& f1 }7 ^% }* J( }; S
retries X - X X8 W! H3 L* s/ D% X1 N
rspadd - X X X& h/ k% t4 E$ r7 K% e
rspdel - X X X
; |3 d" r: h$ ^5 ^rspdeny - X X X4 g# L$ H* G, {; D/ p) K+ I
rspidel - X X X5 {8 ^: y$ V$ q5 b2 U/ U/ N. o! q
rspideny - X X X5 i' b! G/ w0 n. I4 l2 x
rspirep - X X X4 T0 X& f' r, C# `0 s' x. E& f! P( B
rsprep - X X X
; L- e5 n* u! o) j) Dserver - - X X
, D9 ^) A" Z4 @$ y1 w% osource X - X X& w* u: K' H3 h* Y; }( _% o0 X$ p
srvtimeout (deprecated) X - X X
& ]! m7 A Y5 L4 I: Pstats admin - - X X
: M1 B/ Y& ?" m$ n2 q4 ?7 [7 bstats auth X - X X W9 J! V o* s: R- w
stats enable X - X X6 b% e& f' E9 Y: ? [ s# Y4 P
stats hide-version X - X X
* s8 b2 R/ o# [$ Dstats http-request - - X X
2 X- Q8 @% U6 Dstats realm X - X X
/ N/ P# r3 |2 f( }7 tstats refresh X - X X
) t8 Q9 S. n& K' K5 Jstats scope X - X X
3 H6 M! \" u% L7 C7 d6 o- |stats show-desc X - X X
$ D# M3 M9 P0 X4 Rstats show-legends X - X X
. ?- D9 Y' H+ [stats show-node X - X X
* f! ]8 b/ N! Vstats uri X - X X
P/ a' M J( Y7 K-- keyword -------------------------- defaults - frontend - listen -- backend -
& v, a8 T& \( A7 Jstick match - - X X: F6 R! i! o4 y$ d
stick on - - X X
0 c! R4 U& Q7 [; F2 jstick store-request - - X X
0 g4 p5 Z9 g8 x# D9 istick-table - - X X
! L: e% F/ {5 \& etcp-request content accept - X X -5 k: [1 m% |) P1 o
tcp-request content reject - X X -9 K% Z" i% R2 ?
tcp-request inspect-delay - X X -
% O! b* O7 K( etimeout check X - X X
6 R1 P6 B8 }9 t# v2 _/ S' ?' ntimeout client X X X -% A) o" ]5 N7 l0 B; }$ Q$ K. O
timeout clitimeout (deprecated) X X X -
+ t3 C' n3 f8 z @timeout connect X - X X, o: h& P2 R& I$ {3 q3 H ^
timeout contimeout (deprecated) X - X X6 z' `4 y7 A3 `; W1 e
timeout http-keep-alive X X X X
5 ?2 l# p/ q3 Z3 wtimeout http-request X X X X
7 h' |7 u" N) H% f1 g0 d4 Utimeout queue X - X X7 W9 ?# @. o. ~% W0 t+ a
timeout server X - X X
: t6 r! d. W2 S6 Y0 e. q0 Gtimeout srvtimeout (deprecated) X - X X
% {: g0 J- V G: otimeout tarpit X X X X
; x% @7 u4 n! U8 Ktransparent (deprecated) X - X X
& H/ {' C/ ~1 _+ @: quse_backend - X X -3 @+ W# Z1 i5 f+ m8 |- f2 {
------------------------------------+----------+----------+---------+---------
4 ?$ y( G& T8 ?6 s# F keyword defaults frontend listen backend- H2 X7 z" @4 H( ^6 Y
) g E; J9 L- c% a
0 G; t$ w% v3 M: t; G% K% S
4.2. Alphabetically sorted keywords reference' m% f8 q4 [0 q4 o
---------------------------------------------* s* p! K8 [3 @0 x2 L& A7 _( ?4 f
+ z3 w, G7 c' b' a# I
This section provides a description of each keyword and its usage.5 D9 a8 Q" t4 ?6 U+ D$ S2 T
. e8 W3 u6 w3 K! g# \
; x" s$ k. u7 y. W; ~0 ^acl <aclname> <criterion> [flags] [operator] <value> ...- Y# b. }6 o$ w4 H2 d5 H
Declare or complete an access list.
, {+ Z, D$ [' v% U" m$ M" J8 b/ | May be used in sections : defaults | frontend | listen | backend( q( |5 f2 ~# G) }8 E' ~% n' d+ B
no | yes | yes | yes* R+ `6 l2 W4 c9 `% O3 J
Example:5 V/ u7 l% q# @' E1 p; z6 [
acl invalid_src src 0.0.0.0/7 224.0.0.0/38 Z8 @, W5 n3 h* C7 M! }
acl invalid_src src_port 0:1023# k! S1 K1 Z2 Q" b
acl local_dst hdr(host) -i localhost
! U1 k5 a1 j! t1 H6 p
( C( ]/ t, K( e* c2 t See section 7 about ACL usage.+ F, I0 r3 t$ a, X) x$ `
2 _$ Y3 @" Y4 L& h6 S& o' C- d
5 H/ j) L8 V- @) k6 P: E$ tappsession <cookie> len <length> timeout <holdtime>
- {3 ^* H6 H S: D2 f [request-learn] [prefix] [mode <path-parameters|query-string>]
& _" ^6 V' s4 G2 @6 z. Y Define session stickiness on an existing application cookie.8 C5 c, S: _" z7 q
May be used in sections : defaults | frontend | listen | backend
3 d, E- G2 k8 }/ ?; a no | no | yes | yes& t/ J( E$ P! g6 ^/ |: w
Arguments :
; \6 }; S2 }% b) e2 i% C <cookie> this is the name of the cookie used by the application and which
* }% A, b: o& C. E4 i HAProxy will have to learn for each new session.
0 V' T* W) a/ _0 R' \
9 w$ ]- \* d+ `6 x: U6 _ ^" C <length> this is the max number of characters that will be memorized and
- E6 j% H }7 J/ o5 y9 @2 R- x checked in each cookie value.) ^( s8 [5 ~, @
) }" d: F) O2 g* @+ m <holdtime> this is the time after which the cookie will be removed from
! y' P0 W3 d0 l/ G' B6 _7 ^ memory if unused. If no unit is specified, this time is in( c+ X# M) h* a' ?' @1 a Q
milliseconds.
" ]. s, @& j+ O) }
3 i/ }" P3 K+ i3 N request-learn6 I$ i0 O/ y y7 [0 m2 |6 |& e
If this option is specified, then haproxy will be able to learn" k. x1 O3 ~( H& H: Q# [6 Q
the cookie found in the request in case the server does not
( b" ~% I. V6 l1 B- p1 C# v specify any in response. This is typically what happens with
& C6 d6 w! F2 u! ]3 y" m, i PHPSESSID cookies, or when haproxy's session expires before
0 c1 P8 b4 k8 P/ `' U8 c2 |4 ~ the application's session and the correct server is selected.; L0 N$ h! E9 r6 [
It is recommended to specify this option to improve reliability.
& }% E. Q7 T7 l6 n7 u4 a, T; }3 o9 p Y
prefix When this option is specified, haproxy will match on the cookie
5 m, E# t$ \2 @- R3 P prefix (or URL parameter prefix). The appsession value is the& [- x, s! V/ @
data following this prefix.) R1 p9 X1 w: G7 v5 x1 \
|) e, V" n8 p
Example :
6 `: j% M. }9 x% q appsession ASPSESSIONID len 64 timeout 3h prefix- ]8 e& p# q0 U8 }
% |6 o2 u8 g4 m5 ] This will match the cookie ASPSESSIONIDXXXX=XXXXX,1 ?, R; f' \5 b4 e i4 e
the appsession value will be XXXX=XXXXX.
& f* U- }9 H" P7 d3 @- T; K: u
, v$ ~. _) ^) F# n( T: ~ mode This option allows to change the URL parser mode./ _8 a# N* Z& V5 G* Q3 Q, P9 W
2 modes are currently supported :
& c, U8 e S0 u3 U9 V - path-parameters :
) u) N; y) [% q7 m/ x The parser looks for the appsession in the path parameters
1 l) @. b9 d" ^* ]3 _ part (each parameter is separated by a semi-colon), which is5 H( S l. T. n3 e! l
convenient for JSESSIONID for example.' D( j4 I- H2 p5 r4 i5 X- o8 {
This is the default mode if the option is not set.( C! Z( U2 e V6 |- @; N: |
- query-string :# V/ e2 w; K L' K9 {
In this mode, the parser will look for the appsession in the
w, P& y4 ?$ D4 b' T3 u6 R query string., M- ^+ R1 `; {/ R8 J6 A5 H. M9 Q
9 r1 \3 W4 f; q2 ]% l% }
When an application cookie is defined in a backend, HAProxy will check when, p8 M* H4 k$ G
the server sets such a cookie, and will store its value in a table, and) d& X: M2 b- y/ B% i% \. u
associate it with the server's identifier. Up to <length> characters from2 r4 c- F' g" k3 v
the value will be retained. On each connection, haproxy will look for this
& O* n6 ]) ]. t0 j" }0 E6 w! X1 L+ y cookie both in the "Cookie:" headers, and as a URL parameter (depending on' F I @ Z5 p0 o' Z$ R
the mode used). If a known value is found, the client will be directed to the" H k: y4 Z9 c( v2 u7 H
server associated with this value. Otherwise, the load balancing algorithm is
/ D5 L: h- v3 F& R8 [ applied. Cookies are automatically removed from memory when they have been; b% }- P- c9 N+ E: g9 c' v5 E3 Z
unused for a duration longer than <holdtime>.& w7 u F) P$ q! S9 K- N
" B( `7 L2 V7 {. S5 U& p5 a% h" q
The definition of an application cookie is limited to one per backend.
+ ~. M1 x8 z& \$ b7 W, I. {. m) P5 N! D2 ~
Note : Consider not using this feature in multi-process mode (nbproc > 1)
1 V$ i+ q% r) @ `: b unless you know what you do : memory is not shared between the5 ^0 l# m; w& L/ P+ [
processes, which can result in random behaviours.3 S/ Z6 w z8 w0 P. A2 b
: L5 C2 w5 {4 H& Z6 X
Example :1 S* V3 }9 N6 Q$ w& A2 L
appsession JSESSIONID len 52 timeout 3h
0 g9 V/ i/ l4 b% A/ _2 H6 W: n |' B
( Y6 R: ~7 Q1 ^- x& b8 `) n See also : "cookie", "capture cookie", "balance", "stick", "stick-table",7 t' _! ?& m' t0 a+ {
"ignore-persist", "nbproc" and "bind-process"." J! ^( ?* @ N7 C+ z3 M* E P
- f+ h8 n5 t7 e) Y4 J' H5 S
$ U7 u% ?. f$ W0 F, a* d6 nbacklog <conns>
2 o4 X$ K1 o' E2 ?. S9 b Give hints to the system about the approximate listen backlog desired size* v9 w- Z2 Y- t6 D2 E# ~& i
May be used in sections : defaults | frontend | listen | backend
$ I% |6 f" h* }+ {2 M- k& I: @ yes | yes | yes | no
) p1 B3 h( k0 L& d Arguments :4 `* A. e+ |) Q2 _6 S$ K4 F8 U. p
<conns> is the number of pending connections. Depending on the operating
1 l5 h% m9 r x! z* k system, it may represent the number of already acknowledged# W' h+ `' A/ p6 q2 W
connections, of non-acknowledged ones, or both. ~. r( p. ^6 Y6 M* J
8 I3 m: t) V* }2 x
In order to protect against SYN flood attacks, one solution is to increase
; N! W8 C% p' N. I9 Z the system's SYN backlog size. Depending on the system, sometimes it is just
! x7 x m9 c, Y tunable via a system parameter, sometimes it is not adjustable at all, and
" Z4 Y) n8 i' ]7 `/ _" m sometimes the system relies on hints given by the application at the time of
. @/ {# X [4 v% b the listen() syscall. By default, HAProxy passes the frontend's maxconn value- e, w9 R: I9 m* H- T
to the listen() syscall. On systems which can make use of this value, it can4 B* r6 k I P
sometimes be useful to be able to specify a different value, hence this) }* D5 I7 R# ^) ?% v W
backlog parameter.
7 @) O( Y* F5 o/ ]7 v* A; ]6 k; c/ f9 X* v7 r* }
On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
- o" G, V, b$ T1 V used as a hint and the system accepts up to the smallest greater power of
2 f) R J5 N3 i9 o2 k# V- f two, and never more than some limits (usually 32768).
' b* j5 g! T" Q: {& e8 l& n9 F) f9 O X- x5 Z$ c6 t
See also : "maxconn" and the target operating system's tuning guide.
' C0 [; b9 @* B6 t# m4 ^
' O3 g/ J- t5 B' f$ |9 ^& {& c5 {
# W: D/ m- L, L8 p9 b" j' }( lbalance <algorithm> [ <arguments> ]
4 f+ b$ d9 ^. Ibalance url_param <param> [check_post [<max_wait>]] i" o% V$ ?& }* E. W0 X9 W
Define the load balancing algorithm to be used in a backend.
' V" F% e$ e% o( J9 L* T/ H May be used in sections : defaults | frontend | listen | backend
: U5 P2 u3 U' C+ T yes | no | yes | yes5 b2 ?! V5 B4 U9 {
Arguments :9 P' c) F( L0 r. k
<algorithm> is the algorithm used to select a server when doing load( I& E% V7 \/ ~% G
balancing. This only applies when no persistence information
) x- E8 T e7 r7 @' @5 Z is available, or when a connection is redispatched to another
- Z7 ~/ s9 n% j# I6 G( T& } server. <algorithm> may be one of the following :/ h T& ]+ V& m0 Y
( F4 Q- m6 u( L% F% Z# ~, x, o" ?
roundrobin Each server is used in turns, according to their weights., K- W4 ^8 m6 J. ?0 W5 Q
This is the smoothest and fairest algorithm when the server's
9 D7 L# R) ]* K' e processing time remains equally distributed. This algorithm& I" c+ R+ i$ x) S, d
is dynamic, which means that server weights may be adjusted
V7 m1 L( l) I* U+ m on the fly for slow starts for instance. It is limited by& X% P# x6 S* e4 u8 J8 }
design to 4095 active servers per backend. Note that in some/ N2 @; u( k; o* h
large farms, when a server becomes up after having been down. P0 n' J$ I0 C+ m" D2 t/ W) n& j
for a very short time, it may sometimes take a few hundreds
6 H+ } V$ V; m. N# N requests for it to be re-integrated into the farm and start
, V$ c# A# Q, P) r R/ D receiving traffic. This is normal, though very rare. It is. Q1 _- h; Z E1 I5 n
indicated here in case you would have the chance to observe B E! ?# y# I" C* p' ]* g1 d
it, so that you don't worry.
% F+ H6 Q7 g1 T: h0 o! R
. Y, Q3 \$ Z N+ c8 x5 A7 c static-rr Each server is used in turns, according to their weights.
! L" k, P" K2 V- n7 x This algorithm is as similar to roundrobin except that it is1 P7 J* E. ~0 n% T \
static, which means that changing a server's weight on the
4 V+ |% o! `' X4 Z& n' o" l n2 D fly will have no effect. On the other hand, it has no design( e8 }! \9 A8 w7 {$ U+ n
limitation on the number of servers, and when a server goes9 S* l& d! l4 M E( k8 d4 k. C' x
up, it is always immediately reintroduced into the farm, once
- G9 |- q |" y the full map is recomputed. It also uses slightly less CPU to
5 @4 F1 U: p4 J* l; M9 y9 f4 C run (around -1%).
- @4 P l0 x; w$ R! m( v) Y. i6 n4 z% A2 u, S9 S$ L4 f
leastconn The server with the lowest number of connections receives the5 Y/ W5 u# W1 a, S
connection. Round-robin is performed within groups of servers
0 C0 X) b6 _, g- K8 D ` of the same load to ensure that all servers will be used. Use
- T3 J, k. y* g! j. n" t of this algorithm is recommended where very long sessions are3 h+ ?: w8 U$ O B! k2 ] q T
expected, such as LDAP, SQL, TSE, etc... but is not very well
( D8 E( ~( z- T3 o, Z2 D K suited for protocols using short sessions such as HTTP. This
0 d3 \7 n+ d# E% j algorithm is dynamic, which means that server weights may be
! r% S; ^: G' ]& p$ N adjusted on the fly for slow starts for instance.# U6 \7 @+ z8 q; z. Z) l: D2 }# |/ S
v# H4 i* f5 W2 r source The source IP address is hashed and divided by the total3 \$ J# F9 k1 Y8 s% E; W4 u# p7 l
weight of the running servers to designate which server will
9 }& |; d5 A( l; R receive the request. This ensures that the same client IP: G4 F0 j. B) d. }0 ^& i; Z
address will always reach the same server as long as no, S# i) g1 O$ G5 l; f) \6 q, j
server goes down or up. If the hash result changes due to the+ m' e# f! s! _, r7 |- _& ^: [" j: Z* |. a
number of running servers changing, many clients will be$ t8 Y( l$ \: a7 t- t. d
directed to a different server. This algorithm is generally
' w( M4 Q( d6 q! q; t5 X used in TCP mode where no cookie may be inserted. It may also
P0 ~4 B5 q& I0 k# v be used on the Internet to provide a best-effort stickiness* k. Y+ x- i, [8 ?- [
to clients which refuse session cookies. This algorithm is# }( B- @, G- {4 q7 O, P% x
static by default, which means that changing a server's6 y- [/ s' ` g0 U' X; N8 X( G- v
weight on the fly will have no effect, but this can be
# i s: j% G( @/ N7 y' b$ p1 ^ changed using "hash-type".% V" E# I. k# I; O. P
" X7 B4 w0 d* E& M5 P, A6 T3 h1 B- g uri This algorithm hashes either the left part of the URI (before# i, ~* ?1 U ]. Z3 W! e( a4 ?
the question mark) or the whole URI (if the "whole" parameter
# t- {2 c) t, E% Z' F2 _ X8 ^$ H is present) and divides the hash value by the total weight of
; j! V) I7 F* a9 | the running servers. The result designates which server will
$ w/ S' }# P* A- L* w receive the request. This ensures that the same URI will
5 Q: N% `4 B! \* q! M( s6 ]4 ^5 b always be directed to the same server as long as no server# w6 _1 y( e0 N; @( J! g9 o
goes up or down. This is used with proxy caches and1 V9 X ^ H" {3 g' |# G
anti-virus proxies in order to maximize the cache hit rate.( F) Y5 R# l, K
Note that this algorithm may only be used in an HTTP backend.1 Q, B5 f6 z$ X7 l) ~% e# C8 v
This algorithm is static by default, which means that" H' b; \( p: |. Y4 @: v( Y9 n
changing a server's weight on the fly will have no effect,
, r, s2 [8 \7 I6 d2 x: `) u4 ^" e1 g but this can be changed using "hash-type".
4 @8 c2 X' ?/ h" r
9 K5 C2 x# C8 ~8 E. q This algorithm supports two optional parameters "len" and
# b! t' z# j5 E/ O* L. D "depth", both followed by a positive integer number. These! J! G( B6 m, T! K
options may be helpful when it is needed to balance servers8 @7 L4 r' `- D* g, K& A
based on the beginning of the URI only. The "len" parameter2 x: f0 d+ |2 |3 F
indicates that the algorithm should only consider that many; z9 X, V. l, K1 }3 q% K
characters at the beginning of the URI to compute the hash.* M2 k1 [+ r# G& Y2 k; H# a
Note that having "len" set to 1 rarely makes sense since most/ V- j! e! J6 K( Y( s V
URIs start with a leading "/".* l$ X- c9 a" w0 K T2 O
4 L' A+ Y! p) b6 T9 v
The "depth" parameter indicates the maximum directory depth/ E7 z4 g1 y6 q2 U0 B7 @
to be used to compute the hash. One level is counted for each9 m. h- l( E: {! Q0 s
slash in the request. If both parameters are specified, the t# x7 m2 F8 p% [7 P$ r0 N
evaluation stops when either is reached.
( s- S2 L7 Z0 b4 K. _+ t- x8 k9 M( |% Z: W& \- [/ d7 S
url_param The URL parameter specified in argument will be looked up in j! Q [( w- k+ t) V2 y. B9 U" ^8 ~
the query string of each HTTP GET request.
- j3 x( |7 I. z+ y7 m
" g7 H9 F$ j: O: K+ b- n If the modifier "check_post" is used, then an HTTP POST
+ S4 D3 B6 h8 ? c/ p request entity will be searched for the parameter argument,
8 m. ]) _3 Q. [5 c when it is not found in a query string after a question mark& M, g9 |* C2 g7 U' I8 S1 ]2 _: Y7 d
('?') in the URL. Optionally, specify a number of octets to
3 m b+ n5 q9 y! r- c2 i% e1 E wait for before attempting to search the message body. If the
2 b- s: j# ]8 \+ u$ o6 S* I) n. p4 L* @& M entity can not be searched, then round robin is used for each
& ?" t& {- I$ s0 {+ f: j1 }$ H request. For instance, if your clients always send the LB' b7 U: ]3 ~: T
parameter in the first 128 bytes, then specify that. The
. k. K, D1 G" R default is 48. The entity data will not be scanned until the
3 v; M5 K* i: V" A/ m+ v# h* w. @ required number of octets have arrived at the gateway, this
$ C2 k2 d9 J+ F, L6 ^) I/ T is the minimum of: (default/max_wait, Content-Length or first# n9 q" V" H# B" j2 ]/ W
chunk length). If Content-Length is missing or zero, it does1 ^5 h# }$ M' {; C$ ?( z; I
not need to wait for more data than the client promised to
1 P0 u2 V* l+ D' T5 W send. When Content-Length is present and larger than e! ~, J4 N9 r6 @) s3 H4 C
<max_wait>, then waiting is limited to <max_wait> and it is P$ N- @* D/ G3 Q- D4 [6 b
assumed that this will be enough data to search for the0 a; ^2 z4 x( C9 y, G7 @
presence of the parameter. In the unlikely event that( l- P8 d1 t8 z! |' g
Transfer-Encoding: chunked is used, only the first chunk is
4 ^# }! h, A9 V0 M* w. v; } scanned. Parameter values separated by a chunk boundary, may
; S, F5 t$ L" f4 `6 [7 I be randomly balanced if at all.! D: e5 z6 {& \0 n6 D. `
9 G7 {9 X! O+ P If the parameter is found followed by an equal sign ('=') and' V% M% t! l( I0 S3 x, D4 _8 {# m' B
a value, then the value is hashed and divided by the total
' g2 x7 P2 Y2 H: T; x5 n weight of the running servers. The result designates which( T- |8 g/ v! ]' B
server will receive the request.
' o" C. N; w4 h+ P7 f
1 b6 F$ Q$ h) ~. B6 s This is used to track user identifiers in requests and ensure0 k. u) K% U! S) _0 C
that a same user ID will always be sent to the same server as9 S* a, R M6 X W, ^2 j' L) z
long as no server goes up or down. If no value is found or if
: J2 I6 k3 L8 ^' B# Z the parameter is not found, then a round robin algorithm is/ b! K- d" R3 ?; }
applied. Note that this algorithm may only be used in an HTTP! a& r: B1 f5 p: ~
backend. This algorithm is static by default, which means
& K7 S- G k/ v% ^0 ?% } that changing a server's weight on the fly will have no
% c: b: r6 z c4 S effect, but this can be changed using "hash-type".
1 I# c$ a7 R+ n! w3 N
9 p* {/ z+ U; i- K. a1 Q- r( v hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.& u) l" v3 W' [! k
Just as with the equivalent ACL 'hdr()' function, the header" r2 }8 F* j4 v/ s1 O
name in parenthesis is not case sensitive. If the header is
3 T- A& F& i* E8 ?/ s; Y1 j6 Y absent or if it does not contain any value, the roundrobin
* B T& u, D7 v" G$ r9 y) n algorithm is applied instead.
/ k: T9 Z. n9 g+ s; i3 f0 K8 G7 h( A+ } ]9 \) {6 [
An optional 'use_domain_only' parameter is available, for/ s, {$ J, `. L8 v* r9 r! c
reducing the hash algorithm to the main domain part with some
( D. z v' j/ H5 H7 ? specific headers such as 'Host'. For instance, in the Host
" c" H; X1 [, W' M% A value "haproxy.1wt.eu", only "1wt" will be considered.
" ?; D4 ]: R3 o% J: G
% ~8 i# P' X W7 S7 k This algorithm is static by default, which means that* L& ~8 [% P0 ]7 Y
changing a server's weight on the fly will have no effect,. [# P$ [8 x" X% f+ o$ m
but this can be changed using "hash-type".
- P* ^( {9 g' C, D" Q* f6 r' D r
rdp-cookie+ P3 O; K l4 E& n& f
rdp-cookie(name)! o2 i+ N H2 E6 p. p& Q$ \
The RDP cookie <name> (or "mstshash" if omitted) will be
6 j4 @0 m, ~9 h9 [( U8 n. [ looked up and hashed for each incoming TCP request. Just as# n& e# {' d" g- R9 G6 L
with the equivalent ACL 'req_rdp_cookie()' function, the name
2 R2 Z. H9 E' \ is not case-sensitive. This mechanism is useful as a degraded+ L# }2 U1 D% J
persistence mode, as it makes it possible to always send the
" B- f8 O. X$ n! n, |8 | same user (or the same session ID) to the same server. If the
- ~, Q4 e( s4 [8 o- x cookie is not found, the normal roundrobin algorithm is: A% P1 O& c7 e
used instead.
+ v5 B( V4 p, o7 v
6 P; s4 f9 {7 x/ {" u. d3 g/ t Note that for this to work, the frontend must ensure that an0 A; O- M& U% B& B5 p
RDP cookie is already present in the request buffer. For this
' h8 k/ u# Z& D! F0 Z$ R- q you must use 'tcp-request content accept' rule combined with; k# k# |# M1 Y+ O- a2 ?
a 'req_rdp_cookie_cnt' ACL.
1 M K0 v$ y6 J! c# y0 K7 H4 Z& O8 {" x& u- m# L
This algorithm is static by default, which means that. M& j, d% A- E
changing a server's weight on the fly will have no effect,
; X% a( [) E1 D1 G$ V but this can be changed using "hash-type".
0 x) ]) d; W+ r
. S7 Z: }9 G7 V8 ^ <arguments> is an optional list of arguments which may be needed by some; c5 ], D7 d8 F; s1 r0 ]' X
algorithms. Right now, only "url_param" and "uri" support an
$ Z B5 w T& t' P8 D, N0 c$ D optional argument.
/ N6 s; _0 h( I* @- \% B2 N \& h. X; P( h% z
balance uri [len <len>] [depth <depth>]! v# S: W8 i- B$ k
balance url_param <param> [check_post [<max_wait>]]
3 o: G% b: ?- A+ }9 a2 a
( c: P( k# @0 F4 p" Q: y; N The load balancing algorithm of a backend is set to roundrobin when no other+ P9 m; b; |4 n+ U$ ^$ D
algorithm, mode nor option have been set. The algorithm may only be set once
; H$ U. u. C; h) `% V- s2 | for each backend. Z% a+ f _, m' M' e
' T) D' }+ |* [0 | Examples :$ C; i- L Z1 T9 _% Q& a
balance roundrobin
( z. \) `' C% L balance url_param userid4 [4 i, i! g( |. K
balance url_param session_id check_post 640 g) n; k1 R2 p" y- L* p' q
balance hdr(User-Agent)8 h1 V( H4 @5 Q' F4 v J
balance hdr(host)6 n& x8 A7 P& ~4 x! b4 h
balance hdr(Host) use_domain_only
. v1 E8 y" G0 V" r1 J" F. w) }, k$ V: I/ a; q" E+ S
Note: the following caveats and limitations on using the "check_post"" @5 S+ {9 Q: Y6 ^$ K8 F0 E( ]
extension with "url_param" must be considered :
+ ^% J! j" ?( T! [! t
! ]7 P% Z8 y6 |4 T9 B( P" y - all POST requests are eligible for consideration, because there is no way
4 m, A; x. n P3 U6 [; c Z to determine if the parameters will be found in the body or entity which
9 N& z1 I: S4 h$ N: y/ V% o may contain binary data. Therefore another method may be required to
2 R" T8 v$ `/ e2 F+ D5 r restrict consideration of POST requests that have no URL parameters in2 W. {/ c, P. A9 k
the body. (see acl reqideny http_end)7 U; R! f P& T4 a2 R# o2 ?
, `3 e) F- @$ t$ a5 `+ o! H- _
- using a <max_wait> value larger than the request buffer size does not8 N+ ]( p' y# L" o6 o: [. j1 a$ }" \; b
make sense and is useless. The buffer size is set at build time, and
& b! X1 L' _/ [" q" S$ x defaults to 16 kB.
3 e4 W% u8 }3 e. H3 y* k* }
$ U' v3 x9 r8 {# c - Content-Encoding is not supported, the parameter search will probably
! ^# X5 E/ r) J6 l) b& s fail; and load balancing will fall back to Round Robin.2 P) t# N0 \ \
) m+ z8 u$ V# w. x/ ` - Expect: 100-continue is not supported, load balancing will fall back to$ R, V* m# ~1 U5 J" [, C
Round Robin.) h& m8 w" o2 d+ i* u! e% @- U: L
' L" F" t8 F9 P
- Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.. w, |- p1 V& ]: ~& {
If the entire parameter value is not present in the first chunk, the
6 {1 r' ~* ?3 _9 ]. h selection of server is undefined (actually, defined by how little) a) ~2 h* X+ |
actually appeared in the first chunk).* y/ T2 o6 u) t6 V8 @. F, R
' u' a; E6 q3 p - This feature does not support generation of a 100, 411 or 501 response.9 f& \- B# i3 a# }) C# N
4 \7 E4 z# s: A* V" g
- In some cases, requesting "check_post" MAY attempt to scan the entire5 ^! u) Z; C- b" u3 u, c
contents of a message body. Scanning normally terminates when linear5 F( J3 ^ U9 j5 F& O" M
white space or control characters are found, indicating the end of what
( Y' _6 Q- D% U. [4 s0 b/ s might be a URL parameter list. This is probably not a concern with SGML2 f4 y. `1 g+ F$ V, n
type message bodies." a7 D3 {5 F i% ^0 B
* l3 S5 j* S- N; t3 R
See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and
$ c9 M; z3 X* O$ E+ x "http_proxy".; Q, C& U& d1 f
- G0 \3 Q1 k0 i/ q
9 l% G/ _) L5 k* n0 }+ v! pbind [<address>]:<port_range> [, ...]
7 l1 P4 A. V/ k8 i* h* s/ `bind [<address>]:<port_range> [, ...] interface <interface>0 n. S$ F3 g v0 T0 ]
bind [<address>]:<port_range> [, ...] mss <maxseg>+ _! V( m$ U7 \/ {5 n) L$ t
bind [<address>]:<port_range> [, ...] transparent+ w5 i; s# T, C: j* `! D o: y
bind [<address>]:<port_range> [, ...] id <id>4 ~ P: q4 e$ w2 G1 Z' }1 ^) e
bind [<address>]:<port_range> [, ...] name <name>; `% B3 |4 I( b g* I5 A
bind [<address>]:<port_range> [, ...] defer-accept/ l" T+ `+ Q% W. m
Define one or several listening addresses and/or ports in a frontend.
$ s7 z- d- G/ ]/ S e ~5 y May be used in sections : defaults | frontend | listen | backend- m" ]8 F. Y* D: b
no | yes | yes | no. r/ A# O B7 r8 I9 M7 x X
Arguments :1 z2 w6 `6 X& {3 d
<address> is optional and can be a host name, an IPv4 address, an IPv6
" F: H8 A" `' _* y+ j address, or '*'. It designates the address the frontend will, _- A3 R6 q/ Z9 O: ?
listen on. If unset, all IPv4 addresses of the system will be
6 X/ t0 q8 _( s6 [ listened on. The same will apply for '*' or the system's
9 J' I8 D3 T1 |2 Q7 | }9 Y special address "0.0.0.0".6 C" R& c( x- `) D9 B
' d! V- P. W/ G4 a A) b3 u [ <port_range> is either a unique TCP port, or a port range for which the
0 H% P; e R3 y* } H proxy will accept connections for the IP address specified/ B) X& }+ ~5 a4 C
above. The port is mandatory. Note that in the case of an
. @5 W5 t8 m- t1 C" {7 {, D IPv6 address, the port is always the number after the last
# o5 L& b; @8 E G% S colon (':'). A range can either be :
# Y- i8 p$ N( X( s9 E, l - a numerical port (ex: '80'). _8 j+ @) d3 v! l
- a dash-delimited ports range explicitly stating the lower. v% A4 K' F' _
and upper bounds (ex: '2000-2100') which are included in8 ^+ H/ Z5 T% f |3 P. t
the range.
: u1 }' s- p, K' {. i5 S" U2 Y; I9 B2 V: {: v
Particular care must be taken against port ranges, because
5 S) F5 p: B- P \+ B6 _ every <address:port> couple consumes one socket (= a file& H4 ~5 ]3 q$ Z: d2 K4 t' g
descriptor), so it's easy to consume lots of descriptors$ e9 z; v7 s0 E' E" P5 d6 x* g1 L
with a simple range, and to run out of sockets. Also, each5 g6 z5 r$ M& ~- _5 T) D
<address:port> couple must be used only once among all6 a* x" j# M% ?3 g& m: T! [5 L) u
instances running on a same system. Please note that binding
/ z' W" {& n0 Z, W4 ~0 H" D to ports lower than 1024 generally require particular9 F$ |6 C/ p3 _0 X
privileges to start the program, which are independant of7 q8 ~2 L" \" B! T7 s& N) q
the 'uid' parameter.
7 C- \9 f7 Z: i, a$ h' c6 g% @$ ~2 H
<interface> is an optional physical interface name. This is currently
5 I1 c- g2 |4 M' J T only supported on Linux. The interface must be a physical+ t8 n: H. x, }
interface, not an aliased interface. When specified, all
' u" \) R+ E1 e( W/ ~( t8 e addresses on the same line will only be accepted if the9 U$ r% }4 f$ ^: J1 U3 ]7 f
incoming packet physically come through the designated
$ r# B" w% l) z4 W8 H% U interface. It is also possible to bind multiple frontends to# G9 C+ m& V$ F0 Z: Q" U" t+ \
the same address if they are bound to different interfaces.
# J8 P0 M! q8 D6 m) K U, w+ { Note that binding to a physical interface requires root
0 |) j0 l; O3 d `& G privileges.
" O, {1 U' D/ g! n4 O" g! F9 B' ~# ?' l( P8 t. ?
<maxseg> is an optional TCP Maximum Segment Size (MSS) value to be' q* I2 s* w' x* c9 [3 Z) e. \2 u
advertised on incoming connections. This can be used to force* b% k9 N# L! Y1 P) d: ?0 Y
a lower MSS for certain specific ports, for instance for2 C9 F" a# U" f) ^6 F6 o& a4 C
connections passing through a VPN. Note that this relies on a$ U, a7 H9 B9 _" R! Q5 m; @
kernel feature which is theorically supported under Linux but7 O, b0 r3 n$ l
was buggy in all versions prior to 2.6.28. It may or may not/ s8 q! C' c* K O+ m/ F
work on other operating systems. The commonly advertised
7 l, p6 k8 R$ E2 Q! q: a+ E value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP).! j, g5 ]3 q4 x# `: T, N+ O3 p' q
3 C9 J, W- J5 w3 y/ u7 f <id> is a persistent value for socket ID. Must be positive and
( A+ |5 y: E* J) Z" O5 E unique in the proxy. An unused value will automatically be; I3 j+ |; ?9 P" B( R' q0 X
assigned if unset. Can only be used when defining only a0 y4 p& ~- [) N$ t* C
single socket.
/ c9 p% V, q3 Z {# l0 L; N# }( {, p; M6 q' @
<name> is an optional name provided for stats
6 o# d6 N& ~& M4 u1 G8 i& i! Q* ^' p# o: g
transparent is an optional keyword which is supported only on certain" `0 n6 l& Q! j0 I @
Linux kernels. It indicates that the addresses will be bound* g# J. e, [% S3 I; v/ G
even if they do not belong to the local machine. Any packet8 {$ Y2 ^* H" v
targeting any of these addresses will be caught just as if3 E. `$ F$ v; h z" J3 t
the address was locally configured. This normally requires5 J& c# S; \7 g: r: D& b7 v
that IP forwarding is enabled. Caution! do not use this with+ F. C( T6 @/ A, K# i
the default address '*', as it would redirect any traffic for. v; @ X5 L- H
the specified port. This keyword is available only when( Q" u! h) i/ F9 o
HAProxy is built with USE_LINUX_TPROXY=1.
+ ?- t' v5 x9 Y& x' @& s5 K: n \( I# O
defer-accept is an optional keyword which is supported only on certain
: \3 v" V5 U/ G7 G1 { Linux kernels. It states that a connection will only be5 V& s# J. A" b- t3 @
accepted once some data arrive on it, or at worst after the
9 \9 I ~$ `4 z' m3 F# a first retransmit. This should be used only on protocols for
, {+ k1 r0 R0 |" y2 N% h+ k which the client talks first (eg: HTTP). It can slightly
9 K: {9 S/ w4 V6 I- c improve performance by ensuring that most of the request is
; m$ j" O% A) @& a1 P& ?. d already available when the connection is accepted. On the
/ y+ Q7 }4 r+ l. i8 z9 b other hand, it will not be able to detect connections which, M" b2 V/ [$ G! ]( b& T. { V
don't talk. It is important to note that this option is
4 s/ F( j6 y' B4 d; b broken in all kernels up to 2.6.31, as the connection is
8 P Q1 ]3 [) e p+ c5 e never accepted until the client talks. This can cause issues0 S5 O U/ p4 }" u, W* W
with front firewalls which would see an established$ m% B; W( ?# W# c
connection while the proxy will only see it in SYN_RECV.
* @9 _5 w* V+ s8 C# B- `6 o. z4 T$ M' x; ]
It is possible to specify a list of address:port combinations delimited by
; m0 s, a; m$ B6 z t; k5 ?+ p' {5 b c commas. The frontend will then listen on all of these addresses. There is no# x- e: M+ f3 p' m
fixed limit to the number of addresses and ports which can be listened on in+ u9 \3 S+ Q* Q1 y5 D2 x
a frontend, as well as there is no limit to the number of "bind" statements( s3 d/ a; ^+ y
in a frontend.5 N ]4 e4 D* v1 h4 q
9 w" q. _3 w/ J2 @" Y7 }* e( K" [
Example :
; k- d3 r6 Q) C* H/ `5 z listen http_proxy3 C& h/ Z! x0 W2 O! P7 k
bind :80,:443+ f* L8 B% S3 _' f+ p8 |( [5 o/ [
bind 10.0.0.1:10080,10.0.0.1:10443
- P' q: i2 K7 }) X+ T' Z; b3 J1 I9 A. O8 G0 w
See also : "source".
4 T1 i# Q( B2 T9 `# i+ y, [5 n V2 Y; z, R+ `
8 C* h5 I1 I& A% S
bind-process [ all | odd | even | <number 1-32> ] ...8 J* T, m/ ~! q1 s
Limit visibility of an instance to a certain set of processes numbers.; x! H% u9 n( v. W0 k
May be used in sections : defaults | frontend | listen | backend
7 P4 Y8 u, h- c6 l. H1 X: f yes | yes | yes | yes
, g4 a2 p8 f- q' l Arguments :
7 C/ B( w* i4 O4 O0 ]1 k* Q all All process will see this instance. This is the default. It+ W9 p- r/ s! w! h" a( N. O: q
may be used to override a default value.
# E' c, H- e$ o" T; r2 p4 H! Y
6 v) d( g" }9 Q# c6 J# @ odd This instance will be enabled on processes 1,3,5,...31. This/ X1 A( @$ s5 ~' E- T4 D
option may be combined with other numbers.
% a* |$ ` i+ ? A; W& Y8 d& S' R+ l
even This instance will be enabled on processes 2,4,6,...32. This
8 ?7 U6 x. C* b2 r* [, m option may be combined with other numbers. Do not use it
* z" ~2 Q5 Z" z1 a* O) _/ J+ C1 C with less than 2 processes otherwise some instances might be, z6 T* G# m8 d, h4 \! _; C
missing from all processes.
( ^1 v: @, b. @1 z% i: l8 D4 \ I4 N) o2 N8 m* N8 q
number The instance will be enabled on this process number, between- N6 N# X5 N2 ]0 b, u$ }5 g
1 and 32. You must be careful not to reference a process
2 ~& m0 U# i9 o. ~: x0 M number greater than the configured global.nbproc, otherwise
% ^3 J4 L+ C+ N! `- T8 S some instances might be missing from all processes.' ?$ Y& c: \* b% Z7 E4 ^/ M
/ |4 x0 M1 n- [' t' j
This keyword limits binding of certain instances to certain processes. This
$ w4 r$ }+ I( p9 X" P is useful in order not to have too many processes listening to the same1 h3 a8 p) x2 ?+ x
ports. For instance, on a dual-core machine, it might make sense to set4 P4 h) ^- j" k m+ Y- U
'nbproc 2' in the global section, then distributes the listeners among 'odd': q/ Z$ e" e) \: w! [2 B
and 'even' instances.
) P9 m8 {( r: @/ z7 g Y6 {/ M8 a/ O; _( A2 o; h
At the moment, it is not possible to reference more than 32 processes using
; X$ ]8 Y- R7 b& l5 } this keyword, but this should be more than enough for most setups. Please
, [% y/ \* |" P note that 'all' really means all processes and is not limited to the first, v" W6 }/ g9 i$ m$ X3 S
32.
1 F4 B( w. g k$ O0 V' T# f% ~3 c1 T/ H( k7 `1 G# U. h! T
If some backends are referenced by frontends bound to other processes, the
' G+ M' ]" y2 l- }6 ? backend automatically inherits the frontend's processes.
2 b, l/ q0 L) a6 q7 V F
: f/ ~ g# Q5 E- B Example :
|! T6 F! A6 p2 H) A& ? listen app_ip1
0 I. C9 f/ {% s6 Q6 A& P& S! b2 j bind 10.0.0.1:80
e* m% l3 n% |; Q! F9 D! c9 \+ Q. o, E bind-process odd
- o: T; F4 m& B( ]" W- Z
% G& G5 W! ^% M# j9 v8 d listen app_ip2
& z; y4 N4 l8 c/ h& M: M bind 10.0.0.2:80: V* J# D A3 g! \
bind-process even
& s" S9 T$ U* I3 b8 O4 F; `. w# @/ K- K( L4 q6 B( n0 k8 g
listen management
' X! { O" m' R% Z, y bind 10.0.0.3:800 d" o8 y+ p8 X* K6 |
bind-process 1 2 3 4
2 b2 L0 k+ F5 [/ {3 q9 ^, }: Z k9 {) `5 Y7 F
See also : "nbproc" in global section.
7 z# O' ^% g$ [6 d3 j' g9 U, L
r' \$ e& D! f% L% W. }
2 c; A* K/ t N& ^& z9 a3 Oblock { if | unless } <condition>
' _; ~8 @5 S( \" O9 ` Block a layer 7 request if/unless a condition is matched' ]+ F% R+ G& z) d. E
May be used in sections : defaults | frontend | listen | backend
$ \5 y/ D% ^. t, A, M" \ no | yes | yes | yes9 h' n8 `9 X/ }2 a" o3 `
; m; r- }0 T3 r# m0 ?+ N
The HTTP request will be blocked very early in the layer 7 processing
8 u1 i- i( `) D# f! C" l% q7 D! j if/unless <condition> is matched. A 403 error will be returned if the request4 z8 X, [# G+ B J( E1 h1 t* Q+ }: p: [( b
is blocked. The condition has to reference ACLs (see section 7). This is
9 |. X/ D% Z2 I! k7 E* Y. K4 D typically used to deny access to certain sensitive resources if some
& ~" D. x% o& L- U: f/ W conditions are met or not met. There is no fixed limit to the number of
2 l* G2 r* M% E% f "block" statements per instance.
# C+ j% Y0 x& k' Q& Z
) z, {$ X0 v# a9 j8 L/ t% r- o Example:
4 L* k7 y5 T. q4 M/ n8 ` acl invalid_src src 0.0.0.0/7 224.0.0.0/3
% T# c- m% b: [4 @- Q acl invalid_src src_port 0:1023
" I, W. S; s; X0 S9 V. v1 @ acl local_dst hdr(host) -i localhost6 `' R0 H1 z) E9 a$ ?0 t
block if invalid_src || local_dst
3 J- \0 A" w" q2 {6 n8 G' e: S) c3 O
See section 7 about ACL usage.
* q* S" L; U: Y: [( h T8 c, t
9 T6 F1 w2 f4 }$ r. K6 ?% O
4 h) x1 Z4 v3 @- Z6 qcapture cookie <name> len <length>
" ~% V, d1 p( q7 \# H Capture and log a cookie in the request and in the response.5 ]# c- q4 X$ {, w8 R
May be used in sections : defaults | frontend | listen | backend
2 B1 K5 B: ]8 r' b, H no | yes | yes | no: K: H4 s- \3 _3 I( s* n* @
Arguments :8 E( v5 X0 f; c7 I" `0 u% A" c" ]! T
<name> is the beginning of the name of the cookie to capture. In order- c: {( p R( F9 p/ o8 U' x5 ^
to match the exact name, simply suffix the name with an equal
. @' ~3 E. U( v4 W9 H6 L, A sign ('='). The full name will appear in the logs, which is9 z+ U7 `4 [, j
useful with application servers which adjust both the cookie name2 C; n& _$ }/ ~& Q! Q3 u3 R7 T1 Z
and value (eg: ASPSESSIONXXXXX).1 Q: |# R8 ?3 s8 r) o5 m! D4 I2 }* Z
a M: X4 }( U
<length> is the maximum number of characters to report in the logs, which+ d8 r0 S% M: A- z2 Q! G1 B3 h% e
include the cookie name, the equal sign and the value, all in the
% \9 j* U# e3 Y; }1 g8 q8 Q standard "name=value" form. The string will be truncated on the" t5 e7 r' O. [/ y' U% K+ @. a1 u ]
right if it exceeds <length>.
$ L5 K8 ?5 _# c& b8 _
$ X2 B( K$ O9 l% g" _' i Only the first cookie is captured. Both the "cookie" request headers and the. F" S- S# l8 N8 a/ ?- H/ W9 Z
"set-cookie" response headers are monitored. This is particularly useful to
/ O* e* v: O) r4 F6 u$ f check for application bugs causing session crossing or stealing between9 [/ d4 a7 W5 P6 ]- t
users, because generally the user's cookies can only change on a login page.
) h# h5 e( B# ]: \& y6 |6 X+ z$ r3 |% T
When the cookie was not presented by the client, the associated log column
7 O8 E5 { c6 s9 f, n# Q will report "-". When a request does not cause a cookie to be assigned by the# V% q5 i, ~- W
server, a "-" is reported in the response column.3 p# z/ t) J+ Y8 V0 [0 b6 a
d8 L& \7 S2 ], C" J( H The capture is performed in the frontend only because it is necessary that
, z$ s# Z' W% M) B; `9 ? the log format does not change for a given frontend depending on the9 i5 m- O' q8 t4 ~& ~" ^
backends. This may change in the future. Note that there can be only one
7 v w% D& Q% i! l8 {) H: N: `& A "capture cookie" statement in a frontend. The maximum capture length is" @! p( u2 |, k$ p5 k0 Z
configured in the sources by default to 64 characters. It is not possible to& n5 j; g# j2 S6 l! q+ e
specify a capture in a "defaults" section. k' b4 v. N" \" n% |
0 v. M% ]! ?7 h; }1 w, Y* p6 ^
Example:
. t9 n4 e [# j9 u Y4 f0 I capture cookie ASPSESSION len 32
. d, g/ l1 Q7 l0 _ Y: @+ H' t+ r
- u- Z0 L3 p4 M( A8 \ See also : "capture request header", "capture response header" as well as
?$ ^! q; c. Y4 Q! S2 D section 8 about logging.
3 C, k* z% `& U7 l& m, p7 r" n M5 c; Z. l+ ~+ h
5 o3 g$ x4 [: } |5 P/ Mcapture request header <name> len <length>
0 w, B' c# }8 L/ c& L; O( z Capture and log the first occurrence of the specified request header.
# W% c$ @0 T7 y May be used in sections : defaults | frontend | listen | backend
" Q4 P: K& q& D5 ? no | yes | yes | no
6 J8 x0 a, \! c: v Arguments :
1 m# p5 l4 i0 H! r& C& R <name> is the name of the header to capture. The header names are not
* z0 m: E, C( `- |6 e case-sensitive, but it is a common practice to write them as they" J3 K3 L" E) \
appear in the requests, with the first letter of each word in3 t6 m) A% O1 N/ c; ?2 _
upper case. The header name will not appear in the logs, only the& e( Y4 i6 c% S8 a* l" a& \7 [
value is reported, but the position in the logs is respected.
- M. p; u$ Z$ N# _+ f" P
- c f1 E3 u2 { C# z <length> is the maximum number of characters to extract from the value and% Z& }: Q4 |5 y8 }1 g0 @
report in the logs. The string will be truncated on the right if$ S; }7 Y b) y
it exceeds <length>.
9 e; w. h" g7 _ K
! L/ Y6 j1 g9 r5 a. S Only the first value of the last occurrence of the header is captured. The6 s. ?+ k, Q% D
value will be added to the logs between braces ('{}'). If multiple headers
# c6 P) t& Q- m2 y- w) I# I are captured, they will be delimited by a vertical bar ('|') and will appear
, p& |/ r8 b& z5 q3 U in the same order they were declared in the configuration. Non-existent
7 V# b) X' }+ w% j; `) _- {; r" H headers will be logged just as an empty string. Common uses for request
! m6 M5 ?5 @+ M: p. R" e header captures include the "Host" field in virtual hosting environments, the
5 A, D/ _- l; J" k1 e "Content-length" when uploads are supported, "User-agent" to quickly% L# w7 Y( U5 U1 G5 Q
differentiate between real users and robots, and "X-Forwarded-For" in proxied* h' k5 d( m( X' |$ X& `
environments to find where the request came from.0 w0 E' P6 B6 a+ Q% l" P7 d
- w2 i& v: D x0 o+ t
Note that when capturing headers such as "User-agent", some spaces may be
; R/ z s0 V9 O n, @( I; _1 l K9 U logged, making the log analysis more difficult. Thus be careful about what
7 [, G$ K; h, s* r: \( [3 T you log if you know your log parser is not smart enough to rely on the
. Z" G# ^7 A' |' `- J9 g braces.+ ]9 Y1 y4 I' r3 q: M
T* w2 }3 O, h2 _" S2 x4 g& I; [# X
There is no limit to the number of captured request headers, but each capture
" H4 g# n% l. C8 ~; A% {& _ is limited to 64 characters. In order to keep log format consistent for a
D0 c( v5 |: j. E3 Y V% y same frontend, header captures can only be declared in a frontend. It is not+ y7 X. \8 a. J+ [6 `# F
possible to specify a capture in a "defaults" section.
3 r9 n' }+ `4 I6 [3 {4 S1 q
* {4 v: ~5 S+ O6 J2 X0 u0 Y0 t Example:7 w, y) v! E6 N: V7 Q8 l+ [
capture request header Host len 15+ E6 Z3 M* ^$ x, U S: s1 O
capture request header X-Forwarded-For len 15* ]% N0 E1 P" {/ [* T4 V; d
capture request header Referer len 15
' u9 F6 D9 J+ T Y( y' [. S5 f/ b$ U1 x) d z
See also : "capture cookie", "capture response header" as well as section 88 B! f0 F2 l& l6 E& e# n `
about logging.
& B* w- G) v7 v) W* w. v% X4 X: [) H% J+ f3 v
9 u+ t0 V9 a: m1 ~0 ^ L! F
capture response header <name> len <length>3 w: G6 u2 E/ D0 ~# q
Capture and log the first occurrence of the specified response header.
4 f+ D9 `) E! q# r p( h May be used in sections : defaults | frontend | listen | backend2 F& G# T- h* ^3 k$ f/ ^: {% H. i
no | yes | yes | no
* P9 J+ a" s9 U9 U Arguments :
$ Q2 C* |0 o9 C$ \7 ?4 h <name> is the name of the header to capture. The header names are not( Z7 L, F2 P" y1 N" o
case-sensitive, but it is a common practice to write them as they$ d0 k0 F! u# B% }3 X3 R% z6 Z
appear in the response, with the first letter of each word in
5 I/ M1 M' t) w; X5 a1 `+ O( x6 X# L upper case. The header name will not appear in the logs, only the2 c4 v: b- g3 g" S+ G& @8 S3 G
value is reported, but the position in the logs is respected.7 W/ b. J# A/ L. x, p+ ?
+ P. \- u( }; J0 H9 y <length> is the maximum number of characters to extract from the value and
, |$ u( O6 I- M report in the logs. The string will be truncated on the right if# h& J, P. u5 ]' R3 z2 c
it exceeds <length>.
' C- D: {/ N, L$ l* Q( `0 M
0 u0 ~3 W* s8 S( r Only the first value of the last occurrence of the header is captured. The! C2 Y3 F- c& w' h. r# F
result will be added to the logs between braces ('{}') after the captured
$ C9 g+ h# l! U request headers. If multiple headers are captured, they will be delimited by4 J3 D# g9 B, X2 ?) n" C
a vertical bar ('|') and will appear in the same order they were declared in
z' \ j3 C) l the configuration. Non-existent headers will be logged just as an empty
3 M1 k* E2 n) j2 o string. Common uses for response header captures include the "Content-length"
% W, U7 `) j3 G1 q* E header which indicates how many bytes are expected to be returned, the
: A* W j2 E6 t. J/ f3 H, Q4 E "Location" header to track redirections.. ]) d4 r" U! ?6 f
4 q* e& E; ]/ @$ o( s; A There is no limit to the number of captured response headers, but each/ w- i: A; t9 `2 J+ g
capture is limited to 64 characters. In order to keep log format consistent
8 C ?* U9 h* r8 T( k6 u3 a! y& W for a same frontend, header captures can only be declared in a frontend. It* Y3 x& v! \7 G0 o U j$ z3 l
is not possible to specify a capture in a "defaults" section.- r* g+ |3 H7 t" g
+ J9 U# P/ i1 M9 D! w1 s! n Example:
. m& r% Z# A, V# y" d; f capture response header Content-length len 9
3 F% ^& w1 J1 ~3 t9 ~" y% }; i, c ~ capture response header Location len 15+ K) [% a7 a# |4 S8 Q4 m2 ^' s; x/ ]6 k M
% L& V2 }# i0 Y+ }$ \ See also : "capture cookie", "capture request header" as well as section 8/ a& O1 l% z* h
about logging.
+ F' g6 H% j- |. C m6 g8 b7 J, s
1 `8 V2 R) I! f
clitimeout <timeout> (deprecated)0 y# `- m. v9 X3 L0 I2 }
Set the maximum inactivity time on the client side.3 _( n) D4 @9 E. I: W
May be used in sections : defaults | frontend | listen | backend. q4 ?. C7 ^9 w. X& m- F. z$ W
yes | yes | yes | no
, Y4 P7 I3 e# g$ W# V Arguments :/ f( g+ F: Y6 l' T, q. {) K9 G) T
<timeout> is the timeout value is specified in milliseconds by default, but' \/ {$ \3 m5 s. _
can be in any other unit if the number is suffixed by the unit,* U! m: F4 N4 w" L
as explained at the top of this document.- |! U( z8 e; [3 c, R% B) `
$ ~5 \' W) k" f( J4 E* B The inactivity timeout applies when the client is expected to acknowledge or
9 A) ?% _7 K3 l' n: K send data. In HTTP mode, this timeout is particularly important to consider& v% z4 d. u" R% i2 K: q
during the first phase, when the client sends the request, and during the
& N. a5 H* T7 R8 E response while it is reading data sent by the server. The value is specified$ J- C' C: I; V# N" _# G9 V! }
in milliseconds by default, but can be in any other unit if the number is
, l( { L. w s* A, r" T suffixed by the unit, as specified at the top of this document. In TCP mode3 O: J( D# P2 j6 x% |" K
(and to a lesser extent, in HTTP mode), it is highly recommended that the
( m4 F* G$ N! i client timeout remains equal to the server timeout in order to avoid complex2 h, s7 g5 M; c0 ?* G, a9 L$ H6 j
situations to debug. It is a good practice to cover one or several TCP packet
2 C5 d6 ~" v5 w8 p) k& C losses by specifying timeouts that are slightly above multiples of 3 seconds# t! o8 Q3 N5 v- a
(eg: 4 or 5 seconds).% W+ N# _7 {, L' r5 r8 @$ P
, N# K( D! d9 j0 K/ R5 W
This parameter is specific to frontends, but can be specified once for all in
1 u* j$ F n. N) w5 F "defaults" sections. This is in fact one of the easiest solutions not to' p" u7 w* R m/ c/ O D" E7 F! F3 @8 E
forget about it. An unspecified timeout results in an infinite timeout, which
; X& d# j9 h# {8 b: h9 Y! Q) h3 \ is not recommended. Such a usage is accepted and works but reports a warning/ Y7 V, C# n0 w3 W5 N v" | h% G9 {
during startup because it may results in accumulation of expired sessions in3 p9 N" Z. j' c: Z7 `
the system if the system's timeouts are not configured either.; d% t# h4 g- O- |9 D7 v: V( h
% m# @) q5 W) ?4 @+ C
This parameter is provided for compatibility but is currently deprecated.
7 u1 Y+ }$ {$ G' Q( o2 j2 {! { Please use "timeout client" instead.5 y% n9 _& X- S1 m
2 }2 S7 w' U! q. ~1 i See also : "timeout client", "timeout http-request", "timeout server", and
4 N! b$ S- b- ~. P5 G# U "srvtimeout".% N3 ~5 {$ o4 F8 Z2 \
& J! w9 z n" \) N
6 M3 r- [. p J( s/ ucontimeout <timeout> (deprecated)5 M( ]1 ~7 A- [+ l L" w; O
Set the maximum time to wait for a connection attempt to a server to succeed.8 T) Z3 ~+ `' g8 ]* F9 y8 j9 M1 s3 L
May be used in sections : defaults | frontend | listen | backend" ~0 R3 k6 Y! E9 I/ ~) D8 B
yes | no | yes | yes
% R1 l/ V4 E9 z Arguments :' c' g7 d, M1 k% g1 D5 F
<timeout> is the timeout value is specified in milliseconds by default, but* I) h/ k4 e+ l# \0 g" Y k7 i+ X+ z
can be in any other unit if the number is suffixed by the unit,- T7 l9 B4 H6 w1 f, ?
as explained at the top of this document.( z% z7 r$ N% y, x4 Q& d1 Z
4 s. |) _ u6 R8 r If the server is located on the same LAN as haproxy, the connection should be6 s: G( u/ ]$ {! p. X5 G' M' p2 ~
immediate (less than a few milliseconds). Anyway, it is a good practice to
# _/ l4 v x a2 I/ y cover one or several TCP packet losses by specifying timeouts that are
3 w/ x" [3 {% } slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the/ i( Q0 N) A [* B0 N( `2 l; B
connect timeout also presets the queue timeout to the same value if this one
! u" \5 \* L- V/ ~+ Y has not been specified. Historically, the contimeout was also used to set the' }* ]& J2 e+ n( Q# s
tarpit timeout in a listen section, which is not possible in a pure frontend.' u' |/ r2 x- T: j) N& L; f$ V
0 H% a% Y6 q% q* h' d7 C" Z+ R
This parameter is specific to backends, but can be specified once for all in4 b+ ]! ]. {. N; _ l' T9 s& [9 i
"defaults" sections. This is in fact one of the easiest solutions not to
+ q2 F" T3 |2 `: X, |) |5 p forget about it. An unspecified timeout results in an infinite timeout, which
' @- _: Y- X1 |1 y5 I is not recommended. Such a usage is accepted and works but reports a warning3 m+ f- d i; Y0 u) h7 ]
during startup because it may results in accumulation of failed sessions in
4 q2 M) V. J4 @! q3 ~$ Z/ {$ s the system if the system's timeouts are not configured either.$ |) h, N# p x1 x/ o
9 q) @! i' n6 N, d This parameter is provided for backwards compatibility but is currently; F9 k3 Q% ? I. w: y& U
deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit"
( \. K1 M6 x5 r1 ^ instead./ k* C. S- G) u. R( |) W! [
1 B; u* }! {4 G) p6 m; J0 } ?4 D; z
See also : "timeout connect", "timeout queue", "timeout tarpit",
8 m5 d0 M; l* |) o1 P9 O "timeout server", "contimeout"., Q! f/ J% U: \/ R
$ d& D5 T7 x4 m7 v! Y4 N3 M! p; g9 z& X; F, v; O- ^6 {0 k
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
3 [) C( y" A1 N1 s8 Y5 u [ postonly ] [ preserve ] [ httponly ] [ secure ]$ ^# F) E8 `+ e/ O4 L) s9 |4 p2 y
[ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
% [# \6 |. l. Q( t Enable cookie-based persistence in a backend.
5 O2 G: R/ x7 Y. _+ y! G May be used in sections : defaults | frontend | listen | backend
$ B$ m: K! o) `1 n yes | no | yes | yes# G8 _/ O* G+ I( N
Arguments :8 k, k) Z) o" m. W
<name> is the name of the cookie which will be monitored, modified or
; E. p5 K; y- `( Z( Z inserted in order to bring persistence. This cookie is sent to
: q2 I" [0 n* w the client via a "Set-Cookie" header in the response, and is- i/ q' {% t# m& p" U% b
brought back by the client in a "Cookie" header in all requests.7 o1 O9 E% @! _7 X" u2 `' Z" I( A
Special care should be taken to choose a name which does not' E8 E8 G5 c/ Q/ d" s
conflict with any likely application cookie. Also, if the same
' ~$ v3 t$ N" Y6 Q; a1 @ backends are subject to be used by the same clients (eg:4 H7 p8 w: t1 f
HTTP/HTTPS), care should be taken to use different cookie names+ @6 {* N% E" m( c3 S" K
between all backends if persistence between them is not desired.) F2 I( l8 X% a/ O$ S2 x, w: m
/ y8 T8 f! l) A
rewrite This keyword indicates that the cookie will be provided by the* R# F/ f: h$ J# X5 e3 [8 z
server and that haproxy will have to modify its value to set the# ?1 k, \. O0 t% K' {* w
server's identifier in it. This mode is handy when the management4 P. p5 k( U, w: ^" f o, W
of complex combinations of "Set-cookie" and "Cache-control"* ?# v- z% n- p! s6 j; a
headers is left to the application. The application can then, w0 v) m7 K# a% A- |- B- ~
decide whether or not it is appropriate to emit a persistence
" l6 y) K* a8 g a cookie. Since all responses should be monitored, this mode only2 Y9 w+ d8 e. Q: u( u; B
works in HTTP close mode. Unless the application behaviour is) i: u8 h; {3 q+ j6 g- ]1 B: W* J* d
very complex and/or broken, it is advised not to start with this- p' n& J8 K( }2 O% S0 C+ A
mode for new deployments. This keyword is incompatible with
6 d/ O, ]( O, h- y8 ^" Y "insert" and "prefix".
$ G# M, r5 b x. N J3 f* M; w
* M% o; c6 j+ u+ S insert This keyword indicates that the persistence cookie will have to
; H. J& f* n% i! R be inserted by haproxy in server responses if the client did not
7 {: u$ D" c' x9 |0 N9 s `; A
! z9 g5 f7 v; K& Q$ [6 M, ]$ ] already have a cookie that would have permitted it to access this- H2 B) M- { }% l" E* t4 y
server. When used without the "preserve" option, if the server
/ e. t- ~2 v# I; W; b" X" v emits a cookie with the same name, it will be remove before
4 Z6 v/ x: @8 |1 T0 T processing. For this reason, this mode can be used to upgrade
i" d. J! k' t( B' H0 ^ existing configurations running in the "rewrite" mode. The cookie
; F1 I; ^; X* R# ^ will only be a session cookie and will not be stored on the
6 D, s0 z9 o, a5 L* y5 t1 `4 f* p. P client's disk. By default, unless the "indirect" option is added,
* B, P8 s0 T" _( R6 c/ h2 B+ r9 P# S the server will see the cookies emitted by the client. Due to. O0 ~4 A4 N/ U5 V# |
caching effects, it is generally wise to add the "nocache" or( i8 ^2 h( k8 U% p7 F5 t+ o( c, S% z
"postonly" keywords (see below). The "insert" keyword is not
; ], L+ k7 Q/ Z" W6 l! S2 t6 ~ compatible with "rewrite" and "prefix".. w1 w. f8 F( x7 \/ l$ L* x! T4 J( ?
. X7 f+ `6 }% S7 N# H( d/ w
prefix This keyword indicates that instead of relying on a dedicated" a* z$ O( a4 B+ y' ?" t
cookie for the persistence, an existing one will be completed.: s! \1 v. u- _7 M( ?4 U w9 W0 p
This may be needed in some specific environments where the client1 \0 q5 y* K+ y9 i) D" T) ^
does not support more than one single cookie and the application
6 C$ R" f& z1 y already needs it. In this case, whenever the server sets a cookie
" ^) @& T3 A* u- ^- M1 g0 | named <name>, it will be prefixed with the server's identifier$ F& c. o1 e Y/ k. S0 ~& Z
and a delimiter. The prefix will be removed from all client
7 A! L' r; B2 o+ `) q9 H0 V; E6 Y& d requests so that the server still finds the cookie it emitted.% H* z& Q8 R1 V
Since all requests and responses are subject to being modified,- E% U5 p, U2 f0 X3 f e
this mode requires the HTTP close mode. The "prefix" keyword is
% c; ]. m# _6 E- k, z not compatible with "rewrite" and "insert".. W* g1 z, W. g2 b3 b
/ G% t3 q1 H9 K, k; {3 ]. g6 e9 a. l
indirect When this option is specified, no cookie will be emitted to a
% J9 K+ A, h( ?% ? client which already has a valid one for the server which has5 n; G- ^3 G2 @
processed the request. If the server sets such a cookie itself,6 v9 S2 `8 R D6 C+ U* g$ P' B
it will be removed, unless the "preserve" option is also set. In
1 k: d! p5 R0 s# m, e "insert" mode, this will additionally remove cookies from the
+ R4 ~0 d' t9 [$ l requests transmitted to the server, making the persistence
. ~2 r7 n+ w9 b# J& U mechanism totally transparent from an application point of view.
`0 H( F: _' M5 w+ N L; f, u3 I/ V, b5 h/ E
nocache This option is recommended in conjunction with the insert mode$ P: c/ X! Z! @
when there is a cache between the client and HAProxy, as it
) }; z/ Y! d3 L5 b" D) d% m ensures that a cacheable response will be tagged non-cacheable if
3 v' Y/ @, a& u a cookie needs to be inserted. This is important because if all3 W! m5 G/ e0 c- G- f. k, I
persistence cookies are added on a cacheable home page for, x' k. r$ }1 g
instance, then all customers will then fetch the page from an
/ U8 J" D' y3 ` outer cache and will all share the same persistence cookie,# v4 N5 L! n7 i" e V& n0 n& v) G. q5 w
leading to one server receiving much more traffic than others.
4 k' L' p3 O; s& E; T. O9 y See also the "insert" and "postonly" options.
' N: j- V& E2 T7 p Q2 g7 T) T8 {. x5 v0 N) Q9 Y
postonly This option ensures that cookie insertion will only be performed, p8 ~ f3 O3 j. q3 I
on responses to POST requests. It is an alternative to the
4 F+ U& L8 z( B" | "nocache" option, because POST responses are not cacheable, so$ E; r) D g, |- Q
this ensures that the persistence cookie will never get cached.
* N$ b6 i5 x' `0 ^ Since most sites do not need any sort of persistence before the
% t Z8 D1 f! Z7 _5 N0 ^: H9 H7 ~ first POST which generally is a login request, this is a very
9 |* Y" S" i! O: I% w efficient method to optimize caching without risking to find a6 Z; k9 ]" y4 R
persistence cookie in the cache.
7 L8 L0 `$ L2 t See also the "insert" and "nocache" options.
( j$ X1 p) W1 a3 O& b' N* K- S6 {( | x/ O2 ~& @
preserve This option may only be used with "insert" and/or "indirect". It+ x" |4 E: |; Q/ a% e4 d
allows the server to emit the persistence cookie itself. In this D T( f7 X% u2 X
case, if a cookie is found in the response, haproxy will leave it
: O0 p: D7 @/ G5 _$ l untouched. This is useful in order to end persistence after a. }% C2 m# M2 W% M6 _8 w P
logout request for instance. For this, the server just has to, A4 M( f& y* W6 r5 d8 _* o# \7 f
emit a cookie with an invalid value (eg: empty) or with a date in
) f d3 Y/ Q" | {- R6 J the past. By combining this mechanism with the "disable-on-404"" C: i3 Y& P; ~6 W) Q3 Z
check option, it is possible to perform a completely graceful) j6 `4 @) Z8 W# P
shutdown because users will definitely leave the server after3 {' p4 t+ S1 f8 `
they logout.
/ a( p( U6 Q9 g8 G; C) l
) U$ ~$ ]" f' K& A! b httponly This option tells haproxy to add an "HttpOnly" cookie attribute
" @. U* H; j- a: k when a cookie is inserted. This attribute is used so that a$ D. H# U* Y S
user agent doesn't share the cookie with non-HTTP components.
1 o4 v1 Z) h$ b Please check RFC6265 for more information on this attribute.
) K Y* c8 a) P0 T% f( b$ V& S7 i* Y. J- {( T7 y( I c! O$ _
secure This option tells haproxy to add a "Secure" cookie attribute when$ ` I2 _2 j2 @6 T+ X; Z
a cookie is inserted. This attribute is used so that a user agent
$ c8 Q% c5 Q4 ~# Y6 b never emits this cookie over non-secure channels, which means
: z9 u1 I4 |1 f2 D4 M. s that a cookie learned with this flag will be presented only over! y! `5 {& p! c# L0 O
SSL/TLS connections. Please check RFC6265 for more information on
- W |7 E: i8 X" U, Z this attribute.% e' N; `! O* e- W5 ]2 T9 l
) k' `- e4 {5 k8 C3 _; A1 {
domain This option allows to specify the domain at which a cookie is
8 X$ Y1 p3 m! d6 ~0 b/ {) @ f$ c inserted. It requires exactly one parameter: a valid domain
0 e/ \- y7 v2 E1 V name. If the domain begins with a dot, the browser is allowed to
$ p' G! `3 l9 [, x/ p+ [ use it for any host ending with that name. It is also possible to7 R; B( I* I$ V
specify several domain names by invoking this option multiple$ i4 f7 \# M$ R0 n* B# P. }
times. Some browsers might have small limits on the number of
5 r" ?: x; Q+ _- x domains, so be careful when doing that. For the record, sending
/ F; c# `& P+ \! @! v T 10 domains to MSIE 6 or Firefox 2 works as expected.6 m Y+ S& i' `+ s/ |: N0 b! e
- G$ {2 y- O6 M1 f' e maxidle This option allows inserted cookies to be ignored after some idle9 y/ h7 m5 W. i
time. It only works with insert-mode cookies. When a cookie is# W- i" h4 N# F* t% S* B9 H
sent to the client, the date this cookie was emitted is sent too.% S- i9 W+ Z6 L( s1 ^. [, c
Upon further presentations of this cookie, if the date is older3 V8 M: w1 O2 {3 Q. m1 Y
than the delay indicated by the parameter (in seconds), it will
4 w, K: d2 R) `% M be ignored. Otherwise, it will be refreshed if needed when the5 G$ l# F! S8 b
response is sent to the client. This is particularly useful to; z7 C6 X& Z: o }; L* c
prevent users who never close their browsers from remaining for
9 r3 m# p. f% ] H. g% Z too long on the same server (eg: after a farm size change). When4 n8 P) m$ u! N" f% M( L
this option is set and a cookie has no date, it is always
) m# f' B f5 O1 w3 a1 U accepted, but gets refreshed in the response. This maintains the! `" A9 a6 c% h. P
ability for admins to access their sites. Cookies that have a( S& a% d3 v, E8 X. Y: ?$ \; n( J
date in the future further than 24 hours are ignored. Doing so
( j. g: `- V* d6 ^ lets admins fix timezone issues without risking kicking users off
# E* ?" m+ e) \- L& U0 s the site.
/ k2 x* S' }1 d$ M; d& U, N2 a0 F' K r$ A: R
maxlife This option allows inserted cookies to be ignored after some life4 ^- \8 e$ l/ U! H" f" U
time, whether they're in use or not. It only works with insert
. a' i3 N. a) R) T1 O y0 n mode cookies. When a cookie is first sent to the client, the date
& p' ~9 d# c) s8 u/ g% N this cookie was emitted is sent too. Upon further presentations
" X. @) ^; f0 x, ^7 m* B of this cookie, if the date is older than the delay indicated by
' _; A( [8 A1 U. t% z the parameter (in seconds), it will be ignored. If the cookie in
U" E/ r1 l% |& {( ? the request has no date, it is accepted and a date will be set.! U) I# D- L" G( @2 M1 D$ K( H
Cookies that have a date in the future further than 24 hours are8 i2 z- |+ W R& v2 Q
ignored. Doing so lets admins fix timezone issues without risking& c9 n$ i! \# D
kicking users off the site. Contrary to maxidle, this value is' q5 |- `! F5 k( G' p# I2 k
not refreshed, only the first visit date counts. Both maxidle and C7 d: }6 y, A+ ~
maxlife may be used at the time. This is particularly useful to
0 v* B1 C( b& L( Z5 v5 A, U2 S4 m prevent users who never close their browsers from remaining for' D% A$ }$ U' P, {
too long on the same server (eg: after a farm size change). This
+ {; ^" s1 f3 k3 v5 X is stronger than the maxidle method in that it forces a/ }8 d3 f/ U: b& i" Y6 G: p x% I
redispatch after some absolute delay.
& Y) A4 I' Y1 ? m8 e
# z1 \8 h3 G8 F2 z i8 D9 Y5 p& q There can be only one persistence cookie per HTTP backend, and it can be
: L R" K8 t ~+ b declared in a defaults section. The value of the cookie will be the value
. R* T0 I, X" X9 l indicated after the "cookie" keyword in a "server" statement. If no cookie/ G4 c3 V/ h: [) ?& [# A+ U6 e
is declared for a given server, the cookie is not set.
0 \4 _" k+ O# W/ |' R* d; v4 @2 ^* l5 q& B; j
Examples :
* M3 a9 q, E9 T cookie JSESSIONID prefix6 C( w0 Z& B+ K Z6 H: e
cookie SRV insert indirect nocache
% y( V+ e) l! y7 ? cookie SRV insert postonly indirect7 b* I, G2 ]& h* r4 ?
cookie SRV insert indirect nocache maxidle 30m maxlife 8h1 X) k8 a! S0 z1 V4 k" A. i
& w! P, }8 I( F See also : "appsession", "balance source", "capture cookie", "server"2 R- G W! G) b* ~6 X( ~/ j
and "ignore-persist".
/ l' C3 ^0 d4 z. m6 K$ w
( a0 H& `$ c. T
4 Z$ w" Y3 p8 n# Tdefault-server [param*]9 m" X6 R3 C9 T3 ~$ z" ~
Change default options for a server in a backend
. ^5 c p# M* B1 _6 q! y! C May be used in sections : defaults | frontend | listen | backend" R& v8 B/ s! R$ a4 e+ O# O
yes | no | yes | yes( H# w& ^" P! @9 R& P- g, c% l
Arguments:
: F( f0 Y7 c2 v0 o+ b <param*> is a list of parameters for this server. The "default-server"4 N+ I! X8 V7 z. _
keyword accepts an important number of options and has a complete* t( d* W' ]- Z3 S8 N% r
section dedicated to it. Please refer to section 5 for more
z- B- I; j+ Y- y0 ? details.
8 W; ]- H! v, Q3 K7 u9 l& M0 H- z& u+ B2 {- C
Example :
2 Y y- u$ o1 S( N default-server inter 1000 weight 13
2 W( [5 h7 C) c- C0 s. f$ i% G
" V, Q" A& B0 b6 v* Q See also: "server" and section 5 about server options3 E% K: d- t6 k: i
+ y% {! @/ D( p) o1 ]# {
6 x* n* P1 l; N n1 a- A# \
default_backend <backend>
% Z4 d% I" {9 H0 _4 ^7 b Specify the backend to use when no "use_backend" rule has been matched.5 ^1 _2 K$ p7 d5 X6 U
May be used in sections : defaults | frontend | listen | backend0 q+ K: B/ b. M( p! w
yes | yes | yes | no
u- O' r0 H& f. | Arguments :
" E2 I w& Z5 x& z. ]& C+ c <backend> is the name of the backend to use.
) t/ E) d( S5 G1 F# ?8 r# ?% i. W" ~
When doing content-switching between frontend and backends using the, k& G4 Z* x2 A" G6 H0 \
"use_backend" keyword, it is often useful to indicate which backend will be7 J# Z8 b8 Q1 Y# o- J
used when no rule has matched. It generally is the dynamic backend which
' o$ B" u) |( o7 x0 r! } will catch all undetermined requests.
& Y! g' `5 s; F$ u4 ]2 {- M1 i/ E8 n6 C& X! S
Example :) z) C$ `- ]% z( K6 e
7 D; |3 K1 P. q& W5 m+ _; ^: G) o use_backend dynamic if url_dyn
0 c. L1 `0 |3 i* E5 Y use_backend static if url_css url_img extension_img
# b" E, ]! y; b default_backend dynamic* e4 @$ V" E% ?# {# A
$ I ?! C- T" m: t" p See also : "use_backend", "reqsetbe", "reqisetbe"
/ `& e) e' ]- G( L& V2 q/ o; K3 {6 K, m. E6 h6 d. t' g4 B
+ _' v! o) L) i
disabled
' f7 @8 e1 z$ z Disable a proxy, frontend or backend.6 D* _% T7 [* e3 g" p! y$ i
May be used in sections : defaults | frontend | listen | backend' ?% u; M- t9 H& n" Y) D
yes | yes | yes | yes/ M: f3 b3 x" X# K% ]; Y+ s+ P
Arguments :- ^& r& y* E9 w1 k. O
( [: @$ a* t8 t8 x The "disabled" keyword is used to disable an instance, mainly in order to1 q& F, W2 p' F
liberate a listening port or to temporarily disable a service. The instance6 T; j% J) h. N. \
will still be created and its configuration will be checked, but it will be
2 O6 J5 Z2 J/ k created in the "stopped" state and will appear as such in the statistics. It: l6 a" t6 l( H v4 w. X
will not receive any traffic nor will it send any health-checks or logs. It- H. y6 ~. v( R# `: ^ O: m* ~
is possible to disable many instances at once by adding the "disabled"! p# g# c6 E [7 S8 E
keyword in a "defaults" section.
* I+ P% ~2 S0 {( K+ O$ [4 q5 u5 k1 u: `$ E7 n) t. R! H
See also : "enabled"6 g8 { ~( Q) `; h5 P
; q, o" c8 V, U: Z t2 v
1 @: k$ `# ^- f: M' Z9 T/ `5 j" h6 H4 vdispatch <address>:<port>1 a( L0 X* U' b" K& S, k1 f% p
Set a default server address
5 E) r, S! D. C" | May be used in sections : defaults | frontend | listen | backend
: U4 l j- e v- d& c2 t no | no | yes | yes
. F. `- H1 e, ^7 i Arguments : none5 |& }, K( Y( x5 \5 @" D, ]
7 Y7 v* l6 V! W) P( \9 K9 ?5 w
<address> is the IPv4 address of the default server. Alternatively, a2 _) I0 ?$ p+ w
resolvable hostname is supported, but this name will be resolved
3 z' V8 ?- Y1 m! q during start-up.
( C& M. m3 S0 y$ d- P P p" v/ e6 t* |
<ports> is a mandatory port specification. All connections will be sent" m9 q' E7 ?/ B9 l- i" ^
to this port, and it is not permitted to use port offsets as is {; O+ H! g2 ?8 _+ I- ?& r
possible with normal servers.
1 I3 ^! r9 [ `
7 T7 s, [4 Z& n7 a+ f The "dispatch" keyword designates a default server for use when no other
& A/ K5 L( v6 D5 F1 H: e server can take the connection. In the past it was used to forward non0 }( B" a$ U6 p/ K- p& ?
persistent connections to an auxiliary load balancer. Due to its simple
3 c% e! e" U" ] syntax, it has also been used for simple TCP relays. It is recommended not to1 O& j8 W; w9 Q6 i/ }* {
use it for more clarity, and to use the "server" directive instead.8 C U% {6 I# E/ G
; `5 r- @- z7 v+ s j% P/ Y See also : "server"
8 [' d& ~& W* t9 H1 B
! U, z6 a2 R/ f2 M. F% J
+ m$ y* i- J1 {2 @9 j/ N( lenabled* V5 o1 {( P6 S- k( s6 {! q
Enable a proxy, frontend or backend.( t/ W; D. l6 }$ [
May be used in sections : defaults | frontend | listen | backend
7 C) l0 x) v: V4 f# U* D8 v; I yes | yes | yes | yes
2 m% S' p; p4 t9 ]3 k4 m Arguments : none
( d, Z* m) [; U. w x x* x J4 ^1 u4 Q: z
The "enabled" keyword is used to explicitly enable an instance, when the5 G; I% X9 Z% M* k) ~
defaults has been set to "disabled". This is very rarely used.
$ @, }, G8 x' E( e
7 f% y, W C9 }. ^' ]( e" |+ B' f& u* k4 I See also : "disabled"8 b0 x9 e- y! |, b
* [9 l9 g% E3 j( f+ Y( d, p% i7 [) N5 H7 ?" |
errorfile <code> <file>: y8 Y- ?3 j( X$ M
Return a file contents instead of errors generated by HAProxy m. T, A! F; O$ N5 ?
May be used in sections : defaults | frontend | listen | backend1 t) I6 j& ]" D# R, N
yes | yes | yes | yes- X/ u7 x x" ]& G# h2 T: q
Arguments :0 q1 F: y @* r; U
<code> is the HTTP status code. Currently, HAProxy is capable of- N0 ?2 h2 ~3 D+ W8 A& u7 B5 Q
generating codes 200, 400, 403, 408, 500, 502, 503, and 504.4 N" X4 B& ]& M2 k6 D* k+ P3 ?
5 T% i# s' v [- P. _2 f+ s: [( n <file> designates a file containing the full HTTP response. It is
7 P1 o( ~& X! o; g% q; E recommended to follow the common practice of appending ".http" to
( \# q" B, `+ h* {" b& |9 P9 r the filename so that people do not confuse the response with HTML$ r5 c- J: ?$ l
error pages, and to use absolute paths, since files are read
]! \9 l. I* O# G8 o1 d before any chroot is performed.
" E! h$ N# U4 H" @8 F+ U j6 h/ u, i7 m; D7 O7 J' x
It is important to understand that this keyword is not meant to rewrite9 ~* {1 V, K4 B0 P/ B7 {
errors returned by the server, but errors detected and returned by HAProxy.
; @: t- ]6 ?5 C/ v: }5 V This is why the list of supported errors is limited to a small set.
+ K h5 a: Q* Y' }+ s/ G9 {9 d+ M# l, N' d) b/ }. [
Code 200 is emitted in response to requests matching a "monitor-uri" rule.! z" D/ I7 H& [$ ~. {$ J
. [. S5 V! b3 F5 ]* K& d The files are returned verbatim on the TCP socket. This allows any trick such# Y/ y4 f7 A8 I% S* H7 m
as redirections to another URL or site, as well as tricks to clean cookies,
$ {2 ?" I9 t7 X0 @ force enable or disable caching, etc... The package provides default error
+ i( P$ t o5 t6 X files returning the same contents as default errors.3 \4 M d" l( W7 Q
$ e! O9 ?6 H: v7 U" }( f5 I
The files should not exceed the configured buffer size (BUFSIZE), which
* q0 `9 y9 H* e/ ]+ b# i9 O generally is 8 or 16 kB, otherwise they will be truncated. It is also wise
7 N5 [; S" C9 E5 h not to put any reference to local contents (eg: images) in order to avoid; F; L5 g2 p8 \% N! n8 f& ]
loops between the client and HAProxy when all servers are down, causing an) Z3 Q, \8 ^: q3 u
error to be returned instead of an image. For better HTTP compliance, it is4 T2 Q! A$ S* ^3 I1 K
recommended that all header lines end with CR-LF and not LF alone.2 b6 z, b1 }( \5 a0 T4 Q& C- K
( ^* f* A1 G5 N+ X4 ]" M) B
The files are read at the same time as the configuration and kept in memory.: C* a/ {$ v& T! n
For this reason, the errors continue to be returned even when the process is
: D. D+ I. ~, K* Y chrooted, and no file change is considered while the process is running. A
2 b y, a. p! A2 ~3 \ simple method for developing those files consists in associating them to the. d5 h& D# n L. b
403 status code and interrogating a blocked URL." ~! Y3 }- i; ^4 o+ f
' z; |7 x' w3 L8 c See also : "errorloc", "errorloc302", "errorloc303"5 ~& Z+ c& Y% g
& j4 i* H& t9 z0 I, ?: B$ o
Example :( ^+ k( C+ z# | t8 [# N/ l7 H$ T
errorfile 400 /etc/haproxy/errorfiles/400badreq.http# l: b2 _" n$ ^+ {& i" j
errorfile 403 /etc/haproxy/errorfiles/403forbid.http1 u, D4 P2 r' M* Z2 E. T7 C
errorfile 503 /etc/haproxy/errorfiles/503sorry.http8 [3 \6 P# N3 a
1 V8 w2 i4 p Y2 I3 r. w; _
% j; U2 ?% l' ?# d$ U- R7 Oerrorloc <code> <url>
* C/ G" w8 J3 C$ ~* V1 Berrorloc302 <code> <url>
Y7 ^) X9 G9 j6 P* U) }5 ^: B Return an HTTP redirection to a URL instead of errors generated by HAProxy* p5 N. I4 L" L7 I$ q2 Q
May be used in sections : defaults | frontend | listen | backend
2 O% C% \1 j' Y% ] yes | yes | yes | yes
5 R t4 c* C" \: T9 D! Y Arguments :# ?7 y4 b1 f$ \9 u8 t
<code> is the HTTP status code. Currently, HAProxy is capable of0 s1 C& w- V9 @ ^7 w7 D
generating codes 200, 400, 403, 408, 500, 502, 503, and 504." }+ W! D' b; |
! Y% [- Q% E8 A! C <url> it is the exact contents of the "Location" header. It may contain
% D# q+ q9 M0 q- p4 f7 ~% G+ d either a relative URI to an error page hosted on the same site,* |7 ]: V- Q2 r9 [
or an absolute URI designating an error page on another site.! T5 S" Y! z8 m6 ?
Special care should be given to relative URIs to avoid redirect" u4 F) |) ~$ T( L* ~ M& m/ ]. Q/ o
loops if the URI itself may generate the same error (eg: 500).
. r2 ~5 X" @- b: I, [) ]4 H- d. f" m. }. \6 I4 D, w
It is important to understand that this keyword is not meant to rewrite
) G$ J- A% X2 K. W) e5 P; m$ c6 R0 H% h errors returned by the server, but errors detected and returned by HAProxy.+ C4 T* l' G) R$ U
This is why the list of supported errors is limited to a small set.
* G& u6 }$ U& X' B2 C9 P5 o9 s' W+ b1 e1 L9 i& Q/ v8 ~
Code 200 is emitted in response to requests matching a "monitor-uri" rule.6 ]: t+ u; }1 K/ q8 V8 j* T7 x
# I8 z9 v+ o9 E# D% k1 Q5 R Note that both keyword return the HTTP 302 status code, which tells the
& M* J. y) f6 l6 c client to fetch the designated URL using the same HTTP method. This can be7 h5 J* K k, N
quite problematic in case of non-GET methods such as POST, because the URL; G+ [ |; C0 W Y# Z8 D
sent to the client might not be allowed for something other than GET. To# @+ W9 p8 @* r4 u) _& g8 r
workaround this problem, please use "errorloc303" which send the HTTP 303
. s& Q3 y4 z/ O( F6 a1 R& I' G! b status code, indicating to the client that the URL must be fetched with a GET
0 ~% J* i8 E3 B7 I request.
6 o+ {+ `: z, E* d: I' ~
6 [6 U8 e; U) {; W1 k9 Z: n7 x See also : "errorfile", "errorloc303"4 D) {. D5 ]' m/ `1 Z7 @- s8 z% B/ z
$ r+ p+ z1 C- y, p: V3 e* Q' x& s
. u/ ~* o" \8 l8 q- c" Z
errorloc303 <code> <url>
% A; g0 E- T+ I0 ], {7 F Return an HTTP redirection to a URL instead of errors generated by HAProxy
2 p7 p- Z3 I4 `- U May be used in sections : defaults | frontend | listen | backend
2 _9 V# l( \: A" B7 D yes | yes | yes | yes8 C; N E6 A. {: N6 d
Arguments :
# @' o* S7 @8 B0 o$ H% Q <code> is the HTTP status code. Currently, HAProxy is capable of' P, {/ f3 a, f& U) O' G
generating codes 400, 403, 408, 500, 502, 503, and 504.
" q( ]- u) X4 k5 o/ Y1 m# q
! m7 Q$ { }# S) x1 \1 N8 m <url> it is the exact contents of the "Location" header. It may contain
8 A+ g# v2 {2 c either a relative URI to an error page hosted on the same site,7 _+ y( O! R; T
or an absolute URI designating an error page on another site.
4 t/ X Y$ q5 V0 o/ |; s! f Special care should be given to relative URIs to avoid redirect
0 l3 B8 L: P. D F9 V loops if the URI itself may generate the same error (eg: 500).
! W9 T0 q5 p7 i h: H
. A. l" j( U% ]; A5 {0 h& N It is important to understand that this keyword is not meant to rewrite7 z0 k/ _ F% X: M; f' X8 G
errors returned by the server, but errors detected and returned by HAProxy.: `# e) U; X y/ c8 { P
This is why the list of supported errors is limited to a small set.
1 u* }* F0 x, ?1 \2 {0 P6 M, }6 F" v+ W& j
Code 200 is emitted in response to requests matching a "monitor-uri" rule.: D: A7 K) W/ a( y& \( L! a$ r7 ]
2 U* Z* f) G5 G" J Note that both keyword return the HTTP 303 status code, which tells the/ K* f, t* H% {4 z7 }! A( I
client to fetch the designated URL using the same HTTP GET method. This/ t. r9 U/ x# K- |/ X$ M0 t
solves the usual problems associated with "errorloc" and the 302 code. It is
0 o& h7 P8 |/ c$ r/ F* a possible that some very old browsers designed before HTTP/1.1 do not support& G8 g$ c3 j* ?% w. O& d( @8 ^
it, but no such problem has been reported till now.$ K8 g0 z# p" C1 k' w% d
5 L, m1 b2 G8 j0 F0 c" f
See also : "errorfile", "errorloc", "errorloc302"
% _1 t* {7 o1 x- Q
9 N3 E/ V* Q" A
/ r1 M- T9 L! x1 i. q( {" zforce-persist { if | unless } <condition>
: H, i& m7 }$ t9 s* e7 U Declare a condition to force persistence on down servers3 I' i1 w: ~. E. p" e0 w+ K
May be used in sections: defaults | frontend | listen | backend0 {: g. d+ D: Q, M: V- [- M
no | yes | yes | yes' p/ p) M" {& F! \+ P/ U) }
1 h& e' L: Q8 G7 Z' u By default, requests are not dispatched to down servers. It is possible to
% P* u( a5 |" ]: b. x- Z force this using "option persist", but it is unconditional and redispatches
; x) }4 O, j3 N& c/ P to a valid server if "option redispatch" is set. That leaves with very little* ^! t$ m7 w5 B
possibilities to force some requests to reach a server which is artificially8 {9 S7 M$ l" ^* c& d$ V. A
marked down for maintenance operations.
: f1 h% U/ I; S! \! J2 Y7 g% { a
The "force-persist" statement allows one to declare various ACL-based& U( O& ?" s- `% h3 R2 O/ l
conditions which, when met, will cause a request to ignore the down status of+ F. b) i$ p1 r9 Z* J* @
a server and still try to connect to it. That makes it possible to start a
; B# T2 e) g; `9 h server, still replying an error to the health checks, and run a specially
) b: x. E3 G7 @/ X0 C( [ configured browser to test the service. Among the handy methods, one could
K' G' h( P6 ^& P# |5 E use a specific source IP address, or a specific cookie. The cookie also has4 y! r! F. B: `$ u( T. L% [" r
the advantage that it can easily be added/removed on the browser from a test- N. Z( V k; P7 {' C: g- j$ g
page. Once the service is validated, it is then possible to open the service
% A1 M& F' I1 x( G u to the world by returning a valid response to health checks.
2 W9 B/ p" F* D2 M
" E3 X) J- Y% Z The forced persistence is enabled when an "if" condition is met, or unless an
4 S% H; @/ _. h$ [ z "unless" condition is met. The final redispatch is always disabled when this
2 y) L4 N9 I8 ~1 s! M* V# r4 @8 P3 ? is used.5 |( e& X) s5 j
$ o; P5 }& t, J J- J
See also : "option redispatch", "ignore-persist", "persist",; ?1 @$ \6 ]* A2 f( I- _
and section 7 about ACL usage.$ F2 F1 [ G7 {+ N0 t& k
5 U( h6 `7 Q V8 T
2 u0 [9 M7 U3 a5 {8 xfullconn <conns>0 ~8 e, }6 B0 p7 G# y$ t# D5 K3 X
Specify at what backend load the servers will reach their maxconn
. H. ]" \: N( b5 G May be used in sections : defaults | frontend | listen | backend0 Q$ ~( m4 s: ^6 m+ q, V0 A5 {
yes | no | yes | yes
: V/ W# u6 q* j% X% n Arguments :! S2 B: O8 j/ f* P+ K$ t+ L, w! h
<conns> is the number of connections on the backend which will make the
' r. o5 t% I- D" s7 F A9 @+ U servers use the maximal number of connections.
( A( G+ S! V# h; `9 R
0 d7 {. S* ?- ^# q When a server has a "maxconn" parameter specified, it means that its number
* U) }. v" j9 F% e of concurrent connections will never go higher. Additionally, if it has a
+ h- B0 V* `$ t& ~' b' m2 H "minconn" parameter, it indicates a dynamic limit following the backend's! F$ ]6 e5 \3 [: K6 Z( t
load. The server will then always accept at least <minconn> connections,
/ l* _3 Z: C0 X7 h never more than <maxconn>, and the limit will be on the ramp between both
e' I' ?5 ?6 G values when the backend has less than <conns> concurrent connections. This: [0 W1 j: W! F( H
makes it possible to limit the load on the servers during normal loads, but
" ^" `" J' M# u2 L. \- \' T push it further for important loads without overloading the servers during# B* f0 K% N4 r; @1 \/ ^
exceptional loads.
( L8 O; d3 d, A0 X2 z" i- W9 V' d: d- V( D! G3 b$ t
Example :* r. M d3 S- q
# The servers will accept between 100 and 1000 concurrent connections each3 |+ j% P0 n* a% X3 y4 C! T
# and the maximum of 1000 will be reached when the backend reaches 10000' }/ G' ` u% P( {+ {1 V" O5 _* y$ D
# connections.
/ w# H) V: u! q+ y backend dynamic
" X3 {& k6 J. E5 u/ u0 K6 l fullconn 10000. [9 ]- \. [7 Z7 K
server srv1 dyn1:80 minconn 100 maxconn 10005 P3 y; K/ c+ M- ~3 m
server srv2 dyn2:80 minconn 100 maxconn 10005 o5 b/ ?3 ?+ [ C0 p
6 c8 I- r) c8 a! H
See also : "maxconn", "server"
3 t( @# U K4 `' S
( w. w5 ^: V& V
6 P [1 D$ R3 n6 m n+ kgrace <time>
8 t8 i, x' ^. V0 m3 l4 ? Maintain a proxy operational for some time after a soft stop
8 t/ n0 z5 }0 o0 \9 Q May be used in sections : defaults | frontend | listen | backend
6 a9 l3 P5 w+ Q3 a! s. s' q4 h yes | yes | yes | yes0 j9 Q: I5 J! i4 U6 o
Arguments :( E9 x9 A. H& d$ x' X, ^
<time> is the time (by default in milliseconds) for which the instance4 h: h9 P. L8 c( @/ T
will remain operational with the frontend sockets still listening
! h$ t* R, N- Y0 X! g when a soft-stop is received via the SIGUSR1 signal.
4 A- w6 q% c9 G9 w+ i' V* `, P2 k2 f( W& r/ W
This may be used to ensure that the services disappear in a certain order.6 a4 i+ L* U: Y# q4 _2 B
This was designed so that frontends which are dedicated to monitoring by an4 ^7 ^- w* r9 L& _- Z& G" J+ T( Z
external equipment fail immediately while other ones remain up for the time
: B( x1 s' Q, q5 S. t needed by the equipment to detect the failure./ a$ Z) X9 U5 W4 ~$ b! n
/ |6 | {6 M/ c2 ~& L% c. ~5 G+ V1 U Note that currently, there is very little benefit in using this parameter,
7 o% p6 P1 t+ ^ and it may in fact complicate the soft-reconfiguration process more than
/ s* x2 w$ s% ^2 ~ simplify it.
7 [& P- ^9 {" h2 D& j$ U. P _4 ?6 W4 w6 I/ |, i
0 O, |' J; X' g7 n) vhash-type <method>* G# z3 b" |4 X1 j$ f2 d4 I7 @, t6 r
Specify a method to use for mapping hashes to servers5 } y/ W& a1 | X2 \) }4 I+ n
May be used in sections : defaults | frontend | listen | backend
' n: U% I% a5 A yes | no | yes | yes$ d2 Q3 L& e/ C. R! { R' s. b
Arguments :
6 e4 W( l$ @& p2 { map-based the hash table is a static array containing all alive servers. D* H" g- D( i. I4 l! z' Y
The hashes will be very smooth, will consider weights, but will
$ T- p, h6 l+ V3 { be static in that weight changes while a server is up will be
9 \3 y1 H6 {$ R9 y/ ^ n+ J0 s ignored. This means that there will be no slow start. Also,' w% o& @0 j5 a' T. ^6 A
since a server is selected by its position in the array, most# b; S$ b, [+ s3 m# H B% b
mappings are changed when the server count changes. This means. `7 Z8 H5 I* @, D& o: B' ?
that when a server goes up or down, or when a server is added
/ u K) n7 X2 j, E b9 n to a farm, most connections will be redistributed to different9 Q5 ^' |2 K3 R: c) @
servers. This can be inconvenient with caches for instance., u1 {# i; ~# q4 H/ N
2 f( L: z" {8 M" D
consistent the hash table is a tree filled with many occurrences of each
( v8 _, Z3 X. N* G! I server. The hash key is looked up in the tree and the closest2 s' f2 p% _; v8 k& m4 ]
server is chosen. This hash is dynamic, it supports changing1 ^6 S. D, Y3 C
weights while the servers are up, so it is compatible with the" \, z& \8 }1 a
slow start feature. It has the advantage that when a server
6 T6 s% A4 ^: g! M- X$ K7 t goes up or down, only its associations are moved. When a server
7 C. S" p6 \, B is added to the farm, only a few part of the mappings are( T9 `( R$ Y+ P6 I: G1 k% o' z
redistributed, making it an ideal algorithm for caches.- c- f% A3 D/ S) u
However, due to its principle, the algorithm will never be very3 h, z0 R5 U5 L9 p. ~
smooth and it may sometimes be necessary to adjust a server's
) y4 W* ` i! B9 w0 }, {% C' ` weight or its ID to get a more balanced distribution. In order
1 \0 a/ \0 S; n1 Q0 B7 J4 k1 O to get the same distribution on multiple load balancers, it is* s3 r9 y! m" a& O
important that all servers have the same IDs.4 w. t5 J% W2 ]. u; `6 R
/ T; {! T! O- V/ D: x* T
The default hash type is "map-based" and is recommended for most usages.4 g. n; e6 o- c% T- O
0 Z, A m& {% W, q8 k p See also : "balance", "server"
4 S9 K7 I! |& _: x% y1 C+ T
( \3 c, l% I, h. a
) _; Q* z. h! h0 v) ]http-check disable-on-404; h% U6 z3 G0 ~& Q0 Q
Enable a maintenance mode upon HTTP/404 response to health-checks$ |5 B. L& y( H6 ]
May be used in sections : defaults | frontend | listen | backend9 ]4 A! v1 I% ~' f
yes | no | yes | yes7 f1 J) _5 I" }. G9 _: m
Arguments : none
6 g& @) R- p% B+ a" P
# Z4 ~1 V) a+ B8 c When this option is set, a server which returns an HTTP code 404 will be8 L+ p% A2 F6 x+ Q
excluded from further load-balancing, but will still receive persistent7 ^! M W7 S6 _/ E' D$ t% R B
connections. This provides a very convenient method for Web administrators
4 B+ S& R; N! Y8 m4 X, t" k to perform a graceful shutdown of their servers. It is also important to note( A( W& F: m( i2 G7 [: n
that a server which is detected as failed while it was in this mode will not
( I: r% V+ Z3 @7 G5 r6 e generate an alert, just a notice. If the server responds 2xx or 3xx again, it
: @. r% j# _+ L# y will immediately be reinserted into the farm. The status on the stats page7 i5 y! C. g0 Q. s+ \# K9 @
reports "NOLB" for a server in this mode. It is important to note that this! r( g$ B$ p/ Y, A9 c8 N
option only works in conjunction with the "httpchk" option. If this option' x2 J7 }5 d" B: C1 d, K
is used with "http-check expect", then it has precedence over it so that 4040 U8 Y' Z6 ]+ n4 o; c4 T; F$ _
responses will still be considered as soft-stop.
; I# }5 I9 f, F8 z1 A0 X/ W; T3 L7 b/ k' n3 I
See also : "option httpchk", "http-check expect"
' H7 E2 S5 _" T3 f/ ]. T/ E
/ b" y$ P# u8 W, z1 \+ r @' F" h3 ~# Q6 I' p
http-check expect [!] <match> <pattern>
) \. p: S: W5 d8 y5 r4 K Make HTTP health checks consider reponse contents or specific status codes7 n: x/ \) P1 n0 C6 C/ E7 b
May be used in sections : defaults | frontend | listen | backend
7 J) }+ s( Z( R M yes | no | yes | yes; Z8 E p% W2 f; r
Arguments :
5 h3 Z1 n# \' c" a* ? <match> is a keyword indicating how to look for a specific pattern in the" [, t- a* N6 `; B+ _
response. The keyword may be one of "status", "rstatus",
; w- ~# w( @/ k: d7 ^ "string", or "rstring". The keyword may be preceeded by an
: x. `* t2 S1 |: n4 e% s& w4 V2 t0 a exclamation mark ("!") to negate the match. Spaces are allowed
$ n% }7 a d( U/ s1 | between the exclamation mark and the keyword. See below for more" [4 L" @, M5 X7 f/ f* p* ?) v
details on the supported keywords.* S) w7 r9 A+ P4 _' ]
9 W0 d% O6 {# Y k7 R
<pattern> is the pattern to look for. It may be a string or a regular
9 i4 ?' V6 I5 n j3 p expression. If the pattern contains spaces, they must be escaped/ ^9 @' y4 n |/ t4 i; t% g" w0 W
with the usual backslash ('\').7 Q( m! b0 u" H; A2 u9 O7 J0 _
9 \/ E+ B2 U& |0 k% x E* B( o. f By default, "option httpchk" considers that response statuses 2xx and 3xx
8 Y( Y; }* w0 M, j3 [- { are valid, and that others are invalid. When "http-check expect" is used,
( }6 e) m% D- L; r0 m; k it defines what is considered valid or invalid. Only one "http-check"+ J5 n9 W9 a3 E% o* w" T
statement is supported in a backend. If a server fails to respond or times( G! j7 B2 _+ i# Q2 F& u- {% _4 {, ?
out, the check obviously fails. The available matches are :
! @' Z/ k, \: a9 v. t- w2 p( \ h9 ~+ O l# {! u
status <string> : test the exact string match for the HTTP status code.% J/ C- \. l$ G6 c7 a
A health check respose will be considered valid if the4 t& f" v9 U; y7 p6 w7 X
response's status code is exactly this string. If the
# x; X+ U t5 g "status" keyword is prefixed with "!", then the response
2 N# m* b: m5 W0 ~) L will be considered invalid if the status code matches.+ z$ S! F0 N& l- W
$ g( E4 h- k* ]( q: o0 n rstatus <regex> : test a regular expression for the HTTP status code./ r- t2 y& v3 r& a0 c" A
A health check respose will be considered valid if the
9 F; v! y% y% B' b! \ response's status code matches the expression. If the
8 f. M# }7 f% ]! x "rstatus" keyword is prefixed with "!", then the response
/ {" n$ p1 A* {& b+ z& n will be considered invalid if the status code matches.
* m- b8 k; R5 S' G/ E This is mostly used to check for multiple codes.
0 d& e' M3 {3 f$ N: B: ^
3 p; L7 I) S0 `: ^1 k- D* I string <string> : test the exact string match in the HTTP response body.
3 R& V' _" l0 W8 P! S A health check respose will be considered valid if the5 X( l9 Z7 v) Z8 a" [' Q
response's body contains this exact string. If the
# B- L5 w* t6 U- H0 U "string" keyword is prefixed with "!", then the response
) o$ n) C0 R. U& v% t3 V# R will be considered invalid if the body contains this
5 B( b7 {& V" K string. This can be used to look for a mandatory word at' s9 _, `: n3 B) x2 h' l a* o, w
the end of a dynamic page, or to detect a failure when a
7 i# X. h4 o" B [) X( f specific error appears on the check page (eg: a stack
: Z4 W9 O( R9 V0 a: W trace).7 T) S! v! m7 t7 k% g: z
! v- M9 A; W. j+ p, b rstring <regex> : test a regular expression on the HTTP response body.
5 Q+ n1 A5 V1 ~) Q9 P i0 ~ A health check respose will be considered valid if the
- b3 G, p, Y% ^1 c/ H response's body matches this expression. If the "rstring"+ }) `7 E' V% k0 v
keyword is prefixed with "!", then the response will be
5 i6 s# o/ W$ o; q2 L considered invalid if the body matches the expression.
3 ^1 B( j A' m+ B C% @4 k7 U This can be used to look for a mandatory word at the end
/ j: G& V4 y# r) P; X" Q: {% p* V of a dynamic page, or to detect a failure when a specific
+ F0 G$ [" x$ t3 W5 K error appears on the check page (eg: a stack trace).( T, M3 u! C6 [* r
" V/ q/ G& N1 B3 p! B It is important to note that the responses will be limited to a certain size) g) [. D- j- P9 X
defined by the global "tune.chksize" option, which defaults to 16384 bytes.
( w: z+ u2 v: `. Q' L Thus, too large responses may not contain the mandatory pattern when using
- ~* d% h2 Q; \, Y4 n0 Y' v "string" or "rstring". If a large response is absolutely required, it is7 D* [7 m" ?9 \0 P
possible to change the default max size by setting the global variable.
8 ~3 B- J. N+ e8 ?$ Z4 M However, it is worth keeping in mind that parsing very large responses can0 |0 y, A3 S- e8 |7 c) Q2 h
waste some CPU cycles, especially when regular expressions are used, and that0 s. x) I3 ~ ?
it is always better to focus the checks on smaller resources.; P$ q' ~1 n# R
5 M* h t& U, \6 Y* A Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it* A" T4 i, k1 S: l+ ^0 m' ?( S
will automatically append a "Connection: close" header, meaning that this, r2 z/ ` J- p1 ^% ^, d, ^
header should not be present in the request provided by "option httpchk"., W6 q! e' x+ ^5 A
8 U9 t9 Y* S4 M% Z: ?" m Last, if "http-check expect" is combined with "http-check disable-on-404",
( ~% ?) d* @, L( h( E then this last one has precedence when the server responds with 404.! b# l6 H+ {! q1 q
L+ ?' z8 x" t% } Examples :
0 [( w7 c- M9 C8 M0 x # only accept status 200 as valid8 T8 B& x/ D% r/ k
http-check expect status 2005 X5 s! u( z+ C3 z, J$ z+ l
. ~$ p- n2 l3 Z$ A7 D" ` # consider SQL errors as errors
* L8 m( `( W+ g5 a5 L http-check expect ! string SQL\ Error6 Y* d: [" F& k6 z7 W
& M, H; _; s# Y: m
# consider status 5xx only as errors: ?: R$ x( h5 ~+ n, j
http-check expect ! rstatus ^5
4 X0 |$ a* B; \+ T: `
1 Q# k7 K! s4 ], t% E# d # check that we have a correct hexadecimal tag before /html$ [6 v- `9 G7 o: z
http-check expect rstring <!--tag:[0-9a-f]*</html>
; A7 g! O4 D% |/ w: u$ W+ y7 L5 b
See also : "option httpchk", "http-check disable-on-404"
- ~: _* o* J1 {2 v! B. P, d
: w0 |" \4 Q% q. E' |3 j) x T; b5 N5 w) F, x! l+ Q, B
http-check send-state& x- Y3 K) O" O) E+ X
Enable emission of a state header with HTTP health checks0 ]1 W5 K5 w# f% ]! V. r
May be used in sections : defaults | frontend | listen | backend6 ?2 m" T6 D9 E' ~7 {' p
yes | no | yes | yes7 C! J: S# J# k9 [
Arguments : none
]1 u5 c$ v5 w. z; N' b/ t7 ?! O1 M, s' i* P, `
When this option is set, haproxy will systematically send a special header7 l8 I9 D, h: I( e1 I
"X-Haproxy-Server-State" with a list of parameters indicating to each server$ _! h% S7 M& H
how they are seen by haproxy. This can be used for instance when a server is5 m) \: K! l0 D# Y; u
manipulated without access to haproxy and the operator needs to know whether5 K. P; h" u7 g' O/ |$ ?* L
haproxy still sees it up or not, or if the server is the last one in a farm.
1 D ~' ^4 U. {% s9 }; C- J: q
. c+ Y0 N4 [' z9 @ The header is composed of fields delimited by semi-colons, the first of which
3 N. R4 k" g6 U5 k2 `( g1 Q F is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid1 @1 u7 V |4 [6 H5 I1 J5 D
checks on the total number before transition, just as appears in the stats
! W' o# `) @% c8 i- Z% s interface. Next headers are in the form "<variable>=<value>", indicating in& n1 \2 n+ A$ y ^ v6 B
no specific order some values available in the stats interface :
+ C8 m6 E1 F G! i' B - a variable "name", containing the name of the backend followed by a slash: f7 I2 x5 z- E" ]4 s' M+ [
("/") then the name of the server. This can be used when a server is8 b0 R N3 g$ x$ C# s8 k
checked in multiple backends.9 L) X, h) ?( o. z& @- [" e9 P
, m4 }% ?8 j) a7 A0 t- B, b' n3 u
- a variable "node" containing the name of the haproxy node, as set in the
, r/ h" k8 J# ~5 p# Z. E. {7 o global "node" variable, otherwise the system's hostname if unspecified.
, k. F) D# T" \7 i3 y, a/ H/ H0 |1 T5 B4 R' t7 A
- a variable "weight" indicating the weight of the server, a slash ("/"); k+ J! x! A( J: o+ t
and the total weight of the farm (just counting usable servers). This
2 j3 }1 |* J* \ {% Q) C: N* {: g helps to know if other servers are available to handle the load when this( A% C* }0 J2 i; b) ]0 X
one fails. I; |9 {8 Z* B- W3 I! G8 `* |& a
% T; }# ]/ s0 E5 F
- a variable "scur" indicating the current number of concurrent connections
; }4 J& z1 s% F5 C6 j& ~3 _ on the server, followed by a slash ("/") then the total number of
. h4 h4 }" |4 K8 I: C connections on all servers of the same backend., Z5 z1 x, g) ?0 J) Q* Q
7 s) D8 t+ }$ b% k) Y+ `! V; J+ o
- a variable "qcur" indicating the current number of requests in the) {9 t9 F `) D4 }
server's queue." l! v& J" R; {: q
! _7 s' C4 Q6 M2 n: ^1 ?+ s
Example of a header received by the application server :
/ e- K# A- }. v; b' o/ O >>> X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \
. e+ Y, F1 c3 ^/ O scur=13/22; qcur=07 Q' o" Y: d2 L0 y! V
9 v, N" b4 m/ O) c5 K, Z
See also : "option httpchk", "http-check disable-on-404"
" o: _/ L) Z& Z; j
, y9 e2 V" j3 @8 A0 l# j3 P" p% phttp-request { allow | deny | auth [realm <realm>] }
0 L1 t' @. t0 f) T* N) O [ { if | unless } <condition> ]8 c- s- D" Y; j) q4 W
Access control for Layer 7 requests
+ }! |. d0 z- I6 V1 e8 |! b( q% a' k1 Y! R" k
May be used in sections: defaults | frontend | listen | backend
3 f9 b3 @. v4 D no | yes | yes | yes
+ v1 _. t. N- F' S4 Z/ c4 m) _: A$ y) ?2 A% W2 D
These set of options allow to fine control access to a2 K/ d/ g6 |1 H" [0 G* E/ y! x
frontend/listen/backend. Each option may be followed by if/unless and acl.2 C D7 I1 G. Z m
First option with matched condition (or option without condition) is final., f5 n1 t3 }, c( a! D/ B6 D
For "deny" a 403 error will be returned, for "allow" normal processing is3 @( y% y: c; ^3 |1 `9 N8 a
performed, for "auth" a 401/407 error code is returned so the client# h# u6 Z) c- e7 t0 K8 e
should be asked to enter a username and password.; U1 U5 ^" ]0 | b( I
. x3 u0 y+ d+ ?7 N4 d7 n6 g There is no fixed limit to the number of http-request statements per
% [/ u' x$ R) Q2 J instance.0 }' }" V6 H7 B; i/ g g& F& o4 S
! I- x' S" \$ f; E7 @; d
Example:
, U. `* Q9 D! ~% t3 u1 O acl nagios src 192.168.129.3
% l2 Y) F3 B d" r% N acl local_net src 192.168.0.0/16
' g% I/ t W, [- n/ L& ^; ? acl auth_ok http_auth(L1)
+ Y# c/ A. V+ S1 f- K" f* K
# ]! u5 H, m }6 g http-request allow if nagios# _1 Y. U7 R5 k" B
http-request allow if local_net auth_ok6 `! G* a+ {4 S
http-request auth realm Gimme if local_net auth_ok
- E. l, O: `5 C6 b4 m http-request deny
2 I+ C, ~+ P9 q# m- s, Y8 t5 O
. M6 V* d' Z7 b Example:
+ A! S" ]. e$ l# o& f; o acl auth_ok http_auth_group(L1) G1. }: Q( z5 v2 I5 C8 K( p
* R' B g" L3 q, c# U0 B- S# Q
http-request auth unless auth_ok
9 I+ _# y' z" e% ~$ l; J
4 Q7 j: g8 V& Y- o3 _ See also : "stats http-request", section 3.4 about userlists and section 7
% S4 M4 W* E+ g: f* ? about ACL usage.
2 Q$ A0 W w# N9 f! P+ r, s2 y5 o: Q% A3 c( f6 a
http-send-name-header [<header>]1 c d3 q( ]5 v9 t" E& n
Add the server name to a request. Use the header string given by <header>* {! ~. u M1 Y8 C, G8 V! }% O$ U L) m
6 Z( i. W: X5 N4 O8 w K% j
May be used in sections: defaults | frontend | listen | backend6 w9 i, k I" }( x$ m; b
yes | no | yes | yes, x1 W |- ^' }3 j- N+ I: f
* b7 _. k5 ` i: s2 \8 ?7 y
Arguments :
& A7 B1 i# V" W3 E6 J
8 a# }4 h7 _1 B4 u6 N1 k <header> The header string to use to send the server name
+ t8 L2 K; F9 E6 s" m9 O
" b) j0 h/ f T$ J) t& h The "http-send-name-header" statement causes the name of the target
# i0 K9 g& W; u2 ^& R server to be added to the headers of an HTTP request. The name! N5 Y" Q/ }4 H- U+ \5 Q4 U, B9 ^; M
is added with the header string proved.' \* c) Y: A) `2 C c
\% h' w$ l$ _5 F, R2 Q See also : "server"" t% l# |, t- ]7 c
1 Z4 X2 I. J2 ^, U; {# \
id <value>
8 i/ o" Y8 z) D- B0 X Set a persistent ID to a proxy.' i5 N2 C! r1 i+ @. ~
May be used in sections : defaults | frontend | listen | backend
; r3 |4 V# e! o0 r' ^/ l9 g no | yes | yes | yes
( w7 X2 U, _9 o0 d0 g9 } Arguments : none$ ?" a) q# W& |+ U! R3 d" c+ V+ X) k
' W6 S1 S# F. w. D9 `
Set a persistent ID for the proxy. This ID must be unique and positive.
0 ?# `% ?+ F5 T& B# F An unused ID will automatically be assigned if unset. The first assigned7 Z$ z( j7 v. r( x: m6 k
value will be 1. This ID is currently only returned in statistics.% B; x4 ~" G& `
/ r3 r4 N2 X; M4 f8 E7 n, |
! L. [5 f+ u( I# ^. F( X* rignore-persist { if | unless } <condition>
0 y2 x- | i& }7 I4 D Declare a condition to ignore persistence, t0 q" l1 x; t" J: J& @
May be used in sections: defaults | frontend | listen | backend
6 v B; _. p# x- F2 z6 `4 O no | yes | yes | yes
: @' X1 z4 ^1 s! Z \' U+ d7 v; a, d% r5 w, X" i& r4 j
By default, when cookie persistence is enabled, every requests containing- h9 A+ F& p) B% ]$ Y/ W
the cookie are unconditionally persistent (assuming the target server is up
* y$ h0 K8 H+ v$ o' X6 F) {& Y j and running).
/ O$ X; e( n8 o" Y* N9 c2 f) E4 V! l6 ?) R8 H1 S y
The "ignore-persist" statement allows one to declare various ACL-based
/ n# q/ b$ E9 e0 P0 Q! }8 _9 J conditions which, when met, will cause a request to ignore persistence.0 ~+ ^6 d& S& Y3 [. Z( Z
This is sometimes useful to load balance requests for static files, which0 g5 ~/ j9 U+ w
oftenly don't require persistence. This can also be used to fully disable3 Z% h- m/ R9 Q4 _ N% o
persistence for a specific User-Agent (for example, some web crawler bots).; Y o( _9 u0 ~ F! x
1 z# G7 Y. U, ]# M9 I' y/ L) h4 v1 p
Combined with "appsession", it can also help reduce HAProxy memory usage, as m/ L; E$ C1 z- L% V! G; W/ R
the appsession table won't grow if persistence is ignored.
" ]& K1 i$ L: D5 x. D( p( W6 O& t( D6 \( [
The persistence is ignored when an "if" condition is met, or unless an
9 g+ E. X9 E5 L! X+ J$ [ "unless" condition is met.
P3 a* l) R/ k9 _9 q# ~4 |( P4 F: b6 t
See also : "force-persist", "cookie", and section 7 about ACL usage.
* L: g) Q J/ B1 y) a! o: D
, x! _+ C, D* B6 z! S+ n2 c; z1 L" Y+ ]" X8 Q
log global
( X" P( U+ d- w7 N# B( q( A& nlog <address> <facility> [<level> [<minlevel>]]! M, v. l7 O8 Z$ c, u+ \2 ~: n
Enable per-instance logging of events and traffic.9 C+ V" {8 r# m1 ~; ]
May be used in sections : defaults | frontend | listen | backend/ O% |1 ~6 K7 @& Y/ o* U
yes | yes | yes | yes
% F9 @* ?+ ^) m Arguments :
' L% w) O* l3 T" f$ o' M global should be used when the instance's logging parameters are the
% e6 J4 h& l- N6 \ same as the global ones. This is the most common usage. "global"
& ^8 [1 [5 ]8 K5 F replaces <address>, <facility> and <level> with those of the log
) w, @6 x$ V. D3 Y& J( U/ D! X entries found in the "global" section. Only one "log global"& k% K9 d9 x& F. J9 m
statement may be used per instance, and this form takes no other; w7 p3 Y3 i9 c$ q' h1 X; l& F
parameter.
* n: @. ~* o$ Q7 E7 l8 A8 G$ c1 R4 d: E* T, [
<address> indicates where to send the logs. It takes the same format as
$ M8 ~9 T) I" U& }8 [1 n for the "global" section's logs, and can be one of :
0 U+ E: g/ \- a! L4 j
0 k$ r! ?! ]. H - An IPv4 address optionally followed by a colon (':') and a UDP7 ^% I! f( o1 J! Y# p2 [& P
port. If no port is specified, 514 is used by default (the
9 i$ g+ | z4 x' R K3 I standard syslog port).- T" l# y; z6 A. x4 i& U r: K
2 z& l% b5 O' E8 ]5 f
- A filesystem path to a UNIX domain socket, keeping in mind3 Q" _, { R/ X) c: x
considerations for chroot (be sure the path is accessible. o' A+ Z$ y9 r3 {7 i/ |3 S
inside the chroot) and uid/gid (be sure the path is+ W2 b" n a* w0 v
appropriately writeable).
8 Q" I/ @) b$ W+ n7 I
J- Z8 d% [) u1 p <facility> must be one of the 24 standard syslog facilities :
( H3 W$ l9 N% B
$ d/ S, u% D9 }/ K. H kern user mail daemon auth syslog lpr news2 X$ b; i3 v' Y
uucp cron auth2 ftp ntp audit alert cron2 ?5 d: \# O( Z1 b
local0 local1 local2 local3 local4 local5 local6 local7
' e& g, p7 ^, {% N8 l) V
% A" C8 J' \9 b b5 k F# m <level> is optional and can be specified to filter outgoing messages. By
- F) Z* r$ N+ N! `9 w- V3 b7 B* K9 ` default, all messages are sent. If a level is specified, only( D7 f6 I( q4 {2 o+ ]4 h* d1 V8 G
messages with a severity at least as important as this level
' n x: M% D6 q; }, | will be sent. An optional minimum level can be specified. If it+ `( j& D- D: d, M( Y
is set, logs emitted with a more severe level than this one will
0 k3 M: T {( ~# u( G9 Z be capped to this level. This is used to avoid sending "emerg", p4 E/ L& ]7 a$ T
messages on all terminals on some default syslog configurations.
, ~) C1 S% y9 U' b; j2 o1 J Eight levels are known :
1 G* V. a! Q; X1 d: N
' }% O/ p, `. Y# q6 @0 T- K% ^' z emerg alert crit err warning notice info debug+ B* J# k1 n0 c; l, l- j" B
) t( Y- l, ^7 v2 J Note that up to two "log" entries may be specified per instance. However, if
& y! r! x" k5 D "log global" is used and if the "global" section already contains 2 log
8 a! g! j+ a! @4 F, ^1 Y entries, then additional log entries will be ignored.
7 L' _( U- v/ K! S* X9 K
. J. W& c9 o) m! y. W' |8 @ Also, it is important to keep in mind that it is the frontend which decides' Y. [# D f) z2 _) j# t6 F# s/ C. _
what to log from a connection, and that in case of content switching, the log
' Q$ U& {4 D/ F8 | entries from the backend will be ignored. Connections are logged at level% c. l7 k! m, I9 @
"info".# w+ v4 u% Y: b! A+ m, N9 B
, B, n3 J$ W5 m( `! y However, backend log declaration define how and where servers status changes
2 ^9 p: q6 w: o. `% z2 J will be logged. Level "notice" will be used to indicate a server going up,
3 C1 B$ f8 w/ `, W3 \( r- R# p "warning" will be used for termination signals and definitive service
7 S! G0 J3 m6 M9 \3 E termination, and "alert" will be used for when a server goes down.! I2 @+ w3 M7 y L9 ^
' E; z9 Y7 E1 C ?2 X
Note : According to RFC3164, messages are truncated to 1024 bytes before0 a8 P5 B# {/ U/ {! F* s; h
being emitted.4 i2 v1 p0 s- E T$ S6 m' ^
/ r% t$ J& ~0 K+ O+ Y. E
Example :
/ L& U2 H0 a8 e7 ~ q log global# n! N. e1 k: ~5 y
log 127.0.0.1:514 local0 notice # only send important events
4 j4 U* f/ P4 }3 q' A- ~ log 127.0.0.1:514 local0 notice notice # same but limit output level0 i+ C) p6 }6 S
4 h2 \9 B0 w* l' D
3 n' _9 u' F5 c7 P3 K- G0 z' H
maxconn <conns>1 H$ X! k" R& K1 s2 s& E
Fix the maximum number of concurrent connections on a frontend
5 r( Z5 i) t2 c" m9 Q3 W5 C) o May be used in sections : defaults | frontend | listen | backend$ \$ S4 ~1 C4 t h5 X- M% L* n' m0 v
yes | yes | yes | no) c+ N5 {' I2 B2 \9 C
Arguments :& s/ k6 w: S6 G9 y) k7 ^. b! n0 q
<conns> is the maximum number of concurrent connections the frontend will
0 m, {( b/ o- u& k4 n- R accept to serve. Excess connections will be queued by the system) F1 c' z) s0 F+ R# h! c, K" y
in the socket's listen queue and will be served once a connection
* O- e+ h9 } Z9 X closes.
' O6 P& S2 a! H" {, I5 N7 S& X) |2 V1 t9 G( G) ^
If the system supports it, it can be useful on big sites to raise this limit/ B/ @! ~4 [' K7 E
very high so that haproxy manages connection queues, instead of leaving the/ r4 W8 u% Z! s7 H
clients with unanswered connection attempts. This value should not exceed the, ?8 o6 P2 e" r6 p4 w! f
global maxconn. Also, keep in mind that a connection contains two buffers
) K7 e; x# p e+ ?. l5 { of 8kB each, as well as some other data resulting in about 17 kB of RAM being0 i: L5 L$ b) I6 |$ O: W
consumed per established connection. That means that a medium system equipped6 q# u% f" T& e9 a- _0 K, @ _; t: B
with 1GB of RAM can withstand around 40000-50000 concurrent connections if. t' ^ ]; V* |# v6 \7 n2 y; g q
properly tuned.
9 a9 e3 a- ?6 T& d; s! X3 U1 _* C2 ]8 _7 ^# Q4 R. S' ~! x! u
Also, when <conns> is set to large values, it is possible that the servers" \, `: l% i5 G/ [( z/ i; v% ?$ z
are not sized to accept such loads, and for this reason it is generally wise
! _8 [+ Y% L/ N/ x4 K to assign them some reasonable connection limits.
5 X' X& n Z7 V3 u: E7 B' e* D9 L0 J/ p4 S9 m0 N4 v. Z2 L
By default, this value is set to 2000.
6 E% S' E- b1 `, W" }8 c
& W: ~9 q" P+ e$ t. {2 x. f/ J See also : "server", global section's "maxconn", "fullconn"
* U( R y( T- j5 J, v
8 [7 q9 G' M! Q# T8 _" e+ v9 A& k; ^8 z& f7 {
mode { tcp|http|health }9 l5 {. _- G( ?8 C
Set the running mode or protocol of the instance
' \ s) i) `! o( U/ ^ e May be used in sections : defaults | frontend | listen | backend
2 T( Z0 D; C% | yes | yes | yes | yes
0 W$ t7 B) O# x& p* \% a Arguments :
4 B( J( l' Y5 u9 {% } tcp The instance will work in pure TCP mode. A full-duplex connection$ [5 a# Z" p3 A, I) n: R9 Q
will be established between clients and servers, and no layer 7
# x6 e% k+ E% G4 ~6 s2 I) r; ? examination will be performed. This is the default mode. It( l/ b1 u4 N1 K/ J6 ^% B
should be used for SSL, SSH, SMTP, ...
7 @& Q$ |) s _ `2 A3 }& s1 P( d
http The instance will work in HTTP mode. The client request will be4 r5 q t: Y# P
analyzed in depth before connecting to any server. Any request
& l& K/ K# q2 p- y which is not RFC-compliant will be rejected. Layer 7 filtering,& f- ?& V' [9 T8 H
processing and switching will be possible. This is the mode which
' C6 s- g. M/ X2 O3 k6 s7 ]- W3 W brings HAProxy most of its value.# F/ f1 F% W" s* B1 ]) M# f! u
! M5 ?- z2 b0 k* z- G$ d health The instance will work in "health" mode. It will just reply "OK"7 t. u# P# {& E) u$ Y! n0 @4 m/ W
to incoming connections and close the connection. Nothing will be
) K3 t* C) a* T/ [ S2 `' D) d( E logged. This mode is used to reply to external components health1 {* {7 q* d3 r7 X
checks. This mode is deprecated and should not be used anymore as
; A- `4 D$ w% _2 R1 ~/ X it is possible to do the same and even better by combining TCP or( a3 _$ Q" k" X. f: v
HTTP modes with the "monitor" keyword.
1 w% r# z+ j) g' Q- S0 w( L0 W, l' R" U. b- P6 x4 o* Y; V- G! {
When doing content switching, it is mandatory that the frontend and the3 z. a7 C& Q* O/ u) k$ k u
backend are in the same mode (generally HTTP), otherwise the configuration# q* k( H" c: E& I# K
will be refused.% l% J9 p! _7 f3 u! f! d1 {
. R! _ O y& {" O" v
Example :
% {, u {8 Z6 a0 E defaults http_instances2 o& ]; X; B! h9 N* W5 A( L
mode http
3 i& `( b0 k" D$ J: w7 L. }& T( @5 D
, M% N# H# P" x% y See also : "monitor", "monitor-net": C5 ?% u& a- `3 b1 r
/ P/ k/ B# U! C7 b. Z- [ Y+ I0 t/ s4 k4 d
monitor fail { if | unless } <condition>: W* E+ b0 ]- o1 l3 u; ?
Add a condition to report a failure to a monitor HTTP request.
: ]2 {, d: v6 A" M1 p# q May be used in sections : defaults | frontend | listen | backend
# z! \4 E( e& D8 J5 }/ G- g: _ no | yes | yes | no
0 ?6 ~, Z" ^. p) r+ B Arguments :9 I) n5 K8 M! l; F3 G- x |
if <cond> the monitor request will fail if the condition is satisfied,
7 @9 i0 p% v, D0 ^9 y and will succeed otherwise. The condition should describe a& d% C: X$ |# w% g
combined test which must induce a failure if all conditions
! J3 Z* T7 l" Q: T are met, for instance a low number of servers both in a
+ N8 J3 b- F9 H! j' t1 K backend and its backup." d* Q# A) u! N0 I( L
' e3 s- S6 s" A2 y3 X* W+ B
unless <cond> the monitor request will succeed only if the condition is6 \/ n: ?6 e/ ^$ {2 q; a: c% K" |
satisfied, and will fail otherwise. Such a condition may be# D1 T- B! q( u! n# `6 a
based on a test on the presence of a minimum number of active+ ]2 C7 x/ r4 K$ I/ n+ X- Y8 t
servers in a list of backends.$ R- G* y5 Y0 B% S
! }# Z( W7 `6 e* R1 i5 A7 z This statement adds a condition which can force the response to a monitor
' H! j: ~' M, i5 p3 h# B. N- V# Y request to report a failure. By default, when an external component queries, \1 u# P; G) G
the URI dedicated to monitoring, a 200 response is returned. When one of the
2 S/ ?. ^4 m! D% g$ q conditions above is met, haproxy will return 503 instead of 200. This is' w+ Q9 g, f& E
very useful to report a site failure to an external component which may base
. S, |8 z9 f7 C. P! d- O# K* B" t/ I routing advertisements between multiple sites on the availability reported by- S! b) Q) ~7 y) }
haproxy. In this case, one would rely on an ACL involving the "nbsrv") J! J, Q# O) t1 k! d- l' W+ u6 G
criterion. Note that "monitor fail" only works in HTTP mode. Both status
( \( e& I* n, i. k' J8 U messages may be tweaked using "errorfile" or "errorloc" if needed., t5 _+ g4 \4 k. \& ~) K
1 Z9 o1 {/ d0 I6 e- y Example:
6 e+ B8 l$ C; t: N- U6 b frontend www
. A) N, H. P1 I% ^ l6 {2 B mode http
7 M; H4 {( a- d0 S% v+ B acl site_dead nbsrv(dynamic) lt 2! Y6 r, Y* {# h& d, K+ p
acl site_dead nbsrv(static) lt 29 y2 k8 a: l* q$ E, G! _6 [5 W
monitor-uri /site_alive
! M% g: v& A+ Q monitor fail if site_dead
% r+ U2 u1 z: a1 X! ^9 \" h( p# [& ?- W% e
See also : "monitor-net", "monitor-uri", "errorfile", "errorloc"- m6 Q/ ]7 Q) s/ b8 R) c
$ O. V$ Y* L9 R6 T
0 H7 B7 r; F: Ymonitor-net <source>5 ]% U6 g+ w. t; R: w
Declare a source network which is limited to monitor requests4 b4 U1 S' J. k4 k& v+ q
May be used in sections : defaults | frontend | listen | backend' D1 Q4 b7 R8 _1 A
yes | yes | yes | no
1 h: B5 V T; X" W Arguments :
$ |& l" F0 b p% u$ h8 h0 @) v% h <source> is the source IPv4 address or network which will only be able to, G# z$ r+ G: y% V! O; o& P4 q; E
get monitor responses to any request. It can be either an IPv4# B7 A$ J3 M/ v/ e% H9 D
address, a host name, or an address followed by a slash ('/')
/ r' r5 p- E2 p! Y& A followed by a mask.( M( Q. V* _7 i( c8 `. m; s
! \# |5 ^2 K; G. e" N
In TCP mode, any connection coming from a source matching <source> will cause
) T7 I- L1 `$ E/ I& C+ L. x the connection to be immediately closed without any log. This allows another7 n4 ?5 `+ U3 x! C3 N" s( A
equipment to probe the port and verify that it is still listening, without/ r' E" @, a/ @
forwarding the connection to a remote server.
, T# p1 n9 s( j
- K Q4 ]' X' o In HTTP mode, a connection coming from a source matching <source> will be
8 ~ B, V' h; y( m1 y/ @, K0 s accepted, the following response will be sent without waiting for a request,
7 D+ D, L0 ^* ?2 z* K then the connection will be closed : "HTTP/1.0 200 OK". This is normally/ v" i8 e; q/ u ^" S3 o* s
enough for any front-end HTTP probe to detect that the service is UP and% c. O- U6 A0 U7 A/ J& \ S1 t
running without forwarding the request to a backend server.( E+ s/ l4 F5 V/ }7 y
% C! E. p% i5 `: \7 Z M Monitor requests are processed very early. It is not possible to block nor
1 [, M g2 P- ?0 K& P, ?- K9 D1 K divert them using ACLs. They cannot be logged either, and it is the intended
8 D6 j: Q; I, ]' H, S3 U4 J purpose. They are only used to report HAProxy's health to an upper component,
9 }' y% r1 N3 b nothing more. Right now, it is not possible to set failure conditions on* u. U3 z% r/ `4 v- a
requests caught by "monitor-net".
# d% G- n8 n, f; F: V' ^4 {
8 J! \/ H8 v5 h; s2 K+ ~ Last, please note that only one "monitor-net" statement can be specified in, _4 [8 o$ [" v
a frontend. If more than one is found, only the last one will be considered. ]: Z) {9 }( V/ k4 v
$ ^9 T, t% p# }! q7 g
Example :
% v; E. {# _; n- y% I: N" s4 j # addresses .252 and .253 are just probing us.
4 Q: w; R$ @1 @' e# [& Y frontend www
$ n! L, y7 s3 Y, o+ Y' V$ z5 t monitor-net 192.168.0.252/31
N6 |6 y' c2 X/ \% b9 Z
T/ S6 c$ t) @, t) }; a M6 T- u See also : "monitor fail", "monitor-uri"; a& l$ _# W' F0 |( j
" Y0 l" g. B8 }' ~! H" F
3 |* Z$ q% `' e& M! f3 s8 z
monitor-uri <uri>5 u! z, Q1 Z, E, ^
Intercept a URI used by external components' monitor requests
4 O9 m+ M8 S8 w$ p May be used in sections : defaults | frontend | listen | backend
# X' S8 ^0 _ B yes | yes | yes | no
$ R7 E2 V4 r( w9 d Arguments :
k6 a* d8 B' v* M <uri> is the exact URI which we want to intercept to return HAProxy's
. {3 a4 F) a z; q1 l. b0 X health status instead of forwarding the request.: x2 m: D, H. k7 T
5 P8 u' W: k# O6 j When an HTTP request referencing <uri> will be received on a frontend,5 ~4 j$ n1 c( S3 r$ B
HAProxy will not forward it nor log it, but instead will return either5 S+ ^7 h: S+ N7 T' X& H8 X
"HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure! r7 T8 f6 M7 [/ j/ H* M# [
conditions defined with "monitor fail". This is normally enough for any$ L- a* K* R) ]2 ^& o: z# J
front-end HTTP probe to detect that the service is UP and running without3 L9 o$ b: G! \9 c' D
forwarding the request to a backend server. Note that the HTTP method, the" \+ S$ ]1 J# T/ r; K# F) ~
version and all headers are ignored, but the request must at least be valid; O: Z& x, M; ~1 Z, K
at the HTTP level. This keyword may only be used with an HTTP-mode frontend./ {) d" F5 s: H. R# R
( \5 X G: E* ~' k6 [$ j
Monitor requests are processed very early. It is not possible to block nor' w# H) ?6 Z: w; o% p) Z1 h6 E9 K8 S
divert them using ACLs. They cannot be logged either, and it is the intended
# A% p0 A8 Q: f$ P7 I# f3 j purpose. They are only used to report HAProxy's health to an upper component,4 V: X; [5 c5 L5 q/ a4 v
nothing more. However, it is possible to add any number of conditions using
/ Z5 a7 C4 ]0 ?, P "monitor fail" and ACLs so that the result can be adjusted to whatever check
3 f$ B; a9 v6 K) q$ ]3 j2 u can be imagined (most often the number of available servers in a backend).: c) g7 e3 m8 v; L
! r) w& h" t$ Y1 t$ ` Example :
0 ]$ d6 O T- b# k! ~, W # Use /haproxy_test to report haproxy's status
$ ?6 L! l* Q! J; V frontend www
' ~- i: \: o; m3 a0 T mode http
' L5 b1 C4 w. v' M: \- L7 w monitor-uri /haproxy_test
; @! }9 n+ U% ^3 d/ Z1 ^5 H. J) T& v/ X8 Z0 p
See also : "monitor fail", "monitor-net"
5 {. b; q3 U q+ ]6 P3 D3 G" [5 b: `: d |: a
0 G# k7 G% O. s- ~
option abortonclose
% r' q X. a& N# }- o( t9 m- yno option abortonclose
# O s. u5 i: n* p, s/ D' J Enable or disable early dropping of aborted requests pending in queues.9 e8 c) n. m8 g. L: g8 U
May be used in sections : defaults | frontend | listen | backend
% _" c+ S. N9 Y3 Z' k5 t3 F yes | no | yes | yes
. P% }( y% U. H- T Arguments : none
) t3 W. m3 X' x+ L7 D0 r' ^4 G+ K( Y+ I$ |
In presence of very high loads, the servers will take some time to respond.
( r8 M% c8 Y& |4 Z" C9 p, d The per-instance connection queue will inflate, and the response time will# a3 B8 a a" P8 Z9 n8 [5 ?+ K
increase respective to the size of the queue times the average per-session
/ X, S' ]( q6 ?! W; b+ t response time. When clients will wait for more than a few seconds, they will d3 I" B& {) L2 Z; q5 ~" ~0 b9 N9 i
often hit the "STOP" button on their browser, leaving a useless request in
& }7 L/ `5 {+ R0 Q% z4 @& Y1 N the queue, and slowing down other users, and the servers as well, because the
3 h1 c/ l" j* V( R: c7 N \! }9 ` request will eventually be served, then aborted at the first error, I$ i& }/ I! @" Z( a
encountered while delivering the response.! {6 }8 p# }9 L8 l Y
; C6 l7 s1 s0 ~+ \( S$ T( O# l) X) s
As there is no way to distinguish between a full STOP and a simple output
% z: R |3 ~9 H3 m7 c1 u close on the client side, HTTP agents should be conservative and consider
8 Z7 A! [5 e" S. H; Q* n; h that the client might only have closed its output channel while waiting for
0 Y# ~; `+ f& X8 ~- C0 _4 ^ the response. However, this introduces risks of congestion when lots of users( V$ z( t; {: h0 W0 I- H
do the same, and is completely useless nowadays because probably no client at
. R3 v+ u0 Z6 W% E7 ?' Z6 t all will close the session while waiting for the response. Some HTTP agents
7 A. G7 M- ^; v+ N7 `! p! ?- Z support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most- D$ {9 j1 F9 S
hardware-based load balancers). So the probability for a closed input channel
* H' n, T, d9 j+ f0 E to represent a user hitting the "STOP" button is close to 100%, and the risk
7 N4 K; p L. Z* { of being the single component to break rare but valid traffic is extremely& I+ Z7 T! O9 @
low, which adds to the temptation to be able to abort a session early while- d8 k# A9 ?6 G4 ?6 N
still not served and not pollute the servers.
8 p2 o: p* d( q5 m0 Z( W& n0 ^' R3 j# H7 W: p/ G4 J9 l( P& g
In HAProxy, the user can choose the desired behaviour using the option7 G+ O, ?. l9 N- O
"abortonclose". By default (without the option) the behaviour is HTTP
' d% }" ~" o9 X compliant and aborted requests will be served. But when the option is- b1 O2 ~" `) X) U" t: o
specified, a session with an incoming channel closed will be aborted while
4 Z: ^/ y( M! ^/ c0 j% m it is still possible, either pending in the queue for a connection slot, or
, |. _) \9 i$ A7 j during the connection establishment if the server has not yet acknowledged
/ x- {0 ^9 L. }+ x the connection request. This considerably reduces the queue size and the load" l5 f, G. }3 s* a3 ?7 _
on saturated servers when users are tempted to click on STOP, which in turn, C8 N3 i8 F3 f- ]
reduces the response time for other users.& X' g2 r+ F5 J$ g% \1 M
4 e* M. v" r. G' b If this option has been enabled in a "defaults" section, it can be disabled( h3 o4 `! d0 i9 ]
in a specific instance by prepending the "no" keyword before it.2 H Q' U" C$ N- Q* O3 }
! W% v- s( j! h* ] J7 @6 c See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters( ^$ }. N; C: ^! h7 H" O
+ O$ N. i2 C$ L$ f2 z6 s: B4 Z: i, K, Q
option accept-invalid-http-request
1 e% e0 [( w. f( |, ~* v* Uno option accept-invalid-http-request- X6 o. ?8 i2 U! F" h {
Enable or disable relaxing of HTTP request parsing9 |. @/ i( U" c7 f8 `! S. F
May be used in sections : defaults | frontend | listen | backend; K' B J0 H. a J5 I
yes | yes | yes | no
# z1 \/ z) e, P" L/ z8 |3 z Arguments : none7 m) r, q% e; Q2 B
, F6 Z9 z+ D+ b" Q. t; {: k. n By default, HAProxy complies with RFC7230 in terms of message parsing. This
# N! `6 P/ ~+ ^' M means that invalid characters in header names are not permitted and cause an, |! @9 Y9 W3 h
error to be returned to the client. This is the desired behaviour as such
( u! h/ ]+ B% g forbidden characters are essentially used to build attacks exploiting server$ I: ^/ e/ ]7 _; r7 I7 F$ f
weaknesses, and bypass security filtering. Sometimes, a buggy browser or
, ?: m& H2 Z& Y. a' [ server will emit invalid header names for whatever reason (configuration,
# N- h/ e! |+ {1 q implementation) and the issue will not be immediately fixed. In such a case,
( `* X4 ^6 _8 g7 z/ O/ ^" P it is possible to relax HAProxy's header name parser to accept any character
- ]- \" w0 ~, \* C% d; | even if that does not make sense, by specifying this option. This option also H0 e. J5 s+ g: H5 B
relaxes the test on the HTTP version format, it allows multiple digits for1 q% C; r9 a4 x/ _
both the major and the minor version.
5 M* u0 n) X& O5 `+ W& L# k7 x
2 |% S$ W0 C. w This option should never be enabled by default as it hides application bugs! t i( G( Y p+ o! M+ y
and open security breaches. It should only be deployed after a problem has9 Y0 X/ a* H" p! d$ A* S) L+ r
been confirmed." ^3 {+ C4 L9 I0 L2 o
5 W5 `* O8 B: F q
When this option is enabled, erroneous header names will still be accepted in/ b+ }' [" o: t2 ?
requests, but the complete request will be captured in order to permit later l! k. J2 f3 \8 s
analysis using the "show errors" request on the UNIX stats socket. Doing this
5 E, i! U" j- ^: b, ? also helps confirming that the issue has been solved.1 }& i2 C2 Y3 T9 t* t F9 Y
# x, w, L B: V* E2 U If this option has been enabled in a "defaults" section, it can be disabled0 E' u' S t M7 L9 \- |
in a specific instance by prepending the "no" keyword before it.
1 T( J- F; H9 [& i
6 J7 t+ z) \# `2 w, w5 G8 l- V See also : "option accept-invalid-http-response" and "show errors" on the
9 k7 _$ ~% q* j: u" a8 ^5 ~ stats socket.: y7 q3 D! S9 Y( `( |( l
/ w# v+ [ [# E: y7 Z
& s5 w0 @) y2 b; G' `; J& ^* C. I
option accept-invalid-http-response
9 f% ^* ?$ p' G- Z, xno option accept-invalid-http-response
1 T5 a6 @5 [- y$ B$ c Enable or disable relaxing of HTTP response parsing
, T. a" S2 Q: z/ s May be used in sections : defaults | frontend | listen | backend
7 i: u+ g. K9 M yes | no | yes | yes
7 o7 x0 P- X7 V/ P4 z/ J0 { Arguments : none
; \0 e/ X6 I7 ~3 ^! I2 q
* V8 C* f Q/ R By default, HAProxy complies with RFC7230 in terms of message parsing. This
% u" N- O* R/ U/ d( L means that invalid characters in header names are not permitted and cause an
# N+ U; ^( E6 m error to be returned to the client. This is the desired behaviour as such+ u, a$ ^$ K! q* Q! p( m
forbidden characters are essentially used to build attacks exploiting server2 T9 m i+ q' t9 X) \8 g# I
weaknesses, and bypass security filtering. Sometimes, a buggy browser or
' \3 Q7 l6 J. t6 A6 P1 P server will emit invalid header names for whatever reason (configuration,& S3 z7 D% o" R W- g
implementation) and the issue will not be immediately fixed. In such a case,: O# L8 G4 O7 y
it is possible to relax HAProxy's header name parser to accept any character
* n9 `' t' {. ?1 T) {# p I: g even if that does not make sense, by specifying this option. This option also& J1 U0 I! a1 _, @3 R
relaxes the test on the HTTP version format, it allows multiple digits for
8 b$ I; Y4 G5 h, y both the major and the minor version.
1 F# J! h8 M, ^& }+ Y! h3 L+ Q# g' [# {" x
This option should never be enabled by default as it hides application bugs; h& t/ s! r6 H6 I/ m8 k% N
and open security breaches. It should only be deployed after a problem has
, G0 c, F+ g" B1 F# A X5 r5 _5 L C been confirmed.! d) I' v( j! n6 T+ Y( p0 n8 s
3 \# t* ~; _9 W$ X3 V4 m9 h- W5 l When this option is enabled, erroneous header names will still be accepted in; q6 I0 R: \. j( ~$ U; @& F
responses, but the complete response will be captured in order to permit
; F- s8 P: K6 z- H9 u% z$ { later analysis using the "show errors" request on the UNIX stats socket.% w& J+ ^0 q0 k) h
Doing this also helps confirming that the issue has been solved.
6 v5 O e/ Y5 L9 Q$ r* s7 `: i- e& I7 _2 J1 o
If this option has been enabled in a "defaults" section, it can be disabled
* \! w/ z( x$ g6 b& H in a specific instance by prepending the "no" keyword before it.
5 U. g, u8 q( {7 {) I) k
0 o% `0 n, |$ d) g- I: E" b. R; W- K See also : "option accept-invalid-http-request" and "show errors" on the6 e* p( Y) Q8 k- `
stats socket.+ [8 L+ r+ m( V% ~; W9 {
4 ^$ S' I Q) l7 n# Y
- ]9 G6 j" Y- O. g- Y$ {1 x$ a
option allbackups4 N5 v3 }0 z% Z1 X* L" ]- i/ e
no option allbackups0 I9 ~1 k6 m, v5 O0 s" w
Use either all backup servers at a time or only the first one
7 |: w$ k* g7 W- I1 v! _* l May be used in sections : defaults | frontend | listen | backend' i W6 y* J3 k- B8 X- r
yes | no | yes | yes
, U( e) x- T( t O, j! _5 d Arguments : none
' W3 K+ C- p Q v8 z2 N" h$ F6 W0 Q Z
By default, the first operational backup server gets all traffic when normal" d9 h+ z2 Q- {4 z- {* I1 U" e1 |
servers are all down. Sometimes, it may be preferred to use multiple backups- |. ~) _0 Z5 I: s% }
at once, because one will not be enough. When "option allbackups" is enabled,2 Y/ _/ e- Q' P* K7 Y- n/ o
the load balancing will be performed among all backup servers when all normal
2 T% u. ]+ T3 u: z4 m. z ones are unavailable. The same load balancing algorithm will be used and the; m% C2 J6 Q9 B! I4 b
servers' weights will be respected. Thus, there will not be any priority5 {( E/ I: j2 P6 I
order between the backup servers anymore.% Y X( f& B! W9 s$ N( b
! _5 D0 k' Y( ]
This option is mostly used with static server farms dedicated to return a `+ H8 }7 g$ c+ l
"sorry" page when an application is completely offline.
" }" r* v! B! r/ w! Y3 m# T# M$ d* l( j' k+ t2 o5 r
If this option has been enabled in a "defaults" section, it can be disabled# ~! n; a1 f! n3 w' q
in a specific instance by prepending the "no" keyword before it.
5 z7 x- {% {! l, m: O- S# \6 b1 F N1 ^/ \! H- K- P9 f0 ]9 Y& w) x; s
" V$ X: r- M$ m" @+ x! m
option checkcache
! S% j9 |6 E8 I0 rno option checkcache# k! S0 U; L9 ~' ^+ ` ~5 \
Analyze all server responses and block requests with cacheable cookies
! W0 U+ T6 j8 ^ B1 h May be used in sections : defaults | frontend | listen | backend2 s! P. j+ g( |" D1 B6 H
yes | no | yes | yes- b3 G2 Z: m. }# r# F1 b! s
Arguments : none6 ?' F- ]; I5 D2 g
- m- ^: ~) m' v1 f( \$ } Some high-level frameworks set application cookies everywhere and do not
# e/ G; b: B& c5 ^( q8 u3 T always let enough control to the developer to manage how the responses should, I+ K: s# b' I/ n7 T
be cached. When a session cookie is returned on a cacheable object, there is a" M h% k' r0 t0 X' V% ^; C
high risk of session crossing or stealing between users traversing the same2 n5 R1 C0 N% l5 g
caches. In some situations, it is better to block the response than to let6 i9 x) D5 M' |% D$ L0 c
some sensitive session information go in the wild.4 N l7 Q* L) i/ n B6 B9 b+ F
# p9 a2 q8 P; u5 h5 a W
The option "checkcache" enables deep inspection of all server responses for9 y# I' e% C# U* d! _+ m0 Z" c+ Y
strict compliance with HTTP specification in terms of cacheability. It, D/ e6 P% ?% z, u: M# R
carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
P5 s* e4 Z( N1 n response to check if there's a risk of caching a cookie on a client-side
_7 M1 p6 K' _8 q, T proxy. When this option is enabled, the only responses which can be delivered
. z& v! y0 `# D, |6 a to the client are :
0 U$ U) c- y9 B- s1 S# a - all those without "Set-Cookie" header ;
" f6 `% a( G1 w; q3 O - all those with a return code other than 200, 203, 206, 300, 301, 410,# B% ]8 B, q7 }- P% f" N) b7 u
provided that the server has not set a "Cache-control: public" header ;8 ]2 N" \; s s2 ? _: _3 j
- all those that come from a POST request, provided that the server has not
5 h" \0 \1 u& @) T: f1 x, c) [. X set a 'Cache-Control: public' header ;% T4 C B j2 Y' B
- those with a 'Pragma: no-cache' header/ w0 d# y- r( c, r! D
- those with a 'Cache-control: private' header9 y) M, o$ e/ y1 q( L
- those with a 'Cache-control: no-store' header
6 Y, t3 e! R8 x. E- B- } - those with a 'Cache-control: max-age=0' header
# Q& l: }) ~' s9 }- o - those with a 'Cache-control: s-maxage=0' header
6 c+ W' x. E9 E6 t - those with a 'Cache-control: no-cache' header
, a( u2 Z* y: Z4 R& _ - those with a 'Cache-control: no-cache="set-cookie"' header
* v: f/ A" O& v" [ - those with a 'Cache-control: no-cache="set-cookie,' header: y, F+ {$ U' l) h Q6 L. n# F
(allowing other fields after set-cookie)
0 D0 L& f( e/ L" v) z
; Y9 P B8 C7 C& {4 W* | If a response doesn't respect these requirements, then it will be blocked
. t2 f7 Y, z, `5 Z- X just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".
( k5 y% d3 e& @1 E' q5 Q' L The session state shows "PH--" meaning that the proxy blocked the response# S9 H8 t: c2 g* ^& d
during headers processing. Additionally, an alert will be sent in the logs so
8 _2 }- `8 J0 O) Z6 |- G" g that admins are informed that there's something to be fixed.
5 z3 u% H, h% X% m1 Z% t. B( r$ G5 J& C9 _& U$ [
Due to the high impact on the application, the application should be tested
0 m7 ]6 c+ n2 Q$ u8 n# A* g in depth with the option enabled before going to production. It is also a$ T' e" r9 {! A8 Z! k" P% Z
good practice to always activate it during tests, even if it is not used in
' I3 v. ^, B6 R9 e# r7 ` production, as it will report potentially dangerous application behaviours.% D0 C" d- I/ j
1 S+ ?4 ?" I( V If this option has been enabled in a "defaults" section, it can be disabled* I, G& R+ T! }" }( K4 I1 o
in a specific instance by prepending the "no" keyword before it.* N5 l8 e, n) K0 S% K. g0 A
/ }+ X! r1 U& _/ z9 K
& S" m6 D9 u+ [8 i6 ]option clitcpka
/ {3 a- I. F8 K: ?; K N( D6 wno option clitcpka
+ x6 k6 P( F0 O9 h( K! i( C! a: I Enable or disable the sending of TCP keepalive packets on the client side! f: r$ ~* f; C, n/ |! P
May be used in sections : defaults | frontend | listen | backend
+ I' W: A) T( V yes | yes | yes | no
6 o( G% q8 E' n# M% L! T Arguments : none+ Q9 v% e, ^- D4 j
9 m, s& B" Z! \1 p7 k When there is a firewall or any session-aware component between a client and+ E8 p6 W1 Z% w7 F9 o$ R z
a server, and when the protocol involves very long sessions with long idle
/ i' A9 e8 Z. f0 v: u, I8 W" K periods (eg: remote desktops), there is a risk that one of the intermediate
. c3 t% U; y) Q: D components decides to expire a session which has remained idle for too long.+ ^$ } Y5 q/ I4 p6 I
; A* c$ K7 J. S5 g0 m Enabling socket-level TCP keep-alives makes the system regularly send packets
0 w$ e$ w2 ?8 L7 n' y, X; Z to the other end of the connection, leaving it active. The delay between& B* x3 k3 Y/ A
keep-alive probes is controlled by the system only and depends both on the2 P) g# n$ P" w* b, z) c1 v% ]
operating system and its tuning parameters.1 Q! \" P5 @4 {; b4 t' H# T
- B, |1 U- x9 q! c, c" m& @1 l; i It is important to understand that keep-alive packets are neither emitted nor
9 y7 y4 k/ {9 Z/ |, ^6 o0 v( B1 m& B received at the application level. It is only the network stacks which sees
* Q5 T5 N" w% C" C" h& W3 }! g; j them. For this reason, even if one side of the proxy already uses keep-alives; {; u' k5 Z9 t7 I/ m4 s: c3 \
to maintain its connection alive, those keep-alive packets will not be- c/ U" I1 v( Y7 X
forwarded to the other side of the proxy.
/ T% i* [# m2 G% }7 K; t: h+ t+ J; t
Please note that this has nothing to do with HTTP keep-alive.) u- T" K* b8 H% L+ [* S
0 ^' t% A/ }- ?- H: X
Using option "clitcpka" enables the emission of TCP keep-alive probes on the
) A7 T( t4 Q; c5 a0 I! v! g( N client side of a connection, which should help when session expirations are
1 A$ s& g$ T0 o- G9 B D4 }& r noticed between HAProxy and a client.. y( j o" n T( [3 T2 R$ I" w
. H) i1 u- }( e- r( {
If this option has been enabled in a "defaults" section, it can be disabled' D& v) P8 L$ G+ z W- j
in a specific instance by prepending the "no" keyword before it.1 I% n( b, J& g2 p; U5 @" T6 M+ |% {
3 K% b2 f. a) b1 q" F/ s: _# _+ e2 v See also : "option srvtcpka", "option tcpka" I& l/ s! L' m+ K) U
) }& H; I+ l$ q7 ~/ L
m0 X/ E5 k* z1 U8 Soption contstats0 c% G* b% `3 L7 K1 r6 j! X& \9 C
Enable continuous traffic statistics updates! L' {" n* Z8 P1 |6 g
May be used in sections : defaults | frontend | listen | backend1 q! O! D1 N6 ]9 X$ ?
yes | yes | yes | no- E$ m2 y) p; v; i" _
Arguments : none
" s4 F2 O9 X5 u/ C) ^) p, D4 n8 M) l. N; W/ K
By default, counters used for statistics calculation are incremented
; s( @9 Z- I" |3 X+ Y only when a session finishes. It works quite well when serving small
5 A h1 w( x* ]* l0 l objects, but with big ones (for example large images or archives) or
3 d7 v a- J! B. s; Z with A/V streaming, a graph generated from haproxy counters looks like* o5 E- l$ l. k
a hedgehog. With this option enabled counters get incremented continuously,, K5 G! F4 t, b
during a whole session. Recounting touches a hotpath directly so
" |: O* b* J+ s' v it is not enabled by default, as it has small performance impact (~0.5%).) P) b6 W- U/ V9 z1 \4 }. A; k
) R/ u2 K" h+ x# q8 s9 L
4 S4 t1 x% F6 K$ ] A; Uoption dontlog-normal
# G! c2 e, b; T- k) a) nno option dontlog-normal
+ d @& j/ H$ G Enable or disable logging of normal, successful connections
( V# e C7 q1 G2 b1 T: o9 Q May be used in sections : defaults | frontend | listen | backend# r0 g, R W% J- v/ L, G2 ?* [+ d) F
yes | yes | yes | no/ _; } j9 _# q, D: m0 d4 d1 w
Arguments : none1 \& R8 l$ L5 R2 n" f
0 R; }* r3 R K+ `+ ? There are large sites dealing with several thousand connections per second) j0 \! U- D8 v# h2 d
and for which logging is a major pain. Some of them are even forced to turn
# b. T, K( I. N logs off and cannot debug production issues. Setting this option ensures that: G; p/ o' ~& |% ^/ F
normal connections, those which experience no error, no timeout, no retry nor
) W( \+ A* }3 w( J redispatch, will not be logged. This leaves disk space for anomalies. In HTTP$ X3 m b2 l2 H& P O# {
mode, the response status code is checked and return codes 5xx will still be% H; C+ Q1 F& R3 r6 t7 S+ b
logged.' V& s: n G" ~1 D: R& J3 E" u
- B) b/ w: z: w2 q2 |# c- V
It is strongly discouraged to use this option as most of the time, the key to
( W$ U: J, e4 A. \' f complex issues is in the normal logs which will not be logged here. If you
5 p+ `2 w9 T- H7 k% A' ]9 E need to separate logs, see the "log-separate-errors" option instead., u2 X) f! |7 e
1 L- }; Y' C/ O3 R& i
See also : "log", "dontlognull", "log-separate-errors" and section 8 about# Z( H& @* c4 N# \) r
logging.
3 K* K1 y! l# q, \- M
% i3 T( r, P, A0 O" L* T h
9 b5 ^+ H5 w" _% t/ doption dontlognull
: D K8 T3 x& S6 R. Kno option dontlognull5 Z( T) \0 R% I0 S |
Enable or disable logging of null connections
4 x Z: H1 ~- u/ A! [( { May be used in sections : defaults | frontend | listen | backend
% ^# H1 R2 H1 [/ E6 z yes | yes | yes | no
: v# n3 s. V7 } T& C! t Arguments : none
, m( m4 Y; B% {' P# t7 f4 v* |5 u
) y) A& N I' P" V In certain environments, there are components which will regularly connect to
( l+ r6 ^" o0 K q/ ?- j* C various systems to ensure that they are still alive. It can be the case from0 p) p" N1 e, U. x9 D% x! c
another load balancer as well as from monitoring systems. By default, even a, Z/ { R7 k0 h4 ]7 S
simple port probe or scan will produce a log. If those connections pollute
; `+ A! a; [; x the logs too much, it is possible to enable option "dontlognull" to indicate
* _* I' P$ L, o1 t that a connection on which no data has been transferred will not be logged,$ I+ z8 m W4 T% X7 g1 L
which typically corresponds to those probes.8 `) x0 ?1 u0 H
) b$ ?1 r2 O. Z) G: ~$ Y; Y It is generally recommended not to use this option in uncontrolled( K( a" L/ H) [2 t
environments (eg: internet), otherwise scans and other malicious activities
( L8 {; N3 i0 A" k0 o would not be logged.
$ k0 M# {9 T/ M5 }9 [, q8 L) S% j" e9 _/ k Y9 j+ S
If this option has been enabled in a "defaults" section, it can be disabled; p, T: |7 q( [$ K# g$ d/ E
in a specific instance by prepending the "no" keyword before it." ^) {" z; c9 B
U1 w1 w* U% Q See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
- b7 M u5 J# G5 X G
2 y7 `! B8 |+ i' H7 M; |
* K2 N" [; ?' e% koption forceclose
* H6 a- a5 Q: R1 E: B5 p9 r: ?, [) Jno option forceclose+ _ A; z; y9 G2 _( ]" P W
Enable or disable active connection closing after response is transferred.
0 l: f7 P& [+ F% w' _+ h6 c May be used in sections : defaults | frontend | listen | backend
, s; q) S# ]# t2 U1 ^; { yes | yes | yes | yes
9 x& e% H( M/ p# M6 `, p+ O Arguments : none' Y- w+ E% b0 @9 O
! h5 K9 k: C& G4 @! L1 F! G8 L. M Some HTTP servers do not necessarily close the connections when they receive
, _4 f; [4 }+ O# K5 |, N, q the "Connection: close" set by "option httpclose", and if the client does not( |$ {# J, t, R
close either, then the connection remains open till the timeout expires. This
+ x) e6 N) a2 t+ ?/ O/ s causes high number of simultaneous connections on the servers and shows high
2 T0 b: D2 ]3 n* n# U* X' o+ ]9 w global session times in the logs." ]% Q: ?" N9 t
4 U/ }7 K$ q. v" g J" Z& r. B When this happens, it is possible to use "option forceclose". It will
`8 {$ N6 b- D' n1 j5 @ actively close the outgoing server channel as soon as the server has finished
. d/ m) Y N0 n$ t6 a to respond. This option implicitly enables the "httpclose" option. Note that
3 o" c5 s6 p( Q( X0 d this option also enables the parsing of the full request and response, which
6 {0 `" Y3 i* a! {9 Q5 E7 D- ~' Z means we can close the connection to the server very quickly, releasing some2 \* r5 _# H9 z4 N
resources earlier than with httpclose. s" i, ~% W% q9 j9 V6 f
) q: }2 V8 D9 Y6 _8 K( K" t
This option may also be combined with "option http-pretend-keepalive", which8 j% S1 i! ?, P) e8 M
will disable sending of the "Connection: close" header, but will still cause. s- L- t z( q6 H; {. A6 H
the connection to be closed once the whole response is received.
9 S4 ~1 T3 t3 P( p) d& G
; O- D" ^9 |3 r$ U/ [+ p2 D7 U If this option has been enabled in a "defaults" section, it can be disabled
" }; M8 n) r/ [ in a specific instance by prepending the "no" keyword before it.
2 H& k% ^/ K' T9 T7 b* U) d6 V/ L1 q( {7 h: c+ f7 ^
See also : "option httpclose" and "option http-pretend-keepalive"
p* _- Q% d% O: X1 G# P8 x) w* ^
" x& H( W1 t7 }3 U
$ f0 B* B5 K3 a: F, poption forwardfor [ except <network> ] [ header <name> ] [ if-none ]3 q5 A: o' F1 ^+ G. V
Enable insertion of the X-Forwarded-For header to requests sent to servers+ j- N( I) w5 e4 F
May be used in sections : defaults | frontend | listen | backend8 r# ]6 J1 I! J# ` y$ S
yes | yes | yes | yes
& V: D& i; K1 i' C! q) j6 y Arguments :7 t8 {0 l6 |7 g% x5 d" ]6 n% n' L0 d$ b
<network> is an optional argument used to disable this option for sources
+ ^) v, m) T. {+ |; a matching <network>' z: P' ^$ F- w0 B/ l
<name> an optional argument to specify a different "X-Forwarded-For"
/ C1 l! I: \2 u) o5 B header name.* p: D3 N" p6 c/ F
/ K- l; F. A4 |, e Since HAProxy works in reverse-proxy mode, the servers see its IP address as
c9 S: s1 m: y, ?& B- Q) ^# P their client address. This is sometimes annoying when the client's IP address
2 {( ?8 W0 g' Q1 I1 R' s4 r+ g is expected in server logs. To solve this problem, the well-known HTTP header7 T" p2 I6 ]% [" ^. b0 C
"X-Forwarded-For" may be added by HAProxy to all requests sent to the server.4 O- |: m7 W" w3 K7 i; x! Q! G
This header contains a value representing the client's IP address. Since this
# i4 |# h/ H9 w# r! r; Q2 m$ e header is always appended at the end of the existing header list, the server. p4 c Q( o1 E% k
must be configured to always use the last occurrence of this header only. See
# m; `; ?/ d" D the server's manual to find how to enable use of this standard header. Note# p3 V. D, o( K: P" _" l
that only the last occurrence of the header must be used, since it is really% T- ~" @- b. {# y0 b, l9 A
possible that the client has already brought one.
! u5 c1 C4 a9 J" j$ _
, [8 z# L! M& ]& q The keyword "header" may be used to supply a different header name to replace" n6 w* n' E7 k3 C9 T1 u
the default "X-Forwarded-For". This can be useful where you might already
; K" X/ X9 d4 P$ H( _ have a "X-Forwarded-For" header from a different application (eg: stunnel),
8 ~: Z$ L! \, C y& j and you need preserve it. Also if your backend server doesn't use the. P. V9 _$ R( ?( X F" S' M- W0 d
"X-Forwarded-For" header and requires different one (eg: Zeus Web Servers
+ z/ v4 b& z8 f K$ z) N$ R4 N' I- D require "X-Cluster-Client-IP").
) \" g8 V+ j- z- F- Y6 Z% @, N- Y, g, \4 S
Sometimes, a same HAProxy instance may be shared between a direct client' S# S( Y. M0 |6 w+ i
access and a reverse-proxy access (for instance when an SSL reverse-proxy is
& z5 I5 \& ^" o4 a- e used to decrypt HTTPS traffic). It is possible to disable the addition of the+ ?: u+ V) \1 h
header for a known source address or network by adding the "except" keyword
1 ~% F, b$ [/ I# ]3 L followed by the network address. In this case, any source IP matching the9 Q7 {0 k* R/ O, X% K7 O9 Q
network will not cause an addition of this header. Most common uses are with
- L2 \3 V; f" j/ c0 W private networks or 127.0.0.1.
C e/ l9 i3 i7 r$ x( T! L% w# g9 m; Y% \5 F' ?9 [
Alternatively, the keyword "if-none" states that the header will only be
, J1 P9 B; K% z/ O3 m added if it is not present. This should only be used in perfectly trusted
6 _) G: {) K# E5 e/ ] [0 Q environment, as this might cause a security issue if headers reaching haproxy2 R' p! C7 J9 \) w: }
are under the control of the end-user.- W% J; N: L3 D8 Y2 g( O
5 L3 ?; H/ a; G# Z- L/ y This option may be specified either in the frontend or in the backend. If at$ l, a* f! X6 @& U; E/ ~
least one of them uses it, the header will be added. Note that the backend's/ W1 V# N5 k0 a) }% l, j9 } c
setting of the header subargument takes precedence over the frontend's if8 G% \( F4 _- C' j. |, a1 K' u+ y
both are defined. In the case of the "if-none" argument, if at least one of" O' _4 s5 {+ [* W
the frontend or the backend does not specify it, it wants the addition to be7 f& h! w5 d3 @- t
mandatory, so it wins.' A8 ]$ t& D u& E) X# Z$ b a; }
5 s& s2 c) G+ d3 @" o* Q
It is important to note that by default, HAProxy works in tunnel mode and1 U8 R) x& a4 Z& b1 m4 |3 o! I
only inspects the first request of a connection, meaning that only the first
0 @4 \! T4 n7 I$ y2 @) Z request will have the header appended, which is certainly not what you want.: ]6 C. M5 M+ C; g9 ?- [- m% l. I
In order to fix this, ensure that any of the "httpclose", "forceclose" or3 ~. f, @# V- z/ _, D
"http-server-close" options is set when using this option.
! R a. M) }" I' A+ G1 u5 K. l$ x: J' ]$ Z' D+ R
Examples :
4 x- u; R! k/ ^* W1 y6 x5 t # Public HTTP address also used by stunnel on the same machine
7 l7 C9 j' N( G) e8 f% M- E; E frontend www1 H; K$ q8 i4 F
mode http
3 e7 L3 ~% r4 a1 K. I0 u6 P; f option forwardfor except 127.0.0.1 # stunnel already adds the header' d+ _3 P$ G7 [- p: k/ p+ S$ J" f
% s M( }0 ? r1 @5 s, m7 Y # Those servers want the IP Address in X-Client8 v! K2 b$ M7 S; |
backend www
! D& X7 `$ i6 O5 ~/ u mode http
+ D1 i: [- m+ y" N option forwardfor header X-Client! \: q8 {6 A6 E, o* m6 q- T
0 C2 v1 L# }3 m- d! a$ N, {
See also : "option httpclose", "option http-server-close",) z4 Y9 E# @& H6 t% Q" m
"option forceclose"2 ]/ g5 w: [. W7 |
5 n; B' v3 c" ?; z# R. x
6 ]% f$ t5 B7 _/ \
option http-no-delay
1 N5 {5 h8 e* P+ w0 ?. Xno option http-no-delay
3 [) [3 j$ ~. b. W4 K Instruct the system to favor low interactive delays over performance in HTTP
% y9 g& e, v5 P# C May be used in sections : defaults | frontend | listen | backend4 T7 @+ _6 m, P( O, S" |3 M
yes | yes | yes | yes9 @7 h4 O6 f4 x, W
Arguments : none
2 t% g0 w! r4 U! p1 K9 E0 s* Q: ]2 @5 u6 f% r) a
In HTTP, each payload is unidirectional and has no notion of interactivity.+ z# C7 o) e5 f& i! Y
Any agent is expected to queue data somewhat for a reasonably low delay.7 h; R& ?3 M, P1 q Q& h( @
There are some very rare server-to-server applications that abuse the HTTP4 N2 [# b3 N# s8 ?
protocol and expect the payload phase to be highly interactive, with many0 Z5 ]/ o( K4 u/ v* u
interleaved data chunks in both directions within a single request. This is5 q6 G6 `: d6 G) n) e, E
absolutely not supported by the HTTP specification and will not work across
! o$ @4 b3 [8 M; k) O most proxies or servers. When such applications attempt to do this through
( i9 m0 I& w- ] o1 j# U1 C haproxy, it works but they will experience high delays due to the network/ ]2 }0 r( J0 T) h" Z0 e4 l
optimizations which favor performance by instructing the system to wait for; w$ I- J8 N6 I
enough data to be available in order to only send full packets. Typical+ Y3 f0 m% T5 k
delays are around 200 ms per round trip. Note that this only happens with' I& V8 [ X. N8 d7 ?1 Y) Y- U. H5 u
abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
' d! h' V" b/ s9 Q8 G. u, H affected.' ]& f+ r) \& Z& w0 z
2 ]; x" T# O# B' d7 \ U When "option http-no-delay" is present in either the frontend or the backend
6 V w7 I( g* E: i, @0 C' ` used by a connection, all such optimizations will be disabled in order to
/ Z' t1 v7 A j" `+ Y* E* Q make the exchanges as fast as possible. Of course this offers no guarantee on/ k& ]7 `0 B6 F9 T: O; Q+ ^+ @& ]
the functionality, as it may break at any other place. But if it works via
0 a/ k5 r$ f1 |) E" Z* A# p HAProxy, it will work as fast as possible. This option should never be used# L0 B# p4 y* k9 l8 b
by default, and should never be used at all unless such a buggy application
5 J, b, s; \* P is discovered. The impact of using this option is an increase of bandwidth7 R5 s# N6 b. s2 |; }
usage and CPU usage, which may significantly lower performance in high; `2 ^7 N( D. V" J
latency environments.( k, [* \1 }9 q9 F. k d) d: u
; I+ R) N8 P3 F: q4 V: R
# ^& u- R8 H3 U- S$ zoption http-pretend-keepalive. @3 x! D L2 x
no option http-pretend-keepalive+ {: I) t4 `- }; d& w
Define whether haproxy will announce keepalive to the server or not
+ Y: P; C4 H/ I May be used in sections : defaults | frontend | listen | backend* k$ q) y5 X8 K8 A7 S0 e
yes | yes | yes | yes
8 I2 @ m. N! v' L# q Arguments : none
3 l) O/ t3 ~/ N* f- i" W4 W1 y. t' }" O+ u
When running with "option http-server-close" or "option forceclose", haproxy" k% M8 q5 i r2 z- h
adds a "Connection: close" header to the request forwarded to the server.# j! Q- C0 f; i8 n. o
Unfortunately, when some servers see this header, they automatically refrain. y: z0 z! ` s( X. j4 {$ w
from using the chunked encoding for responses of unknown length, while this
# ~% K! R0 {* W0 @3 E* H0 W2 K4 W is totally unrelated. The immediate effect is that this prevents haproxy from4 z+ D$ v5 ]( }3 H/ Y
maintaining the client connection alive. A second effect is that a client or5 W# E$ R8 K, A4 b: Q! @8 w9 `1 Z# }
a cache could receive an incomplete response without being aware of it, and. U& [ T9 ?. N, H A; ?
consider the response complete.
0 b8 @: T9 H2 z2 l& W/ R! \
4 E! c8 _' I: S2 x" n By setting "option http-pretend-keepalive", haproxy will make the server4 d8 P' S6 l4 b2 M1 ^
believe it will keep the connection alive. The server will then not fall back& D$ E+ Z( R/ O9 V
to the abnormal undesired above. When haproxy gets the whole response, it6 j" {, m0 w, Q: {( w/ L
will close the connection with the server just as it would do with the
$ a" z6 c9 Z9 v "forceclose" option. That way the client gets a normal response and the
0 z' s+ s" a) c0 j# A connection is correctly closed on the server side.. o) O0 P/ ~8 Y4 r: c
. [* q' _6 k- Q It is recommended not to enable this option by default, because most servers, h5 H' n/ z6 c, P2 Y
will more efficiently close the connection themselves after the last packet,. a% P, t m ~8 v2 f3 }
and release its buffers slightly earlier. Also, the added packet on the
$ y9 `7 ~' l N network could slightly reduce the overall peak performance. However it is
( R# r# |+ ]8 ?, M8 D2 i worth noting that when this option is enabled, haproxy will have slightly
& b: Z3 F$ a9 F. j$ T9 I less work to do. So if haproxy is the bottleneck on the whole architecture,% b% `8 U" }$ W; \- A0 H
enabling this option might save a few CPU cycles.' e. `4 C8 N3 v' v, m1 l2 J
M; C% B3 F1 z9 V0 Q7 | This option may be set both in a frontend and in a backend. It is enabled if( Q- g& t5 v) H; D2 k0 C# n$ ~
at least one of the frontend or backend holding a connection has it enabled.9 l6 L2 S& V% O: J
This option may be compbined with "option httpclose", which will cause
; a+ e# z0 D% q) J/ ~! J: T keepalive to be announced to the server and close to be announced to the
: `: \8 h) o8 ?$ z+ b client. This practice is discouraged though.
# b$ W$ d1 \, C2 C' \8 x! H: c- y6 D+ |; L1 j
If this option has been enabled in a "defaults" section, it can be disabled
) H8 R' e) I2 S; ~( w+ {3 e in a specific instance by prepending the "no" keyword before it.
. o# g+ ~" M8 z8 O% M" ^0 L# X8 U$ y/ w$ y$ e/ o/ A# z
See also : "option forceclose" and "option http-server-close"9 m0 m, G! M6 ^' x; Q1 T
# r* q6 U; G$ q) A# ]8 Y
( B) S4 J; n1 c1 joption http-server-close3 Z! B2 B$ {3 k6 q" Q# J
no option http-server-close
* u' p c. o4 @0 G+ I- f( P* M Enable or disable HTTP connection closing on the server side
" B/ A4 h- D0 h* a May be used in sections : defaults | frontend | listen | backend
3 m5 |' L9 P y9 {& a) G3 _: f3 V yes | yes | yes | yes
7 z4 F* } Q- l, J6 Z7 [+ @' V6 A Arguments : none0 i, H4 `" ]/ J
( D f. {# f7 c4 t By default, when a client communicates with a server, HAProxy will only* v( I, S$ s5 T% B* U
analyze, log, and process the first request of each connection. Setting
2 K N3 ~0 O" U "option http-server-close" enables HTTP connection-close mode on the server4 r% M4 ~0 q2 w3 z8 H
side while keeping the ability to support HTTP keep-alive and pipelining on. ]- a+ Z; c. C1 u- |! u4 @! V) M
the client side. This provides the lowest latency on the client side (slow' r0 @" U/ Z; t% ?7 G* y
network) and the fastest session reuse on the server side to save server
' t6 z# S4 s7 q4 i& ` resources, similarly to "option forceclose". It also permits non-keepalive8 q6 ~- A' E/ w
capable servers to be served in keep-alive mode to the clients if they
) Y7 z; b# U# k) z7 y conform to the requirements of RFC2616. Please note that some servers do not
4 e3 ]5 v+ L% \$ B4 m5 {0 x, z always conform to those requirements when they see "Connection: close" in the
6 g5 E; m% o" N/ c- n request. The effect will be that keep-alive will never be used. A workaround
1 ]5 \* H' ^( U0 D. g' { consists in enabling "option http-pretend-keepalive".
8 P* U, F h6 E. z' a( [) l5 t* a
( q5 Q( u/ l( ]1 s4 C6 j At the moment, logs will not indicate whether requests came from the same5 D, a a/ ^: e
session or not. The accept date reported in the logs corresponds to the end
7 ~ t# {# z9 L% O& Z of the previous request, and the request time corresponds to the time spent+ V9 n. _1 J7 b: w; {- D% m
waiting for a new request. The keep-alive request time is still bound to the
* G: v# H! L9 O) f8 }$ c4 D% s" D timeout defined by "timeout http-keep-alive" or "timeout http-request" if: A7 p3 B5 w' q0 B
not set.3 t5 E. C$ d* H- H" P
( m* c1 o& w" F% C This option may be set both in a frontend and in a backend. It is enabled if
) v: c! D1 w* k at least one of the frontend or backend holding a connection has it enabled.5 J# V! w# W5 S; J" d5 {
It is worth noting that "option forceclose" has precedence over "option
+ p5 q7 _$ v! j: x$ y http-server-close" and that combining "http-server-close" with "httpclose"
: K% j R% Y% z" H2 L4 \' V basically achieve the same result as "forceclose".4 c: Z1 ^5 n J. O7 {
$ b: {9 \2 @# c# B$ O- P& i
If this option has been enabled in a "defaults" section, it can be disabled
9 P- m2 v5 R9 m1 t& ?/ x in a specific instance by prepending the "no" keyword before it.
! C7 X" n& e2 [8 a, q& c* e
. _; O9 j* }9 u/ K See also : "option forceclose", "option http-pretend-keepalive",$ s0 w& N1 A6 X' B: r
"option httpclose" and "1.1. The HTTP transaction model".
8 ]5 ^! I: T. p5 G# Y% F$ v( E( i) l7 Y* i' g0 \
6 C$ l/ L1 n) |5 {' y
option http-use-proxy-header5 a0 T3 E. r; d
no option http-use-proxy-header) X$ W: r& Y0 j; K3 n" Z3 D( e
Make use of non-standard Proxy-Connection header instead of Connection
* a, N1 @8 o' s" c/ V May be used in sections : defaults | frontend | listen | backend7 Q. B1 J1 I; f: B' \7 w3 A) P
yes | yes | yes | no% R" \' s+ Q0 G& R7 w
Arguments : none
4 ^2 Q; x% Y2 v9 b% j
|+ i4 o; B% ]& w While RFC2616 explicitly states that HTTP/1.1 agents must use the5 O: H4 J" L- y. D2 }
Connection header to indicate their wish of persistent or non-persistent
: {. i/ I; y& F# B( { connections, both browsers and proxies ignore this header for proxied3 b' s$ f; k& A! t8 g, o3 b
connections and make use of the undocumented, non-standard Proxy-Connection
. I+ p: A* Q9 x% d* g1 M7 s" R header instead. The issue begins when trying to put a load balancer between4 P) y% G( H& I1 D) B. z% g) L. D
browsers and such proxies, because there will be a difference between what/ c/ Z6 ]3 v/ ?
haproxy understands and what the client and the proxy agree on.9 ?+ K0 r% ~5 P" ?
9 r, e1 @" Y; z M7 s1 t7 Q
By setting this option in a frontend, haproxy can automatically switch to use7 M/ W; ]- B8 \" f8 e- b. C' v
that non-standard header if it sees proxied requests. A proxied request is
6 b! d7 U5 |1 g) E- H# T2 C0 ?+ f3 E defined here as one where the URI begins with neither a '/' nor a '*'. The1 \( S" \1 g1 N% T* C
choice of header only affects requests passing through proxies making use of
( J& G- Q; ^! t" N one of the "httpclose", "forceclose" and "http-server-close" options. Note
X; \, V; ^' R; ]# B8 n4 A& ? that this option can only be specified in a frontend and will affect the, V4 J, g3 ~& ]
request along its whole life.- j- A% J! h: p$ a6 Q8 C2 m ]
0 A, f; Q, I$ H% I$ l M Also, when this option is set, a request which requires authentication will8 n& q3 D; c$ {
automatically switch to use proxy authentication headers if it is itself a/ A ]6 v4 Q8 r- c* V+ v! @
proxied request. That makes it possible to check or enforce authentication in
" ?3 l. t- i2 I( w3 x1 ? front of an existing proxy.4 T! D% v4 b3 [ |3 F- @" |' O
4 j7 d+ y& O J
This option should normally never be used, except in front of a proxy.5 q# d9 m- x8 Z M5 Q
2 l4 b" m1 i- c1 j) w2 c* L
See also : "option httpclose", "option forceclose" and "option- ]+ f z9 d, Z6 i' ^
http-server-close".
* l* [$ q6 m: ^! y* p @& Y- x8 Q9 j& C# H' ^, d$ v W
5 |; N1 U# ~" k
option httpchk8 i. n; d7 c6 T7 _4 F8 C
option httpchk <uri>/ R, W4 c" X: S2 Y) i+ ?: S* v7 Y
option httpchk <method> <uri>
6 H' }+ j' a( ~9 u1 Qoption httpchk <method> <uri> <version>$ i5 W: S' O. n. J
Enable HTTP protocol to check on the servers health
' G8 b; e* L+ B. t/ | May be used in sections : defaults | frontend | listen | backend2 P: k. E& q/ M4 N; y
yes | no | yes | yes
; L/ t K7 m' r0 U0 U Arguments :! Q3 V' [% Y5 Q8 ? g% H% P z
<method> is the optional HTTP method used with the requests. When not set,
, _/ }: A& \; Z# w4 n the "OPTIONS" method is used, as it generally requires low server
2 s- q, Y$ ?2 n' |3 m" k- J' p processing and is easy to filter out from the logs. Any method
) X0 ]* }& m6 a! a, i: N6 T0 _8 I may be used, though it is not recommended to invent non-standard1 H7 P8 u& M2 F6 h7 x
ones.
' X1 X' f: }8 p6 [# r" ^ h/ ]' N
4 ~8 a, z( J3 j0 g! U ~4 n <uri> is the URI referenced in the HTTP requests. It defaults to " / ": D! V. n% m% f E
which is accessible by default on almost any server, but may be! e) Z' n+ ~6 C# a& j+ W
changed to any other URI. Query strings are permitted.
/ d- |% _+ \: T- r: |$ V: F0 T; a; n* y) [, V9 w+ j
<version> is the optional HTTP version string. It defaults to "HTTP/1.0"' z" g2 O ~7 `+ i
but some servers might behave incorrectly in HTTP 1.0, so turning
$ g4 U1 Y9 V: q" L+ K; s it to HTTP/1.1 may sometimes help. Note that the Host field is
% P5 O2 _0 h7 y mandatory in HTTP/1.1, and as a trick, it is possible to pass it. b8 R. u2 A& a6 y
after "\r\n" following the version string.
$ P0 T/ C( Y2 [4 N! [; a0 n/ Y0 R5 }$ ]1 D
By default, server health checks only consist in trying to establish a TCP
, q) Y0 v. |$ z$ T connection. When "option httpchk" is specified, a complete HTTP request is" y6 g* L* g3 u2 {8 X% z
sent once the TCP connection is established, and responses 2xx and 3xx are. \! }, |3 r! E; K6 d5 y7 t7 N+ l; Z
considered valid, while all other ones indicate a server failure, including
3 V- |8 N- P/ s0 P8 u& }8 Q& z$ W the lack of any response.
( e) R. ?! f! k% }; A! U* X! [) i- t% J* {* \3 U: X' w
The port and interval are specified in the server configuration. R5 p' f( @" O" F0 n# E) f4 }
" r& o4 y& u# P# J This option does not necessarily require an HTTP backend, it also works with
6 E! l1 M2 q2 z# O plain TCP backends. This is particularly useful to check simple scripts bound' X. A( f! n' H& A. I+ J
to some dedicated ports using the inetd daemon.
5 i3 T& k$ M: I. E# ]0 y) N7 t) D$ w0 Q& g. l
Examples :
1 A. W% l0 x# Y! s # Relay HTTPS traffic to Apache instance and check service availability% |) K* Z. _5 V8 s _+ ^. ~+ E% d
# using HTTP request "OPTIONS * HTTP/1.1" on port 80.
- J2 E$ N) p, W# G& f, ?+ o3 T2 \! A3 x backend https_relay7 T+ h) N$ ]$ W" m0 W: P8 s
mode tcp
+ Q% a; O; {: F3 D option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www& t- o; O8 r8 Y' B1 Z
server apache1 192.168.1.1:443 check port 80' t, b0 ]( M* I8 C* @6 L" `
% L' s! l- c0 J, E. B; ^
See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
$ I2 D& m/ A$ m& \ "http-check" and the "check", "port" and "inter" server options.
+ P @- k, Z- p9 a* O7 {+ W. k' L7 `& x- J. G" @# n
, a7 ?" {0 P+ I3 X' S
option httpclose* m9 C: f' T/ T& H" u
no option httpclose; n7 J8 K3 R3 v! Y4 b- t% N* y/ q4 q
Enable or disable passive HTTP connection closing
5 Q' d( H6 `; T# y May be used in sections : defaults | frontend | listen | backend2 `- @$ D* y/ S J5 }2 k- ~
yes | yes | yes | yes5 a2 V( F4 N; v Q' m& K
Arguments : none
; Q8 h" d# ]! i% ?* ]% y5 y
1 N/ O% h% d9 o$ {' N! b; a By default, when a client communicates with a server, HAProxy will only
: f# X5 b, W6 |! ` analyze, log, and process the first request of each connection. If "option
9 C1 Q% g+ n5 p- _ httpclose" is set, it will check if a "Connection: close" header is already7 G A% ~7 R) j( W, j2 x/ a& n6 G
set in each direction, and will add one if missing. Each end should react to
/ X& p8 h6 |4 f( C; J4 o2 C! s2 b this by actively closing the TCP connection after each transfer, thus
8 _2 V$ j+ x1 B# |' k' B resulting in a switch to the HTTP close mode. Any "Connection" header
; x* b: { l7 D5 Q: F# p different from "close" will also be removed.
4 S( k! i+ `0 H) R1 f- N5 i7 r
" U! U: _8 S* u3 J* Z9 q& C It seldom happens that some servers incorrectly ignore this header and do not
7 B+ a6 [- B# l- C close the connection eventhough they reply "Connection: close". For this
* Z, ?/ r. V1 d% f( G8 t) g5 }# ] reason, they are not compatible with older HTTP 1.0 browsers. If this happens B7 K. n% D- \" n
it is possible to use the "option forceclose" which actively closes the
' H% P Y1 \3 J7 {% i request connection once the server responds. Option "forceclose" also
! y6 z$ N( N3 ^" i5 O releases the server connection earlier because it does not have to wait for
: g1 U; O; f+ A/ I8 p/ t the client to acknowledge it.
4 G* Y7 g& b1 P/ T& r) i: T
6 e$ D/ ]) g- c$ {2 \ This option may be set both in a frontend and in a backend. It is enabled if
* o7 }! k2 T7 C$ I5 E at least one of the frontend or backend holding a connection has it enabled.
- K( A# w1 t% f a% B. c6 v0 D If "option forceclose" is specified too, it has precedence over "httpclose".
, I4 j1 U% I0 g" I0 v* R( q1 s$ K If "option http-server-close" is enabled at the same time as "httpclose", it
. H1 c+ Z0 t& B basically achieves the same result as "option forceclose".( q% } S3 l4 G; K
' k P+ q6 ]- Z6 x7 _% w/ X
If this option has been enabled in a "defaults" section, it can be disabled
) m4 j2 U" r& z# P# y9 O in a specific instance by prepending the "no" keyword before it.& K! w/ a7 [8 x0 Q- e4 b# E; _! y% K
4 Q( b/ R- o. o3 m& N1 T
See also : "option forceclose", "option http-server-close" and
, I$ W; i- C! B9 s5 K6 y8 Z "1.1. The HTTP transaction model"., ~; ~; [" B- m* H7 `& n
% B7 h8 ]% J9 Z+ }' u" C+ ]( o9 t" {/ ^+ P. F
option httplog [ clf ]* `0 k, s- L" o$ l: x V. R0 C
Enable logging of HTTP request, session state and timers
9 K) m4 X C" W; `6 H2 i May be used in sections : defaults | frontend | listen | backend, Q( y) b8 C& n' }
yes | yes | yes | yes
8 ]' K6 G s; K/ D Arguments :* d3 M: v9 P0 m7 a0 Q( z$ Z8 x1 U
clf if the "clf" argument is added, then the output format will be
" q( n& x. |( y b+ H( }, B! A the CLF format instead of HAProxy's default HTTP format. You can8 w+ l- n# u! O# e
use this when you need to feed HAProxy's logs through a specific
& ]. L# b8 V- w7 M1 V3 ^+ ], o! D log analyser which only support the CLF format and which is not. [$ w) J! Y( k! \
extensible. X) l. v0 ]3 g8 t( U- l; q
: G9 b7 l- u/ D5 u3 z6 t9 k
By default, the log output format is very poor, as it only contains the
& o. i2 n# H; @" ~ source and destination addresses, and the instance name. By specifying
; Q) _6 D+ W6 {3 Z3 p% ~ "option httplog", each log line turns into a much richer format including,$ y F- s5 V; \9 Y) v& B# s, ?# E" _1 X
but not limited to, the HTTP request, the connection timers, the session2 I( M" r& d& i
status, the connections numbers, the captured headers and cookies, the
5 m1 a4 n, Z# y5 s4 ~ frontend, backend and server name, and of course the source address and9 f0 w+ j4 b% O' {2 V0 F
ports.
& @, ]9 o# J& y( a) ]$ |
4 W8 L! u4 ]& r# m- z0 w& f This option may be set either in the frontend or the backend.
! t B% x0 _: _0 }9 N
6 H: R9 ]0 ^: v$ L1 Q+ Q0 c: ? Specifying only "option httplog" will automatically clear the 'clf' mode
! B" v* ^ k3 v" ]+ E3 j8 N if it was set by default.# I6 K/ C, d9 m6 x
. s9 L- J4 }# e& X( b See also : section 8 about logging.
+ U5 @2 p7 ?" I' \$ ~ g B; V# p0 i9 R$ }2 }! b, E% t
( r( w% R% k5 S+ ]
option http_proxy- |: H$ [* {7 I: j C, i. W
no option http_proxy8 X4 f% f1 o/ p5 I$ [
Enable or disable plain HTTP proxy mode
! r, z+ d6 j% @, W) V- s May be used in sections : defaults | frontend | listen | backend8 T, W" t( X" j7 q1 d' T
yes | yes | yes | yes6 y: U4 u0 _) k" h: C
Arguments : none
; v o4 Q# o1 v6 q% r
- d2 N# X; v* J4 @! ? It sometimes happens that people need a pure HTTP proxy which understands- Z) I% M- z+ L$ `1 n
basic proxy requests without caching nor any fancy feature. In this case,0 h: m; T' [" c& o; C
it may be worth setting up an HAProxy instance with the "option http_proxy", ^1 H' F5 W% {# |! d/ ]$ T7 T# H
set. In this mode, no server is declared, and the connection is forwarded to3 c: S6 V( g5 K7 l+ y
the IP address and port found in the URL after the "http://" scheme.; T; D4 y6 g% N) k9 R5 ?
# G; P, p7 ~# P
No host address resolution is performed, so this only works when pure IP3 ?# h D# V# K
addresses are passed. Since this option's usage perimeter is rather limited,
6 P4 {( H) }- v, K1 |8 { \ it will probably be used only by experts who know they need exactly it. Last,- h. R" i! v9 I1 C9 o2 y$ A6 A
if the clients are susceptible of sending keep-alive requests, it will be
* @1 c5 J2 k3 k6 V% B needed to add "option httpclose" to ensure that all requests will correctly0 g1 K* _ K& { w4 n
be analyzed.+ t! U/ f- o; }7 h8 f: F' N0 p
" J( @+ X1 l( v/ I: p. f3 {* o If this option has been enabled in a "defaults" section, it can be disabled
s1 U( B) E, N% S3 E" Z) W% c in a specific instance by prepending the "no" keyword before it.
. C8 h ]9 a0 g4 G) H' q( d+ I( n* K ?! z
Example :+ F; J0 h5 ^5 l& [% I+ A* i& q
# this backend understands HTTP proxy requests and forwards them directly.
5 H; K% A: e3 [; s7 `! p backend direct_forward
, g" u' R3 h Z. Z: M, t% F3 M9 B option httpclose
* z- U! u( i% q: r: N: D: Q7 m, O; E! O option http_proxy
. o& y/ X9 g( N9 X! C9 u8 F2 O/ @ z1 L! J
See also : "option httpclose"
: W2 {5 n5 [1 p5 x# D: r' s E! w4 o/ |5 A: J9 O! }- R
, C8 |, r. J" D0 G- a
option independant-streams
& l7 B: n0 c" P4 U* Vno option independant-streams! P) T8 s v; s& i$ e* w
Enable or disable independant timeout processing for both directions
$ E% N, k6 F$ u- U5 g$ n _/ w May be used in sections : defaults | frontend | listen | backend
1 Z5 N1 j7 O3 O E$ H8 S2 ` yes | yes | yes | yes
) w. s. A r# J, { Arguments : none7 }# O/ V8 x2 J' h/ I% H2 o* T0 p
" w8 J& q$ S) I By default, when data is sent over a socket, both the write timeout and the
& n4 y/ b$ v9 r$ a: ]. i read timeout for that socket are refreshed, because we consider that there is
L+ l( K1 }/ |0 Q1 s6 S activity on that socket, and we have no other means of guessing if we should
, r* }' u6 i. Z% P- R* }8 ~ receive data or not.
3 Q4 ^2 E3 q) H
2 \& o3 L. n2 o" `, F, p H! a While this default behaviour is desirable for almost all applications, there3 ?. {0 ]- G ^( l' N
exists a situation where it is desirable to disable it, and only refresh the
8 U' A+ s" z" J! {5 ^& ? read timeout if there are incoming data. This happens on sessions with large& f1 A+ x) D" k2 Y: e7 g0 h
timeouts and low amounts of exchanged data such as telnet session. If the& ^* H( ]/ h$ E9 H1 y# I% m6 z
server suddenly disappears, the output data accumulates in the system's# F. G; J4 q$ R! E- a- n" v
socket buffers, both timeouts are correctly refreshed, and there is no way
0 V' B% C* w# l" U4 S9 S' w1 f/ U to know the server does not receive them, so we don't timeout. However, when$ E! `- E( N/ K( M
the underlying protocol always echoes sent data, it would be enough by itself# @* B9 k, k: U' c
to detect the issue using the read timeout. Note that this problem does not
8 ]9 I) n% ^" W+ k& ] happen with more verbose protocols because data won't accumulate long in the) y3 j- m& U: M
socket buffers.
6 i1 D: S) e& D* }5 o3 Y
# O F" z% c5 u! U When this option is set on the frontend, it will disable read timeout updates+ T! J8 y% Y4 k9 y
on data sent to the client. There probably is little use of this case. When6 V) j& T0 G" ]- Z5 }
the option is set on the backend, it will disable read timeout updates on
2 W+ p8 ]1 I4 D$ v- r' _; U! p( | data sent to the server. Doing so will typically break large HTTP posts from
6 N' r& ^9 r! h9 [1 K$ Y& r slow lines, so use it with caution.0 h4 t8 q; a, p/ w9 I# a
, t( N3 F7 m4 z! }; k( i
See also : "timeout client" and "timeout server"
$ X r+ N, p+ }; h7 J) ^7 w
7 U/ Q* z, p B0 M1 `' E2 o( f8 d
, C) a7 i1 O3 |$ i; W% u/ W8 R: poption ldap-check p/ j* `* O) I/ F6 k
Use LDAPv3 health checks for server testing/ r- t# V, E; a$ D3 A! P0 z: c
May be used in sections : defaults | frontend | listen | backend
- \* j+ H! C7 f2 ?) X' t yes | no | yes | yes( i2 e4 k1 \2 `) J
Arguments : none4 Q1 ]8 i, G7 W+ ~7 }' p5 n
+ e8 \/ ]# t/ y0 L/ ]: Z# E) N6 {
It is possible to test that the server correctly talks LDAPv3 instead of just
: \. G# n$ Q" ^- B& y6 {, q$ C testing that it accepts the TCP connection. When this option is set, an
% I5 S8 m3 ?+ }* W LDAPv3 anonymous simple bind message is sent to the server, and the response
% m! E- D8 r* n/ |- P5 z is analyzed to find an LDAPv3 bind response message.
& b$ h8 G* H5 V5 W& S" S/ H& _, ^% [2 c7 p
The server is considered valid only when the LDAP response contains success @/ E& I( `% }2 m4 Q& ^; P8 K
resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).& o3 X0 X5 }( [9 E
: v$ X9 t# l; B$ b$ k' v, r9 L- M
Logging of bind requests is server dependent see your documentation how to: M& o: f: n- V: s) t
configure it.
u3 \3 \) T/ m2 c) { F9 q* Z' Q/ F; d+ H* n
Example :
' D/ _! ~% t6 v, T4 i* C option ldap-check' |) h5 y5 Z! w l4 Q4 X2 D
' c8 K( M1 k8 k5 A; J
See also : "option httpchk"
0 o" r- ` D. }5 i! {- B: v' |
% j5 c! M9 o( b. q- n, Z
option log-health-checks' U, Z$ p% D+ l! K8 X$ y- u
no option log-health-checks
4 s7 f, J3 F" [, A0 |, c/ S Enable or disable logging of health checks9 l* {0 t+ [* B# R% a3 ^, P1 M: k7 J0 L
May be used in sections : defaults | frontend | listen | backend
$ O: ~. m4 C/ x6 N E* @1 Z7 R yes | no | yes | yes
! i/ E# q/ k( D9 D Arguments : none
- i% `& G, D e! p) Z
& c) q }! B1 t Enable health checks logging so it possible to check for example what: e! D0 e; Q8 P' o' n& Z# R! N0 x
was happening before a server crash. Failed health check are logged if
0 E. ]4 a) A9 v8 Z server is UP and succeeded health checks if server is DOWN, so the amount' x8 ]! T& h! S: q9 v
of additional information is limited.
1 g* y6 z6 V" \4 u: @+ m: y# q8 L" ~/ j0 t. o. ^% b
If health check logging is enabled no health check status is printed
# k% q# h' q/ p" J+ s8 z when servers is set up UP/DOWN/ENABLED/DISABLED.3 V) h) N5 E; p. i" A* y' |# L
$ }' c& I9 W( \9 @9 Y
See also: "log" and section 8 about logging.
; e0 @# e4 x2 I2 U! w0 {! `0 t1 X9 o- c; ^, X- a
: z8 r$ M$ e4 S1 Z5 Z& G# Q) Roption log-separate-errors
2 q. i# p" ~1 n9 ?' e( Tno option log-separate-errors" `2 d. }4 S# Z. ^0 s) k
Change log level for non-completely successful connections
" P' D6 C. ~/ W! X$ H2 M May be used in sections : defaults | frontend | listen | backend1 P% D; |, N+ ?+ o! f) w# H
yes | yes | yes | no3 u! C' Z* z9 s2 ?; p
Arguments : none
1 P! Q9 r) h( l3 }- ]- i8 W; C" C: D
% K k8 @2 s$ v" n9 p Sometimes looking for errors in logs is not easy. This option makes haproxy
5 Q% [ _, @( g" S- X raise the level of logs containing potentially interesting information such5 m+ ?: L- V0 t* m7 v. t E/ p! a$ [
as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The
; B/ J+ ^; u; T+ k" q" p level changes from "info" to "err". This makes it possible to log them# b5 c- D) r I* {
separately to a different file with most syslog daemons. Be careful not to
' \' F. I9 F. ^" Q* [# Z remove them from the original file, otherwise you would lose ordering which5 |" ~; t" l1 y# I% J
provides very important information.
- ~9 B/ S2 b8 p" {9 s) R0 K2 I* t- {
Using this option, large sites dealing with several thousand connections per0 S0 B* C, c" c6 h+ J
second may log normal traffic to a rotating buffer and only archive smaller
! T2 K5 e* }2 }9 ?+ L error logs.
8 L- c: |# F# i3 z: H9 q8 W2 u8 z( Q0 o
See also : "log", "dontlognull", "dontlog-normal" and section 8 about
, ?! J2 f: O) o logging.
' w, |; n0 Y9 K7 I' G' ~0 }0 O, [9 ?8 |6 M( Y+ r
# @+ ~4 L/ k4 H$ B7 e
option logasap! l! |3 O1 R- A* K N
no option logasap; D. F6 k" G: e1 Z1 V$ m. M
Enable or disable early logging of HTTP requests; V6 c+ Q8 C7 a6 w
May be used in sections : defaults | frontend | listen | backend
. ]$ z! r& h# e! T" I/ B yes | yes | yes | no( L3 f3 Q2 w, g
Arguments : none, p+ L' z! v: O8 e
& O$ f- J& D$ H7 U) ?0 T6 U By default, HTTP requests are logged upon termination so that the total
2 {- ?% \& L# b( m, X" Q. Y8 N transfer time and the number of bytes appear in the logs. When large objects
. h; P7 O( X @3 @ are being transferred, it may take a while before the request appears in the
/ S+ s& |6 C0 r logs. Using "option logasap", the request gets logged as soon as the server; E. B! _2 I' R" {, z# ?1 r, j( C
sends the complete headers. The only missing information in the logs will be; B5 k( U4 u) B1 x" D v8 Q
the total number of bytes which will indicate everything except the amount
5 K$ l' m1 \* A% b0 T+ ?+ q8 B of data transferred, and the total time which will not take the transfer6 |4 }& _0 `+ s
time into account. In such a situation, it's a good practice to capture the
$ H$ [, Q6 o" C8 T) A o; X "Content-Length" response header so that the logs at least indicate how many5 j2 V- W4 @& w: P( |' i
bytes are expected to be transferred.4 ]* d/ A% x9 a8 | X% Z
; W3 d( W8 p: S/ ^5 x! x
Examples :5 ] T. K" D* G8 y
listen http_proxy 0.0.0.0:80
8 D ?2 Z `: E7 i& l mode http( Q( @% H6 X$ C3 \' |
option httplog; Z' n5 D( w0 g/ z
option logasap
$ d/ G" o2 {# ], v4 @) o' B log 192.168.2.200 local3
3 D1 a6 r! T9 j# L; d) J+ D- H! V# @& `7 T& y
>>> Feb 6 12:14:14 localhost \
# w! Y/ t. ~8 V6 M haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
O* {; l$ }$ S1 e& } static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \; @. p: \+ V+ o! `- {% d
"GET /image.iso HTTP/1.0"* z" p4 D0 y* X2 d4 {$ R& d
0 c+ X: I5 A& V6 t7 ^
See also : "option httplog", "capture response header", and section 8 about
0 z; o; y% I/ ~ logging.# X6 X3 R, I9 w) n
, N5 g8 j& { w7 m0 q+ w8 |3 n
$ r* [: q7 H' h' _: H; K4 _9 X
option mysql-check [ user <username> ]
, h' R& Y* D. N( y6 Y% F! u Use MySQL health checks for server testing1 B& u7 X7 U- S2 l
May be used in sections : defaults | frontend | listen | backend
) \# Z. K: R: l yes | no | yes | yes
, v) b# u0 f- [9 f0 t* P Arguments :
0 K+ r( z6 f; c1 l& z <username> This is the username which will be used when connecting to MySQL; F& B0 ]4 j C' g' V `
server.
B- M- B6 J8 s
8 ?: d0 H& X* u7 L. r* P If you specify a username, the check consists of sending two MySQL packet,
! x* l7 s5 a& o& J one Client Authentication packet, and one QUIT packet, to correctly close
: G; c' ^% l: u; l8 B- E MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
9 I, _8 }; V! ^. k. @ Error packet. It is a basic but useful test which does not produce error nor
" ] s, }# g# w2 `1 B/ Q# ? aborted connect on the server. However, it requires adding an authorization
/ A- H: t6 {7 ?5 W in the MySQL table, like this :
# p6 W1 j" F8 h' U2 s* p& L* e3 `2 L! K4 [
USE mysql;
: Z9 x4 z! Z' F( P INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
& ^4 c5 }! s N+ q" X FLUSH PRIVILEGES;
: h5 v- E9 f0 F4 \; a2 X: I* B0 {2 s0 @* `1 d
If you don't specify a username (it is deprecated and not recommended), the/ e: Z6 i. C# S8 Q3 X( c0 c
check only consists in parsing the Mysql Handshake Initialisation packet or
7 v2 r9 G0 {0 F- B, J- g Error packet, we don't send anything in this mode. It was reported that it
- { e! [5 z0 _* v0 r0 r' E0 Z can generate lockout if check is too frequent and/or if there is not enough/ t7 U; ]4 O* N s2 w' t6 h. j) X, `
traffic. In fact, you need in this case to check MySQL "max_connect_errors"
/ w0 H7 ?- c/ z, E2 N value as if a connection is established successfully within fewer than MySQL6 P; H4 N) S& N- b( b/ E3 w
"max_connect_errors" attempts after a previous connection was interrupted,% D9 n9 v: w* O" h' D, h
the error count for the host is cleared to zero. If HAProxy's server get
; ~8 Y" o9 F( j/ p blocked, the "FLUSH HOSTS" statement is the only way to unblock it.
0 p i. `: P9 W' ]% Y3 T; y$ c h0 y5 o
Remember that this does not check database presence nor database consistency. h6 {" q4 o$ U3 S8 L; G+ j
To do this, you can use an external check with xinetd for example.6 [3 P! \. F& j9 v A; D
' _1 w5 E# L! [
The check requires MySQL >=3.22, for older version, please use TCP check.
% y1 {1 B$ b' N' N7 |. b% c5 M# f% g9 C. |! r8 g
Most often, an incoming MySQL server needs to see the client's IP address for
; G7 x+ G0 N" X9 X* c various purposes, including IP privilege matching and connection logging.
% r9 S6 T/ |7 ]$ c4 ?5 w% Z9 ]3 n5 t- u( o When possible, it is often wise to masquerade the client's IP address when/ X: O3 j" j5 K9 s6 n! N: _
connecting to the server using the "usesrc" argument of the "source" keyword,# ^5 j# j ?# d; y1 {# i
which requires the cttproxy feature to be compiled in, and the MySQL server, [% Z' G" r7 X
to route the client via the machine hosting haproxy.
0 W. R. y' O; }* r, v
- l! H: P6 t! i0 K" m0 Y( S See also: "option httpchk"& r o( g/ r4 Z( l0 G) P
9 D, c! f' i4 q- X3 Z- D; y1 z0 e" z- s
option nolinger D/ _# z' I/ i* v& k/ n9 @; W
no option nolinger4 N( }4 O6 y9 U, j: z: Q A
Enable or disable immediate session resource cleaning after close
9 L! N& `8 W) N5 U6 J2 Y6 @ May be used in sections: defaults | frontend | listen | backend2 F% L f$ u+ b5 F* r0 \% h- n
yes | yes | yes | yes
1 F7 S0 ~* h2 q4 Y: ^ Arguments : none
# a% a9 d l" }( t: \ V
" ~1 I, D0 X1 r. {3 I When clients or servers abort connections in a dirty way (eg: they are
+ D7 X$ j, O) T5 t- c' q3 E# I physically disconnected), the session timeouts triggers and the session is4 R- D4 z4 I0 G% B2 E' I
closed. But it will remain in FIN_WAIT1 state for some time in the system,& m+ b. ^+ \& n' a6 N+ D' U
using some resources and possibly limiting the ability to establish newer( o; q- n2 z2 N3 c
connections.
% G7 ~ c m1 F3 s5 r6 t4 ^& z* q. B+ S0 I: w
When this happens, it is possible to activate "option nolinger" which forces
1 s4 d+ G w! M9 F; Z the system to immediately remove any socket's pending data on close. Thus,, b0 D7 T3 r' T: ]) ~( _
the session is instantly purged from the system's tables. This usually has
& F6 U" G& y" f3 B/ F( D side effects such as increased number of TCP resets due to old retransmits5 Z7 u/ ^5 a7 Q# o( H3 f
getting immediately rejected. Some firewalls may sometimes complain about5 T7 U- f: M# Y2 \% z9 g5 o! O( p+ S
this too.* Q" ^* U9 w/ N {0 _: b
# n! |) H! a$ G- H) h3 B$ Y: P8 q' K
For this reason, it is not recommended to use this option when not absolutely
. {0 U$ Z4 k, o needed. You know that you need it when you have thousands of FIN_WAIT1
; n" G* x* w) v1 v* m7 l sessions on your system (TIME_WAIT ones do not count).
4 w6 L! y7 V$ }8 d+ t
+ y3 D- t: a Q9 _$ e This option may be used both on frontends and backends, depending on the side
: g# I$ y& D$ T, t2 e% P where it is required. Use it on the frontend for clients, and on the backend+ f6 }1 h! ^8 \# a
for servers.
2 r( X9 y7 Z! E9 f2 y0 E5 F
; m& e, Q u. p If this option has been enabled in a "defaults" section, it can be disabled! Z3 V) n" _/ h) [2 ?8 ]$ e
in a specific instance by prepending the "no" keyword before it.
4 q# S! }" t- t3 Q0 J9 O* w
3 [: l, F0 B' h! |+ I3 ^
/ D7 l- o/ l. x4 c$ q2 a$ ~5 C! Koption originalto [ except <network> ] [ header <name> ]
' J7 u/ b3 O8 e3 w Enable insertion of the X-Original-To header to requests sent to servers) H4 ?2 K- e- i e% i
May be used in sections : defaults | frontend | listen | backend. h- Q6 Z! S1 u* X! Q& D
yes | yes | yes | yes
; ?' Q+ [9 O T+ ?- N0 Y% z' ` Arguments :7 E# J8 x% M7 ~' N9 a
<network> is an optional argument used to disable this option for sources
0 W. m6 y2 E8 a matching <network>
+ Q1 [6 W, ]: m* W8 K <name> an optional argument to specify a different "X-Original-To"' S% g( O# V! d
header name./ q$ K9 ^! |! r% ?4 u
! S5 k! p: Z; d" y
Since HAProxy can work in transparent mode, every request from a client can
9 P2 r9 @. o5 ]! [ be redirected to the proxy and HAProxy itself can proxy every request to a+ j, G( g+ v& P3 E; b3 e! r, `2 t
complex SQUID environment and the destination host from SO_ORIGINAL_DST will
( ]' x5 Z& U" H9 U be lost. This is annoying when you want access rules based on destination ip& f# u* Y6 Z5 P, p4 F4 c/ o) D, x
addresses. To solve this problem, a new HTTP header "X-Original-To" may be
& F& b) Q! o8 x; h! T added by HAProxy to all requests sent to the server. This header contains a
0 W! ^. G/ V: g& r7 |0 W$ M value representing the original destination IP address. Since this must be
8 V9 a" g9 n2 A4 w; l configured to always use the last occurrence of this header only. Note that
; e; `2 J8 y5 {+ _0 J+ s only the last occurrence of the header must be used, since it is really
+ `, r$ J) @3 P4 p/ o) L3 G possible that the client has already brought one.
0 I) A4 `! \% f, \4 k
$ h5 p1 |0 \% ~" U The keyword "header" may be used to supply a different header name to replace
: I- k! C. f7 [" G the default "X-Original-To". This can be useful where you might already, g- ~9 f5 r8 n; e3 }
have a "X-Original-To" header from a different application, and you need( B) U' _/ _6 ~4 a+ S) }
preserve it. Also if your backend server doesn't use the "X-Original-To"
/ p7 \9 P5 e: s o5 V header and requires different one.
}* Z4 B3 k; C! X$ o
) f7 w% ?0 f4 c( a% l/ P Sometimes, a same HAProxy instance may be shared between a direct client
: F4 _( H7 e2 {/ d* t* T+ r0 M access and a reverse-proxy access (for instance when an SSL reverse-proxy is! [, x1 l8 M3 } \! l/ X6 C
used to decrypt HTTPS traffic). It is possible to disable the addition of the
8 w3 P5 _; [/ ~3 S8 E header for a known source address or network by adding the "except" keyword9 Z; w4 w8 i. l6 H8 A
followed by the network address. In this case, any source IP matching the
1 h$ k' _7 i) h" F: Z% B- o5 k network will not cause an addition of this header. Most common uses are with
* h/ s* r- W* t- q$ S0 G0 N private networks or 127.0.0.1.) o/ i9 {& B+ v, y1 v
. Z2 y8 F: \* W$ V This option may be specified either in the frontend or in the backend. If at } u% j- z/ E% c9 m6 v7 \
least one of them uses it, the header will be added. Note that the backend's
/ X3 B" }0 x1 O" f& g setting of the header subargument takes precedence over the frontend's if
: k- C/ {# `- r& P& y* f both are defined.: r3 J* D& N# U2 K. j# v2 s
, s$ N" m' i+ w) Y1 { It is important to note that by default, HAProxy works in tunnel mode and
- L, x' j7 q% S/ j only inspects the first request of a connection, meaning that only the first
) B5 m7 H% ^; B6 N2 r8 B8 {8 s/ |/ p request will have the header appended, which is certainly not what you want.
$ I) p: m" x6 W2 W In order to fix this, ensure that any of the "httpclose", "forceclose" or+ f7 e7 p0 c! G! a W
"http-server-close" options is set when using this option., n7 a& }. G* a- j @! { w
! {4 F6 c, m/ Y( [- ~& N+ q
Examples :, ~, D* z& m8 W
# Original Destination address
! ^; p7 E8 P5 d8 O! F frontend www
. C& t3 O( s5 d' M( Y. g% R# ` mode http# N" y, |3 o: e$ Y B
option originalto except 127.0.0.1
% J8 t! E; O. }+ [9 Y
" P5 |9 s! h6 M; P- ? # Those servers want the IP Address in X-Client-Dst) s8 m: a* ^, [$ Y( x" w3 V- k; y8 F. A
backend www4 w: A) J! P4 n7 j2 y; F
mode http
: E5 T4 i6 [; S: | option originalto header X-Client-Dst
: D* `( ^/ L0 `1 ?4 R' V
3 W1 G5 Z7 B5 {+ r1 K8 Y6 E See also : "option httpclose", "option http-server-close",
) \9 G. R% R* k: e& Y "option forceclose"
3 X' I) L# A2 W: o# H# Y: H% _' d" c. K+ h/ i; l; F; M4 _9 Z
2 F6 k; I/ V: u. n* k# ooption persist$ m+ ~; X) E3 `. W( m7 i+ l% n- [
no option persist8 `+ n/ P7 F6 c2 |2 W
Enable or disable forced persistence on down servers9 B) F2 n) O# h, X# ^
May be used in sections: defaults | frontend | listen | backend
; L( e' r' C" o7 w5 U/ I, k yes | no | yes | yes$ T, a6 h4 S5 j" _8 g9 T q/ {
Arguments : none
6 V1 l/ Y r4 {% I. K2 _; |" Y9 _' A- c- w, C
When an HTTP request reaches a backend with a cookie which references a dead8 w T" _0 Y7 j& A# o7 F: K9 Y
server, by default it is redispatched to another server. It is possible to% e; C) k" M6 ?( D# k+ p; E
force the request to be sent to the dead server first using "option persist"
* }& D% k' o: w2 y if absolutely needed. A common use case is when servers are under extreme, h/ v$ X+ ]+ L, Q6 p% c+ B, ~
load and spend their time flapping. In this case, the users would still be/ s5 M1 |3 q" M, d$ o" p! [. I
directed to the server they opened the session on, in the hope they would be) ?8 u2 N7 j2 |) C
correctly served. It is recommended to use "option redispatch" in conjunction( C E2 |: s; V* I6 v& j: m
with this option so that in the event it would not be possible to connect to3 _& ~& n, G. J9 U
the server at all (server definitely dead), the client would finally be+ P2 @1 k/ ~4 n: }
redirected to another valid server.
5 k' e M# _6 I: O- w1 f9 }, Q, @+ M- p# e
If this option has been enabled in a "defaults" section, it can be disabled
7 n. e0 {! L& X3 H S in a specific instance by prepending the "no" keyword before it.# l% X7 y' g- D% L2 f7 U
" s2 t! O1 R9 p, y- `
See also : "option redispatch", "retries", "force-persist"
! Y/ V( v/ N7 |: s3 }. U4 r/ ^+ o3 ]- ]) v$ F
! P! y& ?& T/ _ e" noption redispatch, l1 v5 Q) p$ `- c5 ?
no option redispatch8 W/ h; j$ m0 i; j5 U
Enable or disable session redistribution in case of connection failure- U7 e9 r j) z. V. ^) ^6 y
May be used in sections: defaults | frontend | listen | backend
4 ` a; Q# a) Y1 a$ h9 [ yes | no | yes | yes; N/ ^& @2 I. A
Arguments : none
) p$ @- y# `! G2 B% Z9 [: w M. t
' x+ \ R& F5 ^8 J" P In HTTP mode, if a server designated by a cookie is down, clients may8 R! ^, m) d5 F+ Z9 e. x
definitely stick to it because they cannot flush the cookie, so they will not
, ?5 g7 M, |7 ~, m, B0 m$ j$ d0 | be able to access the service anymore.
8 m) J% R1 k6 M/ z$ G- T+ l/ Z- p& ?' m7 U, I V8 o
Specifying "option redispatch" will allow the proxy to break their
! N* f- v. x. ^1 V8 a persistence and redistribute them to a working server.
( g$ L7 L3 K0 a( ] v( s
8 q/ P! l% K9 M) D It also allows to retry last connection to another server in case of multiple3 U3 a# [" S/ m
connection failures. Of course, it requires having "retries" set to a nonzero
' k% d% M% Q7 _+ x: j$ @ value.( ?; ^) a [' H4 q! z, J
" g+ S+ A2 n2 U9 l; G
This form is the preferred form, which replaces both the "redispatch" and* n8 ^7 T" Y# F9 J5 Y4 h, }* y6 K
"redisp" keywords.* \: X; ^0 z3 y; [2 ]) Y, ~
" T4 I/ x! q8 Q5 w0 V If this option has been enabled in a "defaults" section, it can be disabled$ X$ n, d: W! L2 K8 |8 c
in a specific instance by prepending the "no" keyword before it.9 P4 `. G, k* u! E, u' f, p5 S
) ~! c6 P/ C8 i& _- x& _1 o
See also : "redispatch", "retries", "force-persist"+ s4 n X$ @8 x. H7 u! r& [* v& V
# }& s( n7 _2 I
3 _. v- [: @1 b. Q! b& w* M1 [option smtpchk3 D0 A: v' A* F
option smtpchk <hello> <domain>9 C8 }8 D' q. @, ?, J
Use SMTP health checks for server testing! a+ ~ q0 Z" R9 Y3 _3 ]6 l& [/ P
May be used in sections : defaults | frontend | listen | backend
! |# d- k9 h# ~; T% d: l yes | no | yes | yes
9 K1 E7 w: [) B' E' L" D Arguments :- `* P% w1 N: D9 ~( p# S
<hello> is an optional argument. It is the "hello" command to use. It can7 |4 q) V) [# n% g% ^/ ^5 s, N
be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other2 O& o, q. w9 o3 r& J2 e' m
values will be turned into the default command ("HELO").4 E8 U* Y, i; Y" M$ Z& M, r
* i$ e- k/ Y3 H/ @; r
<domain> is the domain name to present to the server. It may only be9 @: Y5 g. s5 J$ M" |* v: i$ C
specified (and is mandatory) if the hello command has been
- y8 C$ |( g1 S7 @7 p specified. By default, "localhost" is used.: _9 v- t3 I- l; j% g; N) I
* \$ v$ d: Y4 c
When "option smtpchk" is set, the health checks will consist in TCP
+ d0 q' ?: E0 _+ { i connections followed by an SMTP command. By default, this command is0 _( N1 U: i ]" E& R
"HELO localhost". The server's return code is analyzed and only return codes: E/ F, k, l0 i" C3 k4 ~- w- o8 R" K6 m+ F
starting with a "2" will be considered as valid. All other responses,1 o" O" e% C6 i" f: k
including a lack of response will constitute an error and will indicate a+ V$ |; t& E: H, p7 ?1 V2 \; z
dead server.) R } a0 k1 a* U5 }
& }+ S/ O6 [- c$ h$ W# q7 W9 X3 g This test is meant to be used with SMTP servers or relays. Depending on the3 _8 B* {% O. `& U& G% H
request, it is possible that some servers do not log each connection attempt,
& |0 D1 _+ N; U3 X/ z( z so you may want to experiment to improve the behaviour. Using telnet on port( ?0 A2 Q! Z: I- L+ \$ ]
25 is often easier than adjusting the configuration.* Y: y2 s- C5 H# Q- w
: a6 I' a# N. D4 {7 ~5 f# V
Most often, an incoming SMTP server needs to see the client's IP address for
7 E3 g2 Z& e8 R" ?( j8 e' M% u various purposes, including spam filtering, anti-spoofing and logging. When$ @+ Y( ~$ m% r0 D3 B* o" g
possible, it is often wise to masquerade the client's IP address when) w7 o# T/ H' |. U
connecting to the server using the "usesrc" argument of the "source" keyword,
* n" {! }; S1 G+ |$ M which requires the cttproxy feature to be compiled in.
8 g& R" ^+ p" b9 P% J) O
7 D: }% E/ p9 h3 E5 S+ z/ Q Example :
' w6 R0 e j9 [ option smtpchk HELO mydomain.org
+ |) L+ d& v# U/ y
8 [5 [* m. [9 A6 [) A1 p# | See also : "option httpchk", "source"
5 C" b9 t: a7 b, t$ h2 y1 Y2 f( H& ~3 r, w8 Q
" E) o4 w- Z4 s9 p
option socket-stats
& m' _+ m7 w( J: G V1 @( `! zno option socket-stats# ?: e+ e) r% V' }* f( x7 D3 o. `! v& `
0 b; B3 r; H; t Enable or disable collecting & providing separate statistics for each socket.
3 S0 F# z* P7 J7 q; e( d* R ? May be used in sections : defaults | frontend | listen | backend3 |; t# X4 ~/ j. p
yes | yes | yes | no
# o( c' j' O" |3 p
- c- N& A* H& l" e0 {6 S& M Arguments : none( U1 T! g* a9 S$ B N! D6 A2 T& n
. o5 p* g/ y8 X; W H! I5 X/ k+ v/ _: ~
option splice-auto
' Q7 ?, F( J, K6 R6 Pno option splice-auto
$ s6 s; k* e0 |8 V) ^+ Q Enable or disable automatic kernel acceleration on sockets in both directions
& Q8 g2 B+ M y; ?+ I May be used in sections : defaults | frontend | listen | backend# M" M$ v+ J9 r+ Z
yes | yes | yes | yes
m4 x" } ^5 a0 H' ?" v Arguments : none/ \# T1 X, n3 h
8 y. a2 C/ Z& g) e/ { f* ^ When this option is enabled either on a frontend or on a backend, haproxy
" h4 G. y" z: |) ` d( @! U+ L will automatically evaluate the opportunity to use kernel tcp splicing to1 W* i T) H3 a
forward data between the client and the server, in either direction. Haproxy
, a/ e& E g g+ [$ @# X; o uses heuristics to estimate if kernel splicing might improve performance or8 n o k6 U. j; q2 a$ n# ~' S
not. Both directions are handled independently. Note that the heuristics used
8 s9 I5 ~3 s9 M5 y1 |9 s are not much aggressive in order to limit excessive use of splicing. This
! U ?. R% l: d* t4 o7 ~ option requires splicing to be enabled at compile time, and may be globally# Z9 {* y j$ c6 L' D
disabled with the global option "nosplice". Since splice uses pipes, using it
2 d& l6 j& F. D' R, E |! l$ S- G8 S requires that there are enough spare pipes.# d! ^4 J- ^* X( p. @, p. ?9 i
+ Z [' U1 l% }
Important note: kernel-based TCP splicing is a Linux-specific feature which+ f+ t+ I" C8 ]8 n* ]2 e
first appeared in kernel 2.6.25. It offers kernel-based acceleration to
' L/ T- f6 E7 ] transfer data between sockets without copying these data to user-space, thus' j# o4 X, z: z% K" r
providing noticeable performance gains and CPU cycles savings. Since many
5 c8 J T; D* @6 i+ y/ |: S& F early implementations are buggy, corrupt data and/or are inefficient, this
; r: T7 ? W' q5 x# r feature is not enabled by default, and it should be used with extreme care.
. |' Y( U S- a3 u# p While it is not possible to detect the correctness of an implementation,
" x: [5 J+ L5 G, C" }% |2 J1 W# C 2.6.29 is the first version offering a properly working implementation. In
, a& P8 {& W2 g; T8 b* V# U8 F case of doubt, splicing may be globally disabled using the global "nosplice"
& ~" c- p2 p0 ?: ` keyword.
; B3 q/ p ]- c2 c+ w' L2 W U3 l- n% v+ K7 E" c+ ?# r
Example :- a6 A# @& p! X* P5 a
option splice-auto
0 i9 Q: T' U6 l% o% f+ Q) a; k% X3 h, V- l. ?
If this option has been enabled in a "defaults" section, it can be disabled* o8 }8 Y1 a6 ?5 }7 [2 T
in a specific instance by prepending the "no" keyword before it.8 X6 S, t6 ^$ C
) _& A1 x: g/ d- c) U. H* \0 Q
See also : "option splice-request", "option splice-response", and global
1 |7 ?5 s! h8 h3 }; B* N$ v" ^ options "nosplice" and "maxpipes"' X$ P" I, Z: `3 X1 N) d$ C% ?
. x4 S" z, V0 C7 r, M! o
" D+ h( c" |2 l, T# t
option splice-request8 i9 p+ Q# F! x3 H; p' O. C1 Y
no option splice-request% r9 O8 ^- b# R- M
Enable or disable automatic kernel acceleration on sockets for requests/ d4 f2 H j$ L) ~
May be used in sections : defaults | frontend | listen | backend
* R: R# Q; v5 Q5 E. t2 e yes | yes | yes | yes
; }7 ^7 ?1 @; \$ D, ] Arguments : none/ ~3 r! s, b% @9 x- D
) c# V- l! w' A# @2 Z2 z
When this option is enabled either on a frontend or on a backend, haproxy
# W- f# A" b) ]4 f B will user kernel tcp splicing whenever possible to forward data going from& }- O v: J. h' H
the client to the server. It might still use the recv/send scheme if there
K& R/ H B$ ^% v4 {; ~( w* ^ are no spare pipes left. This option requires splicing to be enabled at: Q3 n2 k7 f2 y! i- j
compile time, and may be globally disabled with the global option "nosplice".0 N4 Y( p/ S$ q3 Y* M$ |
Since splice uses pipes, using it requires that there are enough spare pipes.8 S, s V* \! i; c, L1 L
0 s! |$ K6 e O' D2 N" t( U
Important note: see "option splice-auto" for usage limitations.
/ Q; t* T, D( X) P' c+ @! h# M. T1 ?
Example :
2 D# O, b1 g1 t option splice-request
5 _+ y' O( V# j8 |0 n6 l( _" e8 ?9 S! ?
If this option has been enabled in a "defaults" section, it can be disabled- }; o4 Z( R( N
in a specific instance by prepending the "no" keyword before it.. `; h- ~) y; z5 o; ~$ p% J
! w) N+ E; N0 P& e. i. o: } See also : "option splice-auto", "option splice-response", and global options
1 P& z. y- H F- f( o7 Q "nosplice" and "maxpipes"$ a- F: x$ b% o# e6 k
& f' m, t' } t; W7 W1 o U
% C" B: R( m; A( _" H, Voption splice-response
' o. [+ J7 ~0 t, Qno option splice-response2 s5 _4 [# _- X2 l+ p$ Y" Z' w2 h2 s
Enable or disable automatic kernel acceleration on sockets for responses' |& _7 V1 C1 Y" z+ A1 j# o( l: e
May be used in sections : defaults | frontend | listen | backend7 w8 g9 |6 V7 x$ n. \ ~
yes | yes | yes | yes
- S& Z7 x, l$ q, ]7 f Arguments : none/ H& ^9 l7 l6 d3 S( F$ H0 u; j6 l
2 v8 j- k, X' m/ E; P4 w
When this option is enabled either on a frontend or on a backend, haproxy
$ y* r0 x6 v2 Z2 N! P will user kernel tcp splicing whenever possible to forward data going from1 f# O; o5 H# C+ L, b+ P/ g1 ?* j) w
the server to the client. It might still use the recv/send scheme if there
) ?6 w3 g. w$ }0 _- t8 b) W are no spare pipes left. This option requires splicing to be enabled at
/ D @! N$ a6 M. `# } compile time, and may be globally disabled with the global option "nosplice".
" r0 D3 Y( \0 { Since splice uses pipes, using it requires that there are enough spare pipes.
% C4 P& U4 P% [$ @7 A$ s
- C4 g* R) |6 B6 b Important note: see "option splice-auto" for usage limitations.
8 ~# W+ U, `3 C8 ^. A
) a# x2 ?' p2 @, A" ` Example :$ F# R5 n5 a7 \1 G
option splice-response
s# P+ A" a5 t# W5 y' [
8 X5 x5 z. l. D2 `$ y+ v: N If this option has been enabled in a "defaults" section, it can be disabled
; {" i- I& [: B; n# ~ in a specific instance by prepending the "no" keyword before it.
- B2 b d D% c1 M- J
) y% B; V/ u/ w1 W) q2 C See also : "option splice-auto", "option splice-request", and global options" L) P( v0 r6 P9 r- C
"nosplice" and "maxpipes"3 P( }/ k8 ]0 e9 f# W+ S
/ _0 z; N' Y( U
2 j5 \! `' c: s+ H; U. Q" ioption srvtcpka* y2 j B K N7 C2 Z5 @8 j$ y
no option srvtcpka
7 A& ]7 ^/ G# B Enable or disable the sending of TCP keepalive packets on the server side
9 L' |; {2 H, C0 }0 W May be used in sections : defaults | frontend | listen | backend N0 I, C% p0 C/ w. Y
yes | no | yes | yes9 q4 g1 X) P, ]
Arguments : none
! c6 g$ s: _$ B# H6 w! W% \- {$ z0 K
3 n5 g8 ?9 Y; e" E7 J6 h& \ When there is a firewall or any session-aware component between a client and
! z9 @+ {$ ^, p! Z a server, and when the protocol involves very long sessions with long idle, P6 |) f: b# j( ^8 A& `5 `
periods (eg: remote desktops), there is a risk that one of the intermediate
2 I6 z5 C c( {6 v components decides to expire a session which has remained idle for too long.
7 n- K6 v4 g- [+ c" ?+ H4 J6 O) F/ @+ X% P8 p: _# |) A/ u5 }
Enabling socket-level TCP keep-alives makes the system regularly send packets
- h: Q0 p3 }. k0 @ to the other end of the connection, leaving it active. The delay between5 X% h! J7 Q5 n A4 Z
keep-alive probes is controlled by the system only and depends both on the% }" |: H2 h0 r. g
operating system and its tuning parameters.
. { Y7 n& S7 K9 `9 L* x+ j0 k& s- M5 d- c
It is important to understand that keep-alive packets are neither emitted nor9 T+ \* z! c& c( R# c. Q# D
received at the application level. It is only the network stacks which sees
* y: v+ U6 u) \! y" c6 a5 h( b them. For this reason, even if one side of the proxy already uses keep-alives
5 I" S" Y0 F! B* Z$ T( T) ` to maintain its connection alive, those keep-alive packets will not be
, t0 m* b- E" t1 S; s5 M: b forwarded to the other side of the proxy.
7 n8 N9 {* O: C+ \6 ^
. m; }. U; M$ I3 [ Please note that this has nothing to do with HTTP keep-alive.
$ l$ u. z/ o4 {% j7 A' x# M$ N- q4 T5 s7 A6 t. f" _
Using option "srvtcpka" enables the emission of TCP keep-alive probes on the9 W: h: t9 N) K) C
server side of a connection, which should help when session expirations are' P$ v% f: P4 n+ P' S7 V2 h8 D
noticed between HAProxy and a server.
( c. m: S4 {% x! \4 c
; U4 G8 {, ~. e0 n0 Z4 B If this option has been enabled in a "defaults" section, it can be disabled1 k- r/ J1 e$ U5 j8 s: ~
in a specific instance by prepending the "no" keyword before it.: O: i/ I$ ~/ y* s
" S$ b# t, t: R0 ^ See also : "option clitcpka", "option tcpka" P5 D4 F' z- |# ~9 W- L
0 Q5 ^+ F" u0 L1 i n" U1 l& Z
% u/ o( ]" L) @( u+ w+ U, Ioption ssl-hello-chk
4 `- g) W7 K, B; Y2 S. F Use SSLv3 client hello health checks for server testing1 z8 F+ ]. T; o* `' d3 L
May be used in sections : defaults | frontend | listen | backend K- S4 ~) Q- Q4 B, P
yes | no | yes | yes
8 X: l$ }$ ^# Q8 T3 f9 G; T4 V7 @ Arguments : none
7 D0 F% L3 u, u" U
! K' p2 s7 Y. q5 N$ n When some SSL-based protocols are relayed in TCP mode through HAProxy, it is6 s. y A$ H- A' }( i) N) A( M0 S
possible to test that the server correctly talks SSL instead of just testing0 n |) v5 L. N7 w
that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure1 X4 R% m# _3 Y6 }9 b; P2 t4 D
SSLv3 client hello messages are sent once the connection is established to
# Q/ p1 E7 C! Q Z the server, and the response is analyzed to find an SSL server hello message.
% z/ z) V, U& k4 u, W; ?, Z0 W The server is considered valid only when the response contains this server
& H! I3 @. ?0 C1 s hello message.
* {; ~0 q: b& l# }' J7 S7 a" v( x- q' V% H* `! }
All servers tested till there correctly reply to SSLv3 client hello messages,! N- [: D* I r) |
and most servers tested do not even log the requests containing only hello
5 [. K3 D3 I: D6 S; H# _% h9 @ messages, which is appreciable.& c3 S) }7 L# W+ x3 g5 q
/ V: T6 @9 P) _ See also: "option httpchk"" Y o" i: ]3 M1 y/ ~/ R2 ]
3 S2 V% K9 {4 W+ g" y( q! E
$ n4 Z* }# x( e9 D. A
option tcp-smart-accept
: _- T, } Q7 U9 vno option tcp-smart-accept
; k k( }! l( I; C8 ]0 o5 { Enable or disable the saving of one ACK packet during the accept sequence
1 R% f# i* l' x/ S0 Z) k' U May be used in sections : defaults | frontend | listen | backend* {8 f2 v6 U9 G7 [
yes | yes | yes | no
# S z5 }# i6 S2 f) X* w3 _ Arguments : none, e$ B+ {2 k3 D
: v' V& G1 R+ i! ^; ]" g: Z: V/ C When an HTTP connection request comes in, the system acknowledges it on- ^. K+ G1 I3 O9 h& D0 U
behalf of HAProxy, then the client immediately sends its request, and the/ T2 k; n4 Y9 w4 w/ `
system acknowledges it too while it is notifying HAProxy about the new
8 i2 _" V( r: F4 o connection. HAProxy then reads the request and responds. This means that we
" T" d& ~; w! f" X- z have one TCP ACK sent by the system for nothing, because the request could5 ~$ I5 M! _9 I9 ^( ~9 s/ k
very well be acknowledged by HAProxy when it sends its response.' D; H) w" q+ [/ V! n" d8 k# Y! t
& R" ~5 @9 B+ H! V N9 R
For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
* j# w; m, `% R sending this useless ACK on platforms which support it (currently at least: s4 q" Q( j. o# a7 L! l1 ~
Linux). It must not cause any problem, because the system will send it anyway- G: S9 G1 q. N( `; I
after 40 ms if the response takes more time than expected to come.( Q: x+ M8 l7 ?; h6 V& F! @
" V3 I9 U' ^/ W8 x9 R# u$ P3 `6 p During complex network debugging sessions, it may be desirable to disable
?/ b O7 K8 u. | this optimization because delayed ACKs can make troubleshooting more complex9 T8 X# W5 q1 u+ r
when trying to identify where packets are delayed. It is then possible to
, g3 ~% o, h. {6 d, @+ P fall back to normal behaviour by specifying "no option tcp-smart-accept"." q# v7 ^" T- J( \3 n# h
! l1 |) c. K) v/ W% ] [, n
It is also possible to force it for non-HTTP proxies by simply specifying: Y% S" x+ b2 W4 k3 z' r
"option tcp-smart-accept". For instance, it can make sense with some services
9 d1 x$ ]2 K2 t5 b such as SMTP where the server speaks first.
( z Q8 x8 B* |
. z3 \- b( K) T& j It is recommended to avoid forcing this option in a defaults section. In case
5 Q- k' {* j" \- k of doubt, consider setting it back to automatic values by prepending the: k) s. j+ k9 C1 v7 e
"default" keyword before it, or disabling it using the "no" keyword.
\8 F" Y1 M& q5 o, i/ I( }
* S. P2 C7 P- F See also : "option tcp-smart-connect"- _9 N- b. |: E2 F( A
7 V3 K7 c2 S; C$ i7 r4 ?1 P& T9 c B* l3 H& [- a
option tcp-smart-connect! W* w" t: s$ F+ L
no option tcp-smart-connect5 `1 t5 T5 g6 e+ v1 W+ y
Enable or disable the saving of one ACK packet during the connect sequence8 K( L! {8 ?- U
May be used in sections : defaults | frontend | listen | backend+ e/ x$ e( X. ]% n, J6 E
yes | no | yes | yes
9 [# G. s! A9 m9 O5 s7 H& ~. @; y Arguments : none
! q* Z* a( T- L# V% j+ P0 U+ {8 Y. q- C; w
On certain systems (at least Linux), HAProxy can ask the kernel not to9 p7 j) U% N, X( w* i" q/ O+ t
immediately send an empty ACK upon a connection request, but to directly
z. _& W1 _* q. o( E9 Q send the buffer request instead. This saves one packet on the network and2 g; K0 [* |) v( z1 m$ @. u
thus boosts performance. It can also be useful for some servers, because they, f' R' T, h3 N- s
immediately get the request along with the incoming connection., e# d- H- K4 ]' {' Q' u6 ^: T
9 ~' h: Y; d" f, a# N! a+ o This feature is enabled when "option tcp-smart-connect" is set in a backend.+ ~1 O, w3 q# N
It is not enabled by default because it makes network troubleshooting more
* C! i1 C" k/ W1 g' K$ c complex.( I; }5 u/ ^; }' |3 R4 o# s4 c
* E: ]8 b4 h& F R& `* w% G
It only makes sense to enable it with protocols where the client speaks first. y. c/ U: ?; |: h4 K5 U
such as HTTP. In other situations, if there is no data to send in place of
1 R$ d0 X( F9 j+ c$ ^7 E+ O the ACK, a normal ACK is sent.+ E& X0 m5 M" w8 n
6 B8 L0 d; ^7 C If this option has been enabled in a "defaults" section, it can be disabled$ K2 W& o3 l9 c4 M. T
in a specific instance by prepending the "no" keyword before it.( O/ h1 I/ A% Y5 c) M
- }: [( L$ H3 d: C) i See also : "option tcp-smart-accept"
5 i: F7 B( e2 ^; r5 z: F3 X3 d8 G H2 n) R% M# @* Z5 E2 l
" z5 e/ Q) b; Y
option tcpka* V* M% I; r% W6 F7 @, Y
Enable or disable the sending of TCP keepalive packets on both sides
: F8 k8 C. r' n# ~/ I! j May be used in sections : defaults | frontend | listen | backend
* C! K3 y1 X" d" f/ G$ n yes | yes | yes | yes
# u2 w; l/ {/ r* L Arguments : none
6 j9 x1 g$ e$ c1 d7 @- k
2 W' R& G, D: z. I When there is a firewall or any session-aware component between a client and
, A0 D5 R& ~% S" b! y6 Q: n5 J' e a server, and when the protocol involves very long sessions with long idle6 R/ \7 b% U; E
periods (eg: remote desktops), there is a risk that one of the intermediate
6 p% {0 L/ @' o! `! f components decides to expire a session which has remained idle for too long.
4 D' C9 V6 q0 i2 v; g4 t2 N4 v# P
4 x7 f8 ^# Z9 m" w3 X7 t2 D Enabling socket-level TCP keep-alives makes the system regularly send packets& A4 N8 T% W0 ?6 ?( ?
to the other end of the connection, leaving it active. The delay between4 \8 {, \# g+ _# e
keep-alive probes is controlled by the system only and depends both on the4 Y5 `& h4 v# W. V C
operating system and its tuning parameters.
9 j% \+ _+ a7 p0 q# }" q9 _4 R) H
m- J, C- q$ T It is important to understand that keep-alive packets are neither emitted nor
/ y. r& e3 H; ]& |5 Y2 y8 h received at the application level. It is only the network stacks which sees0 i3 M: n9 c \* M1 a& u
them. For this reason, even if one side of the proxy already uses keep-alives0 J* _4 S+ B: l% W' |! W4 ?' L9 Z0 E
to maintain its connection alive, those keep-alive packets will not be$ O/ j) Z8 _- i
forwarded to the other side of the proxy.( ]) _ Q v- u7 b6 x
8 O7 H3 L5 H2 G) | Please note that this has nothing to do with HTTP keep-alive.
; m/ N5 @; T t' V. e
- a4 D) R- G, r; ?6 `$ W) I( ^ Using option "tcpka" enables the emission of TCP keep-alive probes on both
) |2 r4 z0 z l2 \3 L the client and server sides of a connection. Note that this is meaningful
+ B8 N0 p& ~# Y. y only in "defaults" or "listen" sections. If this option is used in a, C1 E! ]! a" U* V& f
frontend, only the client side will get keep-alives, and if this option is1 C$ d4 _( k$ K6 d6 h5 C
used in a backend, only the server side will get keep-alives. For this
8 ^' c8 d( ~7 v8 f* o9 k reason, it is strongly recommended to explicitly use "option clitcpka" and
- V' b1 Z4 \4 a0 v5 r( E "option srvtcpka" when the configuration is split between frontends and
/ e$ D& }. M+ r; q5 I: B Y8 B backends.9 U( y! g5 [! _( V1 c! U t
( }$ s$ r9 z/ X( m }0 P4 [
See also : "option clitcpka", "option srvtcpka"$ V9 a8 k1 S$ b: M' O
& k6 K! S1 V1 D) o1 C' h# ?% ]
$ u& {0 r" w) k: poption tcplog* Y- n$ u* ]( k+ x* w
Enable advanced logging of TCP connections with session state and timers( m8 b) ^2 H9 s- z+ t
May be used in sections : defaults | frontend | listen | backend1 b; ~+ T/ k6 Y/ S* k- s/ J, ?9 e
yes | yes | yes | yes. z9 D$ r! k% j
Arguments : none+ H7 Y; g# w+ I3 h/ {3 I: S
% I! h5 g( B- p3 W By default, the log output format is very poor, as it only contains the
5 x6 O1 r" E% k3 k; d( _7 ~ e source and destination addresses, and the instance name. By specifying
! T9 [( G2 |6 t4 z$ h3 l "option tcplog", each log line turns into a much richer format including, but
& E; Q; {, x! t( ]; h1 b) ] not limited to, the connection timers, the session status, the connections- p3 ~' b. m: Q2 ]4 l ]$ A
numbers, the frontend, backend and server name, and of course the source" \3 N' A' S* H
address and ports. This option is useful for pure TCP proxies in order to5 S0 V" _: I% o! ]
find which of the client or server disconnects or times out. For normal HTTP+ e- i% P* t! o7 P% T' @
proxies, it's better to use "option httplog" which is even more complete.1 S" i! x9 E7 k( E
( h( a( }* @. x* e' i
This option may be set either in the frontend or the backend.
9 B* k* ^+ O: \5 y, S* L1 }
7 i, T9 D7 ?8 H+ V See also : "option httplog", and section 8 about logging.. a7 W& `. F) }- a4 E) u" `, b
0 X( F2 f1 C! g) l( B" R6 W! d- {) L3 h2 ]% i( m
option transparent
; ^/ Y) a/ s+ }4 f$ F l% Mno option transparent0 c! ]! b B6 P5 T% F$ m1 J/ k: }
Enable client-side transparent proxying
: z6 q& v+ _ S9 E May be used in sections : defaults | frontend | listen | backend
' Y; m$ }* c# d5 b( { yes | no | yes | yes8 l# O* g/ j' S
Arguments : none# \' \4 h+ t9 C- M7 m7 ~
# Y5 j$ Z& i3 [
This option was introduced in order to provide layer 7 persistence to layer 3 J" a6 Y0 u5 q( S+ x
load balancers. The idea is to use the OS's ability to redirect an incoming/ G) K/ Y9 l2 w1 l- W" y
connection for a remote address to a local process (here HAProxy), and let
/ L( W- Y% g2 L/ r this process know what address was initially requested. When this option is
( b+ F! Y! J; s8 Y& l7 i used, sessions without cookies will be forwarded to the original destination9 E4 F% g" S5 I- y; g
IP address of the incoming request (which should match that of another
0 Z: ?9 n% l9 K* g equipment), while requests with cookies will still be forwarded to the
0 t) s0 R* p, i$ z appropriate server.9 K+ F, [. o, [
0 ^! z9 U0 K1 |+ j* U C* z3 D Note that contrary to a common belief, this option does NOT make HAProxy1 i, M4 {8 v/ @
present the client's IP to the server when establishing the connection.
5 E6 g! m' G' j# a x: w0 V/ u3 k6 g0 C
See also: the "usesrc" argument of the "source" keyword, and the
5 L; V! V0 Y: M$ b; J! d* U2 H "transparent" option of the "bind" keyword.
4 k) j% y7 r% T1 T
+ ]4 Z; P" ]& b9 p- T
; V) h+ J% p2 @persist rdp-cookie
( C8 ~( J8 h6 U- xpersist rdp-cookie(name)
$ @# O2 ^0 U, C, j: J Enable RDP cookie-based persistence
. u; L6 w# G- F May be used in sections : defaults | frontend | listen | backend- d! f7 V# ?4 p: ]3 a
yes | no | yes | yes# E ?0 G- Z5 C+ M
Arguments :9 M, X8 ?4 n+ T6 x; \8 M
<name> is the optional name of the RDP cookie to check. If omitted, the) k! r: Y( K1 c7 n
default cookie name "msts" will be used. There currently is no, T- C& x5 p% u* W
valid reason to change this name.
! N6 k+ _. v6 i) d# `8 J# N+ }& O5 i) Y' p, \( ?1 [, r2 d
This statement enables persistence based on an RDP cookie. The RDP cookie
: w5 |- O/ ~, J9 P2 u" U contains all information required to find the server in the list of known
% P. `! U* B8 ]5 t6 T- w servers. So when this option is set in the backend, the request is analysed" x# n& F2 ]) r/ ~7 q) O
and if an RDP cookie is found, it is decoded. If it matches a known server
3 ^2 e6 `# @! A e8 i+ {% u0 l$ _ which is still UP (or if "option persist" is set), then the connection is
3 E. M9 s1 Q- ^- s3 ~9 g forwarded to this server.
# R* H! O4 M) n, u- U" e2 G# \ H% ?+ H; x
Note that this only makes sense in a TCP backend, but for this to work, the
4 j6 N% {8 M+ d# L; Y/ ^' \ frontend must have waited long enough to ensure that an RDP cookie is present
/ y; W M- o$ ]# ~ in the request buffer. This is the same requirement as with the "rdp-cookie"! T7 K. G0 [1 [ n7 P) c
load-balancing method. Thus it is highly recommended to put all statements in* e0 K& [5 n1 n" v" ^
a single "listen" section.
+ a+ X* V9 C. o4 N# N& G, n6 j$ v! K
Also, it is important to understand that the terminal server will emit this
6 Q# R7 N P Z+ x RDP cookie only if it is configured for "token redirection mode", which means7 x' A$ v; n+ E1 }" n0 N
that the "IP address redirection" option is disabled.
2 U$ T d) F7 v0 L k0 T6 s$ e
9 \* T5 p3 {! g; g! W3 q t Example :
: v1 | L. [: h- R9 W listen tse-farm
" T2 V: `$ C- w- u3 i" @ bind :3389
, S& [& I( x+ A) R! B # wait up to 5s for an RDP cookie in the request
3 h- Z9 I8 i+ `4 l/ R tcp-request inspect-delay 5s) C( G! U( L2 B6 g& u
tcp-request content accept if RDP_COOKIE7 F4 t0 S. d' H
# apply RDP cookie persistence. u5 I- F; ~: F1 S
persist rdp-cookie" R/ p. @* V5 s6 y( r% V4 L
# if server is unknown, let's balance on the same cookie.( I6 p; N6 p, G3 E
# alternatively, "balance leastconn" may be useful too.
* ~6 o, l- k: m1 B balance rdp-cookie: i. a' Z% h) S* a( F) v }# h1 M- H
server srv1 1.1.1.1:3389
; Q+ } d6 U' }- w5 i server srv2 1.1.1.2:3389
9 o* s, d" z) D. f9 ^* S% B$ @/ f) p& J y5 t% p7 j) N
See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.. u9 T! Q- H/ W5 r8 `" G0 p
3 l6 }' f7 D1 \
2 F9 A6 J4 c j* irate-limit sessions <rate>
$ @9 e M& H( U5 ^: v$ @: @7 f Set a limit on the number of new sessions accepted per second on a frontend# o) X0 f3 l5 S, s1 `) n0 O$ J
May be used in sections : defaults | frontend | listen | backend0 z/ j9 s6 E! c8 W6 @7 h
yes | yes | yes | no
( i1 Z; b( e6 V( `6 P- I" Y6 X Arguments :% c. r( O6 j' e# D
<rate> The <rate> parameter is an integer designating the maximum number
/ m2 G, M: B [' Y) Z& w" | of new sessions per second to accept on the frontend.
% I+ `% q/ x" c" R& D$ N, |
# y% i2 S) I. R B( b& ` When the frontend reaches the specified number of new sessions per second, it
5 _5 M# n5 x- X* |9 r$ m) o stops accepting new connections until the rate drops below the limit again.
/ I; ~" C& t7 C9 h$ U8 U9 G During this time, the pending sessions will be kept in the socket's backlog ?( V* y% H/ W/ T
(in system buffers) and haproxy will not even be aware that sessions are* C8 \) Q( M5 z6 j
pending. When applying very low limit on a highly loaded service, it may make
- X5 e+ E9 H8 b: U' m' O sense to increase the socket's backlog using the "backlog" keyword.
; M# p1 F$ ]# Z; j3 M- ` q. F0 L
This feature is particularly efficient at blocking connection-based attacks
8 L- G: t7 \5 v* G or service abuse on fragile servers. Since the session rate is measured every
) V) p2 O1 t+ \3 U. F/ Q# a millisecond, it is extremely accurate. Also, the limit applies immediately,
+ x6 \ O2 j9 l7 k) w no delay is needed at all to detect the threshold.
# F- T I. ^+ {9 E- |
* Q( |2 A( S' X Example : limit the connection rate on SMTP to 10 per second max
) {5 g2 I5 V5 N listen smtp# t% B8 k: F$ h. e8 |
mode tcp
% E+ R2 D1 Y! ^ bind :25
: x# Z6 F- v b8 x' |2 B" f, } rate-limit sessions 10
( U% M: m3 K( h n/ L# D$ b server smtp1 127.0.0.1:1025
3 E6 T& w5 n: F& j+ A$ Q) ~, G
/ n6 I( u' }2 E X1 t) h! P Note : when the maximum rate is reached, the frontend's status appears as, l9 \$ ^ ]$ E8 N9 ]6 j# k R
"FULL" in the statistics, exactly as when it is saturated.) j* r ~7 A7 l3 A; p
) U$ x$ O6 O" ]$ m- X
See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion./ S/ q, w7 W, U( t' h; V! m! F# _
& q4 t9 G1 ] d3 y* |$ _
7 r4 u# U3 G0 o- Predirect location <loc> [code <code>] <option> [{if | unless} <condition>]: R8 f5 e6 L2 O( C5 ~+ Y
redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]$ q/ D: a4 h9 W/ u2 D
redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
! D- i6 T; n( e8 T/ t Return an HTTP redirection if/unless a condition is matched7 p: |2 h. I9 p$ o
May be used in sections : defaults | frontend | listen | backend% d3 G" e5 z3 W. S2 E+ t
no | yes | yes | yes
4 ~, T( s2 \) s5 X; P8 V, l+ j& m& J1 T; ^
If/unless the condition is matched, the HTTP request will lead to a redirect% N1 P. ~9 z5 Z, z2 p+ T2 i
response. If no condition is specified, the redirect applies unconditionally.. `( k5 `6 x6 E' ]1 L5 d: g6 S# _
( c/ O/ w" V3 `! {& Z
Arguments :
! f. a, l, S; d1 Q- S7 T <loc> With "redirect location", the exact value in <loc> is placed into; ]9 Y4 E: `) a" u! q2 ~
the HTTP "Location" header.: x t( R. A& F8 l
3 Z$ K6 M$ N8 `
<pfx> With "redirect prefix", the "Location" header is built from the
- {6 w% P& i6 ]/ m concatenation of <pfx> and the complete URI path, including the* o* m. p, C$ E9 E
query string, unless the "drop-query" option is specified (see
6 ~, X3 n6 R) b% _6 G below). As a special case, if <pfx> equals exactly "/", then+ g, g) {& V: h! Z: ~
nothing is inserted before the original URI. It allows one to
/ S4 L5 s ] n2 c redirect to the same URL (for instance, to insert a cookie).
3 M2 v1 s; x5 t; n4 d- M5 l9 |
+ e1 a5 s- m8 n2 H5 X c <sch> With "redirect scheme", then the "Location" header is built by
1 |/ v- P [6 @7 [ concatenating <sch> with "://" then the first occurrence of the" W, C/ P( ~4 t+ M, G8 E
"Host" header, and then the URI path, including the query string
. _# C _! L' b- @9 l9 T4 r& | unless the "drop-query" option is specified (see below). If no* w1 Q% Q7 }( D _& S1 c/ T
path is found or if the path is "*", then "/" is used instead. If! B8 y# I @, O I- L0 D) z
no "Host" header is found, then an empty host component will be
9 l4 }/ o6 `/ H! ~ _ returned, which most recent browsers interprete as redirecting to% ?! k; R$ W4 `6 E% t! e/ c9 a
the same host. This directive is mostly used to redirect HTTP to1 L9 H( |" ^3 [
HTTPS.$ b+ s/ y8 [, p) H
6 Y$ |: ~4 S5 G- ~$ H. j1 ?
<code> The code is optional. It indicates which type of HTTP redirection# L& z, d, j2 q% j1 }
is desired. Only codes 301, 302, 303, 307 and 308 are supported,
& W# U* k- q" P, _) @6 C' I with 302 used by default if no code is specified. 301 means. H2 |, e% V% T v: b d% i
"Moved permanently", and a browser may cache the Location. 302
5 P3 R1 ^) s( J9 {$ n( ]" i1 E( l means "Moved temporarily" and means that the browser should not; e( f6 M7 t3 L2 g" h( {
cache the redirection. 303 is equivalent to 302 except that the
5 T/ ?( y9 m# H* I! L* L a browser will fetch the location with a GET method. 307 is just/ o f4 [( T: T+ `9 ~) k3 F
like 302 but makes it clear that the same method must be reused.
8 x Y+ a$ u: a$ \8 h Likewise, 308 replaces 301 if the same method must be used.5 @7 {8 w5 d2 t
( z! l0 \$ N' _ <option> There are several options which can be specified to adjust the
. B7 d' ~" R$ T F3 n. C S& ? expected behaviour of a redirection :) j/ ? Y' k0 c; {
7 j& {! I1 R( b$ ?1 B, j* Q
- "drop-query"
( t! _2 V8 c* i# I, B1 B When this keyword is used in a prefix-based redirection, then the$ H4 g6 j% `2 J; e+ q. E
location will be set without any possible query-string, which is useful
" v4 F0 T7 h, C' U* l for directing users to a non-secure page for instance. It has no effect
% O: h5 `1 z1 j) F K with a location-type redirect.! z/ t B; Y2 ~0 F1 d8 U
$ h+ r& U4 q. z. K
- "append-slash"4 I# h0 ~; b) J4 e- P1 w* o
This keyword may be used in conjunction with "drop-query" to redirect9 F! }' f- S8 B( r
users who use a URL not ending with a '/' to the same one with the '/'.% ^( D, k3 r) {4 M' ]
It can be useful to ensure that search engines will only see one URL.
" Z: h ^( C7 F0 b* m6 {# `8 L For this, a return code 301 is preferred.2 s2 f, ?2 O7 ~1 `
) V0 _) Y% M* `' a1 _" Z
- "set-cookie NAME[=value]"( a1 Z2 w) i! i3 t2 a- G% ? A
A "Set-Cookie" header will be added with NAME (and optionally "=value")1 B: Q1 e% S8 C3 L
to the response. This is sometimes used to indicate that a user has
2 l9 D2 V3 y* O& c6 M+ E been seen, for instance to protect against some types of DoS. No other
+ c+ Y) u L8 K- _3 i cookie option is added, so the cookie will be a session cookie. Note
% B: _4 S; M6 c that for a browser, a sole cookie name without an equal sign is: n" f X6 B. C. n3 Z3 P
different from a cookie with an equal sign.
+ p3 u2 K" F9 D9 h6 P. M5 ]3 \4 r0 W' E0 H
- "clear-cookie NAME[=]"5 Q# S' L3 i+ h/ x4 o# t
A "Set-Cookie" header will be added with NAME (and optionally "="), but0 B$ N" l" D2 V/ W; t
with the "Max-Age" attribute set to zero. This will tell the browser to- @" d- t" U* R3 k' ?
delete this cookie. It is useful for instance on logout pages. It is s0 t, [9 K! b& Z% H( Y$ J; v, F
important to note that clearing the cookie "NAME" will not remove a
( R8 ]0 X) F% ] ~, U6 W cookie set with "NAME=value". You have to clear the cookie "NAME=" for) g' t2 K. I L
that, because the browser makes the difference.. {, E% A* ^5 p: n
8 p+ W" R$ R' ]4 ~$ n- v( o Example: move the login URL only to HTTPS.* X7 x. r. O: Y/ m8 w
acl clear dst_port 80
, u% Y) d! ?, S( W9 s( n acl secure dst_port 8080
7 Z: L5 @( B) _% {* w( O acl login_page url_beg /login
\- m6 Y4 `+ \* H+ s# K acl logout url_beg /logout
/ t; x! u( Q% E9 i! N5 a- t acl uid_given url_reg /login?userid=[^&]+
3 C% |9 j% m% R& z; C5 I/ G+ J acl cookie_set hdr_sub(cookie) SEEN=1% |% l8 }( s( w" x. ?2 A3 t
* M f" J0 O' {# D! f3 X+ ^
redirect prefix https://mysite.com set-cookie SEEN=1 if !cookie_set! M3 v$ d; V( l/ t6 U" i
redirect prefix https://mysite.com if login_page !secure
4 T( {- T0 @, Y' m5 }) ~3 e' e redirect prefix http://mysite.com drop-query if login_page !uid_given- r1 P" Z3 w& i* Y* v/ x
redirect location http://mysite.com/ if !login_page secure
5 b; M) _0 m* A- o4 ^/ X l redirect location / clear-cookie USERID= if logout4 H4 O( i: ^ u- c% s1 Q/ f
, G8 u( m' f9 |$ W1 Q' W Example: send redirects for request for articles without a '/'.* v* W+ M7 k( N3 E
acl missing_slash path_reg ^/article/[^/]*$
8 q7 |6 h8 S) Q$ B$ W; }( p redirect code 301 prefix / drop-query append-slash if missing_slash
t5 i7 L) f7 _% m3 w$ {' P
3 g$ q. ]- Z- w& K Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.# m' i3 A/ p% w6 Z
redirect scheme https if !{ is_ssl }/ N8 W# I# D& ^; J3 n0 u
* V' Z% o$ V. q; [0 V7 f) x See section 7 about ACL usage.
+ M) K/ a* b! S+ t$ c! a
5 T, \2 P' ^" K: D. C$ K1 j0 V; _) s: q7 z' S/ e7 S
redisp (deprecated)+ d4 X/ l8 E8 c; @1 j6 C4 i
redispatch (deprecated)
) c. `& V% ~8 o5 Z& b* i. i Enable or disable session redistribution in case of connection failure& N% _' ^" [6 p* f% g' U' `& O3 Y7 O
May be used in sections: defaults | frontend | listen | backend
3 t8 |" u$ F2 ~/ v3 y( r$ c yes | no | yes | yes7 S( C$ T X5 v3 c( z' G
Arguments : none, y) v* z7 B9 y( O( `% q8 M0 X8 t
; j/ L, |) A* L/ @
In HTTP mode, if a server designated by a cookie is down, clients may
! `5 K4 c/ [3 p8 y' N7 b* y definitely stick to it because they cannot flush the cookie, so they will not" x7 e% z$ k* s0 a/ w7 n
be able to access the service anymore./ S' R" g" m! I* g4 S/ n& Q3 A, h8 k
5 o5 k, j- E: U1 z Specifying "redispatch" will allow the proxy to break their persistence and7 j2 f0 `4 N- n1 G9 m5 {1 n5 t
redistribute them to a working server.
' u/ m/ u# w* G9 `& B
, b+ I1 }; |7 p8 } It also allows to retry last connection to another server in case of multiple
# y. ]8 @ K7 P0 ?' C connection failures. Of course, it requires having "retries" set to a nonzero
& ] M) n- U: ]- @/ U value.
, p) n9 {. {3 ~& z$ S) m6 {. F' E- ]% R) f
This form is deprecated, do not use it in any new configuration, use the new
" O* v5 S" J$ j$ L1 W "option redispatch" instead.4 l U8 I8 w- P3 Q; m7 K: B
6 n3 ?: g. d5 n/ h) @, K6 o- x4 _# j See also : "option redispatch"& q! Q6 e- O' K5 i/ O
* I8 h! }- Q8 ]: F: g" s* }
5 Z8 |/ A& B w, D* ]reqadd <string> [{if | unless} <cond>]
; ^: D4 P5 L: [- ` Add a header at the end of the HTTP request9 z3 [7 v% M% D, ]) v
May be used in sections : defaults | frontend | listen | backend% v* J. m! t% _* Z7 W/ v
no | yes | yes | yes
( y- p* l, ^5 r Arguments :
, y" i& y: \( e# b) ]* v <string> is the complete line to be added. Any space or known delimiter
7 }* o5 g8 r# x* ^, ]; A must be escaped using a backslash ('\'). Please refer to section' U* e+ m/ ]* F8 m
6 about HTTP header manipulation for more information.
2 ]$ M, q5 z& j* E' L
7 }8 [5 E( G4 ?9 X <cond> is an optional matching condition built from ACLs. It makes it
. `! W/ A% g5 w3 W. I! r+ o1 t possible to ignore this rule when other conditions are not met.
6 {$ s6 K1 q+ R. F: e8 c
# O8 h3 ^8 u# v0 U0 R% k" s4 V# O8 f( y A new line consisting in <string> followed by a line feed will be added after
N2 [; w- }1 W: Y O+ O the last header of an HTTP request.
7 M- D( _8 ?1 W
- @# c2 i' h- G9 P Header transformations only apply to traffic which passes through HAProxy,
q0 [ U% P- m6 f- o8 a4 a) i and not to traffic generated by HAProxy, such as health-checks or error7 G8 q' J' s3 x; |, y9 q8 p+ }) G
responses.
8 K! A U4 J' M/ r4 |( X' f2 L
- r1 A& o# ?( c4 z1 x, i. w Example : add "X-Proto: SSL" to requests coming via port 817 {# c( v5 R1 \0 }2 I W
acl is-ssl dst_port 81/ H+ B' P9 a6 T1 E
reqadd X-Proto:\ SSL if is-ssl
( J# |! K4 x# l ?$ S$ M
' t& P) Z/ s7 ]! K' w+ ~ See also: "rspadd", section 6 about HTTP header manipulation, and section 7) l4 E) Z6 d: }% e8 P9 t
about ACLs.
, F: W8 J: @0 M0 H a; u2 T5 h
" C1 l5 c4 R. S1 x" R- w$ P0 lreqallow <search> [{if | unless} <cond>]
3 g `# x6 r6 M# H# Y/ K: sreqiallow <search> [{if | unless} <cond>] (ignore case)
9 j' V' G8 T5 X7 ?# V p0 | Definitely allow an HTTP request if a line matches a regular expression" T( \" t0 b# F& j2 R
May be used in sections : defaults | frontend | listen | backend
/ J* W9 o+ d9 ]- F5 W0 g( {/ D5 B no | yes | yes | yes( _: A7 Z5 O+ k
Arguments :" o4 y+ x& [8 `, u/ L( d% z* |
<search> is the regular expression applied to HTTP headers and to the2 L$ Z6 c( V& x, |; S# A5 U
request line. This is an extended regular expression. Parenthesis
9 a7 `4 k2 }6 J7 H7 F% y grouping is supported and no preliminary backslash is required.
- |, o3 h/ j" `. r% | Any space or known delimiter must be escaped using a backslash
1 w( {! P, Y G5 Q& J2 l2 t$ _ `5 P ('\'). The pattern applies to a full line at a time. The. E( t- T+ f4 X+ a: \, B
"reqallow" keyword strictly matches case while "reqiallow". ]$ u. Y+ f2 m- r& e. _7 V
ignores case.8 i) Y. h' E' R/ Q6 e( X# e2 R' S& ]
% u; g4 m- G h, k! Y- v
<cond> is an optional matching condition built from ACLs. It makes it
3 l8 h4 v- |5 X, ?# ^ possible to ignore this rule when other conditions are not met., |+ Q+ y7 W: v5 |! L
, l7 W, v2 g7 j4 G# B l5 z
A request containing any line which matches extended regular expression; B9 N, l" n, U4 ]
<search> will mark the request as allowed, even if any later test would4 F/ n/ Z* g2 W! f, n- {. {; R. f
result in a deny. The test applies both to the request line and to request
1 P/ O+ N" Y8 p; ~/ U2 M headers. Keep in mind that URLs in request line are case-sensitive while4 j- x" u5 q q" \
header names are not.
+ Z0 x% j0 B& N* y% D: `/ g
8 D Q- U2 N" G7 c; Z It is easier, faster and more powerful to use ACLs to write access policies.
4 n( E. ^* u2 i/ Y% _$ D5 [1 ^; H0 u Reqdeny, reqallow and reqpass should be avoided in new designs.' K- @7 q& `& b0 T$ O
$ t0 W& ]- u0 ]4 x5 |1 m
Example :# _" i+ j+ c+ {3 E/ [2 V9 z2 B' y* ^
# allow www.* but refuse *.local
3 s( F* t# Y0 U2 r U0 G' z reqiallow ^Host:\ www\.
w9 i# c8 I8 S( v* Q: d$ Y reqideny ^Host:\ .*\.local+ r- B, e* j" U; R% x
. M: M1 u' ^6 Q; J. C/ Y2 w See also: "reqdeny", "block", section 6 about HTTP header manipulation, and/ Q, I! ]0 r( j% F% r. \! n, _
section 7 about ACLs.& ]" o5 |6 ~% i! R8 [2 \& c# t0 |
1 R: C1 b* _$ v* R; _4 b9 j
6 U4 u- W9 I: t# Q
reqdel <search> [{if | unless} <cond>]
" ]; n \8 `6 G- k/ {+ Rreqidel <search> [{if | unless} <cond>] (ignore case)
' n' q, [& r1 y4 ] C Delete all headers matching a regular expression in an HTTP request8 {# |( h1 N L9 ^* e& _) H) g5 Q. M; @
May be used in sections : defaults | frontend | listen | backend
7 O7 b7 F$ b. O( p! H+ k no | yes | yes | yes4 o( _! y5 M7 i* G! }5 T% ~1 A$ l
Arguments :
1 H1 W( c3 u* u) m3 R <search> is the regular expression applied to HTTP headers and to the$ `8 R, K2 l% q. a' _' p
request line. This is an extended regular expression. Parenthesis4 b/ m K9 O6 P5 m# O( t
grouping is supported and no preliminary backslash is required.
, d) k& Q4 Y% m: g( Y Any space or known delimiter must be escaped using a backslash# X; i' [% L" r+ M; v' @0 R: z
('\'). The pattern applies to a full line at a time. The "reqdel"
# V2 x0 Y7 P; J1 R f9 o! l. d- C keyword strictly matches case while "reqidel" ignores case.
; Z. ?# h5 N, S, B. S7 y; i ] f' a q$ ^$ Z" e9 T) g4 S. ~
<cond> is an optional matching condition built from ACLs. It makes it/ N" t/ r; _" a# y
possible to ignore this rule when other conditions are not met.7 {5 U" @% U+ d7 v4 w6 J" e
" y- q+ A; V- w* J Any header line matching extended regular expression <search> in the request
* P% @3 S; c+ q4 i; F" j& l% d will be completely deleted. Most common use of this is to remove unwanted
5 s( F4 L( h$ O# U/ F and/or dangerous headers or cookies from a request before passing it to the9 D3 f8 Y% G' A0 m O5 O5 x. ?
next servers.
) Z5 Y2 |5 x7 ?" N& C
4 y; h8 }7 E' a# p/ m& I: z: i Header transformations only apply to traffic which passes through HAProxy,
9 ?4 [1 l- P3 ?8 k; Y+ \5 ] and not to traffic generated by HAProxy, such as health-checks or error+ C! u2 R3 p8 {' `' O' G
responses. Keep in mind that header names are not case-sensitive.0 Y/ e6 U a) X. k
1 @. l8 E' f9 f3 z# r4 ~2 q% E Example :2 p7 W% q( W! z, I! z( T& ?: {
# remove X-Forwarded-For header and SERVER cookie& w! o6 q8 g/ S6 ?2 D
reqidel ^X-Forwarded-For:.*
+ S- ?( \/ I5 J+ m! a+ Y reqidel ^Cookie:.*SERVER=
4 q+ V- p) S& l$ y+ s4 \
; M' ]% I2 ^# f `/ q& z3 b7 b5 b. j* W% m See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header0 A h8 [ f2 d9 ^2 C# R+ G+ X( B
manipulation, and section 7 about ACLs.( r0 Y; C& E. Z. T1 o
" L, c+ I- c2 F5 u9 ]' d0 r4 z) T, @0 p3 B" |0 ?8 J e
reqdeny <search> [{if | unless} <cond>]
! M+ Z; [8 P# B% E- I1 Rreqideny <search> [{if | unless} <cond>] (ignore case)
5 N; G# d& K" V" u* U& M8 o Deny an HTTP request if a line matches a regular expression F# R" ] w; P# B0 D! W
May be used in sections : defaults | frontend | listen | backend- `' v2 ^" i @1 i- ]5 Q6 @5 g% T
no | yes | yes | yes* O0 w/ T: r& R Q9 A' E) [, x
Arguments :
; q8 \9 t& t. y' F; d; } <search> is the regular expression applied to HTTP headers and to the
9 } f' s9 J4 E0 n request line. This is an extended regular expression. Parenthesis7 m( a4 O1 }+ E9 x7 V
grouping is supported and no preliminary backslash is required.
" G3 {- Q! ^* d7 u Any space or known delimiter must be escaped using a backslash
; [+ o7 v) s, W D. u z; L ('\'). The pattern applies to a full line at a time. The
4 r& c1 D4 `' y9 X "reqdeny" keyword strictly matches case while "reqideny" ignores
: a! V% K. \ L3 |- H case.. @0 N! x4 h( \! t; S
1 S, b; g- X0 q: I <cond> is an optional matching condition built from ACLs. It makes it
) i9 x4 c" {; I possible to ignore this rule when other conditions are not met.
( b* ^6 `( D' j" I
9 P( D: V/ B5 p. r A request containing any line which matches extended regular expression
8 y8 c% p! r2 ?7 R5 ~4 A7 i <search> will mark the request as denied, even if any later test would' v* c0 B5 H( }& S5 I' S
result in an allow. The test applies both to the request line and to request
; {; k6 @, O) P# f headers. Keep in mind that URLs in request line are case-sensitive while
# }/ G3 k. _( E8 f; N header names are not.
$ A1 j- J M; c( ^# H+ O2 h4 C6 C
8 v. L+ w% c6 H; D A denied request will generate an "HTTP 403 forbidden" response once the7 E; C3 m4 h* J R0 K8 v, n2 w% Q, w
complete request has been parsed. This is consistent with what is practiced
3 n% y5 u, B) n6 G6 m using ACLs.
( \( C5 `& V9 _' c
* s/ _) R4 z7 v& ~( }6 A It is easier, faster and more powerful to use ACLs to write access policies., o5 d- Q1 u o7 ~; z. i
Reqdeny, reqallow and reqpass should be avoided in new designs.8 T: ?5 A8 y6 x, a' [6 K6 n$ \
# i) l$ B& J. m8 f* Z; H Example :' ^) m+ o# D2 m! h
# refuse *.local, then allow www.*3 [& C$ y+ n Z
reqideny ^Host:\ .*\.local% a% R3 Y- s: ^ Z' f
reqiallow ^Host:\ www\." A: s; D1 N6 O! E8 w
* H! M+ z- T6 A' ] See also: "reqallow", "rspdeny", "block", section 6 about HTTP header7 ?5 N7 s0 @# ^& ^
manipulation, and section 7 about ACLs.$ n9 J8 O, n1 ?* U; g- w% y! g& S
8 E* r& R, O& d" r' A0 e' C
! d+ W; X* T* Zreqpass <search> [{if | unless} <cond>]: C" l; [) C: [% ?
reqipass <search> [{if | unless} <cond>] (ignore case)( Z- e" c% n' v3 x8 ~0 p$ S- n! B
Ignore any HTTP request line matching a regular expression in next rules
- m6 a2 w. @) \7 w/ p May be used in sections : defaults | frontend | listen | backend- n! I/ {9 p4 y3 M& p
no | yes | yes | yes; D8 R. ~5 z- w: C8 `
Arguments :
& x8 b/ S0 M4 D, b5 u; J5 B" K0 O3 B9 B <search> is the regular expression applied to HTTP headers and to the; V: r! z% n% y! [/ F/ m- k
request line. This is an extended regular expression. Parenthesis/ ^/ O( ~+ N3 C& P' F" x8 F4 C
grouping is supported and no preliminary backslash is required.$ a6 f4 g6 ~7 e1 a* k
Any space or known delimiter must be escaped using a backslash- Z) F6 j* S& @) ^, B3 f4 s- X; e
('\'). The pattern applies to a full line at a time. The4 C% l/ ?, C4 l W$ i B) H8 d
"reqpass" keyword strictly matches case while "reqipass" ignores
6 y7 g6 ~. B& j$ I: Q. V" G case.
$ i, V/ Q* R: O v8 R6 @/ y* O3 v9 B: K3 g7 n/ [; ^
<cond> is an optional matching condition built from ACLs. It makes it
5 i8 [4 h4 z4 B% n possible to ignore this rule when other conditions are not met.
8 Z' v9 m+ J, x4 P. ]" _ k6 F4 l3 m+ _& k/ F$ t
A request containing any line which matches extended regular expression
5 W- |+ R1 D. P+ n- ^1 M* C <search> will skip next rules, without assigning any deny or allow verdict.
4 I+ z: N W) n9 @% x The test applies both to the request line and to request headers. Keep in
/ V! m0 Z+ S+ r, u2 }4 W mind that URLs in request line are case-sensitive while header names are not.: _0 G6 i3 B* R4 _' ^ j4 a/ V9 E
; ?8 T" I1 ^( G) A* `4 [3 } It is easier, faster and more powerful to use ACLs to write access policies.
( G7 n( A1 e) R& J, z" a6 | Reqdeny, reqallow and reqpass should be avoided in new designs.0 f3 z* q( c8 g5 J) |/ l; q
& H, w9 D" K! \7 B7 N) B& V* e/ u
Example :
8 i2 |" Y, f* H, \ # refuse *.local, then allow www.*, but ignore "www.private.local"
" l5 F. \9 H: U reqipass ^Host:\ www.private\.local8 [$ B$ d9 u* J5 R1 Q
reqideny ^Host:\ .*\.local# B! {; Z- H( K: y
reqiallow ^Host:\ www\., ~7 s; @" a0 U
0 {# O* }! t, i5 `! o See also: "reqallow", "reqdeny", "block", section 6 about HTTP header
& ]* A: C! R& t% X manipulation, and section 7 about ACLs.; U5 }2 G- ~5 m; F
+ |4 i9 [5 H# ]2 t$ l3 B4 b7 `0 S
reqrep <search> <string> [{if | unless} <cond>]% o2 `- I. S) b+ m
reqirep <search> <string> [{if | unless} <cond>] (ignore case) l) W% B: B! d0 V E
Replace a regular expression with a string in an HTTP request line# Z# p4 Z7 g! v# i8 _, a! f* q
May be used in sections : defaults | frontend | listen | backend
! {6 F& ]8 P* i# J/ J- C5 h3 Q. S no | yes | yes | yes
$ R7 E. s* } p0 Q4 ^1 r" d T: s Arguments :9 j8 F' K6 w0 I, f, r
<search> is the regular expression applied to HTTP headers and to the0 G0 A2 \5 M" v7 O; \, M9 z8 w
request line. This is an extended regular expression. Parenthesis
, z; {8 D% g, z+ B5 z grouping is supported and no preliminary backslash is required.4 D) K1 H6 c7 ~; e1 L7 Z5 d
Any space or known delimiter must be escaped using a backslash
) `! ~) [, }4 P9 m X3 ?% l ('\'). The pattern applies to a full line at a time. The "reqrep"+ g. b4 {, [3 [6 f% W( v. S8 y0 z9 \
keyword strictly matches case while "reqirep" ignores case.
7 ~$ ?# n" T, c0 N! X9 @. v: v" m0 u) O/ `( W
<string> is the complete line to be added. Any space or known delimiter# J+ }. o% z: s% V
must be escaped using a backslash ('\'). References to matched# Q) X, b7 U* K; [
pattern groups are possible using the common \N form, with N
6 ~5 Y" y& X5 A2 k being a single digit between 0 and 9. Please refer to section2 W5 ]& i$ t! y; h2 Q
6 about HTTP header manipulation for more information.
( h7 y! q; X+ c+ I0 s
/ P- m$ p! W. @2 \ <cond> is an optional matching condition built from ACLs. It makes it9 g0 q0 y' M# O; n
possible to ignore this rule when other conditions are not met." T8 I( {' b2 ~4 n. |# o( K! O3 \
4 x" p9 m1 F+ t! H# C- p& A4 y Any line matching extended regular expression <search> in the request (both
* V5 k- N0 f. A, e the request line and header lines) will be completely replaced with <string>.
" G8 ^% H& T g. u" { Most common use of this is to rewrite URLs or domain names in "Host" headers.1 r9 t5 b' ^/ m0 q
: A* U; \( Q% j5 [1 R+ b8 ^
Header transformations only apply to traffic which passes through HAProxy,) v5 v) O9 J/ m7 p& m$ M
and not to traffic generated by HAProxy, such as health-checks or error, E1 G8 y' n% ^ p C+ w6 B/ X
responses. Note that for increased readability, it is suggested to add enough
5 z& v% N# x% ^. C3 `5 T# x8 D spaces between the request and the response. Keep in mind that URLs in
8 i$ q4 l8 m" S6 q request line are case-sensitive while header names are not.' r% r: i0 P! [; P' F4 q
9 L* w' A# n) w; `
Example :
) p n! s( j2 `: R3 \9 n( ? # replace "/static/" with "/" at the beginning of any request path.+ ?, j& X% r& p3 f3 c
reqrep ^([^\ :]*)\ /static/(.*) \1\ /\2
# r" s" _( L6 {6 l" ]1 @! A! T # replace "www.mydomain.com" with "www" in the host name.4 }6 v! P& n2 K
reqirep ^Host:\ www.mydomain.com Host:\ www* c; K* l' P/ h1 g4 W
* k4 A* V9 @ Q0 k See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header" r/ `) q7 E k# G5 i
manipulation, and section 7 about ACLs.
9 h0 h) h7 ^' H6 w/ @ c. w& K
( {% \! x& v* Q& Q/ a. l
& i; b3 c* s: E; S1 z9 I+ ]reqtarpit <search> [{if | unless} <cond>] H# F) [1 {5 w, u0 @2 n
reqitarpit <search> [{if | unless} <cond>] (ignore case)
5 v. E2 a7 r6 s9 Z2 y Tarpit an HTTP request containing a line matching a regular expression
* l& O8 F0 p N7 b3 T( @ May be used in sections : defaults | frontend | listen | backend+ }+ B# ?+ n2 o
no | yes | yes | yes/ O. V- U8 L* A; P
Arguments :
h4 S, V' @2 o7 w& k: L! \ <search> is the regular expression applied to HTTP headers and to the! q( x5 A0 }' M$ D
request line. This is an extended regular expression. Parenthesis: c. \% y: [9 X9 t
grouping is supported and no preliminary backslash is required.# i! r3 u: [5 v2 |) e
Any space or known delimiter must be escaped using a backslash
7 z. s; } W! s0 @% C, B1 {9 l ('\'). The pattern applies to a full line at a time. The5 y, T2 F; V5 \( i( E& B; F. b
"reqtarpit" keyword strictly matches case while "reqitarpit"- L a' U3 l c8 K3 {, Q7 T0 @
ignores case.: q* @1 d6 c. }% g1 K) c
& m* o. x! ^: B% r( r1 ^% t6 f
<cond> is an optional matching condition built from ACLs. It makes it
, M# s7 ]3 M, V/ _6 ?' k" N, J5 N possible to ignore this rule when other conditions are not met.
: a6 {! r. l- g( o
~. [# H' o+ b' i! _- t8 R A request containing any line which matches extended regular expression
- [( k0 Y1 J: y2 U <search> will be tarpitted, which means that it will connect to nowhere, will; h# D% P+ ~+ f3 D
be kept open for a pre-defined time, then will return an HTTP error 500 so/ t' X6 x( B3 [6 Z0 M7 o
that the attacker does not suspect it has been tarpitted. The status 500 will
7 l9 J) S4 V$ ~3 | be reported in the logs, but the completion flags will indicate "PT". The
' D! V( G3 A r$ s0 n% m& g delay is defined by "timeout tarpit", or "timeout connect" if the former is* v0 f; J- a- ?' g; M9 o/ o4 d
not set.
- Z2 U. C. Z. j F
( V# Z5 S0 W; \% Z The goal of the tarpit is to slow down robots attacking servers with& t1 [2 S1 _" k: D8 n
identifiable requests. Many robots limit their outgoing number of connections
$ c$ M% c9 v5 I6 y and stay connected waiting for a reply which can take several minutes to
& g* @+ H; P" p9 R+ Q come. Depending on the environment and attack, it may be particularly9 L1 d& j' R3 I5 J' F# ?9 O/ \3 j
efficient at reducing the load on the network and firewalls.: f9 V% L& u4 s( d
3 E* K2 E/ c, d1 S; i Examples :
- m" o, y6 X; Y @% w1 g% B # ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but
, J' T7 Z2 e& A& O2 @ # block all others.8 B/ ]+ c1 e& g) f, f8 E
reqipass ^User-Agent:\.*(Mozilla|MSIE)" o6 d& b" ~* C" `* ]/ L9 q
reqitarpit ^User-Agent:
% t/ l8 l% s) W2 @# s7 [
, C/ w9 q) A0 V# q # block bad guys+ A6 }0 k) [ g4 z9 x; Z
acl badguys src 10.1.0.3 172.16.13.20/28$ Z% }% K1 j* ]! R
reqitarpit . if badguys3 L$ }$ B% k& J- F9 H# E& ^/ q
" c1 g# c; ^. B: X; q$ w+ t See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header, T5 i# F6 w/ M& i6 o3 i" S* H
manipulation, and section 7 about ACLs.
; A6 n! O7 V: V
' b5 ]: F4 U! W+ A! p! E* v; L9 S5 i# Y' ^% o
retries <value>
+ o. x0 N& K! \6 O4 _6 `& G Set the number of retries to perform on a server after a connection failure
3 M$ K8 ^+ z8 k; e+ I9 w- j May be used in sections: defaults | frontend | listen | backend0 x: S/ f) W- Z0 \
yes | no | yes | yes& X9 a) s" c3 ]8 ?+ m
Arguments :
. k9 D: x% ~9 z <value> is the number of times a connection attempt should be retried on
, ]% ?0 V0 O" O) [2 A$ [) J a server when a connection either is refused or times out. The% E8 w- s! a, J# g0 Y6 M# _: [
default value is 3.8 ^1 D& T: u3 s+ c
$ |" b2 x" [3 S
It is important to understand that this value applies to the number of8 }9 t3 l/ G- {* _; \% Y6 i/ h2 ^5 U
connection attempts, not full requests. When a connection has effectively
# N+ k* w/ n# O ]8 j/ Y0 ~" T been established to a server, there will be no more retry.
* g8 m& y- ?$ }( H% w% d# v' j) V( c* D% O0 n; I& ]) F. F
In order to avoid immediate reconnections to a server which is restarting,+ K3 ]) G. E6 @; A% U! r6 S
a turn-around timer of 1 second is applied before a retry occurs.
# W" j. c# d+ U" g, h) l/ S8 D
. z& ^0 R. h' C( d3 V+ A When "option redispatch" is set, the last retry may be performed on another% a# p5 } {, Z" G8 b+ j
server even if a cookie references a different server.5 J5 @2 X( K: ]5 ~( n- }1 v. {
- f3 t5 v) g$ J% S1 I+ p See also : "option redispatch"& J3 c6 E+ t% Y" t
6 ], o6 E' n G. T
1 ~) \ J: R/ K' T' i- Drspadd <string> [{if | unless} <cond>]- E3 ^$ f# d$ q
Add a header at the end of the HTTP response
' g0 h, C( c" E2 R( V7 n May be used in sections : defaults | frontend | listen | backend
1 Z& `) ^- H- k- L- p% p no | yes | yes | yes. J2 P, J Z7 q" J4 q R, a
Arguments :
, ^* p2 x: ?5 I8 ?( Y. P <string> is the complete line to be added. Any space or known delimiter: i4 U* d+ d* H7 A
must be escaped using a backslash ('\'). Please refer to section
2 `/ K. v, h" i0 s, T 6 about HTTP header manipulation for more information.
) T( J5 Z3 {' W: S1 b" ]) H/ D- [% ]% W: h! L1 ?, I* j
<cond> is an optional matching condition built from ACLs. It makes it3 h1 ~+ Y. d" F5 `# r' ?8 d6 q. s2 p
possible to ignore this rule when other conditions are not met.
: C3 C9 E+ E; y' v3 k8 R
$ S9 ?& i! @; U, g5 a. M A new line consisting in <string> followed by a line feed will be added after4 Q0 ]" H( P* i. [; A4 I
the last header of an HTTP response.
7 k! o, K6 k' K" \. @: s0 o0 E N [: {, B4 j6 a% G
Header transformations only apply to traffic which passes through HAProxy,
# O1 a$ n' `# @9 n0 P( u% z) K and not to traffic generated by HAProxy, such as health-checks or error7 O1 g { |. n+ j; c2 t
responses.7 C1 ^$ f/ U% ~
. P' c& C2 ?- F( t( Z' [ See also: "reqadd", section 6 about HTTP header manipulation, and section 74 w% O$ f0 Q) o) B* p5 Q% ?
about ACLs.
0 F3 n2 `' w7 l( I: S/ n
" f# i* o, d2 P) G% r5 A w
' R- l2 H& C8 r2 y* f4 Jrspdel <search> [{if | unless} <cond>]6 _: z! H8 ]+ @* G/ Z6 D
rspidel <search> [{if | unless} <cond>] (ignore case), b3 e- X0 a8 h+ |
Delete all headers matching a regular expression in an HTTP response
- C+ X, c8 u/ f* e% n* W May be used in sections : defaults | frontend | listen | backend
$ _+ R$ \- i- I# T/ h no | yes | yes | yes, \; m9 g& f) J+ N
Arguments :( P/ V! w( `, r8 r
<search> is the regular expression applied to HTTP headers and to the
4 f1 f6 y& E% L4 A5 h. i response line. This is an extended regular expression, so( y; B9 K5 j% |% s. g+ |2 Q3 \& M
parenthesis grouping is supported and no preliminary backslash
4 \% D. k: V* @4 X6 z% h is required. Any space or known delimiter must be escaped using* }( U7 i8 a* Q* z0 u
a backslash ('\'). The pattern applies to a full line at a time.. x1 P* N; U& `
The "rspdel" keyword strictly matches case while "rspidel"
) Y0 p* ] h' J4 P7 E0 r' f ignores case., x4 F O7 C4 k; {- K$ L1 l( f3 U
& i0 r, I/ B$ `; D9 V
<cond> is an optional matching condition built from ACLs. It makes it7 h- @9 y, {9 n+ @ D1 h6 B: {
possible to ignore this rule when other conditions are not met.# @. c% B0 q; f2 `/ G
( N# F& O L( J6 w6 P6 I! ^! E
Any header line matching extended regular expression <search> in the response
5 ]/ A: {2 I; S7 H1 M will be completely deleted. Most common use of this is to remove unwanted
7 k% v ]; ^0 T7 J8 K and/or sensitive headers or cookies from a response before passing it to the0 b# C4 X- ?& c- \5 Y
client.
& {8 F0 A# ?" V5 I' E" `" d# F
6 ~2 ^. T k+ F. b8 H Header transformations only apply to traffic which passes through HAProxy,
" a ^. q& |" m3 @* Z9 ~! e and not to traffic generated by HAProxy, such as health-checks or error
7 S* G' w: E( y responses. Keep in mind that header names are not case-sensitive.
( G( J, V2 c% t4 v/ ^
! O* s) Z. U. O9 o" u) h Example :. g; Z n- ^* D
# remove the Server header from responses
$ q1 j. I5 ^3 r+ J1 c. O% A* w8 n reqidel ^Server:.*
# ]" x% z7 m0 j3 \' z3 E: s
& e) C3 E$ M2 m6 c7 ^0 \ See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header n# d6 o& L T$ R; j
manipulation, and section 7 about ACLs.
/ S0 B8 _( G7 q" P* D& B' h% M% g
% X, ~' Q1 Q4 R2 |2 r4 x. j' H, g4 m/ w
rspdeny <search> [{if | unless} <cond>]
; ~) ~, f1 R0 Xrspideny <search> [{if | unless} <cond>] (ignore case)
/ K1 ~- A! [* p: }$ _5 x Block an HTTP response if a line matches a regular expression) k: r8 [' H' r, W [+ ?9 _+ L
May be used in sections : defaults | frontend | listen | backend, @/ g) }4 I# c
no | yes | yes | yes0 I( ]) ?5 p. y6 c+ ^3 b, W9 j
Arguments :
# N5 ~' N3 T P$ K7 j <search> is the regular expression applied to HTTP headers and to the
# l. T4 i1 Z7 W' a4 k response line. This is an extended regular expression, so* B4 H! N0 A5 D# x/ J
parenthesis grouping is supported and no preliminary backslash5 d$ Q0 K' f, j$ r& S! \* k8 q0 _0 [
is required. Any space or known delimiter must be escaped using8 M. [. J' g& v" L8 m
a backslash ('\'). The pattern applies to a full line at a time., F$ Y& m( C5 t; [, Y% u3 B
The "rspdeny" keyword strictly matches case while "rspideny", p1 U+ O _. a. R
ignores case.* @9 B/ s4 c/ p# M- y c4 o
: f( b. ? A3 D) m1 L! ` <cond> is an optional matching condition built from ACLs. It makes it
: i( o0 v5 r+ W6 |7 c possible to ignore this rule when other conditions are not met.
0 ^; P- r0 ~2 H' w8 K# [; t: v3 U$ e# Q/ t* a3 C
A response containing any line which matches extended regular expression# B1 A7 Q; R$ o0 p! Z/ y
<search> will mark the request as denied. The test applies both to the
9 P X4 T+ T7 q, k response line and to response headers. Keep in mind that header names are not2 C r9 C& m" W# j+ E' H& B$ J
case-sensitive.. D2 ^0 |* y" J2 A
! i+ r n* L) D9 x3 m Main use of this keyword is to prevent sensitive information leak and to
; W% N/ u/ h% K' m) x' l block the response before it reaches the client. If a response is denied, it) x9 X. n! G% F: i- h
will be replaced with an HTTP 502 error so that the client never retrieves
* X5 g( ^, [9 b# g% t/ u any sensitive data./ n) S* ^' U! u( f1 n
, `2 I) h! F6 [; O% J g& A
It is easier, faster and more powerful to use ACLs to write access policies.
5 T& }' n, i+ U4 F Rspdeny should be avoided in new designs.) w+ t2 w5 W" q& q
# |/ w- `& b+ l5 Q" O9 I Example :: w. R/ L- n) [/ C
# Ensure that no content type matching ms-word will leak
% ~6 b3 |2 ^, X7 `! @! `' ? rspideny ^Content-type:\.*/ms-word5 R r7 R7 D3 y' J8 _1 n( N
4 H! z2 J) M- L7 V& H
See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation6 k8 R6 n3 M$ d
and section 7 about ACLs.
0 x+ V& c6 W/ Q+ Z3 j! e6 e! A; P( _) g; z; P& E$ s2 f+ b* y
& p0 o6 y+ |( n! P( I% d) Irsprep <search> <string> [{if | unless} <cond>]; R9 O4 {9 A& [4 X2 k- \
rspirep <search> <string> [{if | unless} <cond>] (ignore case)
$ i8 _1 a# G% Q- _, r9 s Replace a regular expression with a string in an HTTP response line9 [: z W z8 y& E! @
May be used in sections : defaults | frontend | listen | backend: N ]8 \$ g0 f/ ^
no | yes | yes | yes
# B5 C1 p" o( Y0 E; h$ b- [+ b. H0 n Arguments :: o2 N8 ?0 `( q% e; h
<search> is the regular expression applied to HTTP headers and to the) O; A9 K- A; _7 B% W
response line. This is an extended regular expression, so8 k" d; ` R( N; X5 A# S0 W( u5 p
parenthesis grouping is supported and no preliminary backslash3 E/ U/ C" n6 `% \
is required. Any space or known delimiter must be escaped using+ \" {; Q; s& d! ?
a backslash ('\'). The pattern applies to a full line at a time.
/ _6 b, C# m$ I% L The "rsprep" keyword strictly matches case while "rspirep"2 D( H+ l7 A) l! W, t9 J% S# u; H
ignores case.
0 E7 }5 T& V3 V1 N. F
/ v2 U" f: ? n# p5 g" U <string> is the complete line to be added. Any space or known delimiter% u* y. R# Z5 y- `! W; c
must be escaped using a backslash ('\'). References to matched& g7 a4 D, v# |& E
pattern groups are possible using the common \N form, with N
3 w9 z# D. h- E2 U8 X Y being a single digit between 0 and 9. Please refer to section8 K0 t- y" ?" H- p- ?; D6 h+ R
6 about HTTP header manipulation for more information.
* e$ n# h( E B G5 L2 @ Q$ X; T
<cond> is an optional matching condition built from ACLs. It makes it
/ ?3 P+ m- K8 h" G possible to ignore this rule when other conditions are not met.
- I! m! V8 W: n |* \5 j# J8 H
' H0 i) x6 c! B Any line matching extended regular expression <search> in the response (both* K8 ~( D% H* p$ L1 K6 C# w6 B
the response line and header lines) will be completely replaced with
|% Y: ~4 f; _% v! m6 _- R/ L: x <string>. Most common use of this is to rewrite Location headers.. P9 @1 [4 i4 b3 K4 E
. V$ d( T/ |+ }) n0 \4 F# g
Header transformations only apply to traffic which passes through HAProxy,
2 _3 a7 q1 ~6 ?8 j9 y# ]* _ and not to traffic generated by HAProxy, such as health-checks or error
; @$ }& j: r- i4 V7 K m% `5 a responses. Note that for increased readability, it is suggested to add enough1 X- D0 [( g/ G
spaces between the request and the response. Keep in mind that header names8 Y% D2 D2 R+ Z( `2 X4 M7 X0 {
are not case-sensitive.
: Z' E5 \$ d! z& r- n8 k+ I9 W% f* N5 `
Example :( I4 H/ ?* s. y) z! @
# replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"& y8 `! w# F6 L1 C" J
rspirep ^Location:\ 127.0.0.1:8080 Location:\ www.mydomain.com* J% |; G; r0 P$ Q
% C+ c7 ?+ U1 z5 N; u1 c; B
See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header
4 N& ~: G# B) t9 Q manipulation, and section 7 about ACLs.) u! t" r% B% x# G& Z3 x$ B- g
7 Q L3 ?" ?" N8 [
5 i; a; [1 \0 I' Z' Y+ \+ o2 ~server <name> <address>[:port] [param*]$ y( x& T( y% {# K
Declare a server in a backend
( c9 T. N0 D6 ?& G) @4 F May be used in sections : defaults | frontend | listen | backend% y" _* P! L# c7 ?
no | no | yes | yes
: j/ r8 s0 B# y Arguments :0 n' G0 W0 C& [/ L) D) I
<name> is the internal name assigned to this server. This name will+ ?" D1 `8 h4 k. K
appear in logs and alerts. If "http-send-server-name" is8 h( K0 I! @6 r9 D4 ^. g$ c
set, it will be added to the request header sent to the server.9 K4 t. R( L7 @! }
6 u- |4 k% ~# }+ T
<address> is the IPv4 address of the server. Alternatively, a resolvable8 f& z( N/ Y( `" P9 T& C! C/ W
hostname is supported, but this name will be resolved during
( e6 h$ g0 g+ P% Q start-up. If no address is specified in front of the port, or if* J9 O$ k T( `( O
address "0.0.0.0" is specified, then the address used will be the
2 g% `$ }% [2 f same as the one used by the incoming connection. This makes it( P) m, a S6 p/ T4 e! K5 L s/ b
possible to relay connections for many IPs on a different port or
8 S3 K1 S3 m& G9 J4 ] j to perform transparent forwarding with connection limitation.
( }( G* a9 e( C" P) a( j# c" W5 O7 j) n( ?) v9 ~
<ports> is an optional port specification. If set, all connections will, j8 I8 s$ P* B/ ^# a
be sent to this port. If unset, the same port the client
) q4 `% g* {, M connected to will be used. The port may also be prefixed by a "+". j% X( n+ x2 \
or a "-". In this case, the server's port will be determined by1 P" m) |& S7 ~& @) P2 M3 f" m$ h
adding this value to the client's port., ?6 L! W4 G; R( @8 a/ B/ D) K! {/ a
6 L7 L( C {: E2 a
<param*> is a list of parameters for this server. The "server" keywords9 m0 c& k% f8 E& Q
accepts an important number of options and has a complete section' G7 t5 j$ j p# ?9 D/ E
dedicated to it. Please refer to section 5 for more details.
1 r( @2 j7 }1 B; E
2 }% ]+ ~ B/ Z Examples :
4 w7 _+ K, C5 N* b3 T server first 10.1.1.1:1080 cookie first check inter 1000
8 [. w* ]+ Y( T7 l5 U, L6 m server second 10.1.1.2:1080 cookie second check inter 10000 S7 h( v1 t. E% l, {( }
! @- i; K1 q) V, x) n R; A
See also: "default-server", "http-send-name-header" and section 5 about
1 W7 q9 a* \ k* l" S. A. X6 W server options3 e2 L! E3 _3 w* _* b
& q- b( v1 u8 q1 J( N% ^+ F
0 y0 a" d0 d9 C+ G9 w* g
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
! g( D$ o) J0 F3 F& e* T2 g3 }source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
R6 u8 I) S. A7 w& e2 x, ~ {2 bsource <addr>[:<port>] [interface <name>]
# {8 O' U, L) ~6 n Set the source address for outgoing connections
8 {5 T+ D! c8 w- O+ e f May be used in sections : defaults | frontend | listen | backend" `) X/ v. u- b3 Z- ]) D5 `
yes | no | yes | yes' y$ s9 l4 ]5 F' t
Arguments :
# o% d; q- X! Y% b6 R <addr> is the IPv4 address HAProxy will bind to before connecting to a6 E. x( t( I# Q" s1 p
server. This address is also used as a source for health checks.
# [( v! t9 a. n6 t f: q; p The default value of 0.0.0.0 means that the system will select# G5 t( B! f; |1 k7 f* Y+ I
the most appropriate address to reach its destination.
@0 L J/ q, f
) `/ ]* P% U7 a, L. S <port> is an optional port. It is normally not needed but may be useful
' F. }, d: P2 y" { in some very specific contexts. The default value of zero means
, G0 `/ M: G3 i: {( Y3 f. { the system will select a free port. Note that port ranges are not
$ V. v. k5 v% q supported in the backend. If you want to force port ranges, you
6 g5 L7 ~( } P+ T3 T" O6 Z0 r have to specify them on each "server" line./ L3 z/ T0 n! O+ B7 z
. X) K5 x' |0 t8 ^3 T <addr2> is the IP address to present to the server when connections are+ x0 V6 O6 {- v' r2 o6 \4 N8 h
forwarded in full transparent proxy mode. This is currently only
u+ p& ?4 M Q7 g, K supported on some patched Linux kernels. When this address is6 E6 ~" z3 y# \
specified, clients connecting to the server will be presented) n3 ]+ u1 V2 V- l- o9 G( s9 S
with this address, while health checks will still use the address
, W) r6 x& r- g( n( c8 y <addr>.
: s) R/ q- |& p8 B1 K% F
" }7 `# @2 `6 R. q. v <port2> is the optional port to present to the server when connections$ F6 E( G, o- [- j8 ~6 [
are forwarded in full transparent proxy mode (see <addr2> above).
: E' W5 b4 @$ g9 f The default value of zero means the system will select a free
( }1 c, N1 B" f% O) ~1 }5 S& p9 n port.6 v! o1 \) S: B7 ]1 V6 V4 `
. {$ d( G! f s, x' H) G% T
<hdr> is the name of a HTTP header in which to fetch the IP to bind to.8 w. G z1 X7 B( R( S' N
This is the name of a comma-separated header list which can
% U" M# G- W2 ~ contain multiple IP addresses. By default, the last occurrence is1 W% H6 Z' {/ i3 ^0 t: l2 M# d9 A
used. This is designed to work with the X-Forwarded-For header% x% R; l9 c' N, J! ]
and to automatically bind to the the client's IP address as seen
- p& W( d+ k; R" W1 Q5 c# g by previous proxy, typically Stunnel. In order to use another! K+ q# Y/ \3 B$ k3 j* j
occurrence from the last one, please see the <occ> parameter# z: e: u3 o Q% e5 Y4 a' H
below. When the header (or occurrence) is not found, no binding
S! O2 n& Q4 w% ] is performed so that the proxy's default IP address is used. Also: P) w8 r/ j) S( r$ H
keep in mind that the header name is case insensitive, as for any& F/ Y, ]& _* t
HTTP header.1 Q( h# ]& V4 o/ ?0 ~
* G1 Y1 y- T9 Y! Y <occ> is the occurrence number of a value to be used in a multi-value
0 ^9 d6 J( N+ a O header. This is to be used in conjunction with "hdr_ip(<hdr>)",0 o9 l" `+ ^3 F$ c1 T+ Z) L& c% j
in order to specificy which occurrence to use for the source IP
u5 H1 e5 D; b) X- Q; G address. Positive values indicate a position from the first O8 R3 _) D4 k* }$ P; g
occurrence, 1 being the first one. Negative values indicate
4 y- a# C, j% }7 D u4 w% T0 r( [ positions relative to the last one, -1 being the last one. This
& a7 \2 D1 f4 }' U) S" Z0 g is helpful for situations where an X-Forwarded-For header is set
$ Y- D) D; y( C8 D at the entry point of an infrastructure and must be used several
1 ?5 |% h% {" Q& Z proxy layers away. When this value is not specified, -1 is8 Y0 T7 `4 z3 M# C# B% {8 Q
assumed. Passing a zero here disables the feature.0 d! E& t6 x0 x
/ j# k4 z* T6 V% r, Q) j7 m' P! b <name> is an optional interface name to which to bind to for outgoing
0 p* N' Z# m; y- {' n# \ l8 k traffic. On systems supporting this features (currently, only* M" T6 h- |2 K. a. C( s/ |
Linux), this allows one to bind all traffic to the server to( i7 g( \! a5 a* t8 s! ^- |
this interface even if it is not the one the system would select7 Q& E7 @# Z9 {8 d
based on routing tables. This should be used with extreme care.
& a! j" H% `5 P# O) f) Q Note that using this option requires root privileges.
" C3 [* d M& f9 N" U
/ F9 V( O- f- v- w9 O1 c The "source" keyword is useful in complex environments where a specific
3 I8 j- O) H) p c& ] address only is allowed to connect to the servers. It may be needed when a3 C2 `; C- @3 P: [5 P
private address must be used through a public gateway for instance, and it is
7 m' H2 O# l* f! e3 d e9 N& _7 X known that the system cannot determine the adequate source address by itself.7 H5 \( R6 G6 v' c; C
% d9 [4 x5 p$ C7 M6 J/ x An extension which is available on certain patched Linux kernels may be used
3 m3 O$ } y$ |4 b9 k, F( M( n through the "usesrc" optional keyword. It makes it possible to connect to the; q$ ?. J$ V( ]" D' t% ~5 f2 U9 O
servers with an IP address which does not belong to the system itself. This- N' |, T v% A
is called "full transparent proxy mode". For this to work, the destination
/ K4 W' s; I2 f6 t$ M+ `. K, H( _! w servers have to route their traffic back to this address through the machine
" O+ B" I/ s8 D/ j0 g& z$ { running HAProxy, and IP forwarding must generally be enabled on this machine. I! \/ N. L3 Z4 @. q) f! F5 u
6 Q0 j; g; B) j- L7 X" @4 u. \" M In this "full transparent proxy" mode, it is possible to force a specific IP/ ~! E/ a$ J4 N! m, a; N) D, e
address to be presented to the servers. This is not much used in fact. A more
& ?( k! N3 B0 G" u% G2 K3 C common use is to tell HAProxy to present the client's IP address. For this, n k; h* L0 O) L3 S1 x
there are two methods :
" o `. b, W3 m+ J
+ ~" v# {0 J3 A/ O: w/ u - present the client's IP and port addresses. This is the most transparent0 `1 _: W: ?% T* V7 }2 C9 H
mode, but it can cause problems when IP connection tracking is enabled on
9 Q: I- n9 d3 t, F/ Z2 `/ G the machine, because a same connection may be seen twice with different4 s* K2 y" r0 i. h& {7 G
states. However, this solution presents the huge advantage of not) V8 r. E! D( F. r z
limiting the system to the 64k outgoing address+port couples, because all
+ j% F6 Y0 I/ f of the client ranges may be used.0 J+ u7 X* Q9 J
* |( H- \5 A9 C) \7 | - present only the client's IP address and select a spare port. This/ j9 ?/ l" q' T/ P m( R3 v
solution is still quite elegant but slightly less transparent (downstream
x8 D. g2 V6 X) @2 _ firewalls logs will not match upstream's). It also presents the downside8 j% W) T4 a; H
of limiting the number of concurrent connections to the usual 64k ports.
' L1 R4 q B; d1 D However, since the upstream and downstream ports are different, local IP
6 d0 `* q- d1 [2 B! O connection tracking on the machine will not be upset by the reuse of the
" U* ]& N* b9 f) {' Y8 a same session.
2 V, h3 i' ^' v% H2 t+ W% x3 g0 \' C
Note that depending on the transparent proxy technology used, it may be
3 Y9 l$ d4 j% X' P2 @& Q required to force the source address. In fact, cttproxy version 2 requires an( \, j8 E) U( U; H- D% W
IP address in <addr> above, and does not support setting of "0.0.0.0" as the3 t' y* l8 r0 @0 b: z0 }
IP address because it creates NAT entries which much match the exact outgoing* }; x3 N5 `" C) {% y3 B
address. Tproxy version 4 and some other kernel patches which work in pure7 ]9 Y& C* Z; K9 ?, G+ i5 @! D0 h
forwarding mode generally will not have this limitation.
9 T( |4 H& M" U
4 j) H% K- \5 N% a1 i This option sets the default source for all servers in the backend. It may; n* d5 F$ b- {" F* o8 g
also be specified in a "defaults" section. Finer source address specification
. `+ P4 ]/ ]% h; X& Q' g$ y* j is possible at the server level using the "source" server option. Refer to
( W6 e: [% H6 R+ m, V6 H section 5 for more information.& r" C1 c- y/ F
9 \: J3 s+ P: G9 H v: ^! ^
In order to work, "usesrc" requires root privileges.
# J9 ^( V. a2 j1 u; q! }
% V' F+ m2 I k' e) E1 y1 A, F2 u0 z Examples :! ]3 v! W( m: o
backend private6 c. K$ ]! R U0 I; h8 ]. g8 \
# Connect to the servers using our 192.168.1.200 source address! w" o2 Q- {+ U X, `5 ~/ ^% ?$ }
source 192.168.1.200
' @! m! j( @( ~+ Q3 Q! y1 x$ u9 M# G a( m1 h y& b& \& T% |3 c
backend transparent_ssl1
3 z5 f# l8 |! @5 y% v # Connect to the SSL farm from the client's source address
/ z% C4 h$ t2 A3 V5 ^: o source 192.168.1.200 usesrc clientip) H6 ]" O/ r$ }" r7 r
: R# E5 K2 e$ l s% R7 _ backend transparent_ssl2
" y5 f- \/ M3 f3 D8 S # Connect to the SSL farm from the client's source address and port) m7 f3 X& x1 b1 E! o# O
# not recommended if IP conntrack is present on the local machine.# U) w) V; f* j5 \9 [; v; w
source 192.168.1.200 usesrc client
. P/ L3 E9 R7 X: A; e( H7 Q& y9 [
- B" Y2 m, d. f$ X! u+ e: A9 i/ n backend transparent_ssl3
- S" r$ j1 a! \* e # Connect to the SSL farm from the client's source address. It6 k) {0 w: a0 V V
# is more conntrack-friendly.8 b9 m$ s b1 ~8 q% _8 X
source 192.168.1.200 usesrc clientip3 W3 U& X# t3 m9 W! z5 k0 Q; w7 E$ n* t
, \! J9 E9 W. n( s/ F backend transparent_smtp, h8 |4 Q' ~3 Q8 h; Z: D3 Z* P
# Connect to the SMTP farm from the client's source address/port, x. {- @% H% m# ]( H& H! H
# with Tproxy version 4., W* \, w5 r0 D7 j4 G* K) R
source 0.0.0.0 usesrc clientip
/ S& h/ V. n/ Y3 P7 V [. R$ N) D3 d' G, M
backend transparent_http
5 Y, R7 m" W A8 C( t, r/ o( ? # Connect to the servers using the client's IP as seen by previous% N9 e! x/ K V7 i4 g$ p% s
# proxy.) p: z' D4 }% V6 |: ~. p3 e# S
source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
$ e8 X# o6 \1 q1 w' ?$ w% @+ g: `2 Q* ?+ _
See also : the "source" server option in section 5, the Tproxy patches for
, \, x' I2 G2 c/ t: o the Linux kernel on www.balabit.com, the "bind" keyword.$ T2 Z/ s* w. e5 [# r
& D: A5 q# q3 J
( V1 T$ F$ e+ M# z- P* R$ Bsrvtimeout <timeout> (deprecated)4 l- @8 a9 t, x, H; @2 |
Set the maximum inactivity time on the server side.; v* s+ j6 \ A
May be used in sections : defaults | frontend | listen | backend- ^8 U+ i9 @3 O$ d; \. d, X
yes | no | yes | yes4 W3 G6 n" f) |
Arguments :
; |$ [/ c. F% V <timeout> is the timeout value specified in milliseconds by default, but7 z& C/ j: n2 J) x A
can be in any other unit if the number is suffixed by the unit,$ R) {, C1 r' U8 h, T7 j" l* y
as explained at the top of this document.3 v# |6 e1 {+ ]: w! P! k
( v; b/ K; @/ H The inactivity timeout applies when the server is expected to acknowledge or
; y) \6 m8 e' B7 c send data. In HTTP mode, this timeout is particularly important to consider
9 }3 P( ? v. N4 C* b+ W during the first phase of the server's response, when it has to send the( _" w3 T7 h& p' d0 K, ^
headers, as it directly represents the server's processing time for the
2 Q1 y6 Y! o, p4 I9 L request. To find out what value to put there, it's often good to start with
( Z6 n4 A1 g- _ what would be considered as unacceptable response times, then check the logs
* U: ~& K g$ W- \# F3 U to observe the response time distribution, and adjust the value accordingly.
+ N/ W, Z- n. \1 |3 h+ p G& z9 w" R# Y$ N9 \" C/ A
The value is specified in milliseconds by default, but can be in any other
- t* ?8 ?! W+ G; O% r unit if the number is suffixed by the unit, as specified at the top of this
% e- x: U# j6 b3 Z document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly, l& M" }. e9 Y5 m" P& P, X
recommended that the client timeout remains equal to the server timeout in* Z i6 k; Q7 o. G0 z' Q
order to avoid complex situations to debug. Whatever the expected server
) }5 |& g- p$ [ response times, it is a good practice to cover at least one or several TCP' U" @* D* W; C. h
packet losses by specifying timeouts that are slightly above multiples of 35 x3 Y& {" m3 J5 {' `9 H- D
seconds (eg: 4 or 5 seconds minimum).5 d( D) Y k/ q4 t: N5 t
]' Q3 ^ M0 C" [3 l
This parameter is specific to backends, but can be specified once for all in
, h* U2 z, j o) o+ C "defaults" sections. This is in fact one of the easiest solutions not to: |3 [. F8 G, o& N, d* h
forget about it. An unspecified timeout results in an infinite timeout, which
- h& b6 \! u6 @5 ` f is not recommended. Such a usage is accepted and works but reports a warning6 Z1 d8 c% @: K1 E' r
during startup because it may results in accumulation of expired sessions in0 q" V4 I) }( L2 I
the system if the system's timeouts are not configured either." A( f0 o. \- p& T0 _1 U
2 _4 x) ~2 }; o. Z
This parameter is provided for compatibility but is currently deprecated.
' q' O. Y0 t, l1 h" y @6 r# k8 @2 { Please use "timeout server" instead. V# V# A8 L" n9 `/ ~# Z9 c
4 p) x0 S& A% W3 o See also : "timeout server", "timeout client" and "clitimeout".* [' V% }6 {. K
. {+ b2 R; Q# T! M+ `4 ^0 J: ?4 q! Z _5 `% e/ y# Z
stats admin { if | unless } <cond>
7 y# n: Q6 P( h- n0 t; I i/ Z& o Enable statistics admin level if/unless a condition is matched
/ _ K/ |1 C7 X6 h( G' P. |# B May be used in sections : defaults | frontend | listen | backend
" p/ [) ]$ a; n1 p! g no | no | yes | yes
9 c6 |, d- j% u" I! D
$ F2 n9 |: N3 v# S This statement enables the statistics admin level if/unless a condition is
/ e+ B* A- t: |- y7 i n matched.
7 y3 Y- }2 z% F7 O$ {( r
- n6 M1 ], ?! z0 [ i3 v8 S' |0 u: } K The admin level allows to enable/disable servers from the web interface. By
+ t. I2 g" V/ o7 ? default, statistics page is read-only for security reasons.
& T- S4 H3 Y( y* T5 ^9 |1 k I( K8 r0 k A9 M' P* U# D+ L
Note : Consider not using this feature in multi-process mode (nbproc > 1)
+ I4 W7 s$ y; C- ~$ d% E unless you know what you do : memory is not shared between the
3 B! W) N0 U( ? processes, which can result in random behaviours.6 b1 `, ?/ {% K
F6 {& k& D7 K- g+ Z, ] Currently, the POST request is limited to the buffer size minus the reserved$ T a7 f2 I" N: P+ h
buffer space, which means that if the list of servers is too long, the
: i( C/ z Z( d' }, q7 V; P request won't be processed. It is recommended to alter few servers at a* i& Y T. |9 O: ]+ E
time.
. r @4 w$ p$ ^
% P9 s! u" f& D3 D8 R Example :
7 R' y3 l' t3 k2 J # statistics admin level only for localhost6 t1 B) S$ T) b3 i3 E9 n# O6 j
backend stats_localhost
3 X2 P6 {0 X( r6 R% j8 g& G stats enable
7 [0 B6 }- [3 X& K5 [! J( N2 f1 x# ` stats admin if LOCALHOST; h4 V s3 ~) l. j* z- B
s) y' `* Q5 w ?$ ^% S. A Example :; U. x: r- [6 t; p9 G' {3 a1 b( }
# statistics admin level always enabled because of the authentication
- n9 S4 ~ D5 `! k, G1 X) W% [ backend stats_auth# j; ?. j& S& |+ `5 @4 N; O
stats enable
* I7 g: n( q) L! V3 P$ _4 n stats auth admin:AdMiN123
+ z% ?! Q: M3 z. P. p( d( [( i% H stats admin if TRUE8 i9 I6 S5 s% E' O# y4 j. E
+ b; u/ }) J0 X* ~: O0 W" N
Example :8 \+ o9 h5 z1 ?3 _# u: p
# statistics admin level depends on the authenticated user) c" d9 ~4 H# r, M' b
userlist stats-auth$ c+ ~2 a' X& H. n
group admin users admin7 G2 v1 t5 ?9 N& }0 D6 `
user admin insecure-password AdMiN123
2 d9 p0 K) [: a group readonly users haproxy
) y9 }9 ?" R9 q: K j user haproxy insecure-password haproxy
0 h4 t4 c2 Z- x
& T+ ]9 a! m% D1 u" | backend stats_auth
O( H% X/ J0 @" E7 o5 c" ` stats enable
5 H/ O* N w5 b: ], Z# Y acl AUTH http_auth(stats-auth)
' t( p3 ~4 q- g: ^8 s acl AUTH_ADMIN http_auth_group(stats-auth) admin; c( r4 v0 y, m3 N
stats http-request auth unless AUTH0 S; \' @+ g! G( c# a, s* }7 C8 E: p
stats admin if AUTH_ADMIN# y" ], V; B9 A% q% }
' ~+ }+ S7 q* I \$ F0 {
See also : "stats enable", "stats auth", "stats http-request", "nbproc",
7 s$ S0 i9 @4 H# h5 y9 x" ? "bind-process", section 3.4 about userlists and section 7 about
- `6 \6 u4 G ]; x& Y* l ACL usage.
0 N* K% J) t ?# x- K
; x1 S, ^; h7 @! M4 i
; a# ]0 R- ]8 D% }& Y# wstats auth <user>:<passwd>
5 R% @1 X: Z2 `+ b2 W; |1 O8 I Enable statistics with authentication and grant access to an account
' J3 t9 A; H$ I9 J# V/ ] May be used in sections : defaults | frontend | listen | backend( I/ M% k# c8 h$ y3 _
yes | no | yes | yes
( I8 r( ?1 C8 \' o Arguments :
! q8 I! x4 O0 Q9 h2 N: P N1 H' H m) m& f <user> is a user name to grant access to8 p. N$ U+ b' n
+ }7 O) T' h7 h0 Y* H <passwd> is the cleartext password associated to this user7 l1 U! F4 e7 a
/ L+ O& k" V% d! T This statement enables statistics with default settings, and restricts access. y" \4 y, n! Z5 [3 Y. X4 @. M
to declared users only. It may be repeated as many times as necessary to0 s5 k" Q! q m( A4 C1 h. V9 y
allow as many users as desired. When a user tries to access the statistics4 o- D7 i, l% j
without a valid account, a "401 Forbidden" response will be returned so that8 x2 L* _) V% ]/ x
the browser asks the user to provide a valid user and password. The real
- e k; t; y h* R( R+ F9 O which will be returned to the browser is configurable using "stats realm".4 d# C' K% }0 V; [
& U& q1 t7 ], `! t. R& L
Since the authentication method is HTTP Basic Authentication, the passwords
0 d* \$ @ [4 Z' d# b8 V circulate in cleartext on the network. Thus, it was decided that the
: r( `1 n! v, P2 @& u$ J% Y configuration file would also use cleartext passwords to remind the users
9 j- V! S3 n# r5 a. a' G that those ones should not be sensitive and not shared with any other account.
) R2 k5 s* g, D! K
- q/ G u- j3 n) E- h It is also possible to reduce the scope of the proxies which appear in the$ [1 n) d- f# I+ s: Q$ |
report using "stats scope".* T& i% a0 Q7 w% m* s, q
/ t/ q6 f9 P7 [: O5 _
Though this statement alone is enough to enable statistics reporting, it is
3 O; l! E- Y! E! x5 ]: y recommended to set all other settings in order to avoid relying on default
& }8 e2 T9 J/ _ unobvious parameters.
0 L1 x8 ]1 a; y, n
$ q- t) v( D! G5 ] Example :9 s9 l4 }$ E/ G7 c( \- S; o) \
# public access (limited to this backend only)
7 i. D" k' ]) S# I( r' v backend public_www
% x/ a! x0 r) o+ ~% d- T server srv1 192.168.0.1:80
$ C- o! S. F* g2 p stats enable
5 `5 w8 S4 D' ?/ V X" I& @2 e stats hide-version
T- L" K6 K& h, g6 J, O; ^' s stats scope .
2 B$ [- \; z' F stats uri /admin?stats! U7 W* R8 B; c
stats realm Haproxy\ Statistics. P( l# s8 n3 K5 K. P8 B+ O
stats auth admin1:AdMiN123
& e" _" x6 F# H8 d stats auth admin2:AdMiN3216 ^8 A) o$ J7 w- a
! t0 d8 \6 W6 T" X # internal monitoring access (unlimited)
) ^) Y3 Y! N7 _' ~( a- Q8 i backend private_monitoring8 @1 X. E' S: B& o' g1 }
stats enable
6 W& K5 D# g0 _ stats uri /admin?stats
2 t2 i+ a) x A$ _/ A- W stats refresh 5s
/ {5 O, Z9 C: A# A$ |, X6 U: i
2 U. }5 |, k# Y See also : "stats enable", "stats realm", "stats scope", "stats uri"
] N: W6 @, ?% l: V7 U: P) S: h9 v' S6 P/ p, C5 `2 y4 m
: a( `4 I4 S ]: m( Z5 R8 hstats enable9 E% { e7 ~6 y" `* g2 \# V9 o
Enable statistics reporting with default settings7 H! O8 t7 F! A
May be used in sections : defaults | frontend | listen | backend
v( V; ~6 W; s: Z. x7 m+ J yes | no | yes | yes
- K- v! S) ]# h7 X. O Arguments : none, w+ r; s g" H, O$ F, o; r
* k7 r; o1 S9 R8 B+ l
This statement enables statistics reporting with default settings defined
* R. n2 Z9 D# b& b at build time. Unless stated otherwise, these settings are used :
- ^' p* \# j6 |- w3 h; @/ c! S) L - stats uri : /haproxy?stats
# o0 o* H+ f% a7 C - stats realm : "HAProxy Statistics"/ T9 K- ]* A4 P" j0 z0 S5 w
- stats auth : no authentication1 f! Z8 ]2 }) A- P. D
- stats scope : no restriction
$ s8 }7 y" e2 H$ @ H N* n8 x, q/ u6 O: R+ D, Z
Though this statement alone is enough to enable statistics reporting, it is! F9 D7 n; x _0 _: q2 w. P5 n
recommended to set all other settings in order to avoid relying on default7 X& v( W. ~) _. O2 J5 d. Z
unobvious parameters.
4 I$ a8 b l' A' L
9 R6 e/ S+ q6 z7 }2 D& e8 Y& _. ` Example :
& ~, e' M* \9 ] m& A# T # public access (limited to this backend only)
6 j2 V0 G2 ~4 B; J% D! X( V backend public_www
* Q. M0 z% X7 O1 M8 z" b7 _# u server srv1 192.168.0.1:80
2 J3 x/ T9 @6 H8 _ stats enable) b2 K" y5 U* G5 n
stats hide-version
+ o7 K4 l" A6 |; c5 E5 ^ stats scope .: ^4 p* J# n' C. a
stats uri /admin?stats
1 @1 Y: E; S. J5 E8 N stats realm Haproxy\ Statistics, Z( u0 K9 D5 ]* C3 Z9 I5 J
stats auth admin1:AdMiN123# n, k/ j1 O& T- [0 @! W
stats auth admin2:AdMiN321
8 y8 c6 c* `5 ]
3 Y7 g" Q7 ~1 U# @& h # internal monitoring access (unlimited)0 [9 r% p# q. z/ R" s' L' |3 ~
backend private_monitoring
3 X) V: c; ^+ f stats enable
1 G( \! v5 _. x stats uri /admin?stats
8 h* `1 k A% A. j ]2 } stats refresh 5s2 X) N; ^2 Y; o
- L6 V2 G( k4 b
See also : "stats auth", "stats realm", "stats uri"! H/ a; E+ Y3 `2 P+ A. ?0 L% X6 o: J
9 h- r6 q& J( O7 h$ m U: H7 A3 l
0 v# v7 r L) h: } S" `( E
stats hide-version
3 ]" C/ E9 k9 `4 [0 P i Enable statistics and hide HAProxy version reporting
- H3 @1 b) _1 u. \) S May be used in sections : defaults | frontend | listen | backend
" E3 G$ Z; Q$ D+ a; j* c& \# _3 |" f yes | no | yes | yes0 Z, S$ y) r" U" H" Q0 S8 Y
Arguments : none
- M4 R( T$ G5 u* t' q9 h% K( `
, A/ Z0 t' d8 b2 f6 O By default, the stats page reports some useful status information along with
* \- U: ?6 s6 X! l* |- f4 G0 Y' L the statistics. Among them is HAProxy's version. However, it is generally5 f0 K$ ~$ ^9 V# R
considered dangerous to report precise version to anyone, as it can help them0 V: M. Z$ R* B7 E2 o, M) X
target known weaknesses with specific attacks. The "stats hide-version"
a9 n3 t: R7 A- r3 p statement removes the version from the statistics report. This is recommended
( T3 M, L5 ^. i: G a; @ for public sites or any site with a weak login/password.9 n) U) X" Z9 d" @1 n5 k7 B; d# h' z
- [+ I7 I' l; Q9 T& b Though this statement alone is enough to enable statistics reporting, it is
8 R- A* X, a6 l recommended to set all other settings in order to avoid relying on default
9 o/ s: J8 e$ M2 u7 Y% Y6 |: k$ Q unobvious parameters.
" f- Q4 J! `: m6 O, t* w8 u+ |7 m8 q2 p# P
Example :
, x5 W, k5 U! B6 E" l # public access (limited to this backend only)
/ R: {$ c7 |- F( {+ z backend public_www; {6 k% U3 y, W1 W i4 B
server srv1 192.168.0.1:80
- @! d( O7 H6 s M4 x stats enable; A# q) ]$ i3 b
stats hide-version$ a+ q$ P3 `: \: U2 G+ R2 i
stats scope .
& B, z6 J9 C* G8 D stats uri /admin?stats* O* w) C5 C p
stats realm Haproxy\ Statistics
+ X( C- I) }: K" X% W+ I stats auth admin1:AdMiN1238 ?8 [, B+ L# h) u) V$ m! g3 O, o1 v
stats auth admin2:AdMiN321
0 c3 y7 D; q z8 ?
1 J" a- z% M" o) T3 k% [ # internal monitoring access (unlimited)) o# N* j/ B0 K: b# L- Y8 `
backend private_monitoring/ Q* `5 o0 s; G9 o( n: Y
stats enable8 x$ [: O% m: a" X8 A4 L
stats uri /admin?stats! L' G8 q- ?. o( [
stats refresh 5s
; a% u4 Q- }# q
- E+ V0 D8 \/ b, N See also : "stats auth", "stats enable", "stats realm", "stats uri"
% x' R% t. y' b. ~. m- T3 a" q0 _7 ~( X$ n
! _; j2 C' S% [; ^
stats http-request { allow | deny | auth [realm <realm>] }
5 Z+ _# Y/ ?: `3 ]3 \ [ { if | unless } <condition> ]
8 L4 b `! |; Y9 a! R0 n Access control for statistics& q- b0 N( A4 D& \( M: B
7 z/ k2 x9 g9 f4 \ ` May be used in sections: defaults | frontend | listen | backend
# V9 C1 a4 w& g& w8 g. B no | no | yes | yes# B$ r( C. y2 e
- A/ K# x* w% k7 c/ i As "http-request", these set of options allow to fine control access to
& X' A3 Q) w+ o" H5 ?& |/ ^- t statistics. Each option may be followed by if/unless and acl. E d \1 x" j/ A4 i; a# \! X/ T
First option with matched condition (or option without condition) is final.8 i' D- f! w) t2 P$ _8 a- O6 ?
For "deny" a 403 error will be returned, for "allow" normal processing is
9 Y4 P( u8 O, a$ G" ^) [* E5 a performed, for "auth" a 401/407 error code is returned so the client
7 ~- O# \/ T+ K. k' @ should be asked to enter a username and password.
7 I/ x! v) ]( ^5 F% i
/ ?( d: M4 X9 O+ G3 ? There is no fixed limit to the number of http-request statements per9 D6 C* x( M' r }3 W, v; T/ |+ v
instance.* y7 d9 B h+ n8 `+ Z7 e
+ H [6 {8 R, t# x See also : "http-request", section 3.4 about userlists and section 7" p6 U+ E5 j2 U: w& E/ L4 {/ X
about ACL usage.
8 P: Z! g' p3 i0 [+ C
0 k+ \% N/ c- H/ F
5 y* a: W; X5 @, k# Z4 s6 d! Estats realm <realm>
0 \" a: ~( _, f3 h. B" _) R# H, H+ l/ _ Enable statistics and set authentication realm
/ f* C) X$ T7 D& ^" r May be used in sections : defaults | frontend | listen | backend- ^, ^: c' P5 G s) U
yes | no | yes | yes3 Q5 D9 h; ?- F7 t1 f
Arguments :0 k6 `) d+ l( t6 ?1 P0 h
<realm> is the name of the HTTP Basic Authentication realm reported to( L [: V2 u1 _ v2 }2 g# o
the browser. The browser uses it to display it in the pop-up3 g( H$ s# J$ y# g. l" s) ]
inviting the user to enter a valid username and password.
9 v1 R' ^1 s Y
7 Z6 W/ E; m0 l. Y5 `5 o- {' S The realm is read as a single word, so any spaces in it should be escaped
! y; e7 q; r" S5 d3 z using a backslash ('\').
. }* r& H1 H$ R9 B+ G2 d q, f1 l1 z
This statement is useful only in conjunction with "stats auth" since it is
/ [: I3 B6 u; W6 z, V2 B. R/ @9 l only related to authentication.
* D# ^3 A5 d' _( A
- h8 N6 G1 l2 G( o0 z0 x4 o Though this statement alone is enough to enable statistics reporting, it is
5 S3 @, `/ P* f+ Q+ F# t4 i recommended to set all other settings in order to avoid relying on default) n( F6 E3 P$ o" h) ~
unobvious parameters.
: Y9 P {( X/ v
; S3 D: X" A4 s9 o Example :
: g6 O. `4 {( K1 e6 W # public access (limited to this backend only)
/ N8 U! @6 H1 A4 P backend public_www
4 J% O% C& ~0 D% y5 Q6 Q& ~ server srv1 192.168.0.1:80
$ w; F5 s# a* M1 }' N( ] stats enable/ ]: N- V9 m1 u2 K' T
stats hide-version
/ o0 f3 B: Q9 ]% f- S stats scope .% w, J8 t& k' I+ j2 L
stats uri /admin?stats4 ^' t' n) N7 j5 X
stats realm Haproxy\ Statistics. v& L" ?/ E6 M% _) X6 H1 ^
stats auth admin1:AdMiN123% Q5 O' K' U! O$ m! N
stats auth admin2:AdMiN321- o+ Z- r8 k0 b
* U f+ o }4 R. n4 R v # internal monitoring access (unlimited)( L/ G' B; M0 n+ O* q
backend private_monitoring
% E1 t- k {6 X6 c! c$ T% s stats enable# Q; ^% j% Y1 z. b! O
stats uri /admin?stats! Q( K4 o$ Q9 ]2 N
stats refresh 5s T8 n9 ?! k2 |* t
1 ~8 D _- B+ b
See also : "stats auth", "stats enable", "stats uri"; i# D7 G/ j9 F) J& Y8 v4 l$ R
0 L. ]" K7 P( ?
( G# v# o4 R0 q. }# J) r1 Lstats refresh <delay>( ?. k" ]9 x2 s7 F g
Enable statistics with automatic refresh$ b# Z8 d! a5 P5 K f
May be used in sections : defaults | frontend | listen | backend
5 ~3 Z0 _+ w8 c6 I& @& K2 N yes | no | yes | yes. [) H J n6 Q* W3 X; f# g# ?! l
Arguments :9 x0 S+ ^8 H* k P/ G' B$ s
<delay> is the suggested refresh delay, specified in seconds, which will; _0 ^# g! t+ ^8 e. d) s
be returned to the browser consulting the report page. While the
; h) Z8 B$ P2 Z7 \; R browser is free to apply any delay, it will generally respect it, }6 h1 F# B6 ~' N' o* P
and refresh the page this every seconds. The refresh interval may K7 d; r( ?. w. T8 H
be specified in any other non-default time unit, by suffixing the* ^4 b- }& ?! x+ o! c3 q
unit after the value, as explained at the top of this document.9 k$ C( u3 w g3 B$ A7 |
8 k) T4 P4 x2 ?$ Q- T* J
This statement is useful on monitoring displays with a permanent page$ s t" }1 P! o* ^7 X0 Z
reporting the load balancer's activity. When set, the HTML report page will
: P# V0 Q" O! Y, ^5 {" [ include a link "refresh"/"stop refresh" so that the user can select whether
1 j6 X. h: J0 w! `. T8 O% w A he wants automatic refresh of the page or not.) }7 Y( D" q8 R8 |" j9 c4 W8 n
2 n$ i$ k& Y8 K0 @, j4 n3 J8 P9 c
Though this statement alone is enough to enable statistics reporting, it is
( Z6 r7 v M" i7 N7 ` recommended to set all other settings in order to avoid relying on default0 V& o4 ~7 x" s/ w4 T3 K
unobvious parameters.
' A8 ~; s9 N% W' `; R0 s' M% {) Q- V/ K
Example :
3 ~ f- B0 P) V6 K+ p# J # public access (limited to this backend only)6 m0 N; y: ]& T4 g9 A2 j1 l
backend public_www9 [; y e3 ?* k
server srv1 192.168.0.1:80' d9 k0 | X+ f W. S7 m; w) h% ^
stats enable( c0 B& K; B$ n7 ?% q% y
stats hide-version
: c. T3 L9 E% o stats scope .
1 s! v* T- [5 w; P# [) W: M stats uri /admin?stats
4 q) I6 M+ j/ x stats realm Haproxy\ Statistics- m3 }, Y. z6 ^( Q
stats auth admin1:AdMiN123' G7 n& J( l3 s- S6 \/ x( S
stats auth admin2:AdMiN3215 `9 I7 f: l4 a6 N
3 `4 G7 l9 U4 Y3 S
# internal monitoring access (unlimited)
6 Z5 I' o0 r3 q6 R0 Q backend private_monitoring. s) s6 _4 l% B7 t; n
stats enable
! ?' [9 G/ f( x" M1 y' E stats uri /admin?stats
8 }! ]- @9 l# c! M, Z stats refresh 5s
7 Z3 V9 `/ X8 r# {( e; b$ l8 x$ m |$ h, P, P$ Y( J2 X. j
See also : "stats auth", "stats enable", "stats realm", "stats uri"
, u2 I9 h" a; {: O2 z* Z# c
) v5 D* e, i( F! |; o) Q# R$ @% D
- E! M0 `& i3 [1 ~3 g6 ?stats scope { <name> | "." }
6 T, P) d) B$ {6 m9 k' o Enable statistics and limit access scope1 N- A8 p9 V% P3 R( T2 {% E! @) j0 K
May be used in sections : defaults | frontend | listen | backend. q5 X& I8 k: n3 s" P# l1 F3 \
yes | no | yes | yes0 \3 a( [9 B5 R$ J9 I9 n& ?
Arguments :
* _: L* h. g! y2 q. k, A8 f <name> is the name of a listen, frontend or backend section to be
: f# n7 Z7 g' V5 T reported. The special name "." (a single dot) designates the
& k- `; T& b% l( B$ y section in which the statement appears.0 G* I( F D0 M) X% Y R$ O- k; c+ _
w! \% m; D# Y4 `% _( |- v2 {
When this statement is specified, only the sections enumerated with this
2 @) t; y q. h& `" m; e3 @. R statement will appear in the report. All other ones will be hidden. This4 w, T2 n9 O0 X# ?" h
statement may appear as many times as needed if multiple sections need to be
+ y: W; X2 X2 i% J1 u reported. Please note that the name checking is performed as simple string8 X8 m4 f" p' ~' a
comparisons, and that it is never checked that a give section name really- |4 \ r5 z) k' f
exists.
+ v# f; c7 x* c4 {$ Q( ^
# E' M7 u5 y/ O" v$ q7 I Though this statement alone is enough to enable statistics reporting, it is
0 z! a8 c j) A' v! `. ` recommended to set all other settings in order to avoid relying on default
% f4 V o, O! \+ b' K8 S, t# n unobvious parameters.8 b( v5 _6 j7 [3 _1 T+ _
2 n8 A* Q+ g I* T- H Example :. u. F5 |' _1 p
# public access (limited to this backend only)
& _! c# u# i {+ B2 \) K/ W1 ^ backend public_www
; d- @9 `; R4 C: | ^* N server srv1 192.168.0.1:80
0 W0 y6 U3 ?' z/ k stats enable
& ?( p! X; d3 h2 [8 N3 ]/ g2 n4 |+ g stats hide-version
6 p& c, k2 O" F- I stats scope .* j" Y# I. Q$ m: r% |5 x
stats uri /admin?stats1 x' Y3 x* u- b$ T- i9 [! i
stats realm Haproxy\ Statistics
6 {! m) f, ?* [, m& C, H2 u3 h$ B stats auth admin1:AdMiN123
0 u6 b; M3 y: X( `9 | stats auth admin2:AdMiN321
! X" R# J5 u2 L' h$ X' A& ~0 H0 s+ \/ F# r9 a
# internal monitoring access (unlimited)
9 l8 S% w( N0 i z; E: R backend private_monitoring% U$ k& i8 B8 |1 n5 D* u4 T0 x, U
stats enable
& j9 _4 [+ y. v& _, i+ v stats uri /admin?stats
/ Z# ?+ S* U% t( U5 m stats refresh 5s
0 j6 t% {! c/ Z: y9 U
6 K$ I3 h C8 R' R* c See also : "stats auth", "stats enable", "stats realm", "stats uri"; W6 n# O" Z* d. _
8 A! |4 ~0 L' a5 ~$ Y, Z
9 Z$ A9 k/ z" C. J6 z
stats show-desc [ <description> ]
! K: D/ |6 Z+ Y- r Enable reporting of a description on the statistics page.) R: e7 b3 k7 n) h2 N
May be used in sections : defaults | frontend | listen | backend
1 k+ V$ k r6 Y) T1 m yes | no | yes | yes
5 z6 S! ?. L+ w! U* ?0 }" }4 Y5 A& `6 C, ?
<name> is an optional description to be reported. If unspecified, the: \: x; ? ?3 u# B) |
description from global section is automatically used instead.
+ ~9 J8 S1 y7 a# j: z0 E$ [9 F$ }1 @7 R
This statement is useful for users that offer shared services to their, _, Q% F7 T" X- d. B4 C. j
customers, where node or description should be different for each customer.. ^ x# v) y2 B8 T& l2 t' d. h( N
' x+ h7 e$ `% B/ e; p9 \8 h) ~
Though this statement alone is enough to enable statistics reporting, it is
; Z" H0 h) x, Z* b0 z: j- U i+ s& i7 O recommended to set all other settings in order to avoid relying on default
( \" H2 A) b# j9 \9 H unobvious parameters. By default description is not shown." D7 b5 |7 A. i2 X, S
7 [( R( x6 b+ @0 o Example :
+ C3 @/ V6 A+ k) s" q # internal monitoring access (unlimited), [7 i5 ^' G6 i" q7 ?& ]; {
backend private_monitoring
8 L6 B) K8 J# t( }. B0 G I; V# \6 H stats enable
, Q$ v$ Y% M4 N+ \/ y4 t; ` stats show-desc Master node for Europe, Asia, Africa
5 a% m, ?6 T, U0 P) v stats uri /admin?stats
# k3 M/ c- P# t4 q9 z9 S- w stats refresh 5s
9 T; y( q# c: ^# {0 e0 J: T8 X" z! r/ ?: c: B
See also: "show-node", "stats enable", "stats uri" and "description" in
& ]6 r: x2 h7 @/ ] global section.2 m b8 o* E, S2 ^
& H+ l" q& }* w9 Y+ | |
* Q2 Q9 l7 d; c. M" bstats show-legends8 H5 A: e$ F! m% z) b, z1 V
Enable reporting additional informations on the statistics page :
- |% _3 R. e) A. @5 r# m- t6 \ - cap: capabilities (proxy)
) T* w! D# W+ r - mode: one of tcp, http or health (proxy)
# I" D# b* h* ?8 j1 Y4 P - id: SNMP ID (proxy, socket, server)
1 I6 z& B! }8 g' \ - IP (socket, server)
, a" T1 P0 n+ f0 V+ H! n8 O - cookie (backend, server)0 l2 i" d" I- d' A
! k0 G8 N/ w! o, z3 D" X6 ? Though this statement alone is enough to enable statistics reporting, it is
5 ~: d3 M* x( H7 ?: W* U* p recommended to set all other settings in order to avoid relying on default
- b, O- u' }" e unobvious parameters. Default behaviour is not to show this information.$ c2 V0 O# n0 [7 Y
0 K$ L. |6 I: S9 f
See also: "stats enable", "stats uri"., G! K/ e7 ^1 E' ~) @8 q" `
( N7 p; o6 @7 x# H- Z0 v
! g3 Z% b1 `9 `, q- k, istats show-node [ <name> ]& k# T" J" r. }- ]! S
Enable reporting of a host name on the statistics page.3 e- p# V% u1 h: U
May be used in sections : defaults | frontend | listen | backend* P% y9 |% o; ^' n$ w( N$ {7 U6 M
yes | no | yes | yes* u. ?/ \. s7 ]3 u9 y
Arguments:
y8 y8 n" e+ l* C$ c+ \3 U' n <name> is an optional name to be reported. If unspecified, the
; P3 r" _: A; u/ D2 s; f' l node name from global section is automatically used instead.
( ~+ ?" z7 t. \5 _- G! n: k- |9 ]1 T, L* M' x
This statement is useful for users that offer shared services to their' g6 r. p! }9 s' x; ]
customers, where node or description might be different on a stats page9 [7 t7 H) ?4 Y, k: J( l
provided for each customer. Default behaviour is not to show host name.5 T% D+ J1 |( `5 x' n
! m! `+ l, q2 C+ r Though this statement alone is enough to enable statistics reporting, it is+ J# p# H; R$ I: l& b
recommended to set all other settings in order to avoid relying on default
. u/ p! M8 O2 b. z8 x unobvious parameters.
( m6 C! |- X1 b$ w! S3 R& d) w' X* V q( T; @
Example:1 T% n# u1 L% q/ I4 }) ~1 X
# internal monitoring access (unlimited)! W5 @" [" G4 d- S/ D
backend private_monitoring7 R! L- [# \& M/ p; \# t% e( l: i
stats enable# F2 {7 G* D& I7 T& t+ v
stats show-node Europe-1! n- q; k/ B+ V# O$ W
stats uri /admin?stats" C! q* t; c6 V6 K( m
stats refresh 5s
# U) {2 c+ |. c# b0 ~4 A" s& M6 m0 I
See also: "show-desc", "stats enable", "stats uri", and "node" in global
( x; i5 M0 a. j7 T4 u5 z7 E section.+ c+ t, p# Z ~, b$ G, t3 |2 C
! p K+ J4 u' {5 v( S- b: A: I1 o" Y5 O* s7 t- r/ Y
stats uri <prefix>
8 o5 h3 i0 X* W+ k* J Enable statistics and define the URI prefix to access them3 ]) A2 `" V* i# C9 d
May be used in sections : defaults | frontend | listen | backend
5 E' E6 V( O/ {1 N9 U* O+ T! z( g yes | no | yes | yes
1 h( h0 v8 R) }2 g. B7 ^" `- R Arguments :0 y! C2 f- E, `6 K, m
<prefix> is the prefix of any URI which will be redirected to stats. This
" O2 w6 ^1 T% [! p. [- M prefix may contain a question mark ('?') to indicate part of a, L2 Y9 f; n8 f8 o+ z
query string.
0 h. u' D5 J# J! u( T; ~0 ^/ m/ \2 M8 V/ p# E, B# U
The statistics URI is intercepted on the relayed traffic, so it appears as a
8 `+ P# E5 x- Y page within the normal application. It is strongly advised to ensure that the
, T9 d+ x, k2 x selected URI will never appear in the application, otherwise it will never be
: N% b0 p9 T! H+ K- t4 o possible to reach it in the application.! Y! ?4 @2 L/ B1 _% Z0 Z4 Y+ F
( z$ T2 R; H8 H3 p
The default URI compiled in haproxy is "/haproxy?stats", but this may be" n- ~9 E8 @' X9 O' c3 L
changed at build time, so it's better to always explicitly specify it here.7 o: |0 ?! m) R3 M. S- e- j6 K
It is generally a good idea to include a question mark in the URI so that
, Y! A* c! G( g% B n intermediate proxies refrain from caching the results. Also, since any string
& g) A7 ^0 n9 x3 c7 b2 e* h beginning with the prefix will be accepted as a stats request, the question
( t2 z' F2 }& U0 I" P mark helps ensuring that no valid URI will begin with the same words.
; q: z+ s% i, ?) s# `% U/ [
" V' u7 \" i, Y% }1 P It is sometimes very convenient to use "/" as the URI prefix, and put that
/ v8 z- d9 E: t; U) v4 d statement in a "listen" instance of its own. That makes it easy to dedicate
. {1 L7 H/ i4 I: x an address or a port to statistics only.+ e2 k b4 y4 ?* G3 r& @0 [. h" ]
9 G7 a8 j5 b& m7 x9 x
Though this statement alone is enough to enable statistics reporting, it is
# w: w! o' M' j* |8 J" ] recommended to set all other settings in order to avoid relying on default
; Y, \. z! ]5 p ^: w7 i unobvious parameters.
9 J7 m# f& v# V: Q* {2 |& Y4 y3 `* ?; @' B4 @
Example :
6 z8 O2 w+ o' t7 G* O& C" H # public access (limited to this backend only)
& t6 V' ]# b7 U0 i backend public_www
. l) t H! L" x: ?* v _% x server srv1 192.168.0.1:80( R/ }9 w8 K9 {/ ?& p5 V8 I
stats enable6 j# ~# }! U H' S; G. y) J7 m
stats hide-version0 G. b+ C, D) V( _7 Z: s: t+ l
stats scope .
% J h4 O6 x e: C stats uri /admin?stats$ z1 G& {6 |* @$ x) c1 i$ l
stats realm Haproxy\ Statistics: f$ F9 T' l4 x# c3 Q/ x9 {
stats auth admin1:AdMiN123
- k, M* r3 |; w stats auth admin2:AdMiN321
, C/ f b/ U6 M; V: x" B% p- L7 `( s& ?# T t) w' o
# internal monitoring access (unlimited)+ }1 [4 u5 A3 R! _+ L3 ^
backend private_monitoring: J: l- Q, i! }% L+ D3 I' A
stats enable3 H! u8 E1 V K4 J1 E
stats uri /admin?stats. d' f& m! ~& F( K! I* Q L
stats refresh 5s* x- a! a! y! M6 h6 N$ u
- K( m* t0 l+ X7 c- G7 N See also : "stats auth", "stats enable", "stats realm"1 y) d( s) @; Q4 p# U% }
% N+ k0 `; W7 t( ?) m2 |* D
: ?4 `+ K9 U% hstick match <pattern> [table <table>] [{if | unless} <cond>]
9 F( J& N: O: W" z Define a request pattern matching condition to stick a user to a server
2 `. d2 k2 I; c F% [1 c+ ? May be used in sections : defaults | frontend | listen | backend) l! I9 f6 g# z+ [8 L( ^. r6 Z
no | no | yes | yes
6 N7 h- S) J. n+ V7 y A4 l4 k
- A% I! S' M9 s% D: w3 k K Arguments :
: O' \* X! [6 }/ r. Q" X" e* k6 A <pattern> is a pattern extraction rule as described in section 7.8. It
0 k8 W7 d1 A5 `1 \' u4 H describes what elements of the incoming request or connection
- R: B- m! [+ V! S: d4 g will be analysed in the hope to find a matching entry in a
/ r% k2 F0 O! B6 @2 g stickiness table. This rule is mandatory., t+ O& O5 N9 f4 P3 `
7 g6 R8 s& }% v0 O/ a, e4 W9 ?/ c <table> is an optional stickiness table name. If unspecified, the same; w! g1 G! y5 A* q/ }+ T2 I- C
backend's table is used. A stickiness table is declared using
g. J' ^" a7 r! _/ T the "stick-table" statement.
( u( X6 v* {1 ]' e8 b
8 |. u/ O$ K8 [ <cond> is an optional matching condition. It makes it possible to match
* w% r( a3 }2 ?; v9 W2 o on a certain criterion only when other conditions are met (or
& K7 s' t, }7 q2 e$ f not met). For instance, it could be used to match on a source IP
% u0 ^( f+ P7 R% ?1 }0 M) l address except when a request passes through a known proxy, in4 E: Y* b% ^' ~
which case we'd match on a header containing that IP address.2 S8 ?/ {: J# N! ~) ~+ t
6 r) h7 K/ H# L/ E4 ]
Some protocols or applications require complex stickiness rules and cannot- D" M- J; f: Z8 _- B' E+ j; V7 A( n
always simply rely on cookies nor hashing. The "stick match" statement* x2 `3 |7 F# j% l, u/ D
describes a rule to extract the stickiness criterion from an incoming request
J- p P9 a9 c5 x+ U or connection. See section 7 for a complete list of possible patterns and
3 c4 r( m- B. ], n( r# r6 e9 ^ transformation rules./ O* A9 Q! j! R5 p/ W
2 N( q/ Z. o7 s* ] The table has to be declared using the "stick-table" statement. It must be of
J7 o% @+ D2 l, n# k5 C) ]* [ a type compatible with the pattern. By default it is the one which is present) q0 H; @+ g, `/ W$ G g
in the same backend. It is possible to share a table with other backends by5 q% h' ]4 d7 g5 K
referencing it using the "table" keyword. If another table is referenced,
0 k/ U8 C9 k1 Q( n! G0 J* C the server's ID inside the backends are used. By default, all server IDs
% v5 G! d% c% x' p* g* |9 C6 t# { start at 1 in each backend, so the server ordering is enough. But in case of. f( X( ~4 u6 S+ K( O1 l
doubt, it is highly recommended to force server IDs using their "id" setting." c! w; M3 G F8 t$ T, ?" q. ?* I
* `+ W: V) t- X4 Y
It is possible to restrict the conditions where a "stick match" statement5 t: R# Q- f* f. P! m
will apply, using "if" or "unless" followed by a condition. See section 7 for
& R/ @$ B F' {8 D ACL based conditions.) m4 l4 E3 Q2 v
2 r& M3 _5 g7 ] There is no limit on the number of "stick match" statements. The first that$ N) Q; f( V( h9 T
applies and matches will cause the request to be directed to the same server
; v! b- o* M4 f7 a* d7 d' ~4 d as was used for the request which created the entry. That way, multiple# M. z& r8 S* x& C
matches can be used as fallbacks.
, g7 T6 C* U P+ A2 j
, G" Q4 n& G: C- R& r The stick rules are checked after the persistence cookies, so they will not) [& }2 G1 f* \2 r
affect stickiness if a cookie has already been used to select a server. That" O. M" e* L/ W# n& c
way, it becomes very easy to insert cookies and match on IP addresses in
& u7 c7 H. ~9 H" y: |& T9 w order to maintain stickiness between HTTP and HTTPS.+ X0 v) a* F# x
# k* S& ~' P. J! S Note : Consider not using this feature in multi-process mode (nbproc > 1)* U: I! r. H/ o
unless you know what you do : memory is not shared between the
/ [2 P# n4 u8 g( ?) }9 I processes, which can result in random behaviours." f1 |5 R. O7 \
7 B- D9 r1 S ^
Example :
: t/ j. v O, x1 Z# E# A # forward SMTP users to the same server they just used for POP in the B, u# x* v a" @" h
# last 30 minutes F2 g, W0 k* b; M) V. k% \! k h
backend pop: j, R1 J. b$ s5 N
mode tcp2 j3 k9 Y/ B2 G9 y0 c
balance roundrobin
- M2 }) F1 n7 p stick store-request src4 n4 |1 [! Z' S3 d5 g6 @
stick-table type ip size 200k expire 30m
4 v( S2 ^. V) B K" |( Q( g& u server s1 192.168.1.1:1106 I/ Y* c; E; L, M
server s2 192.168.1.1:110
& r5 p& w6 d% k$ O" \# w; N8 ?; G5 U" P, p
backend smtp r- a% \* g( {3 t7 i, q- t
mode tcp
& {# u! r" z+ ~+ z4 O balance roundrobin
" r1 h* |8 O) U2 T \ stick match src table pop
4 H2 X, A0 l/ {: M server s1 192.168.1.1:25
# b- F6 d6 P! ]+ ^( m) a server s2 192.168.1.1:25
# k( ~" e, }0 e7 d$ \+ _1 B) `
! {$ K: c$ N) x) ] See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7; r1 }" j& p: X- p
about ACLs and pattern extraction.( v" R( N) n! }" P0 n$ ]/ d
1 I8 K* M0 f+ V7 ~( ?# ^
4 p/ y A7 j! b+ `) B5 v) Zstick on <pattern> [table <table>] [{if | unless} <condition>]
+ Q4 E4 }" L f( ^ Define a request pattern to associate a user to a server; P. i* N6 N1 k4 L: w3 N
May be used in sections : defaults | frontend | listen | backend
/ t% y, \% R; n/ l; F6 w no | no | yes | yes
3 u1 X& a7 k+ r4 ] W# @& W
1 f4 W }. q% `7 f9 h M Note : This form is exactly equivalent to "stick match" followed by
9 u& ]$ Y( k2 v2 P "stick store-request", all with the same arguments. Please refer8 w# n0 [* H+ d( W# K" D% _, @
to both keywords for details. It is only provided as a convenience
% q, [ _' S$ ]+ p; [ for writing more maintainable configurations.3 l4 u2 I' F' S5 K$ c
+ I* o* Z2 a- V/ d3 R1 O
Note : Consider not using this feature in multi-process mode (nbproc > 1)
6 X% U* y2 {& f5 K! U' G unless you know what you do : memory is not shared between the
7 G! y6 a+ C M7 M1 \: m. [) B& z processes, which can result in random behaviours.
, {' Q ~5 ?6 }7 u' [; G& \
# D3 [- [% i2 U Examples :$ H: x+ Z7 Q; u: P2 M. S
# The following form ...9 U* i6 s2 O! C4 n( M. O- D
stick on src table pop if !localhost1 p+ ?/ U1 z5 a1 S
8 b! F5 q( }* t
# ...is strictly equivalent to this one :2 q- C* {3 A2 f' s! l
stick match src table pop if !localhost
1 f. I# ]+ d0 H, n stick store-request src table pop if !localhost
6 N( v$ G9 [% G
C: @2 T3 a8 T* o/ r( Q' C
7 a% V; l3 Z+ b: r9 B9 e ]- b/ f # Use cookie persistence for HTTP, and stick on source address for HTTPS as) j2 k/ @7 \# t+ P- G7 j& [% I' S
# well as HTTP without cookie. Share the same table between both accesses.
F4 @% V. ~/ e backend http/ L! A3 z6 D& q. {0 w
mode http2 k, C4 m1 m/ f, ~1 G
balance roundrobin. C/ E/ c: [6 Y& f7 a2 a
stick on src table https& M' v' t- W! w! M8 A' p9 q# f1 O0 g
cookie SRV insert indirect nocache
4 f. |5 A0 K+ b9 V+ @8 `( { server s1 192.168.1.1:80 cookie s1" o8 E: j# U X, f7 L
server s2 192.168.1.1:80 cookie s2
' k3 S7 I- f E2 {
8 A6 S7 f% O( M" Z backend https. r+ x+ j! I. Y
mode tcp& \8 s e- i0 _/ V4 r! E D' a3 j1 x
balance roundrobin7 E. I1 Z' p/ e5 f/ y9 Z
stick-table type ip size 200k expire 30m( Z8 e O$ V& |" ]. ?
stick on src
9 z4 P, g8 L3 w server s1 192.168.1.1:443
- B2 T# a6 ?6 \# ~0 g/ j server s2 192.168.1.1:443
$ V0 ^" o3 u( [
0 H4 P7 [% k$ @" [ See also : "stick match", "stick store-request", "nbproc" and "bind-process".
, ~1 h, z+ S2 R: b! c2 w6 u' h/ W H1 M" {6 q8 I" z
( a% D3 `3 I# U
stick store-request <pattern> [table <table>] [{if | unless} <condition>]2 V6 _3 e- T8 k! I. o' u
Define a request pattern used to create an entry in a stickiness table
2 Q' B- X( T( W- ~4 D+ Y May be used in sections : defaults | frontend | listen | backend
- a. v0 ] j! A0 @( ]* y$ R no | no | yes | yes
" I! `4 q) G: u0 [% j: q, K r7 B; [: F! K' y3 r( ~
Arguments :$ J b; E' I E8 p! B. J' ]" d
<pattern> is a pattern extraction rule as described in section 7.8. It5 E* g! l9 V0 r* N& W
describes what elements of the incoming request or connection
I: @: L8 U5 l, m: @1 I' o will be analysed, extracted and stored in the table once a/ u q+ C/ o8 Z
server is selected.4 y4 e; ?. w$ }/ f
7 M, n) J9 j$ P- k1 W
<table> is an optional stickiness table name. If unspecified, the same
% s) n/ @/ L3 v& P backend's table is used. A stickiness table is declared using1 k* R0 [. z n) p% M! \
the "stick-table" statement.) X1 x" y/ d9 x' {+ r7 _
1 P* ?( C4 [ ]1 U7 \: L <cond> is an optional storage condition. It makes it possible to store
; T# ^- C3 u: y5 n$ A# ~- W certain criteria only when some conditions are met (or not met).
* ^( n, ]9 U% R! a2 z For instance, it could be used to store the source IP address
+ x4 l. w% t* V! x except when the request passes through a known proxy, in which" Q$ T- Q9 M6 `- a2 t
case we'd store a converted form of a header containing that IP& n4 O/ I W5 `' ^# I) T9 j
address.
& [' W& T- u, `( C# T! `& r5 l# y' v( a' n' G
Some protocols or applications require complex stickiness rules and cannot- S2 L) A8 C+ N9 W: K1 p
always simply rely on cookies nor hashing. The "stick store-request" statement o5 j3 Q& d) [' u
describes a rule to decide what to extract from the request and when to do
, D( L; G& N2 q8 o* V$ {, ? it, in order to store it into a stickiness table for further requests to) T% F" j0 H, n4 k
match it using the "stick match" statement. Obviously the extracted part must, V& ~# j; R) N; J' j2 z
make sense and have a chance to be matched in a further request. Storing a
8 g5 p( ?' {# t0 s! k9 p client's IP address for instance often makes sense. Storing an ID found in a
! s0 c% H3 s2 U N* [4 r$ y URL parameter also makes sense. Storing a source port will almost never make) O7 q/ v7 s$ Q8 _
any sense because it will be randomly matched. See section 7 for a complete
0 N4 L* `, m0 E0 @1 z' c list of possible patterns and transformation rules.
9 o- j$ O! Q6 ~8 R" l3 g; Z* ~9 _
% |3 O/ h. i, s7 f( _ The table has to be declared using the "stick-table" statement. It must be of8 F, Z8 O) I* ]4 L5 C" O
a type compatible with the pattern. By default it is the one which is present
0 |; J v$ S+ N [$ x' Y in the same backend. It is possible to share a table with other backends by2 R- d; }8 C! j1 v) \ {0 K' d
referencing it using the "table" keyword. If another table is referenced,
Y/ X' j3 F0 v* d the server's ID inside the backends are used. By default, all server IDs
% u; V, e9 f* w$ g+ U8 S% I. ~+ Q start at 1 in each backend, so the server ordering is enough. But in case of
1 M$ f; {' ~$ |/ s( } doubt, it is highly recommended to force server IDs using their "id" setting.
+ @4 ?# B$ G6 x' X' N" ?* [" L& @. ]3 _1 Q; z! _
It is possible to restrict the conditions where a "stick store-request"
* E3 \: t3 {% z6 |- T7 V statement will apply, using "if" or "unless" followed by a condition. This
! \( ?& _; D% q7 n/ R& j" x; F- z condition will be evaluated while parsing the request, so any criteria can be. ]3 k2 o( X4 X& V m
used. See section 7 for ACL based conditions.
6 |* n. r& w: T. p' T
) t% Y/ Y! R$ j* m, H, ~, R There is no limit on the number of "stick store-request" statements, but3 u( E0 _5 v- ^# f( S
there is a limit of 8 simultaneous stores per request or response. This2 F1 y( ^, Y, W% B. k" ]
makes it possible to store up to 8 criteria, all extracted from either the
+ N% s! Q/ o5 P2 ~5 p. [ request or the response, regardless of the number of rules. Only the 8 first5 {6 X) h. F; }" y+ C5 B
ones which match will be kept. Using this, it is possible to feed multiple; C! i2 O& d/ N( f& E9 [& C7 I+ `
tables at once in the hope to increase the chance to recognize a user on9 g" v( f* L: w
another protocol or access method. Using multiple store-request rules with
$ Z7 ^8 l( t! q+ y7 \ the same table is possible and may be used to find the best criterion to rely p/ m& \+ G* w. \1 N0 ~
on, by arranging the rules by decreasing preference order. Only the first
3 T& B% V9 L: Q4 E: t extracted criterion for a given table will be stored. All subsequent store-
$ l# S- ~, g. J request rules referencing the same table will be skipped and their ACLs will
1 J4 D8 i9 g% ~5 W+ u1 s3 r not be evaluated.
5 k% B" r. N3 ~7 w
4 J j$ i$ a/ H- {1 J2 ~4 J The "store-request" rules are evaluated once the server connection has been
3 T/ Q' k& u( ~9 e+ Z" M/ k3 W8 v; X established, so that the table will contain the real server that processed
* s! i: e( Z6 f d R0 m the request.
6 x) `3 m% J& B& f+ V6 B' u. X4 w/ b2 _( [- u2 q1 S! s9 M
Note : Consider not using this feature in multi-process mode (nbproc > 1)7 w) ~6 }4 z# t8 ^8 G* j
unless you know what you do : memory is not shared between the9 y h2 D; i6 q2 R5 L5 A7 {1 a
processes, which can result in random behaviours.
9 y+ A& v0 @/ l( M5 K/ {" `4 z
! F9 I1 ]; g( J* t Example :
; \' N1 j4 }( L' w: V; G # forward SMTP users to the same server they just used for POP in the2 {" _- [. F5 [/ P, x3 F: P/ ?0 L
# last 30 minutes
4 J: Q0 `! F( s7 F% a( v7 n. j backend pop
" p$ X# N3 S p7 |" N' Y* w+ F mode tcp& X+ X8 o1 `8 J9 n
balance roundrobin
9 c0 |8 @1 \6 `* \1 m( R! f7 Q stick store-request src" D$ I3 ^7 t" W3 l# W0 L
stick-table type ip size 200k expire 30m
+ u& @0 G- O8 a% b9 {9 t7 X server s1 192.168.1.1:110
l4 y \% \$ ]$ p! I server s2 192.168.1.1:110' O: X# }: X9 J; y
8 V+ L7 G. |8 H& L. z: J+ W
backend smtp \8 o5 X9 Z9 K6 `5 g( [
mode tcp0 p, M1 M/ p8 b) A; n
balance roundrobin
4 ~* m# | M7 D6 x/ N stick match src table pop
7 K1 q" \2 X Q) k; N server s1 192.168.1.1:252 c, G+ ]* Z; k9 ?$ \
server s2 192.168.1.1:25+ e: P( A. |: d* I! Q
. z: |& Y3 s" n, B Y- v/ r See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
1 X5 p$ A) C( |' F9 B8 D about ACLs and pattern extraction.- Q+ b2 {+ s6 W' n( c* j* M
$ ]( I7 N8 k. U# Y+ L9 V; I) u9 Z' e, I9 m; A6 j. F
stick-table type {ip | integer | string [len <length>] } size <size>6 C, p/ J- Z, [; N/ r/ ^
[expire <expire>] [nopurge]% B/ l, a6 g4 p/ T: ^
Configure the stickiness table for the current backend
+ u \7 r9 n3 f# V, t, g8 {, g May be used in sections : defaults | frontend | listen | backend6 h) W% g$ p h. M+ }+ S5 P3 D
no | no | yes | yes
9 @. w" X/ Y1 Z1 Z, X; }5 i4 s
* a/ D9 `3 u% F# E0 Z+ \' _9 s Arguments :( [3 s% W% A3 W+ {7 S1 g
ip a table declared with "type ip" will only store IPv4 addresses.8 {) \- m2 v! M8 I9 ^6 `) }/ m; _
This form is very compact (about 50 bytes per entry) and allows& n$ d" P/ }+ i& r7 H3 M
very fast entry lookup and stores with almost no overhead. This
. J; z( o$ m, a; i7 p5 P- ^ is mainly used to store client source IP addresses.
0 A6 x P! g- H& ^- L; r% ^! Z5 [! T, s$ V9 h; d& q
integer a table declared with "type integer" will store 32bit integers* s3 T0 T$ Y9 ~% b1 S( U
which can represent a client identifier found in a request for
/ M; k$ A2 `( B) Y. ^ instance.
0 r; K* L& [; V% |: |
. g S# R: m5 W5 [1 ^+ P string a table declared with "type string" will store substrings of up
, h; H, X% y4 u3 a to <len> characters. If the string provided by the pattern, z1 c0 Q' ?# r. v7 W/ O! ]9 C2 g$ f
extractor is larger than <len>, it will be truncated before& W2 r7 f* q. e% w
being stored. During matching, at most <len> characters will be' y( w& c& K- d+ N* q
compared between the string in the table and the extracted
, y& B: R4 u" r+ h, d4 ^ pattern. When not specified, the string is automatically limited
m' c! ^9 g* {/ y4 [0 k" L to 31 characters.
. d" c1 n4 x/ k1 ?9 ]2 }1 \* e* C0 |4 ?
<length> is the maximum number of characters that will be stored in a
# ] @+ f- Q2 h# k' Y( `# Z "string" type table. See type "string" above. Be careful when3 ]2 E: W" v$ x
changing this parameter as memory usage will proportionally/ r' E1 Q; Z8 m: D. {: a
increase.
: w6 H* @: j5 h1 C# _2 _* T$ X
( Q0 W, I C& e8 d; Q4 [ <size> is the maximum number of entries that can fit in the table. This" j0 f& o B( v4 x H. ?! u
value directly impacts memory usage. Count approximately
0 V3 D5 m: B4 Y" m y 50 bytes per entry, plus the size of a string if any. The size# \; U1 i, ~" N$ @: ]) m9 E; m
supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
8 Z% h4 d& q4 l0 j% J7 j; n+ r, i2 y- I7 E% }( p" T6 r: N
[nopurge] indicates that we refuse to purge older entries when the table
8 G4 |- [2 |& \+ ] is full. When not specified and the table is full when haproxy+ {6 ]3 U0 O. I6 p F. m
wants to store an entry in it, it will flush a few of the oldest
; p/ u% f' @. C; Q% }" R( ~. Z entries in order to release some space for the new ones. This is
. Z5 { N. q7 u3 z) b most often the desired behaviour. In some specific cases, it
( J1 F$ H4 { [% ^ be desirable to refuse new entries instead of purging the older
9 F# z; ~! B% W! t ones. That may be the case when the amount of data to store is
' c- M5 h8 c$ O far above the hardware limits and we prefer not to offer access. t3 w" z s% f: w
to new clients than to reject the ones already connected. When
5 G8 v; D( ?3 v using this parameter, be sure to properly set the "expire"
% B4 {; _7 p) @+ s# u6 x, S parameter (see below).4 L$ Y, p& A7 ^) d% a9 F
P9 G8 E* J8 S
<expire> defines the maximum duration of an entry in the table since it/ |. E* W, M% p4 g
was last created, refreshed or matched. The expiration delay is: a! q$ |. R" s, Y3 I* q7 }* L2 J
defined using the standard time format, similarly as the various
2 f9 ?& m3 f# [5 X/ T timeouts. The maximum duration is slightly above 24 days. See g, p6 B. X, z% ~) z5 X
section 2.2 for more information. If this delay is not specified,
0 {& S; {; ~1 ^ the session won't automatically expire, but older entries will% W! ~5 U% g y( `
be removed once full. Be sure not to use the "nopurge" parameter4 @) _, @: y0 f
if not expiration delay is specified.
! L3 [" @8 v8 O7 e1 h1 ~ k7 f W* F: t' S* o
The is only one stick-table per backend. At the moment of writing this doc,
5 U8 ~, c1 I& n. }! x5 Y/ {/ Y/ z it does not seem useful to have multiple tables per backend. If this happens
5 M/ t! K9 s$ t7 y* k/ k4 i9 k to be required, simply create a dummy backend with a stick-table in it and5 G3 O0 |6 G; g# W
reference it.
$ N( [* F0 j% e, y
* D. {% B; a7 d! _' ` r It is important to understand that stickiness based on learning information
8 R" v2 i; }* v. J. d has some limitations, including the fact that all learned associations are2 T" a+ k$ ^2 S3 R3 _8 L
lost upon restart. In general it can be good as a complement but not always
- C/ z7 {, j! q$ {, B) g. G' _" [% I as an exclusive stickiness.& r d- g7 e0 }1 C3 S
# P# U) l+ y6 B- t* N
See also : "stick match", "stick on", "stick store-request", and section 2.2
7 E- K3 D9 ]5 n3 n! T9 `" k; X. m( M about time format.
2 w8 b' w/ c6 ]- D" K
% l9 D0 f4 ^- q% Q3 d8 P. }0 A2 z+ C- K9 K# w
tcp-request content accept [{if | unless} <condition>]3 ?# b$ s4 ^2 g
Accept a connection if/unless a content inspection condition is matched: ~( w1 u% K' _5 c6 S. h
May be used in sections : defaults | frontend | listen | backend3 i7 e7 `) c' d8 z* v5 P8 [6 |
no | yes | yes | no
& P3 M0 h# u$ M
0 p" e. ?% e j: c4 o During TCP content inspection, the connection is immediately validated if the3 t, M$ I. O1 D2 q' ^) J
condition is true (when used with "if") or false (when used with "unless").- @) c% E: s' v3 t8 i
Most of the time during content inspection, a condition will be in an: Y8 ?8 v b/ Z# {0 R
uncertain state which is neither true nor false. The evaluation immediately
. j3 a2 ]. i3 K* M1 B( Y/ N stops when such a condition is encountered. It is important to understand! R% z9 N- u8 f, s
that "accept" and "reject" rules are evaluated in their exact declaration! T! t8 z1 W& s: W& q* t; @: i) ~% r
order, so that it is possible to build complex rules from them. There is no
, p/ {1 {, e8 Y4 b specific limit to the number of rules which may be inserted.; i+ i/ v) @3 r7 I
6 [: }2 P! F" S2 [+ s" J
Note that the "if/unless" condition is optional. If no condition is set on
, W7 k9 G- K. l R the action, it is simply performed unconditionally.
" O" |7 h8 T! p2 ^" w% b$ }0 O1 a3 @- n1 l4 v; b
If no "tcp-request content" rules are matched, the default action already is
( K" s" M" @( T8 B/ g8 t "accept". Thus, this statement alone does not bring anything without another& M+ ?8 a( K. [$ u- b
"reject" statement.! D9 i9 L, r9 V9 r, R: H
; B# N$ f8 x% ?! A
See section 7 about ACL usage.; w( [8 {" D; r. }) G8 U4 v
) A6 M" M/ o; W w/ ?% B
See also : "tcp-request content reject", "tcp-request inspect-delay"
+ R2 A3 z s- ]( G6 g: [. H7 \5 x: y9 D
& b* j. M5 x) y% ?9 e! x: ^
tcp-request content reject [{if | unless} <condition>]$ x5 [) _2 m6 G! S; n
Reject a connection if/unless a content inspection condition is matched3 l4 g! t* p1 \, b$ e3 q
May be used in sections : defaults | frontend | listen | backend
" \( V J1 i2 P no | yes | yes | no5 R3 I+ u3 f x# [# E" J+ i, J9 D
( K0 k& C5 {- u$ |0 a
During TCP content inspection, the connection is immediately rejected if the4 z8 q' W V/ K0 [# ]$ h
condition is true (when used with "if") or false (when used with "unless").! C- G7 p6 f7 J3 I: ?
Most of the time during content inspection, a condition will be in an
0 c" X) K8 H$ M& O& ^1 q' | uncertain state which is neither true nor false. The evaluation immediately# e3 `+ J: J: O) I0 u
stops when such a condition is encountered. It is important to understand1 A- _2 z) {, l3 _' a4 N
that "accept" and "reject" rules are evaluated in their exact declaration
: }/ \5 w. @( u J8 k order, so that it is possible to build complex rules from them. There is no
$ c' \ E: P, u specific limit to the number of rules which may be inserted.' M. [; E, n4 G; m: I* c1 r! q) Z
: i& Z6 T1 ]1 q% y ~$ n! @' O Note that the "if/unless" condition is optional. If no condition is set on
! i3 B9 D( c5 S" V7 K* ?% p& n the action, it is simply performed unconditionally.8 W( `! k' b: q$ j
4 D' F. Y) X0 `+ e5 U p+ P7 n If no "tcp-request content" rules are matched, the default action is set to
/ g# q+ v* x& ~; K" I3 \$ B "accept".2 \; S3 u9 w+ x# W0 t
- N0 y/ p5 X" U* I3 F8 _ Example:
|4 i/ M5 P. C ~) g6 m3 i # reject SMTP connection if client speaks first
' ?0 ^4 R) J" Z. b ^ tcp-request inspect-delay 30s7 h: {- i+ s. e r
acl content_present req_len gt 0- e/ k0 a& p3 o# G1 ~
tcp-request reject if content_present
' e1 g0 T: ?# S( [1 H* t' g6 s0 S3 ?. v8 c. S# x
# Forward HTTPS connection only if client speaks
: a% [$ d8 r( I/ E tcp-request inspect-delay 30s
2 m! f- w8 B: {7 \ acl content_present req_len gt 01 f/ S( r* V u7 |% Q
tcp-request accept if content_present: h% q+ ], ]! B+ P/ R7 c7 p
tcp-request reject& ^" a( ]) s, f# }
$ g- t! [3 }% Y2 C1 i
See section 7 about ACL usage.! }6 \0 W2 v3 M! N* r& Z8 ]
* e* [% e- @7 n4 `3 e2 |$ p
See also : "tcp-request content accept", "tcp-request inspect-delay": @$ P2 Q7 \2 |, N0 l" o
; U1 d( f5 f; J5 i, i8 F
m6 p8 M0 N" X5 x$ O q$ E2 itcp-request inspect-delay <timeout>1 F4 g+ C. P4 ?" y% }: v; X
Set the maximum allowed time to wait for data during content inspection K# }; B$ i0 c$ n; v6 S: Y
May be used in sections : defaults | frontend | listen | backend
2 N2 Y& _4 _4 Y0 n; Q. f4 h no | yes | yes | no) b& I1 |2 b. K8 I+ o' d
Arguments :
6 m9 `8 [* C& F9 }. f, a& l <timeout> is the timeout value specified in milliseconds by default, but% V' \$ u, f: Y( i% A, E9 R5 I$ h
can be in any other unit if the number is suffixed by the unit,
$ z# Y- h' e: ^ as explained at the top of this document.5 [9 D: m. @6 r( q1 k" c. ]8 C( V
/ n5 m* `- a" E) u# g# E People using haproxy primarily as a TCP relay are often worried about the
2 K$ ]7 s# v! c1 q5 w+ o2 L risk of passing any type of protocol to a server without any analysis. In
2 M8 t5 L% z' p! N5 t4 x! h order to be able to analyze the request contents, we must first withhold
/ O% X/ l v# f+ } the data then analyze them. This statement simply enables withholding of2 R X# X; ], j/ U5 q% L% f/ X
data for at most the specified amount of time.% u! _$ o9 z$ m& c5 Q2 y
7 ^) j: f# J$ t9 ^ E# k, Y
Note that when performing content inspection, haproxy will evaluate the whole) n# L$ \; N+ E# V( n z1 F
rules for every new chunk which gets in, taking into account the fact that& E+ z* s- u& O6 c" y4 H
those data are partial. If no rule matches before the aforementioned delay,! P- l1 D* X# E5 R8 E6 i" u
a last check is performed upon expiration, this time considering that the {+ ?1 X+ d6 j* Y; h+ T. A5 w* B; S
contents are definitive. If no delay is set, haproxy will not wait at all3 q2 x- ~3 `% m9 Z a0 D! q
and will immediately apply a verdict based on the available information.+ t/ G. c1 I3 {0 b1 _% X
Obviously this is unlikely to be very useful and might even be racy, so such3 o$ p4 {. |2 `6 g' S
setups are not recommended.( R; O& j8 h" Q9 c% O. e Z
$ Q7 H* V- i+ F* B( \ As soon as a rule matches, the request is released and continues as usual. If# C+ L& c" N, L- v9 x
the timeout is reached and no rule matches, the default policy will be to let
" Q! _1 F; o% A; e* | it pass through unaffected.$ g8 h$ {: F/ m
7 D8 N3 ~, `/ o) D1 b
For most protocols, it is enough to set it to a few seconds, as most clients
3 \1 H% O$ S( i# P- ^ send the full request immediately upon connection. Add 3 or more seconds to
5 M ?! \* [: W; w8 F5 X cover TCP retransmits but that's all. For some protocols, it may make sense
8 W# J4 [% M1 a to use large values, for instance to ensure that the client never talks
3 Y i' j4 a% T [5 T2 h% j8 q before the server (eg: SMTP), or to wait for a client to talk before passing, ?: r5 W% Z' o O1 A
data to the server (eg: SSL). Note that the client timeout must cover at
) O* y9 J" M; u- R# P' K, n least the inspection delay, otherwise it will expire first. If the client# w$ [$ t6 Z j! y1 `6 \+ N* Y/ U
closes the connection or if the buffer is full, the delay immediately expires+ H# r. I. V% x6 m
since the contents will not be able to change anymore.+ T- x4 E: `+ S. r& I- I
* @* D* a, _2 N4 \7 @5 E6 o) O3 G, \ See also : "tcp-request content accept", "tcp-request content reject",! g# N1 K/ G! c U3 S" n# J2 s
"timeout client".
6 c$ P. i9 u5 Y
" k5 f* N6 d$ s* ^
+ ?' f2 u* G8 i& ~timeout check <timeout>
) {( m! w; ^. ~- ?5 k Set additional check timeout, but only after a connection has been already( @' n0 [7 n% b' c& P
established.1 h; u ]% Q9 n
p: m& Q; V D: X, J$ E/ X3 q May be used in sections: defaults | frontend | listen | backend6 [& S: k2 [8 f; J8 u; U6 ^
yes | no | yes | yes& j% w6 ?3 j4 |7 P
Arguments:: C$ W$ B4 l: \6 D& c
<timeout> is the timeout value specified in milliseconds by default, but+ z' f0 [( U' U8 Q
can be in any other unit if the number is suffixed by the unit,
2 E" O: b# o/ j9 s$ a+ \* T6 d as explained at the top of this document./ D: f3 c \5 ^; ?6 j2 J9 v3 n
9 M4 a1 a% m# f+ L; j# u# E$ C+ a
If set, haproxy uses min("timeout connect", "inter") as a connect timeout
& g f8 V; e$ U8 k) K* G for check and "timeout check" as an additional read timeout. The "min" is# o) k7 `# D2 Q8 f3 o) n: i# Y
used so that people running with *very* long "timeout connect" (eg. those
: {4 x ?5 g5 T7 c who needed this due to the queue or tarpit) do not slow down their checks.
! G! K. J4 Z; g" G7 G, p (Please also note that there is no valid reason to have such long connect
0 {) c9 V" I" V m timeouts, because "timeout queue" and "timeout tarpit" can always be used to
3 y+ l5 a! A/ I7 ]- y4 f' L avoid that)., V2 ~3 n# Y6 E5 M
$ U9 j6 @* p! r8 T" | If "timeout check" is not set haproxy uses "inter" for complete check
4 i' P' |. m1 h5 @' H timeout (connect + read) exactly like all <1.3.15 version.& ]& c1 W% o1 Q9 S; E) ^) l
; H3 R1 l' g l+ _* h p) O In most cases check request is much simpler and faster to handle than normal
" g$ M @2 G8 R2 m requests and people may want to kick out laggy servers so this timeout should
: G& E( i7 y* q& }+ P) d# j! _ be smaller than "timeout server".
2 B+ j" t# {. w& L& ?+ W3 @: a# N8 r( U/ g" k# L
This parameter is specific to backends, but can be specified once for all in
$ }. }: n# o. K) o0 A, H7 T& N, [ "defaults" sections. This is in fact one of the easiest solutions not to
c; Q; @# s7 S8 ~$ K W9 J" k forget about it.
: w; F; ` @- F' y! g. k' E# r+ ?8 `1 I7 z$ ~
See also: "timeout connect", "timeout queue", "timeout server",
2 J' a' Z2 \6 l3 l" B; n9 I U "timeout tarpit".$ r; r n* H3 I- H
: o3 B. K. H7 {6 n2 _. g9 C" T' p; G
' C* u7 K; S/ q& z: S2 Ntimeout client <timeout>
8 m# F# u8 g8 C) ztimeout clitimeout <timeout> (deprecated)
5 ]# t! k3 }. Q2 t Set the maximum inactivity time on the client side." V; J" A& p( Z- F+ m
May be used in sections : defaults | frontend | listen | backend
' H6 w' g+ y$ U% P* ?. R0 A1 x yes | yes | yes | no
4 B$ M5 c) f$ ~5 ^ Arguments :' }1 ?6 ?% r2 [% h' M8 P. z
<timeout> is the timeout value specified in milliseconds by default, but: x! e$ I3 C( R; @+ k
can be in any other unit if the number is suffixed by the unit,
) i4 | }+ G8 y6 ~3 K: h as explained at the top of this document.' w4 \! G! Z1 x8 K% ^2 E
2 r& R+ Y$ k( j' y
The inactivity timeout applies when the client is expected to acknowledge or% n# ~; B' t1 O
send data. In HTTP mode, this timeout is particularly important to consider- q3 k6 y/ x4 R4 {* u7 l$ V
during the first phase, when the client sends the request, and during the( }! ~6 [; I" g2 m
response while it is reading data sent by the server. The value is specified
) j3 s" @9 I* Y3 @3 `' }- H; J in milliseconds by default, but can be in any other unit if the number is* k; [4 }2 m! P6 i/ ]' y
suffixed by the unit, as specified at the top of this document. In TCP mode
: B7 T* o& j0 k0 C3 Q$ I8 V1 J (and to a lesser extent, in HTTP mode), it is highly recommended that the' v0 E& W' n5 M, }
client timeout remains equal to the server timeout in order to avoid complex0 [6 B. n# l1 a* ^- D
situations to debug. It is a good practice to cover one or several TCP packet
9 c1 \4 T6 V$ B* I, T9 m losses by specifying timeouts that are slightly above multiples of 3 seconds) C" v0 P0 s8 F: V$ S+ t
(eg: 4 or 5 seconds).
% X$ p# M- [' m2 B$ G
# O9 z$ G0 x/ d! n/ I( h This parameter is specific to frontends, but can be specified once for all in3 Y. W t e: r4 ?# c+ Y+ a4 V+ E
"defaults" sections. This is in fact one of the easiest solutions not to
8 {1 T2 D5 z8 ~: Q' V) v forget about it. An unspecified timeout results in an infinite timeout, which7 u( N- u* a2 q. ^" n9 T
is not recommended. Such a usage is accepted and works but reports a warning/ ?3 _5 N; [: D2 \$ S C
during startup because it may results in accumulation of expired sessions in
, |2 |. [6 G$ ` the system if the system's timeouts are not configured either.
& t1 _$ u1 V0 u) r; y r& l$ p- w {( l6 `
This parameter replaces the old, deprecated "clitimeout". It is recommended
6 D) t. z8 q8 j# Y6 A4 J! T ` to use it to write new configurations. The form "timeout clitimeout" is
e( @& m6 R- e' O E( { provided only by backwards compatibility but its use is strongly discouraged.2 p. |. F& J. y5 P5 a7 k* H
4 c: Y! @9 M( p4 g) P See also : "clitimeout", "timeout server".% c: I3 Z3 r2 ]7 ^
d- B, m2 O8 G+ ~7 n( N" F7 w( c0 p& R) M5 M' r y9 R7 }' J
timeout connect <timeout>
& |) E+ g9 g% ~. |! Btimeout contimeout <timeout> (deprecated)
) i: [5 w9 d W& W Set the maximum time to wait for a connection attempt to a server to succeed.
1 f C- p$ \, I. P4 u May be used in sections : defaults | frontend | listen | backend
( Q0 ~7 O3 {/ o9 R6 C! E yes | no | yes | yes
5 T* z5 q6 d) X# t/ f Arguments :
: c. [$ y6 X U# F$ |9 N <timeout> is the timeout value specified in milliseconds by default, but
2 H X* P* h5 ^) w" } _ can be in any other unit if the number is suffixed by the unit,- v, z, _! M5 a/ @8 }8 L7 S: c
as explained at the top of this document.% r6 \7 S. ]; V
( `5 P4 V" U- n* j* R3 H$ [ If the server is located on the same LAN as haproxy, the connection should be
1 J& n$ f- M2 {1 U w9 x3 h) E: y* x immediate (less than a few milliseconds). Anyway, it is a good practice to3 u( G. }3 V: E( Y. O
cover one or several TCP packet losses by specifying timeouts that are
. p4 r5 K9 A* r. K( q( \4 n slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
9 X/ F* w6 d% ^' A T% a connect timeout also presets both queue and tarpit timeouts to the same value
. p& e* l* x5 F8 o' q$ k! D( \5 y' q if these have not been specified.
. c9 P1 ^, S$ v# G4 M3 C8 P. v0 H6 }$ [0 `
This parameter is specific to backends, but can be specified once for all in7 W/ x- a* q- ^+ L
"defaults" sections. This is in fact one of the easiest solutions not to/ t& w1 ^- ]0 P- [4 w
forget about it. An unspecified timeout results in an infinite timeout, which
+ K; r0 ~) \ S3 a. n is not recommended. Such a usage is accepted and works but reports a warning& ~$ D C3 z1 N3 a
during startup because it may results in accumulation of failed sessions in
5 k$ O/ x$ v, w the system if the system's timeouts are not configured either.
, A9 j% u7 B7 b# r8 [, V! J( {9 n4 c0 C' D+ s. U/ }
This parameter replaces the old, deprecated "contimeout". It is recommended
8 c1 y( }$ f: q4 C2 h to use it to write new configurations. The form "timeout contimeout" is
2 {6 w6 k1 y4 E2 i0 U3 P: _" f provided only by backwards compatibility but its use is strongly discouraged.
! V/ s% }* W$ l1 Q" h
- T& d( s! f9 P: R" @4 R See also: "timeout check", "timeout queue", "timeout server", "contimeout",* S2 |) N# b- @( O) n: v
"timeout tarpit".
' T; r# W: ~3 P6 O/ o2 @9 s3 L/ K$ j' V( ?
2 z5 Q) | [8 rtimeout http-keep-alive <timeout>4 K( q* [" S3 d& I: E0 y
Set the maximum allowed time to wait for a new HTTP request to appear
) T$ U% B6 s9 y' U4 C May be used in sections : defaults | frontend | listen | backend
- N: `) U/ k' c* w7 R. K* q yes | yes | yes | yes) [9 c8 s1 J/ O
Arguments :" }: U1 A' c, w$ X: z
<timeout> is the timeout value specified in milliseconds by default, but9 T6 v- w8 H. f t6 O- T
can be in any other unit if the number is suffixed by the unit,( Z5 b' K! H9 T# U; I6 a
as explained at the top of this document.9 w0 g. }4 y$ z; I: [. v
, D6 x! [! q4 c By default, the time to wait for a new request in case of keep-alive is set
0 @! v& A( Z! U* { by "timeout http-request". However this is not always convenient because some
' ?8 C) ^1 T+ [* N people want very short keep-alive timeouts in order to release connections. _, s/ t; g7 \: C/ @- q p0 F
faster, and others prefer to have larger ones but still have short timeouts( x4 j2 e1 R) ?7 T2 N
once the request has started to present itself.
& p3 @2 ?6 N2 @- h' |# X
) Q0 u8 r i9 u) x3 u6 T# f The "http-keep-alive" timeout covers these needs. It will define how long to9 F/ \5 w, H+ l/ t. P
wait for a new HTTP request to start coming after a response was sent. Once
7 c0 d: E9 N l! A- @$ W& r the first byte of request has been seen, the "http-request" timeout is used- n L% j3 J! X0 a
to wait for the complete request to come. Note that empty lines prior to a" P0 i: Z; p4 ]
new request do not refresh the timeout and are not counted as a new request.) m! s1 N; {- }9 ~) V2 j
% }' j: v v \8 t7 B# J4 {
There is also another difference between the two timeouts : when a connection
2 ?- w/ p) X2 f$ {: O- T, m expires during timeout http-keep-alive, no error is returned, the connection
$ L3 t2 e$ h. Y) H }% T just closes. If the connection expires in "http-request" while waiting for a6 I$ V' f- I0 u0 n
connection to complete, a HTTP 408 error is returned.% Z# Z2 N% [$ W( C
8 k5 x7 g+ G0 o3 q5 A$ m+ x. O In general it is optimal to set this value to a few tens to hundreds of9 ~0 y9 v. b- E* M4 F% q
milliseconds, to allow users to fetch all objects of a page at once but
- L- x N8 S9 F# o without waiting for further clicks. Also, if set to a very small value (eg:
5 {$ S% `$ j7 D+ A) O3 i9 r H 1 millisecond) it will probably only accept pipelined requests but not the: S/ ]$ R1 k6 p
non-pipelined ones. It may be a nice trade-off for very large sites running, U0 f3 k3 t6 a) P/ e, E9 _' ^& B
with tens to hundreds of thousands of clients.2 ]5 Z3 i T& X/ v3 A# }9 e9 p4 P" ~
2 e9 l2 B: L9 b* Z+ c3 J+ E
If this parameter is not set, the "http-request" timeout applies, and if both! _- @6 R% f5 {3 B
are not set, "timeout client" still applies at the lower level. It should be. P& h, `1 B1 C6 S( F1 K: G
set in the frontend to take effect, unless the frontend is in TCP mode, in) s$ u! v% v. F( {& M6 B
which case the HTTP backend's timeout will be used.3 {. c2 d i0 s9 m2 {- I/ {
' f4 t. m1 \, ?. N4 e5 @ See also : "timeout http-request", "timeout client".
2 _! e; X( `- A, b
9 x, n/ a. j, f2 d% X2 c! E) o& c
1 i s) H3 ~8 C# q& H. jtimeout http-request <timeout>: F; P. u' v" K! {. w
Set the maximum allowed time to wait for a complete HTTP request
- J+ c3 j# |& k5 H) H May be used in sections : defaults | frontend | listen | backend
p2 F. p, A6 y) L2 @ yes | yes | yes | yes
, E# Q% @1 t4 j: O) { Arguments :
0 f7 M2 z9 d+ e3 v <timeout> is the timeout value specified in milliseconds by default, but. D, G; ~9 X8 [9 ?3 z. _8 X2 }
can be in any other unit if the number is suffixed by the unit,
9 n/ {+ {7 V8 k t3 z2 b! j as explained at the top of this document.! X! {- M+ ?! c2 {; p Z
' ^( Q1 L) s, u
In order to offer DoS protection, it may be required to lower the maximum$ }* I O; J) h# q
accepted time to receive a complete HTTP request without affecting the client
# y1 Q. i# L( |( i* x9 ^% ] timeout. This helps protecting against established connections on which9 a% R) T6 X8 ?7 J& X: V- X2 U
nothing is sent. The client timeout cannot offer a good protection against: i+ g/ I' p" y( X# F
this abuse because it is an inactivity timeout, which means that if the
2 R+ U' A! t9 H. _8 t) j attacker sends one character every now and then, the timeout will not
3 l" g$ l4 q9 n+ p" ] trigger. With the HTTP request timeout, no matter what speed the client, @. O4 `$ Y$ F0 N6 A( c. K8 H
types, the request will be aborted if it does not complete in time.
4 Z9 f9 L7 x7 C: m1 I9 a5 X$ M+ e! ^2 M" p& S0 y6 Q
Note that this timeout only applies to the header part of the request, and
1 ^* o) u9 n& P, W, v, z not to any data. As soon as the empty line is received, this timeout is not
$ p# [% h+ j6 O6 E1 N; t8 d7 R8 I used anymore. It is used again on keep-alive connections to wait for a second
' |, e: U4 [0 v# B request if "timeout http-keep-alive" is not set.* e: W B, i% C0 A
- C S4 `/ I* s5 ~ Generally it is enough to set it to a few seconds, as most clients send the$ c) _( H! G; u7 w- I
full request immediately upon connection. Add 3 or more seconds to cover TCP# h1 d- \" g: U! Z: ~ t
retransmits but that's all. Setting it to very low values (eg: 50 ms) will
& ^! d; b! t9 E4 _! S2 E generally work on local networks as long as there are no packet losses. This
# h; G. W' i; r- [0 w/ M will prevent people from sending bare HTTP requests using telnet.
2 `. N7 e0 F9 |, s3 @+ n! _7 ]
( E/ }& m- K' m9 o. @) n7 \8 d If this parameter is not set, the client timeout still applies between each
4 C8 e& X+ M) W2 u chunk of the incoming request. It should be set in the frontend to take
; ~1 ~* p- H s2 Z" s. } effect, unless the frontend is in TCP mode, in which case the HTTP backend's. z3 B" Z9 I k# ?! T6 n; `1 d$ T! M
timeout will be used.5 P4 ~* w2 ^3 w/ n& ^) _2 H. v- N& S1 ?
' T! p% Y; A% T0 }% k
See also : "timeout http-keep-alive", "timeout client".
7 I6 Y/ t8 h/ ?9 y% A5 o; G: ?: T
1 C0 c* z! D7 O/ u8 M+ k8 I9 }5 D" }0 _9 m$ ~: H
timeout queue <timeout>0 o* S( D0 A+ K
Set the maximum time to wait in the queue for a connection slot to be free$ V* O7 K7 o4 R( y3 \$ j6 k
May be used in sections : defaults | frontend | listen | backend
+ u' a1 W a' f# X: w yes | no | yes | yes
3 I2 M# ^ N8 ~9 H3 b9 s9 B Arguments :
: a8 l1 N0 V$ D4 ~$ R <timeout> is the timeout value specified in milliseconds by default, but
w- H9 W5 B9 K' ~0 O# o, o can be in any other unit if the number is suffixed by the unit,
" @# U) p! H; k1 R as explained at the top of this document.
& k# u) n& G% g; b; I; g# h9 D7 ?" g: {! j
When a server's maxconn is reached, connections are left pending in a queue
) o+ J5 O4 \8 ?$ c) ?7 ]7 b which may be server-specific or global to the backend. In order not to wait- s$ h( D/ Q, b5 B" u0 F: y. K
indefinitely, a timeout is applied to requests pending in the queue. If the" T6 A0 j, w% a1 F1 z4 f! \
timeout is reached, it is considered that the request will almost never be
8 O% H8 d- _8 j R served, so it is dropped and a 503 error is returned to the client.) @% b8 }; h. T! B2 k
S0 M* s! W: C2 L! o( N- K The "timeout queue" statement allows to fix the maximum time for a request to! b/ l) b, b4 f V2 @- ?
be left pending in a queue. If unspecified, the same value as the backend's
2 s4 D8 F. _3 Y8 q4 Z connection timeout ("timeout connect") is used, for backwards compatibility" {1 Q, n' @" C8 K7 M
with older versions with no "timeout queue" parameter.# d1 }6 ~) O: n* H
& ]. I1 w0 \5 j2 u6 R' { h1 F See also : "timeout connect", "contimeout".
) m- I3 A5 H5 K" g G4 o0 y9 Q' P; B% b; [
+ M% }! M* i M M2 ?8 stimeout server <timeout>
0 u4 {: C' e0 k' u3 n" B' h( K9 vtimeout srvtimeout <timeout> (deprecated)
$ h$ M$ ~4 L; l' @# e6 g Set the maximum inactivity time on the server side.4 l& h1 a( _& x! S1 Z
May be used in sections : defaults | frontend | listen | backend& D$ K1 g1 x$ N1 p& D( L
yes | no | yes | yes
4 ] D% a3 o+ W: o: U" z C Arguments :$ Q3 c3 U w7 s# b& F* \
<timeout> is the timeout value specified in milliseconds by default, but+ y# T! b4 q6 H$ L6 G% ]
can be in any other unit if the number is suffixed by the unit,
1 B' r0 }: F9 H3 E as explained at the top of this document.
3 V% X& ~% M9 _- L: q
5 _3 U* A" t& j" b The inactivity timeout applies when the server is expected to acknowledge or3 D( r( \/ K, k L1 Q8 c1 t6 `- T
send data. In HTTP mode, this timeout is particularly important to consider
- Y! X$ ^2 |8 `% o during the first phase of the server's response, when it has to send the; A5 L5 c- L6 h5 l# R
headers, as it directly represents the server's processing time for the3 t, T9 X& L% F+ t& {9 N( O, s# I/ o
request. To find out what value to put there, it's often good to start with
8 R* _1 q- Y. u4 p# v M5 G: k what would be considered as unacceptable response times, then check the logs1 D6 L0 ^* ^ G+ ?9 d' V, |# }
to observe the response time distribution, and adjust the value accordingly.2 k* [/ k8 G! Q0 o! @
9 V! o1 L0 p6 O
The value is specified in milliseconds by default, but can be in any other
4 Q$ |0 o$ P, Y4 t/ S1 f% r unit if the number is suffixed by the unit, as specified at the top of this
5 T6 B x+ ?# L& `5 P document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly" v/ ?% U- L s2 H
recommended that the client timeout remains equal to the server timeout in* V2 c( a0 d) Y# K) ?, N3 s p
order to avoid complex situations to debug. Whatever the expected server
2 b' @- x/ }$ |/ F response times, it is a good practice to cover at least one or several TCP
- o" l' N6 w' r& j5 O+ d packet losses by specifying timeouts that are slightly above multiples of 3
. C( F- ?) g8 B- u; N) K( q seconds (eg: 4 or 5 seconds minimum).0 @" U0 ^8 \9 T& A, F
& v$ w; V: c1 [8 {* G This parameter is specific to backends, but can be specified once for all in8 H/ H6 |- T: }1 Y; A
"defaults" sections. This is in fact one of the easiest solutions not to+ [1 {+ c2 D+ w; z* e) G
forget about it. An unspecified timeout results in an infinite timeout, which
8 {8 m" F# m4 r+ j8 b is not recommended. Such a usage is accepted and works but reports a warning7 {1 B% ~! B# p* W/ _0 w
during startup because it may results in accumulation of expired sessions in
9 b7 | |2 F, _. g. G. K8 P the system if the system's timeouts are not configured either.
! O9 j% ?9 `; t$ s, [7 S" }3 }' i8 R6 W
This parameter replaces the old, deprecated "srvtimeout". It is recommended
) l* v+ S; F D8 w8 D) S! s to use it to write new configurations. The form "timeout srvtimeout" is! T( \' D. _. a% N5 o0 h/ K
provided only by backwards compatibility but its use is strongly discouraged.# r. k a; n5 @% k5 a/ r
3 q* o/ B! }* b$ \3 L5 g: C
See also : "srvtimeout", "timeout client".
" X! s. z9 J( l9 i" F6 \
, o/ R7 H6 b v8 x) j6 w. m
2 a8 N! ^4 I3 z, \timeout tarpit <timeout>
2 c6 r! u. i1 z0 K- u Set the duration for which tarpitted connections will be maintained! `$ j7 L8 o6 N/ W
May be used in sections : defaults | frontend | listen | backend
3 _* p- \ q( E" w" F) j yes | yes | yes | yes
' C" h! f8 |( L) H Arguments :
3 y% p d2 J- O3 x+ U! f <timeout> is the tarpit duration specified in milliseconds by default, but
* \4 v$ A1 x) R& I; }% B7 f can be in any other unit if the number is suffixed by the unit,0 j! i$ r; Y4 R4 M% T3 ^& s
as explained at the top of this document.
- C! z' c6 H! e6 y8 f o0 p0 q' ^* g
9 f( Q- g/ W" r I+ U) Z5 z When a connection is tarpitted using "reqtarpit", it is maintained open with
{3 a% M8 O/ t/ y7 f! o no activity for a certain amount of time, then closed. "timeout tarpit"
) d1 a, l* v8 L0 l defines how long it will be maintained open.
6 n: I( ?4 \6 [
% Q4 p( b, n S- q) b The value is specified in milliseconds by default, but can be in any other( s* i3 D, E, `) v& k6 A
unit if the number is suffixed by the unit, as specified at the top of this9 F, v* E! a) Q8 T6 {6 A
document. If unspecified, the same value as the backend's connection timeout: p( {) L) ^ r' K
("timeout connect") is used, for backwards compatibility with older versions- _ B. D1 D1 l1 l% z
with no "timeout tarpit" parameter.
0 V8 `/ ^% I- {& h4 m& K
; @+ u) t$ M) c3 S d# ~ W4 ` See also : "timeout connect", "contimeout".
' O2 \3 M8 L/ Y; ]
" F0 U4 u7 M/ y6 H& G
& M; [% r/ G: j8 N0 j5 }transparent (deprecated)
7 U1 c$ f3 d5 E Enable client-side transparent proxying, K+ k' Q+ U0 r1 b a! P
May be used in sections : defaults | frontend | listen | backend
: d/ H8 y$ F P0 G. y6 k7 } yes | no | yes | yes9 b' l) C; X1 K+ K6 M
Arguments : none
6 r4 {+ d0 z7 T% i7 W3 \5 F: X M! }- i4 g# @1 { _6 L
This keyword was introduced in order to provide layer 7 persistence to layer, q6 W* Y1 m' |
3 load balancers. The idea is to use the OS's ability to redirect an incoming1 p9 ?; T* Z3 U1 u: e
connection for a remote address to a local process (here HAProxy), and let, `6 j! {7 Z9 p+ g1 g; _
this process know what address was initially requested. When this option is
& _& [+ J5 h5 d used, sessions without cookies will be forwarded to the original destination
8 b/ O# u! V& l" M8 o! A* N IP address of the incoming request (which should match that of another0 A# z+ [ g& j, U
equipment), while requests with cookies will still be forwarded to the) G5 G3 n: P9 j I+ k' u$ S& i2 O
appropriate server.4 c* L2 Z/ B0 q) ]+ ~- c0 Y
/ X0 G4 s' f9 E4 P6 H; B The "transparent" keyword is deprecated, use "option transparent" instead.
, m% a9 q: |5 o5 H3 Q& C
: s1 {* y+ q3 p Note that contrary to a common belief, this option does NOT make HAProxy
j, V f* ]+ z- {: Q7 Q* x" j# p present the client's IP to the server when establishing the connection.
$ s, k! ~' R' R: Z( W/ k8 x; I+ L/ ?, L# e: t7 m1 i" a
See also: "option transparent"
2 C+ X3 a0 Y* c* I
0 Z8 X" r1 o+ H/ x; ]- \( b; I
4 h- b6 t& j" Guse_backend <backend> if <condition>% q0 c% Y# B$ I" y# @
use_backend <backend> unless <condition>3 k. | r( [% J( f* q
Switch to a specific backend if/unless an ACL-based condition is matched.
e0 M p7 g2 z8 O& H; C May be used in sections : defaults | frontend | listen | backend
. `4 e# t' Z6 V* q1 Z: m4 }8 E no | yes | yes | no
3 X8 E. t0 P- w& y: m Arguments :
/ O3 W- t6 Y! i$ x x% r% j. G/ G& Y; W# R <backend> is the name of a valid backend or "listen" section./ x8 r" f2 Q/ U
$ s- O- { V; C) P$ N4 R1 B8 X
<condition> is a condition composed of ACLs, as described in section 7.
9 y( m& t; K2 n3 H% P
8 |. h Y9 D% x* q% j) t, P/ A5 \8 i* A When doing content-switching, connections arrive on a frontend and are then2 I1 i- L4 u2 d
dispatched to various backends depending on a number of conditions. The- ]4 b+ q: s! `8 V' J
relation between the conditions and the backends is described with the4 @& `! J3 G& v: V- d
"use_backend" keyword. While it is normally used with HTTP processing, it can! G1 B3 i( p* y3 a
also be used in pure TCP, either without content using stateless ACLs (eg:
2 M: P( @8 N2 P- P: B- V) `4 P) y source address validation) or combined with a "tcp-request" rule to wait for5 }5 N8 ^2 q: L: d. `7 q+ G
some payload.7 t% j" B( h% r& R$ Y+ v
, K' ?/ k( [1 S r6 F8 J5 Y
There may be as many "use_backend" rules as desired. All of these rules are
: `$ S$ H3 P& C% D evaluated in their declaration order, and the first one which matches will
; x" d% v# I r) {8 ?. p! b assign the backend.
& f+ ?: T. K. J2 Z/ S! P5 \" g
& w0 v/ @5 I# z8 b# ~ In the first form, the backend will be used if the condition is met. In the
% R' W; W" Y/ t1 W# k. d" r second form, the backend will be used if the condition is not met. If no
+ o/ W5 h4 L: g1 R! [& W, A condition is valid, the backend defined with "default_backend" will be used.% g* \. h; \: x' b9 i# F
If no default backend is defined, either the servers in the same section are
" a- E/ ?/ g( q7 h* K. o8 e7 E- f5 W used (in case of a "listen" section) or, in case of a frontend, no server is; e8 \4 o. ^9 r0 E/ D3 q, W3 r
used and a 503 service unavailable response is returned.6 s3 F: f. M, ] g
( u# I5 O: y1 u
Note that it is possible to switch from a TCP frontend to an HTTP backend. In
% I, E0 ~1 r; H7 O this case, either the frontend has already checked that the protocol is HTTP,
0 H9 f4 ?- c! Z: P" j- Z and backend processing will immediately follow, or the backend will wait for
/ J# M# e: F: h. q+ L% E- [ a complete HTTP request to get in. This feature is useful when a frontend
' Q1 d& l1 U. w$ w5 ? must decode several protocols on a unique port, one of them being HTTP.
/ g5 j. V% v" R' @4 c$ z& k) v: |- u7 _% x) t. c
See also: "default_backend", "tcp-request", and section 7 about ACLs.
' }5 d/ z; U- w1 `+ B
+ d2 K& m( T) H' P% d( O
( {; J, j) r' f1 q5. Server and default-server options
. m1 d& Y N4 F7 h/ G1 U------------------------------------' s/ M8 N- e9 O# d+ H; ~
7 q3 e- o* R6 [4 XThe "server" and "default-server" keywords support a certain number of settings$ [1 t8 I. f5 s0 p& X+ i+ V
which are all passed as arguments on the server line. The order in which those
% ~/ n' }9 H6 j7 g Darguments appear does not count, and they are all optional. Some of those
{) F; B5 Z) F x% t9 ~settings are single words (booleans) while others expect one or several values$ h& J* x9 J2 \" o2 d8 F3 j* }! h
after them. In this case, the values must immediately follow the setting name.
) i2 p/ c4 O5 A* v' vExcept default-server, all those settings must be specified after the server's1 B3 q- K& n2 ?8 ^! Y7 |1 v: p" J
address if they are used:
" c5 e4 |5 h+ f- M% }( O& i8 H6 B/ U( q* A! Q3 i
server <name> <address>[:port] [settings ...]% T e$ E0 p" R ~5 o1 ]; v
default-server [settings ...]
* a* j5 C$ \: a: v. p
( N) | i1 a& U" g7 G( ?- ^The currently supported settings are the following ones.3 R2 X* D! V' Y9 c
/ |$ _) x, B7 s
addr <ipv4>$ q8 ^' N3 X% ~" H/ x
Using the "addr" parameter, it becomes possible to use a different IP address4 ]% E. N4 M9 ^+ W {* r. ?( x w' \
to send health-checks. On some servers, it may be desirable to dedicate an IP
* g2 x4 A6 K& X; G address to specific component able to perform complex tests which are more
w& Y3 `0 h5 b8 ?# I" q' u suitable to health-checks than the application. This parameter is ignored if
( ]6 T! B+ L) }& j+ n f2 J5 i the "check" parameter is not set. See also the "port" parameter.4 ^! v' I( k- H0 z2 u# [7 v6 s
" K% ?" W9 I' Y) ^5 r8 P9 ]$ w
Supported in default-server: No" ^0 V( E3 o( p. W- e4 Z+ W4 W
# N( \9 n8 O1 u( I, V: _4 |4 }backup
* v( r. v0 D$ `* z1 \. I When "backup" is present on a server line, the server is only used in load9 d" ^' R2 s4 K( z: C
balancing when all other non-backup servers are unavailable. Requests coming* f$ y& b5 X) L( f
with a persistence cookie referencing the server will always be served& d; e" ~, u/ W( L; U. B; K
though. By default, only the first operational backup server is used, unless
( R8 ~7 \# c9 F; K. s7 \ the "allbackups" option is set in the backend. See also the "allbackups"
4 o9 p7 e; x3 R7 u" q- S option.
% l' A) J) z' o9 l6 r2 ?0 S9 u7 R8 P7 q2 |
Supported in default-server: No
- Q: [: O$ w2 W+ n! x# K g6 j4 _$ g8 ?
check1 n: z5 G$ X; E" O
This option enables health checks on the server. By default, a server is
& W2 ^# e \) @/ N4 b& n7 T always considered available. If "check" is set, the server will receive$ w5 [: k1 q! u/ R4 b2 H! f
periodic health checks to ensure that it is really able to serve requests.0 G) V" r2 {/ C( \/ h; |6 y
The default address and port to send the tests to are those of the server,2 v% N8 Y5 p$ T2 O: Z/ p
and the default source is the same as the one defined in the backend. It is
; D8 n" T! {: ~9 j4 v possible to change the address using the "addr" parameter, the port using the- X+ F# Q8 V0 Z) r5 a
"port" parameter, the source address using the "source" address, and the5 P& g3 W, O4 f) @
interval and timers using the "inter", "rise" and "fall" parameters. The
! [3 ~. O1 I: G% K request method is define in the backend using the "httpchk", "smtpchk",/ a/ o* F$ _* {) p( w
"mysql-check" and "ssl-hello-chk" options. Please refer to those options and! \ s% g; @0 E+ z* J h
parameters for more information.7 H4 ]/ T+ i' R% Q) n, D5 Q5 A
, y( |/ M+ w+ g% w7 p1 R5 e Supported in default-server: No+ F9 `2 Y6 o& D; O
) X5 I J. d! z, {
cookie <value>; b; m5 I/ H" _" y2 D2 K
The "cookie" parameter sets the cookie value assigned to the server to2 G% j! V% t5 q# }- l/ {+ M3 t
<value>. This value will be checked in incoming requests, and the first% k; E4 ]8 ]8 h
operational server possessing the same value will be selected. In return, in
/ C$ i; [2 P3 ]) j/ ?- t* r K cookie insertion or rewrite modes, this value will be assigned to the cookie
- ~2 }* m1 q% F+ ~/ N sent to the client. There is nothing wrong in having several servers sharing, b- `6 \& e! n9 V3 x/ F0 _: U
the same cookie value, and it is in fact somewhat common between normal and
+ {/ O" H4 x# s. A" v# R/ b5 C: j backup servers. See also the "cookie" keyword in backend section.) e+ y' a3 K7 `8 S) s2 ^
. K' O/ Y2 h# c4 @' T0 J
Supported in default-server: No
! n" y$ k1 F7 R/ J6 ~! r( n2 f9 o( N
disabled0 k& u$ `8 r% h6 a' s# Z: A0 _
The "disabled" keyword starts the server in the "disabled" state. That means
8 V2 X+ ?# D! o5 X) W that it is marked down in maintenance mode, and no connection other than the
2 v9 D( o" Y9 [) o3 q2 p ones allowed by persist mode will reach it. It is very well suited to setup
' \, f& L; z" h6 e; G' `( p new servers, because normal traffic will never reach them, while it is still, L0 l8 R! `% V W
possible to test the service by making use of the force-persist mechanism.
, x9 t N$ D2 t! q! i9 s2 i( s( Y! |
! s3 q3 I# E5 @; | Supported in default-server: No
- ^% n0 d" q+ L6 X$ k$ D' @) Q2 s5 K0 n: Q; A# \* t$ V! l" i
error-limit <count>
. E9 `5 K0 x7 A, y( S( v If health observing is enabled, the "error-limit" parameter specifies the
/ c5 W9 q7 l& l/ g8 A2 E number of consecutive errors that triggers event selected by the "on-error"5 n4 Z# i- X. d2 ^
option. By default it is set to 10 consecutive errors.
) H% ]; ]! ?8 |9 X; o9 o. ~
3 S$ s' y3 y- S* H6 Q7 ~ Supported in default-server: Yes
9 ^4 E, h, `9 b" e5 @8 E) }) K! k, C# [, V- d# Q$ W1 b# Q* T
See also the "check", "error-limit" and "on-error".
9 J3 t9 Z) V8 m' ^& k
: f, e1 }' y" j" Ofall <count>+ w) _) C! o, e7 ?& ~% ?
The "fall" parameter states that a server will be considered as dead after
, M- V& x" B2 r% {0 q+ ` <count> consecutive unsuccessful health checks. This value defaults to 3 if; Q+ h6 @$ l. s4 b
unspecified. See also the "check", "inter" and "rise" parameters.
: c/ U9 {! R2 W/ W+ w, q6 C9 z' v/ m2 R
Supported in default-server: Yes0 S; f3 ?% U$ n3 [. l% a1 B& C* y7 `7 Z
4 S5 t* `: _' j, j& d4 g( j
id <value>; |7 G$ |! K2 g7 S! E: g
Set a persistent ID for the server. This ID must be positive and unique for
) f- i) x% W) h the proxy. An unused ID will automatically be assigned if unset. The first6 Y' B6 a8 B% V& |" y3 L4 a
assigned value will be 1. This ID is currently only returned in statistics.: @* T- @* \6 M4 O. [4 u3 R
- O8 b& ?$ V: r) H& i: g$ p4 f Supported in default-server: No
7 D% I& q2 a H
4 R1 G& T8 U6 ]- ?: ^$ cinter <delay>
/ Y9 U* N e rfastinter <delay>
( p L7 ]" m* l$ ydowninter <delay>
: ?* l5 ]' a4 o5 v The "inter" parameter sets the interval between two consecutive health checks
# ~) J% `9 E9 |* M% G4 m' } to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
3 Q; I1 S" F8 E7 n# ` It is also possible to use "fastinter" and "downinter" to optimize delays/ D$ U) x$ l% ^
between checks depending on the server state :+ |5 p6 F, F1 n1 ^' _3 ~/ ~
# Y' O# M7 m3 k6 f1 G" k7 c4 M Server state | Interval used
+ O+ x' ~9 N% C* ~: X. u" t2 r ---------------------------------+-----------------------------------------
6 A* K3 R# { u% j2 u0 g; D" b- A UP 100% (non-transitional) | "inter"
: L# ?/ b2 X9 O7 _5 O ---------------------------------+-----------------------------------------
1 g' F6 C; _! t; i- w2 y: S Transitionally UP (going down), |$ i* ^1 P+ k r$ p' T3 y: I
Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise." t% ?& T P* ] S4 ]- J. S
or yet unchecked. |
J1 P$ e! [( ~ ---------------------------------+-----------------------------------------
4 e. u6 l4 K$ T# O1 b DOWN 100% (non-transitional) | "downinter" if set, "inter" otherwise.; _$ j! Z; j* D; x/ I
---------------------------------+-----------------------------------------
7 g, g. P7 T7 Y9 V
8 f2 o. H2 ^, G7 s6 i5 R Just as with every other time-based parameter, they can be entered in any4 h. o6 v" v x8 }2 J
other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also
; p! a7 f8 G5 H0 [' C" o. O8 C+ R serves as a timeout for health checks sent to servers if "timeout check" is6 m: s6 Z k3 a T
not set. In order to reduce "resonance" effects when multiple servers are2 _* Z/ b" \* ~ f) l& c) a3 v- m
hosted on the same hardware, the health-checks of all servers are started
& a1 D3 Y- F3 z+ } with a small time offset between them. It is also possible to add some random
1 [. ^& c# c X4 d$ j/ | noise in the health checks interval using the global "spread-checks"
9 }2 c% q# m' v4 h keyword. This makes sense for instance when a lot of backends use the same
7 m+ S+ x# P- [; u servers.: l: T9 C- \4 f- { w6 l
* m* I( z. `+ q# s8 g. h- j" a
Supported in default-server: Yes
( {) H7 j$ O. J% [7 k
) @* T- d' X0 M: u+ e# R9 h# Tmaxconn <maxconn>2 r5 r# \9 z9 N' S q
The "maxconn" parameter specifies the maximal number of concurrent4 V" Z/ J% e5 T( E/ g
connections that will be sent to this server. If the number of incoming
1 _* [4 R7 I8 w. U concurrent requests goes higher than this value, they will be queued, waiting- f; r! u' a( T. L
for a connection to be released. This parameter is very important as it can! e# |& v j0 |- M
save fragile servers from going down under extreme loads. If a "minconn" F3 V: [( v7 A8 J1 R) e
parameter is specified, the limit becomes dynamic. The default value is "0"
0 X, `7 K- y5 \2 R5 T- G which means unlimited. See also the "minconn" and "maxqueue" parameters, and) D" X3 G. r e% ?2 ?8 P4 i
the backend's "fullconn" keyword. S* M6 b: @# n2 E7 q" Z0 _
/ _' @5 {* \( x: J3 k Supported in default-server: Yes
2 l- [; G& U. j2 |6 o. d$ q5 W4 F& R- a4 D- y3 i/ m
maxqueue <maxqueue>
S- v% k) ?! C$ K. u+ h' V: A3 [ The "maxqueue" parameter specifies the maximal number of connections which, E6 W; z4 C4 U' h2 H7 `) B
will wait in the queue for this server. If this limit is reached, next' t8 R8 n2 `! R2 T# ]4 Y% c
requests will be redispatched to other servers instead of indefinitely# Q- P; D! Q' W5 v; t
waiting to be served. This will break persistence but may allow people to h% E+ `, I5 J/ P0 M% E
quickly re-log in when the server they try to connect to is dying. The: V1 M$ A# U- }9 ]5 n" S/ {
default value is "0" which means the queue is unlimited. See also the8 ~2 J2 ^& [8 i6 v- ]4 e
"maxconn" and "minconn" parameters.) o( P) I, H, U# p
5 i9 d% Q% z% @, B
Supported in default-server: Yes, i: I _$ Y9 B/ i# m& v, V7 {
* z, V0 B! [$ {9 n2 D
minconn <minconn>
4 u2 ?/ R8 U ~* \, \ h# {" `4 d When the "minconn" parameter is set, the maxconn limit becomes a dynamic* H; ~7 y/ |9 K, a) U% x- `6 _
limit following the backend's load. The server will always accept at least
( V* u7 n: {/ }% a2 M& g5 ] <minconn> connections, never more than <maxconn>, and the limit will be on$ x7 j- I8 d) _6 v! e4 G( L
the ramp between both values when the backend has less than <fullconn>
& g$ T" b$ N+ {- I/ i: }. M concurrent connections. This makes it possible to limit the load on the! [: U; U; ] b- ?1 M
server during normal loads, but push it further for important loads without8 W$ O+ y$ F( R* b
overloading the server during exceptional loads. See also the "maxconn"2 g/ d/ B \' d0 @: c% w
and "maxqueue" parameters, as well as the "fullconn" backend keyword.# ]0 ?. y3 e( y
, d& a" W% E, y4 x, R) d Supported in default-server: Yes5 B: f- W' n; I( X3 h
/ Z( A; o% p- w; Z( k5 o$ Y0 c8 S0 Q I$ robserve <mode>% z* {5 M6 T# z1 U" q5 E; ^% V& l( p/ M
This option enables health adjusting based on observing communication with+ e' t$ r3 G) W' w6 d
the server. By default this functionality is disabled and enabling it also
S7 h9 z1 u: j2 P7 s$ w) D* l requires to enable health checks. There are two supported modes: "layer4" and
9 _4 `( `, V) J/ x "layer7". In layer4 mode, only successful/unsuccessful tcp connections are4 G$ K$ w$ ^% ]
significant. In layer7, which is only allowed for http proxies, responses# K; }( s- c' ]9 h( v6 ]: J# U0 w
received from server are verified, like valid/wrong http code, unparsable
# v/ z/ d5 R4 h8 x* B1 h" m2 W headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.
# A7 b: @ |* r# {1 N" k: N, W4 b& C
" ]4 r4 @/ G4 f2 ^. h& |% F Supported in default-server: No
6 L8 n0 k# M: F1 @
9 e0 n8 O$ `; W) G9 |8 e! h/ Z See also the "check", "on-error" and "error-limit".) G9 o+ W4 P! c/ D: I
: O! l2 S$ v% e3 l# Son-error <mode>
/ O$ {0 j# A; {/ n& x Select what should happen when enough consecutive errors are detected.3 {* m% m% c9 t
Currently, four modes are available:$ _. l/ r2 \ O; @- ?# [
- fastinter: force fastinter
- R* k" K/ s0 K% y - fail-check: simulate a failed check, also forces fastinter (default)& L0 S, B, O- b. A
- sudden-death: simulate a pre-fatal failed health check, one more failed+ p' X1 \6 A2 D. z+ M( Z
check will mark a server down, forces fastinter+ t* L! M# y- [+ I0 `! w
- mark-down: mark the server immediately down and force fastinter* ^/ s5 S( @- t: @1 k
& s2 L0 f) @% S! f, S0 K/ p% r$ e& F) L
Supported in default-server: Yes0 J" A" d. e, z/ z
* ]1 d/ {# j% p) y: v% n See also the "check", "observe" and "error-limit".
) b9 O8 t1 u8 G. ]4 ?0 d, Q5 U* @) ~- R* w) X5 m
port <port>
1 I& p. T) ^4 h0 I5 R. y8 } Using the "port" parameter, it becomes possible to use a different port to
2 Q: |1 ~ Q" q! c$ M& v# y send health-checks. On some servers, it may be desirable to dedicate a port
2 T$ ^, J* d% b3 C to a specific component able to perform complex tests which are more suitable, m" R9 i( q c
to health-checks than the application. It is common to run a simple script in
/ i* I/ ~6 ]4 I inetd for instance. This parameter is ignored if the "check" parameter is not7 p4 m4 ~; b( X" I
set. See also the "addr" parameter.
1 e1 |5 {; }- C5 x% Z3 x2 L$ t u5 z$ `, W/ }! S
Supported in default-server: Yes
# F# H, i) i. L$ ^6 {2 R- h
" i& q. ^. \/ t, L8 B4 L' _redir <prefix>" t- Q; s5 _" Y2 C/ h
The "redir" parameter enables the redirection mode for all GET and HEAD
" `. T% N- a* s r4 f+ m' m requests addressing this server. This means that instead of having HAProxy
1 |2 v% n+ L" j2 |6 P6 w" V forward the request to the server, it will send an "HTTP 302" response with
& v |: V/ {% m: F5 a the "Location" header composed of this prefix immediately followed by the
/ Y# w: ^& ]9 f; \4 F3 g requested URI beginning at the leading '/' of the path component. That means
% `, y& Y2 H6 ?; B4 U% V that no trailing slash should be used after <prefix>. All invalid requests
+ z- l) V( v8 Y will be rejected, and all non-GET or HEAD requests will be normally served by
* Y4 j- m. A/ \5 @ the server. Note that since the response is completely forged, no header
$ j" p# v8 ^0 H G/ ?2 J! d/ O mangling nor cookie insertion is possible in the response. However, cookies in/ o- j- X) t4 m& Q
requests are still analysed, making this solution completely usable to direct
. ^! |- l: M3 z5 K! @- G6 m users to a remote location in case of local disaster. Main use consists in7 q) \/ V7 k" {% s2 [
increasing bandwidth for static servers by having the clients directly" T1 N/ k; ^/ d
connect to them. Note: never use a relative location here, it would cause a" S5 U* D# E' F [ }% m' b
loop between the client and HAProxy!
. T+ c" |9 H. L N* W" g
1 P6 S% n) Y$ j Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
$ o4 J6 j5 ^9 E/ z2 P. P# c
% m- u/ k" X# s$ o Supported in default-server: No' z9 S+ |5 r- z. T: T' r3 v
" h: C# u& e( Y) m9 j9 yrise <count>
3 w5 L( H2 h; y4 P1 _7 E/ X0 E, Q4 ^; I The "rise" parameter states that a server will be considered as operational; @, F9 q9 b2 c5 p% n& Z
after <count> consecutive successful health checks. This value defaults to 2
2 G v. Q8 ~: O7 D8 K% a if unspecified. See also the "check", "inter" and "fall" parameters.
+ P4 S6 N0 g+ `3 g1 t, {) g9 h- ~) e4 f! ^5 N# L& `- {4 P
Supported in default-server: Yes
" Q2 a u. l9 A! ]' V! y D( x
?; A9 t' v1 {9 |0 vslowstart <start_time_in_ms>
8 U( G6 K0 ~+ o8 `4 s, b% L The "slowstart" parameter for a server accepts a value in milliseconds which5 q8 x4 B$ f N3 U5 i
indicates after how long a server which has just come back up will run at) X) n! `! o$ a: |+ Q7 c: f) \2 b$ |$ g
full speed. Just as with every other time-based parameter, it can be entered9 n' W2 Z! r: u- Y9 I
in any other explicit unit among { us, ms, s, m, h, d }. The speed grows9 T) o& R( x, C6 j* H+ }) U. h) l( }
linearly from 0 to 100% during this time. The limitation applies to two
0 y. \+ | T. l8 y7 h7 K- p parameters :( h) q! F; }3 a8 u. B
8 B. D& h; X e8 \& o; Z - maxconn: the number of connections accepted by the server will grow from 1
1 R9 N3 f- y: H" \4 ^ to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).. S* g9 L7 n B7 I3 g! G% ~
2 |6 j% \4 C" o, | - weight: when the backend uses a dynamic weighted algorithm, the weight; g: H7 B) \$ M1 }
grows linearly from 1 to 100%. In this case, the weight is updated at every z7 T n* z8 M% }5 Z3 R
health-check. For this reason, it is important that the "inter" parameter4 C5 m% q8 X4 o8 }5 U
is smaller than the "slowstart", in order to maximize the number of steps.
2 L* n' ?; K. Z3 Q% q$ S1 ^+ D
The slowstart never applies when haproxy starts, otherwise it would cause* l. ?9 c% Q: G1 J+ q# B. j
trouble to running servers. It only applies when a server has been previously& x, S% j: ^% i) b9 w
seen as failed. b* v( M( k* w8 l( F
$ l4 t! V: b( [& H0 u# } Supported in default-server: Yes
) n6 D# r- L2 o& X+ g/ t# o2 y+ I
$ r, e- B: t% ~source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]3 C4 L3 _. U* S& u. `
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
3 A S: G1 e6 }9 l+ i6 t. qsource <addr>[:<pl>[-<ph>]] [interface <name>] ...7 e) B$ A1 c% W. U! b7 R
The "source" parameter sets the source address which will be used when3 h6 P: U4 H' p
connecting to the server. It follows the exact same parameters and principle
6 H8 p% b0 ?: ` as the backend "source" keyword, except that it only applies to the server
8 ~# J. M4 K7 L4 l* A+ z referencing it. Please consult the "source" keyword for details.
( c8 t/ X' ^& C7 L! h2 m- r; k) x' ^/ E1 b7 H' t
Additionally, the "source" statement on a server line allows one to specify a* x# r1 M( K( G: a' I: d
source port range by indicating the lower and higher bounds delimited by a
* ^% |5 `! b1 ~3 K dash ('-'). Some operating systems might require a valid IP address when a( ?) L, ^9 X6 D- F
source port range is specified. It is permitted to have the same IP/range for" v6 x+ U" y- t" C2 S8 D
several servers. Doing so makes it possible to bypass the maximum of 64k, B' J, O4 d; w2 A, C
total concurrent connections. The limit will then reach 64k connections per6 z( W. f! |+ F5 g5 t2 B: k3 {% M# n
server.
8 J m; `1 h/ H P7 X4 |% {
0 J. t" a3 R- g$ J h Supported in default-server: No
) b: a& N8 K* q. }5 V* T1 r& R+ s1 }+ e! ?+ U G
track [<proxy>/]<server>- e9 t5 B X1 E5 j2 f
This option enables ability to set the current state of the server by: C3 R2 B( `/ Z( y2 O5 v; M
tracking another one. Only a server with checks enabled can be tracked0 z) N& O' t; y7 h, _) Y& i
so it is not possible for example to track a server that tracks another; {1 h. M' r: i3 @
one. If <proxy> is omitted the current one is used. If disable-on-404 is
8 |8 {7 V) }5 Y( p% x" U used, it has to be enabled on both proxies.
$ N2 z. T6 H! z9 ] r% P
$ f8 S+ @: E; j$ k" ] Supported in default-server: No
; G- Q+ p6 P* k0 x
; O' V% I' m( D+ y% O, b6 f. @4 ?weight <weight>
6 p: G* |* }' J The "weight" parameter is used to adjust the server's weight relative to
$ I3 k3 e; U% s$ D: } other servers. All servers will receive a load proportional to their weight2 |$ p; B) ^0 j! P- N0 W1 ^* v9 E. U
relative to the sum of all weights, so the higher the weight, the higher the* z# Z$ `/ U0 s2 J2 {% a
load. The default weight is 1, and the maximal value is 256. A value of 03 n; d8 L7 ~$ p: M5 C2 q5 Q* j4 K
means the server will not participate in load-balancing but will still accept5 z, o: V7 u# R
persistent connections. If this parameter is used to distribute the load' E6 n; y" S# _+ d- s' d) N2 _4 J
according to server's capacity, it is recommended to start with values which1 ]5 @/ A4 q& Y _3 W
can both grow and shrink, for instance between 10 and 100 to leave enough
4 Z- D7 v# H3 g+ H \ room above and below for later adjustments.) O o4 A4 m" h8 M
6 T! l% ^" ?) ?, J- Z2 ] Supported in default-server: Yes
" n2 @- j' J6 b6 q) F' R! [, i
# g# e) G% f) ?) e. A A
3 b+ Q7 s, O, T) K7 |6. HTTP header manipulation8 I% v; m3 x- R4 C9 P6 x" Y
---------------------------- h7 |5 g5 ]- @' t+ G
2 T0 u: b& E, Q2 g+ s* B$ {In HTTP mode, it is possible to rewrite, add or delete some of the request and
) K# m1 F( y; S* \, aresponse headers based on regular expressions. It is also possible to block a
6 m! q1 F9 ?. _: l* y- W5 Brequest or a response if a particular header matches a regular expression,4 H2 l* N4 [! P4 m" D c& X w
which is enough to stop most elementary protocol attacks, and to protect
1 g! T% D7 ? _8 s3 vagainst information leak from the internal network. But there is a limitation
* h, N% |5 Q* g. a! m& Dto this : since HAProxy's HTTP engine does not support keep-alive, only headers$ d( @$ \# {$ n: d2 N
passed during the first request of a TCP session will be seen. All subsequent
# G+ @. s5 @# {4 p' K' D7 qheaders will be considered data only and not analyzed. Furthermore, HAProxy
( i* L: A6 j9 a% F/ _never touches data contents, it stops analysis at the end of headers.
5 N3 {0 B+ @. J! Y2 B" C6 E
4 S) G! t' o7 t9 z! Y# r/ CThere is an exception though. If HAProxy encounters an "Informational Response"
/ I) f1 x( X" _' Z* `(status code 1xx), it is able to process all rsp* rules which can allow, deny,4 G! D7 z; e# I: B
rewrite or delete a header, but it will refuse to add a header to any such$ Z! }/ M2 H" |, t n4 k
messages as this is not HTTP-compliant. The reason for still processing headers4 J! J- u4 d. m0 ~, {
in such responses is to stop and/or fix any possible information leak which may
2 M/ x! A; W thappen, for instance because another downstream equipment would unconditionally
, Q& G% p7 Q4 V4 G, B6 Ladd a header, or if a server name appears there. When such messages are seen,# x6 m& v6 s O- `
normal processing still occurs on the next non-informational messages.& `) K3 y9 K3 T/ @
5 X4 a6 h5 g) [* i; {This section covers common usage of the following keywords, described in detail2 p0 o6 `$ m, [" g2 y' k
in section 4.2 :
8 G9 u/ K1 \" U5 v8 f7 ~# f4 w( I- Z. S5 q- R. d
- reqadd <string>8 A0 [3 q5 `: N* T% v
- reqallow <search>$ K, S" J* u& ]$ T
- reqiallow <search>& V, V6 U+ e7 T
- reqdel <search>: k- D* U# w; X3 G
- reqidel <search>% A8 e3 b J' ~* }* M
- reqdeny <search>5 m' E. Q9 Z9 a. M. v
- reqideny <search>
* N/ Z. t0 f& X& Q' B P( X - reqpass <search>
0 e' J* g5 z. @' f6 w6 a1 F - reqipass <search>
! {$ [8 u( v* t2 d1 C- x+ T, P - reqrep <search> <replace>
* @ L9 H% v' v" L* ^ - reqirep <search> <replace>
: X- z' x, B; |& r% h. g4 x& R2 i h5 m - reqtarpit <search>1 G* W7 v. E! e9 p& J. Y+ J
- reqitarpit <search>, X1 H( \5 A4 i
- rspadd <string>3 J( l3 a* a9 W+ m/ r5 g) W
- rspdel <search>3 T& L6 B' x' O1 Y& B' z1 e
- rspidel <search>) L0 e7 M) t9 r; {& O/ D) T
- rspdeny <search>& V U5 g ]; q. \
- rspideny <search>
: b# A8 N" G4 r- Q; O: p0 j - rsprep <search> <replace>, R1 e9 g1 S' A$ @
- rspirep <search> <replace>
/ P! j/ |' S$ w+ l9 K! a) F/ k! b
With all these keywords, the same conventions are used. The <search> parameter- H7 m- d0 Z+ u4 ?& H5 W
is a POSIX extended regular expression (regex) which supports grouping through8 ~$ b& X' B) l" w
parenthesis (without the backslash). Spaces and other delimiters must be5 Y3 }9 M* W5 P' G
prefixed with a backslash ('\') to avoid confusion with a field delimiter.4 ]" U# p& ^8 X; R1 G' r
Other characters may be prefixed with a backslash to change their meaning :
1 F8 k% @; Q. p" r+ A
& j' y5 u. K& W. P \t for a tab3 T) B0 P2 H4 G( q% u( _' w
\r for a carriage return (CR)
% N/ Y* T0 u- z; ]2 y \n for a new line (LF): Q& R* N- t) D
\ to mark a space and differentiate it from a delimiter- {, l5 D7 R @2 {/ I5 [
\# to mark a sharp and differentiate it from a comment% C6 Q# T: Y; |& v
\\ to use a backslash in a regex
$ ]$ `. S i$ }0 w$ j3 } \\\\ to use a backslash in the text (*2 for regex, *2 for haproxy)' J o+ j: n2 y4 B
\xXX to write the ASCII hex code XX as in the C language: S7 n5 ? A1 e& b* Y/ b# d
/ X+ l& Q8 T* X* lThe <replace> parameter contains the string to be used to replace the largest( K' D8 ~% y, j6 p
portion of text matching the regex. It can make use of the special characters
/ ]$ i4 f- }& d1 l& b$ S; B: Eabove, and can reference a substring which is delimited by parenthesis in the
; B7 z D# L2 z6 t1 K. lregex, by writing a backslash ('\') immediately followed by one digit from 0 to
2 ], R5 ^% F3 y8 A0 t! C9 indicating the group position (0 designating the entire line). This practice' X1 q7 j. F+ v7 ]7 S( ^8 p* ~
is very common to users of the "sed" program.5 I* N+ l9 `& V. k1 D$ e. z% d
7 `% l: M& T K' g" N/ OThe <string> parameter represents the string which will systematically be added
" ~; U2 m& R4 `6 O$ U |( dafter the last header line. It can also use special character sequences above.8 B/ u1 K9 U T( c3 D1 B) b$ ]! h
7 V! N5 x2 R, f) p$ y [5 t
Notes related to these keywords :
$ B6 z. Z# z" e2 K$ @. Y, Y- j9 U---------------------------------( b- q* F' W2 ^+ B
- these keywords are not always convenient to allow/deny based on header
+ E1 }$ E& ~4 {2 W contents. It is strongly recommended to use ACLs with the "block" keyword
- S/ }- |* p9 B instead, resulting in far more flexible and manageable rules.
. a0 {/ y9 n( g1 N8 q6 F" U4 l1 F, I
- lines are always considered as a whole. It is not possible to reference
* X7 [4 N4 J- A3 z' J2 T7 m8 ]$ } a header name only or a value only. This is important because of the way
/ r3 F# k2 `& w# T) C headers are written (notably the number of spaces after the colon).
5 U* w7 ~3 |+ D1 k* A8 G2 x0 X. z/ y5 ]" N3 w
- the first line is always considered as a header, which makes it possible to$ O1 p8 }0 ~4 P" B# r# T
rewrite or filter HTTP requests URIs or response codes, but in turn makes1 \& ^" q9 q8 \$ l& {1 m8 l
it harder to distinguish between headers and request line. The regex prefix
! X z. }5 \( G) J0 B" Q9 J8 o9 R4 z ^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix- w! b( y; P7 `) f& x) x) F
^[^ \t:]*: matches any header name followed by a colon." U; ]* e1 f0 r
2 R' \$ c* U% ]9 V. \9 }% W8 b- a( A1 o) m
- for performances reasons, the number of characters added to a request or to( e6 e9 o& A& w5 w
a response is limited at build time to values between 1 and 4 kB. This
8 x: O- q" F$ N! O: N should normally be far more than enough for most usages. If it is too short2 R& Y2 i1 _8 z" b
on occasional usages, it is possible to gain some space by removing some
/ ?: i# v5 D8 m$ C- A0 c useless headers before adding new ones.
# e" k: _$ a! B: y# |( M% H7 G0 d L4 e
- keywords beginning with "reqi" and "rspi" are the same as their counterpart+ Q }# t& V/ L" E
without the 'i' letter except that they ignore case when matching patterns.5 W0 S8 t6 j/ m/ F
8 p$ M& o) T- P& M - when a request passes through a frontend then a backend, all req* rules
! z7 L2 `9 I; X6 x: j from the frontend will be evaluated, then all req* rules from the backend
4 A' E- f b: n0 ?1 `+ U3 t5 ?7 _ will be evaluated. The reverse path is applied to responses.
& o& `1 @- j- x9 |8 R
' e# n# N8 t% L! X' V& v - req* statements are applied after "block" statements, so that "block" is4 M9 Y) w, c$ v( b! W( O
always the first one, but before "use_backend" in order to permit rewriting
2 z( r% F" b& O3 J2 s) ~+ q before switching.
9 Z% `0 O, P# w* @6 [ s
! D1 d' i- A5 M `( v% Q
. G" x; G4 y5 y4 q9 B( b7. Using ACLs and pattern extraction8 I6 J( Q& g0 i {; N; P
------------------------------------ r& G, T" G4 h: P O- `
3 n; t0 Z2 t& l) a' ^8 T
The use of Access Control Lists (ACL) provides a flexible solution to perform7 l0 K$ @$ ^% E! g
content switching and generally to take decisions based on content extracted
5 j$ C S- J2 \# K7 n& g4 i# D n! [from the request, the response or any environmental status. The principle is
z; U0 ~: Q* Lsimple :3 I3 x* f" W3 P; c
w$ ^$ |! x9 k F' m1 {; j - define test criteria with sets of values' M! j( e1 I D; \" [! X
- perform actions only if a set of tests is valid
. R4 @# i7 x3 W
0 I6 _+ }/ Y# f# HThe actions generally consist in blocking the request, or selecting a backend.# `( t, z/ e D S' T# }8 H
1 x% R! J8 N* j% d7 a
In order to define a test, the "acl" keyword is used. The syntax is :
7 D: H) G! N3 f0 C% b$ J6 r% T7 h' s2 f3 V1 O$ j) ^, E
acl <aclname> <criterion> [flags] [operator] <value> ...
( B! ^) v* d! ~+ Q9 m) { @5 ?, v3 v6 z6 H: ]# X
This creates a new ACL <aclname> or completes an existing one with new tests.. w, i( w1 S w1 N
Those tests apply to the portion of request/response specified in <criterion>5 t' l* Y& w( Y/ s# G$ F
and may be adjusted with optional flags [flags]. Some criteria also support
+ P1 z, Y0 I$ S- l6 f- man operator which may be specified before the set of values. The values are
2 ]% |2 S4 n6 j" Rof the type supported by the criterion, and are separated by spaces.: @! [5 w3 ~0 I3 F: {( W8 ^/ [
9 d; \5 } n4 p1 {: _: \9 f
ACL names must be formed from upper and lower case letters, digits, '-' (dash),& ]$ T/ o" q0 j2 g! n4 C* o) U& [
'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,( ~; f+ b1 `) M
which means that "my_acl" and "My_Acl" are two different ACLs.+ p2 S$ @! K- `
# p; k; Z; J5 [: B
There is no enforced limit to the number of ACLs. The unused ones do not affect. O5 E: C% @/ @- `! m) Y6 e
performance, they just consume a small amount of memory.
6 Z( K" g' F7 q+ {0 b4 H0 Q4 k" Z
1 v9 w2 g. E5 c: H Q8 ~The following ACL flags are currently supported :
0 S% t( k- Y/ `6 E5 W2 E7 h3 Q/ b5 o0 L3 t
-i : ignore case during matching of all subsequent patterns.1 O& u% m: s0 b) @# P3 y# K# p
-f : load patterns from a file./ C* V9 R6 [) v
-- : force end of flags. Useful when a string looks like one of the flags.
- I+ O3 N! `' T
1 L( ?' e T: YThe "-f" flag is special as it loads all of the lines it finds in the file9 Y" T k! _! q$ x
specified in argument and loads all of them before continuing. It is even3 x+ b2 R/ d/ Y2 _
possible to pass multiple "-f" arguments if the patterns are to be loaded from! q3 c3 F( f0 c/ V% {
multiple files. Empty lines as well as lines beginning with a sharp ('#') will
' i( ^5 Q/ m6 S- Rbe ignored. All leading spaces and tabs will be stripped. If it is absolutely1 U3 i( D) _7 h1 u& G; @; s- R
needed to insert a valid pattern beginning with a sharp, just prefix it with a( T" O5 Z( V0 k2 g' [
space so that it is not taken for a comment. Depending on the data type and
3 ?1 H6 Y& J* pmatch method, haproxy may load the lines into a binary tree, allowing very fast; P0 w# D) O" N9 i- }" ?: D2 i8 P
lookups. This is true for IPv4 and exact string matching. In this case,+ |5 R" R2 b- P3 T; h, m
duplicates will automatically be removed. Also, note that the "-i" flag applies7 _4 i+ v* O) O, T) ]! I
to subsequent entries and not to entries loaded from files preceeding it. For
' W0 S; V% o- i7 p+ finstance :
% v8 F. u7 v9 q6 g; ]: D) r3 X' _9 Y b/ s
acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test
* N) z6 n6 J1 I3 o& n3 M1 J8 Y) f% M+ _/ c @# \9 l" f
In this example, each line of "exact-ua.lst" will be exactly matched against
( B; C7 L: b3 i) X* cthe "user-agent" header of the request. Then each line of "generic-ua" will be
+ h6 T2 u4 l' S( `! L# Ocase-insensitively matched. Then the word "test" will be insensitively matched1 }! k6 S9 b' M, Y/ }
too.8 A3 p4 W4 m+ s& R. h; {! R
/ G5 |8 j- U& E* n5 U, @* t' xNote that right now it is difficult for the ACL parsers to report errors, so if
( x; d: J6 s g7 Q# z4 @a file is unreadable or unparsable, the most you'll get is a parse error in the
* C* G9 Z# ~) ]. V6 y" nACL. Thus, file-based ACLs should only be produced by reliable processes.
0 K+ O( |, q) i9 X- B
& I O2 G) q3 m) l# {6 @Supported types of values are :7 _$ ]2 B+ `* H7 M4 P- D4 K) g
5 l* C# x7 ]9 Z - integers or integer ranges
" G0 ]0 l/ ]1 k) T( Y1 k8 t - strings) ^$ D; Y9 s+ z6 O
- regular expressions7 J0 z2 S! u$ U% [" w
- IP addresses and networks) Q0 e) k# ^, g2 |8 C
6 F8 F$ Y; L q/ |
4 t8 O) f, ^/ Q7 v7 @6 U7.1. Matching integers3 ?1 B' d) P9 r1 [5 p- M- K
----------------------
7 ] n( B2 A% `/ w6 f; F8 Z
/ z: }" {* t2 ^! C5 r, Y2 FMatching integers is special in that ranges and operators are permitted. Note
. l; D) T) G) E6 N: Zthat integer matching only applies to positive values. A range is a value
+ Z1 q0 O/ y5 eexpressed with a lower and an upper bound separated with a colon, both of which
4 [- l, d" O/ F6 k. `9 ~/ @0 omay be omitted.
. w/ i8 j% ?5 a, B/ N% \4 V1 O! b" c: I; u. }
For instance, "1024:65535" is a valid range to represent a range of
/ s8 w3 v4 @& @' ]* |0 |unprivileged ports, and "1024:" would also work. "0:1023" is a valid
4 q4 _! U4 t$ |( \# k% i0 i8 {3 q1 _0 Nrepresentation of privileged ports, and ":1023" would also work.
. m, G( t6 O9 g# T# M. D+ I
8 j0 Q, s; K7 `; t% g- j. Q* @( n7 tAs a special case, some ACL functions support decimal numbers which are in fact4 F0 ^0 h+ m# l0 C2 l8 \2 w/ q
two integers separated by a dot. This is used with some version checks for
$ N! [% Q( I4 x9 {" j0 oinstance. All integer properties apply to those decimal numbers, including
: e7 I+ c& Y; R% }, @! hranges and operators.( B- S" K% t* g, x5 s" M+ y! x+ N
; Z3 ]! A3 {" W; N2 _For an easier usage, comparison operators are also supported. Note that using, E$ L4 K6 m9 `$ t. A0 E
operators with ranges does not make much sense and is strongly discouraged.3 [, [ C; I/ I9 M( x# Z
Similarly, it does not make much sense to perform order comparisons with a set
. A% T F7 ^2 k! H$ k# sof values.9 c/ C. ?* y$ i+ W
& Y3 U( \# X+ E D$ w5 y; @& F$ N- d
Available operators for integer matching are :
' Y5 t; F6 s' Y+ h$ v9 H
4 z( U. J' j( q) d7 I2 w. r7 Q eq : true if the tested value equals at least one value
& Y3 B) l" a6 t: S0 }8 i7 B ge : true if the tested value is greater than or equal to at least one value
# Y u% K! R( P gt : true if the tested value is greater than at least one value2 d8 V7 J' Q" `1 H( d
le : true if the tested value is less than or equal to at least one value
: B- S& Y" u# Q: L+ B lt : true if the tested value is less than at least one value1 f$ n5 f O u( Z+ ?: B( [
! o n: a& ?8 k# ]" t- L
For instance, the following ACL matches any negative Content-Length header :2 P$ L* J5 B. g8 R
/ y6 q7 N3 W' o" _' c acl negative-length hdr_val(content-length) lt 0
! Z& t6 S' w. ]% J% @& d9 s& N' C- o
- D! x4 d/ D5 f2 AThis one matches SSL versions between 3.0 and 3.1 (inclusive) :+ x+ C A0 ^/ t7 s
9 ~ m" x N1 s
acl sslv3 req_ssl_ver 3:3.1& w1 a# w6 `$ s* d& y' G, D! C, ]) F
% C2 g) Y/ c$ w# P
8 Q& [1 A: G% z/ S1 x7.2. Matching strings
) B4 J% ~* g; i3 J) Y---------------------7 j5 q- g6 f# r
' a8 A! V$ K! F1 f- C7 ?& O* JString matching applies to verbatim strings as they are passed, with the
7 G/ I1 _3 k/ B j6 D5 jexception of the backslash ("\") which makes it possible to escape some
/ e* c9 f" e5 Y( s) Q0 `0 R" ~characters such as the space. If the "-i" flag is passed before the first! O* Z6 V4 Q, Q3 b
string, then the matching will be performed ignoring the case. In order5 F b7 u, Z' }$ [. y W
to match the string "-i", either set it second, or pass the "--" flag
$ |% L. X! f: \6 S, g& x9 Ibefore the first string. Same applies of course to match the string "--". p4 F) w6 \, Y1 }7 s
+ M" Z3 x( S' L& {" p7 P2 i3 E: A
' k) k8 v g8 }& ?/ E
7.3. Matching regular expressions (regexes)7 i% r' T/ U, I) |
-------------------------------------------2 o; p1 Y8 |) N- }
' d: `4 I" B+ ~. [Just like with string matching, regex matching applies to verbatim strings as
! u, T& A& [& c5 O, ythey are passed, with the exception of the backslash ("\") which makes it) ?8 q9 I; D. j! B* ~
possible to escape some characters such as the space. If the "-i" flag is
& U4 N) T6 v: U- V2 Kpassed before the first regex, then the matching will be performed ignoring
. n2 ^/ a' W) j! U: Jthe case. In order to match the string "-i", either set it second, or pass- j9 u. G# P% @) H2 n
the "--" flag before the first string. Same principle applies of course to" j0 a, M& q+ `* [7 B
match the string "--".
* C7 W$ R: q9 x% R# Z2 z
+ \6 P% ]: X" @; ?# Q6 A7 X: k
- N: N( a% v; N8 C7.4. Matching IPv4 addresses
+ H# z0 r" [, {& J8 p----------------------------
3 [( p3 k4 T+ \( k R% f- l( Q0 ~( C& a/ R
IPv4 addresses values can be specified either as plain addresses or with a* o( y `" \ t1 j7 }$ r
netmask appended, in which case the IPv4 address matches whenever it is! ]# |) k$ w) s) Z/ s9 q: v
within the network. Plain addresses may also be replaced with a resolvable1 \) }9 }1 J* ^, s+ n$ R. m: E& z
host name, but this practice is generally discouraged as it makes it more; d# X1 R$ a* O
difficult to read and debug configurations. If hostnames are used, you should
. C- J ?( T. O, Cat least ensure that they are present in /etc/hosts so that the configuration
9 w9 K9 a6 u6 Ddoes not depend on any random DNS match at the moment the configuration is. V- k" o' Z2 G* e
parsed., f2 \; t. l' u2 F1 B- R9 F# W
& x* T5 N) E* O6 D$ _- V! D( a( W6 D) v; X; t l
7.5. Available matching criteria
! B3 { V/ T3 `/ F- I1 v--------------------------------( `2 W* Q- ?' q/ W7 m4 G
/ I$ Y' g i- p
7.5.1. Matching at Layer 4 and below3 L$ H X2 y G4 U0 g
------------------------------------: p3 g: a) l: Y8 I0 L2 ]$ Y& L
- t+ M9 _" ]& { t
A first set of criteria applies to information which does not require any
7 ~2 q+ h M! ^8 panalysis of the request or response contents. Those generally include TCP/IP" \" Q! P3 c( w* R
addresses and ports, as well as internal values independant on the stream.+ p% r: k" y( M% e! X C+ f
+ A2 A, `( F' y5 H# `# p( J
always_false
7 Y6 N. [2 ?- S' ^ This one never matches. All values and flags are ignored. It may be used as. w9 V# b7 U' G/ q
a temporary replacement for another one when adjusting configurations.
& Y/ S, Z7 ~" y% _9 [$ O4 B
2 |- e% X+ [6 ~, D2 W! ]3 @/ V$ Y- `always_true
4 l @. C# P7 X5 k/ U/ E$ h6 U( X: F+ v This one always matches. All values and flags are ignored. It may be used as
' o7 O% @1 X0 H1 | a temporary replacement for another one when adjusting configurations.$ x/ v% j& G7 H1 z `; i1 L1 G
% N. _' H( T; G
avg_queue <integer>
7 Z3 l7 z6 e$ ~4 l; R9 e: V( y5 H4 Xavg_queue(backend) <integer>, y4 ?4 N: a# M
Returns the total number of queued connections of the designated backend: b- V6 v' [6 R
divided by the number of active servers. This is very similar to "queue"& k. ]) l6 ~3 ]4 M! L3 W! H* e
except that the size of the farm is considered, in order to give a more& w" x( @$ e: J' Q/ g' i
accurate measurement of the time it may take for a new connection to be7 Y8 `# n! e0 r* A! W; \7 q! y; k
processed. The main usage is to return a sorry page to new users when it
/ g/ a% s! U- _$ j1 Z9 M becomes certain they will get a degraded service. Note that in the event% @9 n* b) S9 r8 v
there would not be any active server anymore, we would consider twice the5 R! D, ?+ F8 C/ J0 q8 ?$ ~) ]/ Y
number of queued connections as the measured value. This is a fair estimate, {6 x2 U/ G4 Q& l$ F6 @% W* |
as we expect one server to get back soon anyway, but we still prefer to send
# ~' |3 [ `/ f& ^" M new traffic to another backend if in better shape. See also the "queue",
3 z% n0 M& t" H* p- _ "be_conn", and "be_sess_rate" criteria.
: M( ~! S8 {) |( \4 d* R- R0 b) \- f+ z9 b: q M6 d! l
be_conn <integer> P) ]. A \$ z& M
be_conn(backend) <integer>7 h3 X1 W# }8 ?. [; O; X# z
Applies to the number of currently established connections on the backend,3 P3 Q/ N) J- L2 W/ k. ^6 d
possibly including the connection being evaluated. If no backend name is
* \$ R( z! {+ U" W specified, the current one is used. But it is also possible to check another
/ ~: {- m- h6 Z backend. It can be used to use a specific farm when the nominal one is full.
1 Q1 n% |% a% |6 C4 o See also the "fe_conn", "queue" and "be_sess_rate" criteria.0 d ]8 ?3 r0 }& ^4 K1 W3 @5 m
" L$ A/ a% u7 cbe_id <integer>
; ?5 ]$ J/ \1 h; y9 @1 W6 U/ G( g+ e Applies to the backend's id. Can be used in frontends to check from which g0 h$ Z9 g% X8 S3 d
backend it was called.! |! M8 P& j7 O0 R' h
9 f+ o! _0 m$ ^% d: ]. r* y* z4 ibe_sess_rate <integer>; K) Q; G. q; ]1 ^
be_sess_rate(backend) <integer>
4 v( E2 L) i/ k: g( I) j Returns true when the sessions creation rate on the backend matches the1 Z8 ^1 b5 j# k; D) S
specified values or ranges, in number of new sessions per second. This is. w ? U, o3 Y. u) |( x& d9 C
used to switch to an alternate backend when an expensive or fragile one8 L. W$ Y5 t Q- H* T' l
reaches too high a session rate, or to limit abuse of service (eg. prevent
k& W# ~' q& R% [' R5 j sucking of an online dictionary).
; l* S) F% T q( f6 j
' D" C6 C, C9 A1 N* |- C. w Example :
8 T& w8 [" _4 P2 E Z # Redirect to an error page if the dictionary is requested too often
0 V6 l4 C( E/ X% v9 C$ g+ n backend dynamic E f/ n$ Y5 q' f
mode http
% t5 C1 P5 Q( g3 Y' c/ q0 W acl being_scanned be_sess_rate gt 100
* U% _- ~. s7 e7 D0 F redirect location /denied.html if being_scanned; D9 d' b) o' a" @8 c( G# u0 k) O
, A' v/ n0 H. Y$ b2 v- Econnslots <integer> Y. X8 t/ _' t
connslots(backend) <integer>
+ e8 b* m; b% G7 q7 C: a The basic idea here is to be able to measure the number of connection "slots"3 I! J% ]2 n3 C8 f
still available (connection + queue), so that anything beyond that (intended
. z( ^) @; ]# ` usage; see "use_backend" keyword) can be redirected to a different backend.) e# W0 M8 L* D: N# k( |
) K7 M- [$ x6 b* K
'connslots' = number of available server connection slots, + number of
7 W9 [5 H1 z0 e available server queue slots.
, ~3 u& K7 E$ Q" d- Z# C8 h d" [8 n3 N( L! d9 J, v- E1 z" K
Note that while "fe_conn" may be used, "connslots" comes in especially
F/ t7 U4 G* x useful when you have a case of traffic going to one single ip, splitting into+ e: \8 h# W' ?8 G( Y( C8 c1 L
multiple backends (perhaps using acls to do name-based load balancing) and
3 Y8 v4 A: K2 a you want to be able to differentiate between different backends, and their7 L+ D5 K- b, h% V1 U5 j9 o4 l
available "connslots". Also, whereas "nbsrv" only measures servers that are& [# d6 V, y, C' Z# a
actually *down*, this acl is more fine-grained and looks into the number of6 D% r2 ^ W- y: E+ p0 Q
available connection slots as well. See also "queue" and "avg_queue".8 Z* ?! l3 v! [
6 C4 U- b. k8 q; q OTHER CAVEATS AND NOTES: at this point in time, the code does not take care
) ~1 y) n4 J& g& d of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,# Y: ~7 N/ ~" R( H" T
then this acl clearly does not make sense, in which case the value returned2 N4 a7 r! _6 ~* B8 a! @; V
will be -1.
) Q& D* b4 T ?1 \# G; F
7 W, p7 N8 X+ Cdst <ip_address>
( G% M4 r; h* W3 } Applies to the local IPv4 address the client connected to. It can be used to; _' {, T2 j7 b) P& l" [* Z+ X2 |
switch to a different backend for some alternative addresses.6 F* r1 \" \9 B+ p' _9 a9 r
. H( h7 a0 l# w% d
dst_conn <integer>0 D) _. \) s# @ r
Applies to the number of currently established connections on the same socket; B3 l8 O5 H) x6 y) E5 U
including the one being evaluated. It can be used to either return a sorry$ |' q1 K8 k6 p0 }
page before hard-blocking, or to use a specific backend to drain new requests
, E$ S1 C* g5 J Q, `: t when the socket is considered saturated. This offers the ability to assign, Q! |4 g; S# r. t6 q
different limits to different listening ports or addresses. See also the- b3 d7 H1 J9 T
"fe_conn" and "be_conn" criteria.
2 U: o8 _/ L8 E* a+ g. d' L; |
- |% o1 O k, W) a; Jdst_port <integer>: l. ]+ o! A( }3 y( h* N
Applies to the local port the client connected to. It can be used to switch, B4 F& D6 { F0 {4 _/ q+ R0 X% y
to a different backend for some alternative ports.) D& R8 }. x+ e5 a$ w
! @" s9 l- D3 M+ W; E, K
fe_conn <integer>
8 r, \8 w! F+ ? D8 i8 ~0 M4 M; afe_conn(frontend) <integer>
/ g9 U% x9 g% Y. S3 ? Applies to the number of currently established connections on the frontend,
* [. _1 F0 q0 `; o4 ?2 V5 D possibly including the connection being evaluated. If no frontend name is$ E1 x( m- K4 G$ `" z
specified, the current one is used. But it is also possible to check another. }8 g4 b9 W9 d& Y7 x
frontend. It can be used to either return a sorry page before hard-blocking,
1 R# o4 ?9 b. v6 G& W ?+ n or to use a specific backend to drain new requests when the farm is( t2 C, d1 o: `( W
considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"
& a% r% `$ Y* r, c2 B! o3 M+ H criteria." k' D, S+ _ G3 T
) [1 T% P& e& D6 f, Z
fe_id <integer>7 n8 E: I: Y& z# Z v) A
Applies to the frontend's id. Can be used in backends to check from which
) h5 ]4 S% R R frontend it was called.
) \7 m; J6 {, }* G; Q: ?: l: a4 }- S3 y) p* g. [
fe_sess_rate <integer>
5 ]# r, Z6 J( a) n, i/ Wfe_sess_rate(frontend) <integer>
; M! d; d3 M z* k9 E7 s Returns true when the session creation rate on the current or the named
' Z* X. C" Q4 |1 i: C$ z frontend matches the specified values or ranges, expressed in new sessions
4 i( ?7 ?' S R8 i: {& R& ~+ { per second. This is used to limit the connection rate to acceptable ranges in
* X( ~( J' t# c0 M& | order to prevent abuse of service at the earliest moment. This can be
k6 m4 d0 Y4 r7 a+ P2 } combined with layer 4 ACLs in order to force the clients to wait a bit for
l" K% x" b1 z5 ]( J the rate to go down below the limit.
: }; i0 j( d# Q8 p3 o& w* a$ m, S+ h
! z0 Y- ~% L1 f( V7 r7 g9 A Example :
: p- \/ H. r, T0 a7 e5 b7 ? # This frontend limits incoming mails to 10/s with a max of 1005 a- k7 s, T* Y% W
# concurrent connections. We accept any connection below 10/s, and2 m& @& m; u8 M B8 K' D2 V" C
# force excess clients to wait for 100 ms. Since clients are limited to
: d, c; C4 v3 \" ? I' E+ Q # 100 max, there cannot be more than 10 incoming mails per second./ ?9 X2 t: \% H+ j# X
frontend mail$ H9 l- ?( G0 Y, ^% v% T0 u( g; S
bind :250 t8 ?& N$ F- L1 I* m. E
mode tcp
~2 r' W4 A. z) B maxconn 100
& T1 t) {8 D; b acl too_fast fe_sess_rate ge 10
' y8 l4 N$ C( b# U tcp-request inspect-delay 100ms
9 l9 M {7 a$ X2 D) T7 K0 I; ~ tcp-request content accept if ! too_fast# V; B& c% ^6 L7 _" n: W" `
tcp-request content accept if WAIT_END ~. B3 i) O+ K. N3 t8 H
2 E. v; {! `5 V8 s. Tnbsrv <integer>
' t y3 L. M# j( `- J; n# ^& Qnbsrv(backend) <integer>
" Y3 I! B$ u# Y. C! o' u Returns true when the number of usable servers of either the current backend
+ Y9 v0 ~, x: H: }% X; Q+ y or the named backend matches the values or ranges specified. This is used to
; n) w# n4 D7 {, r% g( v* O& B( g switch to an alternate backend when the number of servers is too low to0 a- V; y/ v& N( s! [' [
to handle some load. It is useful to report a failure when combined with& U5 M t. n- l8 C4 `- R4 I/ p
"monitor fail". ^/ O2 P2 d _6 b, o, d
; v9 z$ u3 ~) ?' d& c. L5 Y$ H. v6 d7 Q
queue <integer>
`+ c3 s0 u3 a( {! rqueue(backend) <integer>& S- L( r2 o( _8 J
Returns the total number of queued connections of the designated backend,/ F" b' @ c) n/ u2 B
including all the connections in server queues. If no backend name is6 d6 T3 ^/ K' t5 g! ~
specified, the current one is used, but it is also possible to check another6 y5 U( R2 _% t
one. This can be used to take actions when queuing goes above a known level,0 O: ?6 N' h0 z8 o7 R. y1 w8 B
generally indicating a surge of traffic or a massive slowdown on the servers.
/ S6 ^) y0 q- E1 D+ |& i One possible action could be to reject new users but still accept old ones.
) P6 p1 z. g- c2 }3 T See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.8 M# t* b I( i }
+ F5 V7 }7 u% O# E7 J
so_id <integer>/ U+ s% g. F- m- R) N
Applies to the socket's id. Useful in frontends with many bind keywords.% z1 u) E! O! q0 P0 m6 a
6 F9 y, a9 t2 m" ?1 }
src <ip_address>
) l9 y& r0 C- C# q' l% l Applies to the client's IPv4 address. It is usually used to limit access to
2 W1 `& a% q8 x, o certain resources such as statistics. Note that it is the TCP-level source
$ z2 _! D2 {0 X5 J& v+ N address which is used, and not the address of a client behind a proxy.
, \. ?, p3 ~4 S1 T! ^0 Y4 P
4 G- A1 [1 e0 N Qsrc_port <integer>
' Z* W- |1 \" [& X) p Applies to the client's TCP source port. This has a very limited usage.
3 L* C4 E {8 O. S X, `- j0 s2 Q. J
srv_id <integer>
$ G# Y( d7 i z. k! F1 I$ P Applies to the server's id. Can be used in frontends or backends.
9 {4 \" ~- W9 E' h5 _3 y6 ^. ]' n- O7 a, A# q G" u& Q
srv_is_up(<server>)' b N1 f. i5 C% x- k, u7 l. [
srv_is_up(<backend>/<server>)
6 A5 Q6 g1 [9 _ Returns true when the designated server is UP, and false when it is either$ f! X$ \( w- w' l' u
DOWN or in maintenance mode. If <backend> is omitted, then the server is
) `8 ~3 }. Q1 f2 {+ J looked up in the current backend. The function takes no arguments since it
6 \6 k7 H1 Y$ y' \( P, G is used as a boolean. It is mainly used to take action based on an external% {! }( M) J/ R
status reported via a health check (eg: a geographical site's availability).
/ Q3 U) V9 v; b/ \. M: F Another possible use which is more of a hack consists in using dummy servers- U/ |* i U" F" a
as boolean variables that can be enabled or disabled from the CLI, so that
. o) C7 _! Y3 T* f+ s( r rules depending on those ACLs can be tweaked in realtime.
0 a9 g- [! e3 h0 n, @% C- ^' H# i5 k
! K/ o* T1 L/ _: f7.5.2. Matching contents at Layer 4
, u8 u, n% R/ n-----------------------------------9 ~6 P! g$ \1 v5 d
; U- {7 Z* G+ u/ w' JA second set of criteria depends on data found in buffers, but which can change
! r3 Y' h; g4 H" D2 [. @& uduring analysis. This requires that some data has been buffered, for instance. ~, Q6 U3 t+ A$ b7 {) Y9 f
through TCP request content inspection. Please see the "tcp-request" keyword0 l+ ?) D) ]7 e5 B- n- k, I% l
for more detailed information on the subject.
2 G! D( z) U1 q; d0 ~+ R+ S4 `2 \6 V2 }4 ~
req_len <integer>1 K. ~; @) M5 A7 y8 Q6 t9 }1 M
Returns true when the length of the data in the request buffer matches the
, h4 U/ U2 W; U3 l specified range. It is important to understand that this test does not5 }; C F1 h, s& R/ G' V7 S& y
return false as long as the buffer is changing. This means that a check with
2 _/ ]2 Q" m' e# v5 n equality to zero will almost always immediately match at the beginning of the$ J5 x) s' e. K' I4 O" R, v
session, while a test for more data will wait for that data to come in and
7 i, u( x& L5 W; a) Y/ r* j return false only when haproxy is certain that no more data will come in.
) {# P8 q4 o2 Z# U% U7 F t This test was designed to be used with TCP request content inspection.
+ ^& h/ o4 l4 j+ N) p9 V& i8 Y
' A0 a6 Y5 h1 Z; U wreq_proto_http
h- L; h0 C" m7 S Returns true when data in the request buffer look like HTTP and correctly( |8 G' e% V: Y3 i+ d
parses as such. It is the same parser as the common HTTP request parser which* |3 J: L( Z: S1 l
is used so there should be no surprises. This test can be used for instance
9 l/ N# \3 Y; J0 T% t4 J, Z+ ? to direct HTTP traffic to a given port and HTTPS traffic to another one
! V' p* I( W9 V& J2 D/ } using TCP request content inspection rules.
' {6 h' b( k" Z+ {" d0 f. ~
8 O2 T* c6 J9 W& q, }req_rdp_cookie <string> H- T. C, x4 G" X2 C
req_rdp_cookie(name) <string>
8 A/ u. |3 x! G5 A1 E A Returns true when data in the request buffer look like the RDP protocol, and
% O: V B1 a* v8 _' r% j& H a cookie is present and equal to <string>. By default, any cookie name is
% Q ~ { L p! |; C checked, but a specific cookie name can be specified in parenthesis. The
! G# ~: ]* s* E& j* R5 V w parser only checks for the first cookie, as illustrated in the RDP protocol
8 X4 h1 r+ D* d specification. The cookie name is case insensitive. This ACL can be useful
* R% K6 v9 i# m @, i) e% h* v with the "MSTS" cookie, as it can contain the user name of the client
9 Y' o, h" ~; | v connecting to the server if properly configured on the client. This can be5 ~7 x( e9 W ~1 J
used to restrict access to certain servers to certain users.
! \- P! ?/ ?) {" _7 B3 r/ S
2 i% v& y: K% d; x8 o" D+ ~req_rdp_cookie_cnt <integer>* q/ f8 v2 y/ m3 [
req_rdp_cookie_cnt(name) <integer>& ]6 t) l2 K) k2 ^. |
Returns true when the data in the request buffer look like the RDP protocol" s( v: x5 e2 c3 N
and the number of RDP cookies matches the specified range (typically zero or1 H, q; C% `, k( U/ s6 ?8 J% B
one). Optionally a specific cookie name can be checked. This is a simple way( r( p7 ~ X) X7 B8 H+ J+ [3 S
of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH, _% h4 ?8 J; N }; V( P, U% |' F' s
cookies.
+ V) @7 n8 m o- y1 u
! s! f% _* o8 d, Vreq_ssl_ver <decimal>! J( [, L- H' O8 c
Returns true when data in the request buffer look like SSL, with a protocol8 `( c% v7 d) s8 G7 k& L# |/ j
version matching the specified range. Both SSLv2 hello messages and SSLv3! A" q& @1 z; R# b. k
messages are supported. The test tries to be strict enough to avoid being
( d( r9 x& r- S6 C8 j8 i easily fooled. In particular, it waits for as many bytes as announced in the/ @* n/ a0 n8 F, l+ d+ ~
message header if this header looks valid (bound to the buffer size). Note; o; o5 [, {1 P9 |3 a% J4 v
that TLSv1 is announced as SSL version 3.1. This test was designed to be used+ y4 G' q! K3 s7 q, s. x) I# B
with TCP request content inspection.
" S% `# y; H5 _( _* K
9 Q% c9 r: L: Y* E' i& r1 f' Vwait_end7 U. b* [/ \ c, i8 |( Z
Waits for the end of the analysis period to return true. This may be used in' @# M2 {6 w# O( Z$ W
conjunction with content analysis to avoid returning a wrong verdict early.& A) r; q+ {" ~; E6 `
It may also be used to delay some actions, such as a delayed reject for some* o% H, o8 h# ?5 k
special addresses. Since it either stops the rules evaluation or immediately7 l7 ^) X7 l! A5 Q7 `: q- R
returns true, it is recommended to use this acl as the last one in a rule.9 R5 u6 B: c1 M, L# |+ o8 o0 q- V, D N
Please note that the default ACL "WAIT_END" is always usable without prior
) H: ~' v( P/ S% M2 m4 k declaration. This test was designed to be used with TCP request content) E0 g1 i1 s0 q t
inspection.% p5 F8 d Q! ~
. Y4 \7 ]+ b4 {' O5 `7 \" n
Examples :
7 o( x" \0 _4 L9 o( [/ n # delay every incoming request by 2 seconds8 e6 S4 P5 m( d. L9 i
tcp-request inspect-delay 2s8 \& M4 W! {, i* ^$ ^* W, \
tcp-request content accept if WAIT_END1 ~5 @8 p0 A; u) w3 O) f
; i k9 e5 x* I1 X # don't immediately tell bad guys they are rejected1 b% ?; p' g; _& P( ]+ ?7 m( f
tcp-request inspect-delay 10s
7 L1 B# j8 ?1 l acl goodguys src 10.0.0.0/24
1 I* L/ {8 M5 R& J acl badguys src 10.0.1.0/24 ?5 ~: s. H; [: {& U; p
tcp-request content accept if goodguys9 }6 R. b \4 ?! H8 A/ d) ^4 |
tcp-request content reject if badguys WAIT_END
# r6 o, a' F) c( P) O) D: d. l tcp-request content reject' M% Q9 G) g `* O% C g
1 Y! u% D. B% d4 F
0 `( H2 c0 i O
7.5.3. Matching at Layer 75 D) y9 f0 n+ I/ B3 N: q+ S7 c0 |
--------------------------
8 A. Y. |* M: _7 }% p& u( D, b
6 f( v9 l: V+ s8 L& eA third set of criteria applies to information which can be found at the
7 T# f" m6 O6 @application layer (layer 7). Those require that a full HTTP request has been
( J- M- }/ P/ x( lread, and are only evaluated then. They may require slightly more CPU resources9 }9 v3 ~+ K$ ]1 v7 g9 f1 U+ l9 L
than the layer 4 ones, but not much since the request and response are indexed.
( m! Q& F. A) u+ n! { U1 Z ]! R$ D. {$ G4 t" z5 J& z
hdr <string>1 D* A' Z& F1 w* J0 o
hdr(header) <string>
& Q' Z+ F7 n5 T/ k9 V" G Note: all the "hdr*" matching criteria either apply to all headers, or to a
/ A8 e0 F! V, m6 a/ R5 k5 e2 |9 g particular header whose name is passed between parenthesis and without any
. b& O/ y9 Q( H$ z, ~% I4 r, O space. The header name is not case-sensitive. The header matching complies
! F, @' G. L; Q7 ~) G" ?& { with RFC2616, and treats as separate headers all values delimited by commas.
+ ` x; s# H J7 x/ n3 H8 m Use the shdr() variant for response headers sent by the server. B0 d3 B6 w! F
: Q0 _% s6 n8 f& U6 S- d* t! B6 ^
The "hdr" criteria returns true if any of the headers matching the criteria
; ~' [3 H9 Y, u match any of the strings. This can be used to check exact for values. For
3 f$ a! [. t) U$ o3 R. n, e- N instance, checking that "connection: close" is set :
" g! m) y/ L% |+ g! b
, X* f) o& o' ~2 }; c hdr(Connection) -i close) C2 e7 L7 x y- u8 S: ~
8 N" s3 X% o6 M6 V+ |! hhdr_beg <string>9 ?( `: A# I, M* c$ v
hdr_beg(header) <string>* ?! A6 y. O7 k9 ]9 n- D; K0 V
Returns true when one of the headers begins with one of the strings. See
, i% y8 O# q: P6 I "hdr" for more information on header matching. Use the shdr_beg() variant for
]4 D0 G! `* y# N3 v response headers sent by the server.5 m; o6 O0 B! w: O1 p9 S
$ p1 t! Y) W2 e. W e& A
hdr_cnt <integer>
k4 K0 W0 ]3 a6 L" @- t! Mhdr_cnt(header) <integer>% e3 F2 D% j6 y4 J
Returns true when the number of occurrence of the specified header matches
+ d5 y1 C9 y% S& {0 V" @ the values or ranges specified. It is important to remember that one header
1 ]- E- S8 C1 j2 |6 | line may count as several headers if it has several values. This is used to: ^6 E0 z4 R- z8 v
detect presence, absence or abuse of a specific header, as well as to block
! z" H# h6 g/ c0 Q5 ] request smuggling attacks by rejecting requests which contain more than one
' f! Z0 g: h; k of certain headers. See "hdr" for more information on header matching. Use9 H, C5 d" N i5 u2 N( ^( G4 o9 w
the shdr_cnt() variant for response headers sent by the server.( q8 a; {- x) S. f: X8 M6 D8 Y
1 [, q- j; x5 z0 Q3 Bhdr_dir <string>/ m+ x/ ^5 N- U% Q3 H
hdr_dir(header) <string>
: {7 B) ^# V- H2 m5 l3 r Returns true when one of the headers contains one of the strings either
4 c) F$ A* @& f& |. }9 @ isolated or delimited by slashes. This is used to perform filename or
6 l2 P/ \6 s9 z1 Y* a( Z directory name matching, and may be used with Referer. See "hdr" for more
9 U* h8 a/ V1 `% N information on header matching. Use the shdr_dir() variant for response! K' `) @/ j* k% X/ }% t5 z
headers sent by the server.
6 `' _% q. }, x% @# |( ]. Y! i
' F! O4 E; G" J4 S' Jhdr_dom <string>& p4 G) @/ l/ X7 j
hdr_dom(header) <string>
5 \3 a$ S; B. Q6 k7 y Returns true when one of the headers contains one of the strings either
6 q7 K* M k4 F8 Q: s2 `$ g& P isolated or delimited by dots. This is used to perform domain name matching,
D' a* A4 _, Z1 m and may be used with the Host header. See "hdr" for more information on
4 R) g9 m0 Q: b6 F }; E header matching. Use the shdr_dom() variant for response headers sent by the
% Z5 E2 Z1 N) ?; v! R server.$ O$ U5 `+ }- E# S" G% H- K- \% l
! y$ j: \4 n( n) G* n" o' }$ @hdr_end <string>
- a# n" j( F- [hdr_end(header) <string>
* D4 a2 W4 y t. f; Z% N+ o+ C Returns true when one of the headers ends with one of the strings. See "hdr"
/ x) g' f3 C: K& A' O4 M5 d8 N for more information on header matching. Use the shdr_end() variant for& K+ ~& h: q5 w- ^
response headers sent by the server.
2 T- ~" F1 B4 } \( ^) B# l
) V- D( ~, r9 f( ?, nhdr_ip <ip_address>" p- \6 r- D6 D) A) @( Z0 Y
hdr_ip(header) <ip_address>
, J: {, j) e) g- D1 j Returns true when one of the headers' values contains an IP address matching2 U7 V6 A. M1 @3 r9 n' C* C
<ip_address>. This is mainly used with headers such as X-Forwarded-For or
* ^" T1 z2 X. E/ h' m3 { X-Client-IP. See "hdr" for more information on header matching. Use the6 m) {. Q) d; m0 R# a# K1 x/ B
shdr_ip() variant for response headers sent by the server.
& L9 b2 v; Y, U- q* ^# Q
?1 ~, U/ n* w0 Ihdr_len <integer>& a) x: d8 \6 S* M
hdr_len(<header>) <integer>
t" _ ?% x; z Returns true when at least one of the headers has a length which matches the2 i& h$ ]" q' M
values or ranges specified. This may be used to detect empty or too large* I [- q8 m+ [; x
headers. See "hdr" for more information on header matching. Use the& g& A; o5 L& n2 K! i8 g
shdr_len() variant for response headers sent by the server.* q* | ~" V7 X( S
. @8 O7 s P P: Xhdr_reg <regex>) d" ]7 y+ s5 n' X+ w0 N) F. C ?
hdr_reg(header) <regex>9 o' w! k5 Z. y( g6 ?
Returns true when one of the headers matches of the regular expressions. It- `/ H9 j2 m! e% z1 z; Q; q5 A
can be used at any time, but it is important to remember that regex matching
% D( @% ^' r' P1 W) Z* Y is slower than other methods. See also other "hdr_" criteria, as well as: d! z( }0 e8 \8 O
"hdr" for more information on header matching. Use the shdr_reg() variant for: Y; l: j; d) M% L
response headers sent by the server.4 e* d0 V- y7 Z* P# w% p/ \
- g) a9 w7 A& N2 @6 Y. o4 _7 Thdr_sub <string>
- N4 W& l* s' ahdr_sub(header) <string>: t% ~; Y5 a: ~$ L9 k, P
Returns true when one of the headers contains one of the strings. See "hdr"9 q' q9 H- _: A6 P* ^
for more information on header matching. Use the shdr_sub() variant for* R6 Z2 C: m, W: H! E7 p) G
response headers sent by the server.
4 M2 ^1 }* x+ ?& ~$ u0 h: {1 c) L, [1 l/ d7 u% ?" o- Z
hdr_val <integer>
/ b9 ?7 ^) R2 S8 }6 Ohdr_val(header) <integer>
. O8 O* U7 ]* D Returns true when one of the headers starts with a number which matches the
+ @' f8 D0 D0 ]2 ~ values or ranges specified. This may be used to limit content-length to
! J; f1 s! O1 C$ T9 v- ?5 z acceptable values for example. See "hdr" for more information on header, Y1 z/ | d' z* w3 v4 W' i
matching. Use the shdr_val() variant for response headers sent by the server.! x6 |+ W+ T! k* I
/ `! B' ~$ ^* q6 w" ^http_auth(userlist)* U0 c% h! M! e* X
http_auth_group(userlist) <group> [<group>]* `7 r5 R* m8 V8 X7 X8 d
Returns true when authentication data received from the client matches2 r4 ^0 u1 N& R6 x( F
username & password stored on the userlist. It is also possible to
$ `( y3 w7 \9 \, j+ D' @ use http_auth_group to check if the user is assigned to at least one
! M9 C/ P) Z% h+ r; { of specified groups.6 |" {0 D- q- s9 |% s6 k
7 Z! x, `! g0 G/ e% Y
Currently only http basic auth is supported.
; {1 e* E* B4 T6 Y" s/ k1 o+ W/ w4 ` r: t) _/ F: C
http_first_req$ O c9 |" ~. { _% ]8 R' s
Returns true when the request being processed is the first one of the/ d" W% A, V+ ]4 k/ |
connection. This can be used to add or remove headers that may be missing
% E% K# ]4 j& A3 \ from some requests when a request is not the first one, or even to perform4 A$ r/ R) b8 H4 h' p7 j
some specific ACL checks only on the first request.
! s# l: z n- |
2 Z( z( ~1 j3 T4 p* Q8 |$ lmethod <string>
% \; A: j9 v" p6 d& G Applies to the method in the HTTP request, eg: "GET". Some predefined ACL" V7 t6 d% _" S) e# c
already check for most common methods.
: B5 s0 M u5 `( L5 _
6 K$ ~, a7 \+ A6 t7 c0 P7 f% cpath <string>
" V: J9 N" |4 _! v2 I' l* Q Returns true when the path part of the request, which starts at the first f7 s O5 C1 y: ], F5 w2 V; h" F
slash and ends before the question mark, equals one of the strings. It may be, U4 g, m; M3 Z
used to match known files, such as /favicon.ico.
' C8 T. ~7 i; z. q1 q6 s8 o4 f; E1 C
path_beg <string>7 u. P; @. ?7 l5 v" ?6 Q
Returns true when the path begins with one of the strings. This can be used
" a/ [/ c3 X3 G" ~. R- h to send certain directory names to alternative backends.3 `' F* H/ z+ m; ~1 ^
! I- A$ @2 X4 @; F" c' U8 ypath_dir <string>, p1 _, k) r% K2 {/ y: }$ W$ O8 S2 m
Returns true when one of the strings is found isolated or delimited with
8 P! s, j1 t' ~ j* o% ]7 X slashes in the path. This is used to perform filename or directory name% u- R9 s& F/ q1 L! @& k
matching without the risk of wrong match due to colliding prefixes. See also
6 v, N, ~) c* o3 j- x( K/ P "url_dir" and "path_sub".* B" S- X5 y' O C9 v. U- @
- K* o- A) a% |( X. I
path_dom <string>
3 s/ h) s/ s' N; ]$ k: o Returns true when one of the strings is found isolated or delimited with dots
- K' Q4 |( n1 C- v) ^5 N0 B+ C3 Q in the path. This may be used to perform domain name matching in proxy
f+ v# [4 b4 U( U requests. See also "path_sub" and "url_dom".
/ l3 K6 R$ N- s6 x+ d1 c1 M+ }3 g; L, q' T
path_end <string>
: y6 B6 l8 T. R! m2 j' k Returns true when the path ends with one of the strings. This may be used to
8 n5 G( w' X, a% x control file name extension.
* ]& b! m, B {6 `; v
+ c! D" R0 v5 A1 ?path_len <integer>
, Q: R" U" J2 B Returns true when the path length matches the values or ranges specified.
, r1 U$ {* G- _% c- v) e8 |% { This may be used to detect abusive requests for instance.
+ [1 _. _$ S0 G* ?8 B
* l5 x, }! V7 q( G! w; spath_reg <regex>
, V/ G" ~& D3 Q, n: Z Returns true when the path matches one of the regular expressions. It can be
! b9 K1 }' q q used any time, but it is important to remember that regex matching is slower
N; L; ~& B7 J4 U8 k than other methods. See also "url_reg" and all "path_" criteria.) c% l, O ^' l- d, V* I# a
5 T7 b1 G7 K6 H6 B5 @& Zpath_sub <string>
: _6 n, S4 e( U! g) y1 _) ` Returns true when the path contains one of the strings. It can be used to }4 g6 K: _2 {2 `( Y& \( S
detect particular patterns in paths, such as "../" for example. See also
: T$ Q. x* Z4 x, j/ S o "path_dir".
( B' B# J* F9 M9 B1 C
9 x% ?* |& ]0 Zreq_ver <string>+ m6 s. l- T; ]( |7 x/ q6 T
Applies to the version string in the HTTP request, eg: "1.0". Some predefined( h9 L! J) h9 D
ACL already check for versions 1.0 and 1.1.: D' G* d% M- J4 v1 P9 X6 K
; m- o+ f) f- R2 W# d8 N
status <integer>
( b2 `9 l4 M* C- J, p Applies to the HTTP status code in the HTTP response, eg: "302". It can be
$ ~) R1 S8 i8 z/ w8 _ used to act on responses depending on status ranges, for instance, remove
6 E* o& W3 |% i7 H9 c any Location header if the response is not a 3xx.
0 p4 S& o1 I2 o4 y) N* r+ J# O, ^; G5 F c. v! p
url <string>
- E* ?' i2 a5 Y6 Z0 z+ b, A/ o( N Applies to the whole URL passed in the request. The only real use is to match
# a/ x) @3 @# }+ ?6 i; C3 t9 N* f& E "*", for which there already is a predefined ACL.5 m5 f( f- b$ u8 V: }% p
( I- W: F( L; f/ d+ Q$ S
url_beg <string>% b& J5 a8 h+ ?: }- O2 X4 u
Returns true when the URL begins with one of the strings. This can be used to
9 r- d! @+ h9 v$ n; k9 A4 ` check whether a URL begins with a slash or with a protocol scheme.
- |9 @4 v+ q. H
( S2 _- V* C$ @5 G8 D, o h: T+ Burl_dir <string>
0 E) T: }5 D- K0 ^: i; F+ T ^ Returns true when one of the strings is found isolated or delimited with) o! D4 s' ^& n" Z# g, ~
slashes in the URL. This is used to perform filename or directory name1 p3 G$ }1 t9 p6 ^
matching without the risk of wrong match due to colliding prefixes. See also
- b/ `/ A$ C9 [/ |. H+ Q; M "path_dir" and "url_sub".7 t4 G! |* @. V
8 U8 b2 i5 j/ d" ]1 P V
url_dom <string>. E+ B7 Q* E0 T) d
Returns true when one of the strings is found isolated or delimited with dots
# @8 D+ U7 n# |5 A" k5 b) w9 w* d( l in the URL. This is used to perform domain name matching without the risk of, g! l* @* S! C9 U
wrong match due to colliding prefixes. See also "url_sub".
; ^, B; m( r% X, M7 A3 r
3 e. z9 {; h5 C, V" Gurl_end <string>, y% w- \# [) o8 }% g+ C
Returns true when the URL ends with one of the strings. It has very limited8 j! E$ I, M. Y
use. "path_end" should be used instead for filename matching.
" M2 B: s2 K R0 Z9 K7 r1 t3 C& M% @ h" r+ n, c; m
url_ip <ip_address>9 c' ?4 S* l3 g# ~; O
Applies to the IP address specified in the absolute URI in an HTTP request.
2 y- j; h2 a3 U g/ K4 o It can be used to prevent access to certain resources such as local network.. a" L' h6 p. u/ D! ^: P( e
It is useful with option "http_proxy".0 s, F, m/ o1 F1 R) z
/ f) a) Z8 T+ `+ W1 wurl_len <integer>
+ e" L2 P* o' r# O: N. A Returns true when the url length matches the values or ranges specified. This
6 E: N$ \8 L+ @ Q8 g, t; f may be used to detect abusive requests for instance.
) a S0 g: G$ [& [9 I- o! |2 y3 Q5 r) n, h1 ?4 g, U/ Y/ h1 J
url_port <integer>
" Z( i9 h! g |, o2 y Applies to the port specified in the absolute URI in an HTTP request. It can6 t2 g' b5 n3 S l1 B: J7 V4 t( | U
be used to prevent access to certain resources. It is useful with option- ^7 s( e6 u5 N* `
"http_proxy". Note that if the port is not specified in the request, port 80# l4 |+ ?$ H3 n. X
is assumed.
, w' A ?* C+ T5 V) }9 P7 x; L0 B0 i1 T3 T, i& R! k2 j* l
url_reg <regex>, G7 g5 n6 m$ b* a8 y
Returns true when the URL matches one of the regular expressions. It can be
( h2 ^! p( A+ s2 Z) |- { used any time, but it is important to remember that regex matching is slower6 d9 t/ Z, S& c6 h$ |6 P" f
than other methods. See also "path_reg" and all "url_" criteria.
" M' {0 Y; O$ c- q5 r
) o# m# \- H( E( burl_sub <string># U+ x0 {- |1 L( H2 `- @
Returns true when the URL contains one of the strings. It can be used to
7 X& `, M. X% D4 l' X/ e' z' _ detect particular patterns in query strings for example. See also "path_sub".# P5 Y- K* |( \7 \8 T+ I3 L
) {+ I! P+ o# g6 H! V
. }; w) m$ Y, X# [- I7.6. Pre-defined ACLs) ~4 P1 q# J) i
---------------------9 W. c; u* O7 s' v& Z8 h
B8 x$ r: N5 _; U0 `- V
Some predefined ACLs are hard-coded so that they do not have to be declared in; C+ ]$ M/ Q/ F1 w- E) J
every frontend which needs them. They all have their names in upper case in
" i) d* g4 M5 F4 [+ qorder to avoid confusion. Their equivalence is provided below.
3 K M' t) S1 b+ @$ H
% i9 o: F# y6 h- [( yACL name Equivalent to Usage
' b1 `) ?1 E* R---------------+-----------------------------+---------------------------------
- w* Q- A8 ^4 K/ V! n- H. iFALSE always_false never match: b0 w6 o! b4 e$ I% i: C3 V
HTTP req_proto_http match if protocol is valid HTTP
+ m7 [7 E3 d, d1 ^, l0 QHTTP_1.0 req_ver 1.0 match HTTP version 1.0
) p9 L. l: S/ t3 T N x& jHTTP_1.1 req_ver 1.1 match HTTP version 1.1
' b% N; R8 s' P( QHTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length0 Q: F, I+ A1 s( i9 X
HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme2 a& p2 Q% B' G# @) G
HTTP_URL_SLASH url_beg / match URL beginning with "/"
5 L: m* J `) uHTTP_URL_STAR url * match URL equal to "*"
5 m/ I( e A" S& O. @LOCALHOST src 127.0.0.1/8 match connection from local host; o+ q# P# |: f8 P( p. |5 i
METH_CONNECT method CONNECT match HTTP CONNECT method
; G4 U& g a* E/ b4 y s/ dMETH_GET method GET HEAD match HTTP GET or HEAD method0 f, x! ]! A7 I5 z6 S' |
METH_HEAD method HEAD match HTTP HEAD method
& ^7 _( t( G. V8 V2 y/ }2 X" c. gMETH_OPTIONS method OPTIONS match HTTP OPTIONS method
3 x' z3 e6 x( f! s* BMETH_POST method POST match HTTP POST method. N9 K# o, y+ p/ i5 y, h
METH_TRACE method TRACE match HTTP TRACE method
" s0 S1 K: h n7 \5 @0 oRDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie2 ?' n4 ?- `- O* F4 W
REQ_CONTENT req_len gt 0 match data in the request buffer' V, Y e4 T( ?; e
TRUE always_true always match+ I- Q* a E% N0 L, ]$ P; b
WAIT_END wait_end wait for end of content analysis' f6 J9 ~. K) P$ _6 R' C
---------------+-----------------------------+---------------------------------, L9 N0 ~2 F6 S% H( O, b2 ]1 f
: H% ? Q. U4 Z" f* j
! I7 J. I5 K+ i7.7. Using ACLs to form conditions& s' F5 ~ {" P1 h8 ^
----------------------------------% |7 b2 E& t/ U+ j% g
( E8 G! g+ n6 [* w* U
Some actions are only performed upon a valid condition. A condition is a2 W% c: V& W% ^
combination of ACLs with operators. 3 operators are supported :6 Y) H9 f: G5 f& ^& ?
' [8 z0 h0 I: Q& A/ S% ~- g
- AND (implicit)
0 U) g+ |/ s$ C1 s l8 C - OR (explicit with the "or" keyword or the "||" operator)( Y3 `6 c- |% e. w S" F3 P
- Negation with the exclamation mark ("!")
+ A. W5 Z# U" s. }8 D4 |0 A2 H
& P. P3 B$ X' b, i8 P' _3 S; [+ qA condition is formed as a disjunctive form:
! Y1 G0 h& K. o" t# d* E% s X9 j2 |' ?
[!]acl1 [!]acl2 ... [!]acln { or [!]acl1 [!]acl2 ... [!]acln } ...9 m3 s, w8 b2 h( F0 F8 s
& q1 z7 ]. Q6 i. C( J l9 n
Such conditions are generally used after an "if" or "unless" statement,: q/ C2 p3 H+ ^! ^
indicating when the condition will trigger the action.) p! D% @6 ?3 G R% f* z* h
6 [. w# u. ]! ?! |! K: {9 c( O
For instance, to block HTTP requests to the "*" URL with methods other than
0 J, w* i% C! W1 H. D. ["OPTIONS", as well as POST requests without content-length, and GET or HEAD
6 B% L: s& R) Z5 Krequests with a content-length greater than 0, and finally every request which; S1 q. v/ d8 R. i. x# U
is not either GET/HEAD/POST/OPTIONS !! w+ `/ X1 G/ b `7 T7 r
" F1 K# ]0 q& d- B2 Z! ^! f acl missing_cl hdr_cnt(Content-length) eq 0
, z" E- I: R3 R4 t4 }, x4 F5 ? block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl$ Y7 S' c- R! L+ f; K
block if METH_GET HTTP_CONTENT6 ]5 F, S' {# b2 e
block unless METH_GET or METH_POST or METH_OPTIONS
' h* ?$ V" J. t
g; I' o! x7 D8 x! v( ]* KTo select a different backend for requests to static contents on the "www" site2 z) z& a% F* z
and to every request on the "img", "video", "download" and "ftp" hosts : d" P* D. W9 b2 P$ I* e
+ A7 ?3 G, g3 B) j2 s# v acl url_static path_beg /static /images /img /css
; `9 ^7 _/ Z1 U; W acl url_static path_end .gif .png .jpg .css .js* a2 ~6 \& T- `5 e9 z
acl host_www hdr_beg(host) -i www
. m1 b2 A H& p- Y* B acl host_static hdr_beg(host) -i img. video. download. ftp.
f% t+ A( P6 h+ A, k! h6 f( h1 x* T
# now use backend "static" for all static-only hosts, and for static urls
' @, p% l5 g8 {( I6 q& A5 D # of host "www". Use backend "www" for the rest.
/ @' o: Z: V- z0 V& v( M) p+ L use_backend static if host_static or host_www url_static
- m3 ^% ?( y0 \% {2 Q use_backend www if host_www" t7 U3 M2 \$ _ u
3 s6 {- `6 g- o4 E5 ZIt is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
1 {8 N. ~, S+ E1 p6 Kexpressions that are built on the fly without needing to be declared. They must
, g' V# h( r1 \$ Dbe enclosed between braces, with a space before and after each brace (because, D% f9 k7 Y9 E3 K! p) `5 B5 B
the braces must be seen as independant words). Example :% c* B2 o! L5 B) X+ t$ O7 l* G* K# D
! d( s, i- ?9 r W' P2 D The following rule :8 [' F3 d1 c- A# ~- O
* K1 q+ V/ E# P, D acl missing_cl hdr_cnt(Content-length) eq 0
. E! E1 |0 k, n block if METH_POST missing_cl+ M- S) N' _5 s" I/ [& V
/ g4 |: L) G$ \9 |7 o( K( v
Can also be written that way :
" _3 _" |3 t( v8 I; \
! @ C1 y7 `: p1 {1 y8 O block if METH_POST { hdr_cnt(Content-length) eq 0 }# A7 Z4 `9 g9 p _5 y, N: I" W
# R r7 W8 \/ T0 q7 L, {( Q* s
It is generally not recommended to use this construct because it's a lot easier" z, F* p) n; Y0 N \; M3 I
to leave errors in the configuration when written that way. However, for very
7 M4 \# S8 X/ B& hsimple rules matching only one source IP address for instance, it can make more
' k0 X) z' Q g1 n- ssense to use them than to declare ACLs with random names. Another example of
( c/ n: @) a% w+ [! y) g Ogood use is the following :
6 d3 B; j Z1 U! v3 i
- x: N- ]( d* `5 \ With named ACLs :
# ^0 b# k# O; U/ _; S i! J8 c# @( x. P5 B. R G
acl site_dead nbsrv(dynamic) lt 2
- h4 P/ z7 K& f4 |9 K acl site_dead nbsrv(static) lt 2
# O7 }# [* n" M: l6 d monitor fail if site_dead X$ O1 ]8 K/ J' t6 ?
7 [0 _% K% Q& o6 u3 N With anonymous ACLs :$ }* g& i$ s, e/ S4 Q+ _7 d! k3 @
) `" b7 `5 b5 L/ Y$ \ monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
9 p2 X" z. _8 ^5 a- j5 i9 T2 Y
) v z' [- K. L% w& HSee section 4.2 for detailed help on the "block" and "use_backend" keywords.
9 ]& N3 y* i7 j& v( t* O5 F% m+ p5 x4 p8 R+ p
5 d z. v0 i0 T7.8. Pattern extraction
4 @' K1 f1 g( u) { \# O-----------------------, |# n( ~# A7 I5 G
5 M) g) P4 P+ \* i: }! |8 K4 ^
The stickiness features relies on pattern extraction in the request and
4 t, ^' S B3 {# _/ j% P6 H: presponse. Sometimes the data needs to be converted first before being stored,
$ {- M4 n$ S2 a) R. W4 A+ V, ffor instance converted from ASCII to IP or upper case to lower case.- K6 c( e& y) V& s* K( {- T
. Q& d7 S6 \. e9 lAll these operations of data extraction and conversion are defined as9 a. v1 ~5 u8 G
"pattern extraction rules". A pattern rule always has the same format. It
2 O, B2 z" j! Q) ?begins with a single pattern fetch word, potentially followed by a list of
9 u @1 s0 l V' Jarguments within parenthesis then an optional list of transformations. As
3 Z1 d* A# y9 _, D2 Imuch as possible, the pattern fetch functions use the same name as their( V+ E, s0 Q/ ?/ o& W
equivalent used in ACLs.
5 e) `% i8 A5 ?! h# P. r3 O; R" |$ h1 p1 F3 x8 I7 I: n2 b
The list of currently supported pattern fetch functions is the following : ]; O8 ^7 Y' h5 |' v3 v7 s
" G$ j8 p3 l5 z; T- c9 P1 V6 m2 ~( t src This is the source IPv4 address of the client of the session.& e7 V: [# m {7 O
It is of type IP and only works with such tables.8 K3 k4 n; p S7 c% j1 A* A+ I
' g6 c2 \3 U+ P9 Q+ |2 I dst This is the destination IPv4 address of the session on the
' \' k$ T9 t0 ~# A8 W/ X client side, which is the address the client connected to.' v8 @! P5 y9 t7 B+ X+ D
It can be useful when running in transparent mode. It is of+ l$ m i' y8 v h- }1 X
type IP and only works with such tables.- G, \" t# J/ M4 z
, l& g1 i p. X: `8 x dst_port This is the destination TCP port of the session on the client6 v5 `& ^( \9 F, Y9 b
side, which is the port the client connected to. This might be, h2 X8 _8 X6 Z1 [* ~" C5 l6 W
used when running in transparent mode or when assigning dynamic
# H3 C1 N8 Z! J& N ports to some clients for a whole application session. It is of
9 E. R* j. h3 m8 |6 o' g% K+ d% Z, L type integer and only works with such tables.
" b b1 J6 j1 x# x9 z; w$ N7 m* S& ]: Q( v) r
hdr(name) This extracts the last occurrence of header <name> in an HTTP" N2 |4 q5 l& }6 }
request and converts it to an IP address. This IP address is
/ H) j" ~2 P L& c9 r/ @! e then used to match the table. A typical use is with the8 l, n! l* r- a; s$ D: n7 F
x-forwarded-for header.9 x( Z( X/ X: A7 ^
R4 g! j, t% v# w% p0 M. N
7 ~- z+ x" s" n5 j2 ]& F/ B
The currently available list of transformations include :! I; B# a$ K1 p+ u9 l$ p& `
( X& T% F u+ z; L/ g- L lower Convert a string pattern to lower case. This can only be placed
4 H( _! ^8 k Q# ~ after a string pattern fetch function or after a conversion
+ F- i" o5 }! @4 W* B, z function returning a string type. The result is of type string.
?7 E2 g6 R9 N, B' Q' V; q5 c
! b; A- x4 ^; Z' g. g upper Convert a string pattern to upper case. This can only be placed% N* C1 f9 X/ F. r, _; H
after a string pattern fetch function or after a conversion
1 B5 ]9 J# B$ C3 M- v3 K function returning a string type. The result is of type string.# r8 l+ A+ G# ^6 T, I( ]
/ a! _. G/ M: m9 l. S4 c ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups
% G1 b) u$ D( h0 k and storage. This can be used to make all hosts within a
9 F; Z. k$ P' t4 R certain mask to share the same table entries and as such use# b; [3 V0 L; }0 }# _/ |! D
the same server. The mask can be passed in dotted form (eg:
9 X! j2 ]2 ?3 K# ?0 e( L 255.255.255.0) or in CIDR form (eg: 24).
3 z$ ~+ `* Q5 z* J. S$ c6 l
- j- y8 G0 @' c: H* c, I/ E! F0 X: t
8. Logging
3 N0 `& T) e8 o) A----------
( W9 _ o: s a# v
) A+ M l( ?# W- VOne of HAProxy's strong points certainly lies is its precise logs. It probably
I: {0 z3 X$ u/ C( e+ bprovides the finest level of information available for such a product, which is. t, y' B, J2 ~% G% D
very important for troubleshooting complex environments. Standard information4 I& w! l* N7 {2 @4 Z
provided in logs include client ports, TCP/HTTP state timers, precise session+ `, x- m: E6 `1 @7 ]
state at termination and precise termination cause, information about decisions
( V. F0 F2 M1 I& \ H( T2 v/ P8 m, qto direct traffic to a server, and of course the ability to capture arbitrary
9 w& A+ a# R! e" ]headers.
@$ P0 R+ z( e: R# ~' v$ n% D$ P
% p/ C1 k6 u) @; XIn order to improve administrators reactivity, it offers a great transparency
. |6 M4 w8 j3 Eabout encountered problems, both internal and external, and it is possible to
; z: K! H) t) d+ _send logs to different sources at the same time with different level filters :
8 J/ D _! A4 L0 J, @$ J" T+ O: J5 R
- global process-level logs (system errors, start/stop, etc..)3 F: j6 ?3 L( F2 t [" e
- per-instance system and internal errors (lack of resource, bugs, ...)( s1 W- j0 m, w+ |/ k
- per-instance external troubles (servers up/down, max connections)
4 i8 c* r S9 j' K. T7 s - per-instance activity (client connections), either at the establishment or
; `7 h1 v6 M0 }/ C9 M at the termination.
0 x f! ~4 N/ M4 l2 X+ F! `" Q
, f, l) f0 r# E" yThe ability to distribute different levels of logs to different log servers
. v4 M0 i/ z' Z" x6 \allow several production teams to interact and to fix their problems as soon
9 x* e, Q+ I# ^; f& F! K) [' sas possible. For example, the system team might monitor system-wide errors,
) ~4 Z6 @5 x) i" Hwhile the application team might be monitoring the up/down for their servers in M ^! p2 T; v, `; ]% v4 H
real time, and the security team might analyze the activity logs with one hour
" A7 I8 [2 G9 y( |& G) cdelay.# K' m/ z5 F6 [0 h9 f9 k# I
9 v8 M t/ K8 _( D! R8 u
: f# U) c6 Y9 E4 I4 m/ v/ B8.1. Log levels" V( B' f8 d! p: b' L/ {
---------------( `1 ^& o3 v8 j- e4 p
- t/ ~' f" C9 Z0 g& wTCP and HTTP connections can be logged with information such as the date, time,
3 N; Q" l& g! k' Y Q! ]7 D( psource IP address, destination address, connection duration, response times,
D; ]9 V# p0 q% `HTTP request, HTTP return code, number of bytes transmitted, conditions8 _% |$ h) R+ J: ?# N3 P
in which the session ended, and even exchanged cookies values. For example) Z3 S: b, ?9 B- \- ~. R3 ]
track a particular user's problems. All messages may be sent to up to two
9 w* z/ i2 Y0 ~, xsyslog servers. Check the "log" keyword in section 4.2 for more information
5 O1 }9 I9 K% X1 l, ]( H4 Mabout log facilities.
7 H( Q9 h! Q/ I: i F
4 s' F: ?4 @' u
! z4 i" _1 d {' e" T4 L8.2. Log formats6 ^$ m0 m. o, I: j* n' u/ [6 E$ ?: a! S
----------------
$ ^( ? x/ w; m, r
( J* l9 y9 r5 D$ Y& H% BHAProxy supports 4 log formats. Several fields are common between these formats" `+ r- R: u, T, ^! U
and will be detailed in the following sections. A few of them may vary
" f" p& H# K, Q, b3 I4 ]+ D) gslightly with the configuration, due to indicators specific to certain+ f' H, \6 s8 i: I, a
options. The supported formats are as follows :
; C7 i" k1 X& G8 o+ g6 D/ s9 q6 h- A7 U
- the default format, which is very basic and very rarely used. It only
& B6 T0 Y8 v- J, F; g provides very basic information about the incoming connection at the moment
' C6 U9 I- }9 L1 R it is accepted : source IP:port, destination IP:port, and frontend-name.
! J( ~- n1 O0 a1 z This mode will eventually disappear so it will not be described to great0 s5 \ X, \% b( b- v* [
extents.; }, f+ a ~3 {$ U# D+ N' k
" @; J$ g8 l0 [+ w' c/ I' F
- the TCP format, which is more advanced. This format is enabled when "option4 E6 f$ U9 A) L3 v; U( P2 h7 x. U
tcplog" is set on the frontend. HAProxy will then usually wait for the
, k" ~$ h2 R0 w connection to terminate before logging. This format provides much richer) U* @2 ^# }/ b+ W# d6 ^) S
information, such as timers, connection counts, queue size, etc... This) ?/ D% L/ `) U! F! ?! m
format is recommended for pure TCP proxies.
3 `+ \; D- l" V. G, W' s+ }9 T3 \0 x: [+ H1 l
- the HTTP format, which is the most advanced for HTTP proxying. This format
* i/ D# |) l9 ?4 g" `, ^ is enabled when "option httplog" is set on the frontend. It provides the4 d( @: f9 }, [& o& c
same information as the TCP format with some HTTP-specific fields such as
6 Q8 ]8 K: o6 o) b the request, the status code, and captures of headers and cookies. This, N- X7 |2 |$ l5 I( T* v( ~
format is recommended for HTTP proxies.
/ S/ s7 p9 c! n( d- r# {) r1 Z
7 p; b9 A, s0 C1 K5 R( B* u# b - the CLF HTTP format, which is equivalent to the HTTP format, but with the. K; p z0 U+ |2 b
fields arranged in the same order as the CLF format. In this mode, all
; n( n) |' p( f+ h' n' W timers, captures, flags, etc... appear one per field after the end of the1 b+ a5 I# G) d6 b! A! S+ u
common fields, in the same order they appear in the standard HTTP format.( i [1 u$ \0 A% V! u4 P) q2 R
- v* `+ j8 x5 o/ E8 f( h, t, ^6 LNext sections will go deeper into details for each of these formats. Format
d$ H$ c M |+ nspecification will be performed on a "field" basis. Unless stated otherwise, a+ ?( i$ ]. e& r; D3 s6 h3 P0 @
field is a portion of text delimited by any number of spaces. Since syslog1 c9 \. }9 U. o
servers are susceptible of inserting fields at the beginning of a line, it is8 k; n6 ?) C. N$ I; b& R" O# n
always assumed that the first field is the one containing the process name and
5 t9 I+ W" A9 r; p* b$ iidentifier.
, Y. Z- u; @5 Y1 j4 u v5 {4 I( h& K, I
Note : Since log lines may be quite long, the log examples in sections below
* E1 ^' Z. @' ^' `( { might be broken into multiple lines. The example log lines will be8 f4 \) V, I9 F1 E+ h: g
prefixed with 3 closing angle brackets ('>>>') and each time a log is6 r8 q, n" X5 P2 H
broken into multiple lines, each non-final line will end with a' h5 {& `) B! P/ z l. E0 X8 c$ d
backslash ('\') and the next line will start indented by two characters.& r; P3 q) ?. ~. U, k( E
/ N9 u" f6 f, z# R$ L/ x' r {$ V8 l( i
8.2.1. Default log format9 U1 I/ J' u( O% E7 v, v: V
-------------------------; `$ i0 j1 {1 _7 h& o* P. \, n8 f# S
/ l6 ~+ @. X$ N# K% fThis format is used when no specific option is set. The log is emitted as soon
$ T$ u) K/ t) W! x6 R/ Qas the connection is accepted. One should note that this currently is the only5 N$ n9 g( T2 a y; d4 C2 Q5 c
format which logs the request's destination IP and ports.! v7 d" \ Z. \, i0 E+ }
, {7 o7 r1 i) y$ F( J) w) ] Example :
, E/ ? _; n# Z0 W0 A6 P listen www
. E* i7 n; ^ }8 l mode http
' ]- U1 x t6 A+ } log global# F! q4 Y& X1 P& P/ ?: G! k
server srv1 127.0.0.1:8000
& X$ U: t* E( }) D3 J/ x6 S+ X% f9 Q$ c8 T. k! X* q8 ~
>>> Feb 6 12:12:09 localhost \
4 u) v% `; d; L4 a2 R haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \$ E& h4 q" B: n
(www/HTTP)
+ s2 r; e( ]$ I% ^9 X% m0 h
4 U8 }7 c5 o; B0 ` ] Field Format Extract from the example above- f* s: J' E0 k/ v4 N
1 process_name '[' pid ']:' haproxy[14385]:; @ \$ p0 X+ a( O+ B
2 'Connect from' Connect from& b" Q: ~$ M) j! u9 w
3 source_ip ':' source_port 10.0.1.2:333126 @# e6 q% m9 h2 n; b& l( n$ {
4 'to' to
" B5 L2 T8 `6 V% ]& @ 5 destination_ip ':' destination_port 10.0.3.31:8012# W. C" @4 }1 b% t/ O2 W
6 '(' frontend_name '/' mode ')' (www/HTTP)
/ H# @3 X$ D/ U% M
, D. F: l; S& m& J2 ?Detailed fields description :, Q6 s: n0 A- J$ y! k8 L
- "source_ip" is the IP address of the client which initiated the connection.
. Y' j# d& h# K1 |, @, A: _ - "source_port" is the TCP port of the client which initiated the connection.$ I9 @+ G1 n% q8 s
- "destination_ip" is the IP address the client connected to.
$ F6 F1 T7 m8 `# ] - "destination_port" is the TCP port the client connected to.
8 M3 {# \3 v0 M9 E/ D - "frontend_name" is the name of the frontend (or listener) which received
7 }# D& l- n8 E a( K and processed the connection.3 Q0 @4 S( O# M
- "mode is the mode the frontend is operating (TCP or HTTP).+ X* x# T! m: \/ x. c& n& r4 d! w4 g
/ u1 T9 a0 K9 }7 x& q+ S; Z
It is advised not to use this deprecated format for newer installations as it7 X1 t7 S+ ?( {# Q
will eventually disappear.' O+ g9 m5 D: g: R. S1 S
( |& } U& O8 @- O$ n. c
4 O0 ?7 }8 O7 [4 u0 O8.2.2. TCP log format
: U5 x+ N8 a) O( }) b- v( y. p; o---------------------; X3 v3 O( x, k; ~4 F# o9 l
' V; h- U* ^# e8 Y9 |6 |( L/ C5 |
The TCP format is used when "option tcplog" is specified in the frontend, and
/ i7 }+ f/ J& A7 K& ois the recommended format for pure TCP proxies. It provides a lot of precious
3 y. m% r, I; M0 Dinformation for troubleshooting. Since this format includes timers and byte3 \0 k! h8 w% M9 @- l
counts, the log is normally emitted at the end of the session. It can be
. K5 `' C+ k. N. u) }emitted earlier if "option logasap" is specified, which makes sense in most
$ w& N9 w0 y+ O! G& u3 c0 ^environments with long sessions such as remote terminals. Sessions which match
' X2 T* c; B) D* Ythe "monitor" rules are never logged. It is also possible not to emit logs for- X4 B3 y: X. A+ @2 [4 V0 F
sessions for which no data were exchanged between the client and the server, by+ W" d9 H" Q' u
specifying "option dontlognull" in the frontend. Successful connections will
6 H- E$ ^/ P+ ^" S! s" g8 E Tnot be logged if "option dontlog-normal" is specified in the frontend. A few, g9 K* L7 x$ z5 T6 i
fields may slightly vary depending on some configuration options, those are
2 v) D$ S& R0 E1 H# f! nmarked with a star ('*') after the field name below.
0 s( R6 V1 S o) N+ ?; i6 _; Z9 m0 A' @( n1 D
Example :
. ~' v# X. N; I p frontend fnt
/ _" \# c6 e) X, r9 ]; u$ |3 r' {& w, y mode tcp! w$ C9 U, W+ Z: S( [ j& U
option tcplog1 h- P2 H6 Q: a, l+ J K9 v
log global6 L h! n. ~5 L& {* `
default_backend bck9 c0 N( {' J% a" i0 z+ K1 e
- q1 w' O6 g0 D8 j
backend bck
8 [) B8 k5 Y- [6 k4 j server srv1 127.0.0.1:8000( e# {, ]5 l) c ~0 o5 _3 Z; x- T" p
; |" E0 H. b( ]& V9 T >>> Feb 6 12:12:56 localhost \
- F3 @1 ]; l. _3 o# c7 |* x haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \2 A8 c! H9 N- ?& Z; `
bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0
4 j' o7 Q( z k9 M# R. O3 }3 i7 D9 C( u! L7 I! W
Field Format Extract from the example above
; b5 K# T" K, U9 L3 {7 ~, p 1 process_name '[' pid ']:' haproxy[14387]:
, Z1 z2 v) |2 d) w; n 2 client_ip ':' client_port 10.0.1.2:33313
; t$ B5 x) K" P 3 '[' accept_date ']' [06/Feb/2009:12:12:51.443]. ^4 C2 |$ f r8 d
4 frontend_name fnt3 N6 h+ e# p* J! ?; D
5 backend_name '/' server_name bck/srv1
9 V7 F2 R: p5 c( M. W- ]5 t 6 Tw '/' Tc '/' Tt* 0/0/5007) K* S: j' u. t' ]( m
7 bytes_read* 2120 e: Q: U2 u F
8 termination_state --
8 \, x9 }7 [8 \' l1 m 9 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 0/0/0/0/3
, A) T% f; P1 ?+ S' f4 w6 y, B0 V2 v 10 srv_queue '/' backend_queue 0/0) B6 o( _! H6 b" W
( w, ]: a* z5 }% T/ a) uDetailed fields description :& _2 A# N8 P9 U% l7 h( C' o* F
- "client_ip" is the IP address of the client which initiated the TCP, j2 _% p) J/ S b9 _
connection to haproxy.
+ {2 F3 F. w; l; o3 Y9 z$ n( n" q7 X
- "client_port" is the TCP port of the client which initiated the connection.. e: G" v! g& m$ b6 B6 M
' f& U4 I, C7 T% o; k9 {
- "accept_date" is the exact date when the connection was received by haproxy6 z" d# R+ @/ c3 A; x& U7 W2 o6 K+ r
(which might be very slightly different from the date observed on the9 h' ]- r# h7 \. r! B1 y; l* c
network if there was some queuing in the system's backlog). This is usually
+ w: H" v, n7 p& r! w the same date which may appear in any upstream firewall's log.1 W1 K+ n9 h$ A" o- y ?3 ^0 O
/ T) {% W8 ~& U* i6 ?% N _
- "frontend_name" is the name of the frontend (or listener) which received" e6 @! I, V# r) [0 H# Z
and processed the connection.& h0 v/ `; q- V$ I: g
0 z1 e: n# e3 E3 J: x. o
- "backend_name" is the name of the backend (or listener) which was selected
4 F$ d6 X" t1 n! a: D7 x/ ~' q to manage the connection to the server. This will be the same as the0 p; V) q) L. j* O6 F9 ~
frontend if no switching rule has been applied, which is common for TCP
0 M8 S! h% Q5 H7 k2 q1 N# e$ V! P applications.; ~7 b! a1 A6 E
& G7 a# ` }' M6 j+ t( X, k$ L8 ~
- "server_name" is the name of the last server to which the connection was
1 U1 f! i& `) ^: _) o) p B sent, which might differ from the first one if there were connection errors
& ?3 @4 c5 R6 ^3 }& {7 } and a redispatch occurred. Note that this server belongs to the backend& v* M8 s7 F8 V. F* W6 J. I2 U
which processed the request. If the connection was aborted before reaching
( |) w: H( \* F5 U a server, "<NOSRV>" is indicated instead of a server name.
1 J; z' C& t% w; b% A( ^ ?
( E5 V3 ?2 y& I) a0 n - "Tw" is the total time in milliseconds spent waiting in the various queues.
& g r' D0 R$ f) q0 @% z; l! s It can be "-1" if the connection was aborted before reaching the queue.4 @& J7 o/ f/ @
See "Timers" below for more details.
' t" E' w6 p8 _* k" T6 ?( ^! q. i3 c j9 M0 U; X4 M( X
- "Tc" is the total time in milliseconds spent waiting for the connection to
7 U# A, x. N% ~2 n$ U1 ` establish to the final server, including retries. It can be "-1" if the2 q% W. g% n: Q" h: V8 S4 t" r
connection was aborted before a connection could be established. See
' h, o3 d8 a; h* z+ @/ g "Timers" below for more details.( U8 T) A5 \& j9 x
/ {# F/ |9 R' H! K: `0 h$ Z3 ?
- "Tt" is the total time in milliseconds elapsed between the accept and the( s2 T! m: t! _
last close. It covers all possible processings. There is one exception, if
5 g9 v- o: k4 q "option logasap" was specified, then the time counting stops at the moment9 I: J* ?' f8 I3 {
the log is emitted. In this case, a '+' sign is prepended before the value,
1 Z- t6 q# i% d indicating that the final one will be larger. See "Timers" below for more% n/ C. }! U. X) n" y9 |: ^
details.
3 Z+ f; n$ G8 G( t0 T
: a, g0 e; N0 }- M3 {; g2 I - "bytes_read" is the total number of bytes transmitted from the server to
( |7 x: v( f R: {/ G the client when the log is emitted. If "option logasap" is specified, the
, F L: y, V& w( [8 ~- v2 v this value will be prefixed with a '+' sign indicating that the final one3 z# \, t& f! c T/ f' U6 w! Y4 P
may be larger. Please note that this value is a 64-bit counter, so log
2 L1 i! p) E( i5 Q analysis tools must be able to handle it without overflowing.
! G, b) F% s$ Z6 G2 u S% Q# O, H! f$ W" x+ l
- "termination_state" is the condition the session was in when the session
+ K- f3 Z2 [' i ended. This indicates the session state, which side caused the end of
) P" \) q$ p5 o9 c session to happen, and for what reason (timeout, error, ...). The normal3 X6 O: _, _' w, X* `
flags should be "--", indicating the session was closed by either end with, G6 ?$ [) @! H6 q; U0 M
no data remaining in buffers. See below "Session state at disconnection"
" L, p5 t- u* s2 @) Y for more details., n( Y/ d' h5 Z
5 ~+ ` o; Z1 J5 c" Q1 S
- "actconn" is the total number of concurrent connections on the process when: R- q9 e( A" M% X2 d: U
the session was logged. It it useful to detect when some per-process system
% q a1 N1 l% z2 K( H( W1 E. [ limits have been reached. For instance, if actconn is close to 512 when% H+ l: p0 k/ D6 u2 x
multiple connection errors occur, chances are high that the system limits
3 j8 J* t9 R4 f4 u& d) a the process to use a maximum of 1024 file descriptors and that all of them, k* O: ^' Z" q; W5 e
are used. See section 3 "Global parameters" to find how to tune the system.$ j- N: n& v6 k n
5 w' c. ]! j d& O
- "feconn" is the total number of concurrent connections on the frontend when9 d6 x3 V! N0 E
the session was logged. It is useful to estimate the amount of resource
p9 \9 V5 W' c3 h8 y required to sustain high loads, and to detect when the frontend's "maxconn"2 j1 F8 t6 N" k" b! D6 k
has been reached. Most often when this value increases by huge jumps, it is2 p1 A- b* |9 H7 m
because there is congestion on the backend servers, but sometimes it can be
6 x& M* |/ @/ M* K+ o: u9 v caused by a denial of service attack.: ~$ U" x* q, B( W
7 j4 W$ X4 Y3 I4 s' \8 v - "beconn" is the total number of concurrent connections handled by the
2 ?8 k1 b9 K" x' v. }. ^3 f* @ backend when the session was logged. It includes the total number of. `' W3 I# `; s& h' {
concurrent connections active on servers as well as the number of
0 \0 J l2 Z I: K3 N7 z' f connections pending in queues. It is useful to estimate the amount of
+ u( i: X/ S2 h; r& _# u additional servers needed to support high loads for a given application.: u+ \. {1 l5 k9 V# Y$ ?
Most often when this value increases by huge jumps, it is because there is: S2 }6 G7 \- b2 j
congestion on the backend servers, but sometimes it can be caused by a
" w6 C- D3 i# S denial of service attack.& D5 e1 j$ y- Y( T
* L* O+ h8 |" t - "srv_conn" is the total number of concurrent connections still active on
. M, B- x8 S0 _3 ^) W the server when the session was logged. It can never exceed the server's
j) A+ k Y0 q7 L5 W configured "maxconn" parameter. If this value is very often close or equal
* c: `6 K, Y- }+ p5 u7 C# v# k3 S to the server's "maxconn", it means that traffic regulation is involved a
2 J4 q- [( |5 Q% n8 V* Y! A l lot, meaning that either the server's maxconn value is too low, or that
% i# N. x6 i N5 ] there aren't enough servers to process the load with an optimal response
# ^0 M$ w2 [) \- j( z$ u time. When only one of the server's "srv_conn" is high, it usually means
5 ]% {, X: A* l# v2 ]' ^ that this server has some trouble causing the connections to take longer to
- [: V2 d8 X' o% r2 j2 O be processed than on other servers.; E) {! X- p5 v+ @5 ?
H1 _9 H$ T8 x# ^" ?7 R) @ J - "retries" is the number of connection retries experienced by this session' y5 J1 m# \/ m$ Y2 O4 ]
when trying to connect to the server. It must normally be zero, unless a* ]0 ^6 D) Z. ^: @7 |+ ~ x
server is being stopped at the same moment the connection was attempted./ }. h i: ~ _, w' W4 j
Frequent retries generally indicate either a network problem between
7 q9 V) x# n) s haproxy and the server, or a misconfigured system backlog on the server9 E% r( w# R+ o9 K$ U
preventing new connections from being queued. This field may optionally be
* n( h4 Q: }, B; D# N @ prefixed with a '+' sign, indicating that the session has experienced a* \9 z) k I/ A3 a; X% a1 |
redispatch after the maximal retry count has been reached on the initial
% G( ^( W ?7 M server. In this case, the server name appearing in the log is the one the" j+ D6 R ?7 s$ g' _
connection was redispatched to, and not the first one, though both may
% h% h' ^; q$ a$ s sometimes be the same in case of hashing for instance. So as a general rule
( y j% m9 k T of thumb, when a '+' is present in front of the retry count, this count
1 a A2 C) R/ C8 y should not be attributed to the logged server.
& U4 d! O5 t* j/ y4 C8 R E
3 n: n+ h& |. z8 z- e2 U - "srv_queue" is the total number of requests which were processed before |9 M2 J: T+ H& ]
this one in the server queue. It is zero when the request has not gone: `. _- o( l* A
through the server queue. It makes it possible to estimate the approximate
* x, z$ {$ P- ]5 }) G1 W9 R server's response time by dividing the time spent in queue by the number of
S: k" ^+ _2 b Y/ P6 U requests in the queue. It is worth noting that if a session experiences a
6 `" N1 G3 R! x3 Y/ g! H. t! E redispatch and passes through two server queues, their positions will be0 _& Q8 B0 h! c8 }
cumulated. A request should not pass through both the server queue and the
0 c8 J9 f3 `/ u9 a3 G' h backend queue unless a redispatch occurs.
: J; [+ F2 P4 i- s# v' u1 b) H7 W$ @: I1 Y* x- d; |
- "backend_queue" is the total number of requests which were processed before2 O1 `5 w7 T" m% s4 O; ]; W
this one in the backend's global queue. It is zero when the request has not. x8 L: x( z! L/ B( a* d3 p
gone through the global queue. It makes it possible to estimate the average1 R/ _- |2 F; |: E. u
queue length, which easily translates into a number of missing servers when* E) w- u4 o! K& y0 t
divided by a server's "maxconn" parameter. It is worth noting that if a9 h* f2 V+ E' u
session experiences a redispatch, it may pass twice in the backend's queue,
- E9 ]& H1 M i5 [- d, T+ J4 |! b$ w" i and then both positions will be cumulated. A request should not pass, T4 b4 b4 {; V! E: C
through both the server queue and the backend queue unless a redispatch" b2 z7 n4 {9 o8 C2 c( n8 y( ^1 ]0 G+ D
occurs.+ {; H" X1 |2 ]2 q, F u( `
, N9 b% y0 n Q* v$ m
, w8 p" z& d) h2 y
8.2.3. HTTP log format
$ I/ [. G2 T1 a! _4 l8 k----------------------
& h" Q" ^: q$ D. @3 B* s9 _/ a4 P. B( r9 Q
The HTTP format is the most complete and the best suited for HTTP proxies. It
4 R1 c+ D9 g- X+ M8 n1 lis enabled by when "option httplog" is specified in the frontend. It provides1 V, ^1 h2 q' W1 s; J9 _9 Y1 S
the same level of information as the TCP format with additional features which; J& r' q/ o1 H2 l# L
are specific to the HTTP protocol. Just like the TCP format, the log is usually
: d0 u" I/ C, p& p* X( A4 F# qemitted at the end of the session, unless "option logasap" is specified, which' S# A4 L6 k5 I1 G& i4 F
generally only makes sense for download sites. A session which matches the
. H5 x* b# I$ j, F"monitor" rules will never logged. It is also possible not to log sessions for, n8 R* v9 q& S
which no data were sent by the client by specifying "option dontlognull" in the9 D7 ?3 U. a4 J+ D5 Q- B
frontend. Successful connections will not be logged if "option dontlog-normal"
0 P6 ]; G- n) c" f& Pis specified in the frontend.
% d6 g9 W/ F1 }& u* B. [1 m
7 ]; v# f; n9 @, \* N, ~, [! c; o6 ]' LMost fields are shared with the TCP log, some being different. A few fields may
0 {% r' q7 V. A" n' I1 \6 Nslightly vary depending on some configuration options. Those ones are marked( k7 w4 h5 S6 }
with a star ('*') after the field name below.- y2 I2 Z f- r5 x+ j1 Y0 f* N( I
( @: Y+ Y: r8 M& O- A
Example :! u- j9 {0 x2 j' u3 V2 O Y
frontend http-in
0 Q) `* f8 v( i( t4 h5 \* @ mode http. f3 u6 | L' G% \
option httplog
5 X* t/ r0 N) O& T: D$ b$ o* H log global' Q/ _. h& ^5 } ?' R* I i7 X
default_backend bck
9 C5 Z. k8 j: @* X* H, I. Z' J6 q! B% _, o7 r
backend static& |* @- @7 O& b$ v. Z2 e
server srv1 127.0.0.1:80008 ^9 c" \0 [+ }
E* O4 {( |3 ~5 d* q% W$ S& ~ >>> Feb 6 12:14:14 localhost \/ X7 ]+ d$ A9 M- j0 C' b; A" {
haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
$ K- C; G' c9 b: S. Q- V static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \9 S F) W t# Q2 T
{} "GET /index.html HTTP/1.1"
4 m, @8 E# R+ j5 S. @
; U8 g. J/ R+ W Field Format Extract from the example above! B- b4 s8 E8 `* l; ?
1 process_name '[' pid ']:' haproxy[14389]:
1 V0 U0 Y+ }$ T 2 client_ip ':' client_port 10.0.1.2:33317
2 N- a: e( \6 `5 u7 B/ U 3 '[' accept_date ']' [06/Feb/2009:12:14:14.655], ]4 ^2 W5 ~2 P0 F A/ N0 m
4 frontend_name http-in' J' m8 g' G. o0 o) b; b
5 backend_name '/' server_name static/srv1 R' \# j" Z8 n
6 Tq '/' Tw '/' Tc '/' Tr '/' Tt* 10/0/30/69/1098 G1 ~- d& H7 m/ K
7 status_code 200& `( t/ o' Y; q' e6 P
8 bytes_read* 2750
7 U7 e% y8 }, R, i 9 captured_request_cookie -6 K- ~: P. I8 z& W7 M# n6 C
10 captured_response_cookie -7 g$ C$ f, }5 v; H5 M
11 termination_state ----
3 v0 X5 X8 }& C# B1 { 12 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 1/1/1/1/0" ~/ d3 \! Z% P) N1 b% l! u! B
13 srv_queue '/' backend_queue 0/0
+ p" O m, l8 S; }: f 14 '{' captured_request_headers* '}' {haproxy.1wt.eu}$ A4 S, T5 u% x( F" w
15 '{' captured_response_headers* '}' {}0 J5 [' m3 ^- M8 ^9 j: X
16 '"' http_request '"' "GET /index.html HTTP/1.1"
8 d6 c) V6 \; f
4 A( u$ ~+ r( a8 m, r0 D
1 c' m, c/ e* d3 z _4 `Detailed fields description :
- s5 \9 ~; Z- B# ]; w - "client_ip" is the IP address of the client which initiated the TCP, ?. I* E! G" }* d! W
connection to haproxy.
! e) n: F6 ]9 ] Z9 }; X9 W0 m5 `& R! W; `/ V
- "client_port" is the TCP port of the client which initiated the connection.$ P, D, ], ]3 c, z
! e4 E$ z* S' o2 K' W
- "accept_date" is the exact date when the TCP connection was received by
+ A3 j2 p8 b/ Y9 ~ haproxy (which might be very slightly different from the date observed on
+ s' s5 j, q7 T1 ]: E' ^ the network if there was some queuing in the system's backlog). This is
) R+ s5 K7 ?, N- T8 z usually the same date which may appear in any upstream firewall's log. This
6 r( ^% u: j. l9 z/ v! d does not depend on the fact that the client has sent the request or not.
# e/ q( E, f6 D4 Z ]5 p2 \) }9 ]# Q& S9 Q$ o
- "frontend_name" is the name of the frontend (or listener) which received
+ j6 E+ K5 x/ r+ H and processed the connection.
4 e' |( }& O4 A; v9 x# W; B- g8 Z0 `7 Q+ _' V' X# s; s
- "backend_name" is the name of the backend (or listener) which was selected- a; z' N; Y+ m; h3 L/ ^% L
to manage the connection to the server. This will be the same as the
?0 h3 o3 F1 a! J# Q1 p; c frontend if no switching rule has been applied.
4 K4 O+ P- c. e$ _- K. q5 P
% o9 G( v, ^% T" Z1 C! S" I' o - "server_name" is the name of the last server to which the connection was
# X) M' T# _5 q/ G3 q sent, which might differ from the first one if there were connection errors
$ A5 r' t+ H7 l, ~, `, P and a redispatch occurred. Note that this server belongs to the backend! |; D7 I1 T1 L; w/ B
which processed the request. If the request was aborted before reaching a
: \) V" z* }1 l( F* h server, "<NOSRV>" is indicated instead of a server name. If the request was7 l4 e% G4 ^, N7 c, V
intercepted by the stats subsystem, "<STATS>" is indicated instead.8 Y" o8 V5 E" _3 ~" Q3 H: b
6 v! j+ w9 d& |; p4 } - "Tq" is the total time in milliseconds spent waiting for the client to send% \5 P5 r: \$ m8 ?7 P* F& E
a full HTTP request, not counting data. It can be "-1" if the connection
' B3 x; a$ I9 d h) H7 d was aborted before a complete request could be received. It should always
0 a: r8 C |( N; n' q be very small because a request generally fits in one single packet. Large
+ E/ Y0 ~% D5 m4 W1 o3 | times here generally indicate network trouble between the client and
- {9 _! R. `0 r4 y& f# x haproxy. See "Timers" below for more details.
' j9 H# c) j( C* [2 w' U* q: s/ n5 k7 _( y' x, y
- "Tw" is the total time in milliseconds spent waiting in the various queues.
& t8 L5 D5 A' F7 c( p- y( H It can be "-1" if the connection was aborted before reaching the queue.* H/ u+ Q8 q# E
See "Timers" below for more details.
( M; z+ Z- w0 f# f: U' _
g( \( {$ z. d+ M - "Tc" is the total time in milliseconds spent waiting for the connection to7 @. m+ [ T, p% u) z4 q+ L
establish to the final server, including retries. It can be "-1" if the& a4 O7 F/ z# K* \& J4 L2 F
request was aborted before a connection could be established. See "Timers"" l1 ~! d5 M3 M) |# Y' r* F; b
below for more details.
8 ^: V: r3 ~. t5 |1 t8 A
, x+ C, E9 X7 F, [7 C - "Tr" is the total time in milliseconds spent waiting for the server to send7 r0 O, A0 u( e) P- I& u% B* b/ |0 Q
a full HTTP response, not counting data. It can be "-1" if the request was, [0 a7 `7 h: R* z* O p
aborted before a complete response could be received. It generally matches
# x' c5 I0 i. S& p ]; ?: S' l the server's processing time for the request, though it may be altered by
# c& E6 J9 e6 z$ O9 H/ e the amount of data sent by the client to the server. Large times here on
" o6 ]* z* J( M+ Z5 v* I7 Z* a8 W "GET" requests generally indicate an overloaded server. See "Timers" below5 W: U, V% h. _ g* i' P1 M
for more details.# v0 K$ A2 L) o
* o! X# @, U! m) I; {+ [- y
- "Tt" is the total time in milliseconds elapsed between the accept and the! i d! |; B) L0 c- j
last close. It covers all possible processings. There is one exception, if$ ?6 A$ [9 y7 |- U |3 ], I
"option logasap" was specified, then the time counting stops at the moment
( I: d3 T7 z2 y! S! B" }- o the log is emitted. In this case, a '+' sign is prepended before the value,+ U1 J: q* F0 |; [; }* r, T
indicating that the final one will be larger. See "Timers" below for more# g4 g* f P+ h |5 K0 ?& C' X# p
details.
3 a+ H+ }- i/ q/ h `: x u( n: S
: J4 i4 k& J0 R% ]. S - "status_code" is the HTTP status code returned to the client. This status) d, W/ i* F0 b& S4 _$ d
is generally set by the server, but it might also be set by haproxy when
0 S, V( X- y0 }) J& n+ N9 ? the server cannot be reached or when its response is blocked by haproxy.& u7 O' e5 m" Z7 }% r
6 g- N! d3 V/ L# Y# s. p1 J; T7 i
- "bytes_read" is the total number of bytes transmitted to the client when* q- G) W; d, Z/ Y6 ~
the log is emitted. This does include HTTP headers. If "option logasap" is
% U0 R: s- y$ o [3 E- \ specified, the this value will be prefixed with a '+' sign indicating that, }" B" Z! q) P3 @+ }! i$ C& O% o
the final one may be larger. Please note that this value is a 64-bit
0 I6 T' {% `' D3 _7 B$ W2 c9 D7 c P counter, so log analysis tools must be able to handle it without6 N* B. M. x% h1 @
overflowing.
9 ?% ~) u4 ^3 V: }: H0 P! ]& O: K& v: E( I# c( U( ~* L: C
- "captured_request_cookie" is an optional "name=value" entry indicating that" {" N6 i6 J( y4 z( k7 ^! m
the client had this cookie in the request. The cookie name and its maximum
6 r0 r9 M! E j0 n2 N% ` length are defined by the "capture cookie" statement in the frontend; e' b5 F" K* ^* d- e+ O" k1 M
configuration. The field is a single dash ('-') when the option is not
" m' L ^+ l/ A! P$ @5 K; B set. Only one cookie may be captured, it is generally used to track session6 `4 Z8 ^0 L; K+ O: @
ID exchanges between a client and a server to detect session crossing2 M" ]/ x; ?7 Q
between clients due to application bugs. For more details, please consult
7 ]8 f' I3 N3 K) L |$ o: `; m; t the section "Capturing HTTP headers and cookies" below.4 r+ x& U9 x1 L2 O! V a* U
8 K' {- @! h+ Y! X1 J( F! f - "captured_response_cookie" is an optional "name=value" entry indicating
4 H7 {- v9 Y1 K2 E that the server has returned a cookie with its response. The cookie name: ]* k) K- x3 G% Z
and its maximum length are defined by the "capture cookie" statement in the
2 G) l% c1 K2 `6 j$ R! T frontend configuration. The field is a single dash ('-') when the option is6 u2 Z" h# Y0 t
not set. Only one cookie may be captured, it is generally used to track4 Z2 [) G+ L$ C( i
session ID exchanges between a client and a server to detect session$ E b% T& S z" [' h8 ^- E4 F7 q
crossing between clients due to application bugs. For more details, please. U$ N; _% R7 d+ G
consult the section "Capturing HTTP headers and cookies" below.
1 |6 v0 U1 @; J' `* u. P$ |7 d6 u4 C% Q* h
- "termination_state" is the condition the session was in when the session
' j' `6 G& i% f3 [+ T ended. This indicates the session state, which side caused the end of
0 P9 a4 S/ E6 V" z# F" s session to happen, for what reason (timeout, error, ...), just like in TCP
* h: M: i0 ?9 r% Z6 B" d9 J3 J logs, and information about persistence operations on cookies in the last
9 D0 ?! \+ k3 B) B u two characters. The normal flags should begin with "--", indicating the
Q {! ?9 V9 @+ C8 }! v5 B8 W session was closed by either end with no data remaining in buffers. See3 A( Y! J) |8 x
below "Session state at disconnection" for more details.
; e- h; k7 U8 o. W! X# b* A4 l
' [2 _0 S) Z$ G7 Q - "actconn" is the total number of concurrent connections on the process when& ^/ a0 b4 l _( ` q3 a: H% ^
the session was logged. It it useful to detect when some per-process system
, \' E+ D' R6 e" a2 }% _6 s" z limits have been reached. For instance, if actconn is close to 512 or 1024% n) k- b% y4 Q/ W0 D
when multiple connection errors occur, chances are high that the system$ c, _) D& ~$ I: I) B: V
limits the process to use a maximum of 1024 file descriptors and that all
9 K% E P& b: e' u( u1 l$ h$ e of them are used. See section 3 "Global parameters" to find how to tune the3 P- U( Y5 n0 v, i: H
system.
& X4 C# J: Y/ n) G8 Q! y
8 Y1 k. q3 b. U- M9 G - "feconn" is the total number of concurrent connections on the frontend when: O, v2 t8 [4 D2 f3 O4 g
the session was logged. It is useful to estimate the amount of resource
/ @6 y7 r% I+ Z' s" ^" W required to sustain high loads, and to detect when the frontend's "maxconn"6 H% G7 G/ c; }0 ~3 j5 p& K
has been reached. Most often when this value increases by huge jumps, it is
1 r& |, V: e) B# t& h because there is congestion on the backend servers, but sometimes it can be; P ^% |6 V. s2 D7 V
caused by a denial of service attack.% j8 T- P( K8 m
& G j3 f$ j7 w - "beconn" is the total number of concurrent connections handled by the1 o; y* ^8 e7 p8 O
backend when the session was logged. It includes the total number of& v2 Z2 C, y2 Z# J
concurrent connections active on servers as well as the number of! {. x. ~" w' Z8 }. R
connections pending in queues. It is useful to estimate the amount of
4 X# `' ^. d7 Z. r additional servers needed to support high loads for a given application." n$ y1 ~& i- Y5 i
Most often when this value increases by huge jumps, it is because there is" ~2 m1 u' H4 f7 o4 x2 w2 ]9 d
congestion on the backend servers, but sometimes it can be caused by a L# k& W! f5 p* M. h# y3 w' m; i+ L; c
denial of service attack.4 b. Q7 V5 o7 J1 Z t" b
, z% N+ }$ g$ E1 J: V/ m7 P - "srv_conn" is the total number of concurrent connections still active on* o* G" E6 G, f6 G1 f) X' o- a
the server when the session was logged. It can never exceed the server's
/ P. @, y* {, _9 i configured "maxconn" parameter. If this value is very often close or equal: U) J2 L4 R4 k
to the server's "maxconn", it means that traffic regulation is involved a
! j) V& D( K+ \9 b5 A, C- x5 u lot, meaning that either the server's maxconn value is too low, or that
% d0 J q- h% b* I& ^ there aren't enough servers to process the load with an optimal response1 C: l% c+ h! j$ ?, w( W
time. When only one of the server's "srv_conn" is high, it usually means
; Z7 x' o- ^) i7 k9 q9 a that this server has some trouble causing the requests to take longer to be
( Z$ F" W' I; q processed than on other servers.: H( v# R1 G5 Q* j' r; P V
! n+ ~& W& n1 S
- "retries" is the number of connection retries experienced by this session
+ D7 S* _$ H- ]0 n" J6 a8 } when trying to connect to the server. It must normally be zero, unless a' `" |" n% R& f* F8 s# E! \* [
server is being stopped at the same moment the connection was attempted.
; H" @/ a* J# d0 E+ ~ Frequent retries generally indicate either a network problem between+ Y9 o p* Y3 u# o; E; ^0 t" u& w
haproxy and the server, or a misconfigured system backlog on the server
9 r' g, E1 L/ v4 W. O1 f1 F preventing new connections from being queued. This field may optionally be2 \8 z0 \" Y7 t5 M- g4 Q
prefixed with a '+' sign, indicating that the session has experienced a) ^1 S& c( T# U
redispatch after the maximal retry count has been reached on the initial
' w. s8 h/ s8 N- P: h% P server. In this case, the server name appearing in the log is the one the. p/ T: u# k) ^6 x% H% L
connection was redispatched to, and not the first one, though both may
, q/ b0 A1 q5 h9 k sometimes be the same in case of hashing for instance. So as a general rule5 k7 W# h! s1 ]7 h( p
of thumb, when a '+' is present in front of the retry count, this count
" M5 X5 ?0 E9 |# |3 H should not be attributed to the logged server.
1 ~# e V( f, l& D
) ~ M' J! _( h! S# q - "srv_queue" is the total number of requests which were processed before* b' X5 O+ @ E3 o/ [+ ~
this one in the server queue. It is zero when the request has not gone
" x- L, r, ~/ ]" }6 j& R, ] through the server queue. It makes it possible to estimate the approximate/ h$ y8 n' p# h3 \( }
server's response time by dividing the time spent in queue by the number of
. j, S% O, `% o/ t/ d requests in the queue. It is worth noting that if a session experiences a
+ K6 b+ N. ]9 r. H! ?" B: ~( B redispatch and passes through two server queues, their positions will be
% z0 j/ L p( v# C9 X1 J) ^6 W cumulated. A request should not pass through both the server queue and the
: G) C f7 ]7 c4 s, B# _ backend queue unless a redispatch occurs.
; k' K' y, Y$ [* m' m6 B- e4 f% x: l9 z1 U- V! V
- "backend_queue" is the total number of requests which were processed before% c5 R9 U6 j: K5 a. U; J0 Z
this one in the backend's global queue. It is zero when the request has not/ V' y9 |% u- T" A, p
gone through the global queue. It makes it possible to estimate the average
, @+ E T5 n H& v6 L t queue length, which easily translates into a number of missing servers when$ U( v$ ?; i% ?. B
divided by a server's "maxconn" parameter. It is worth noting that if a
9 W4 l0 Y# ]5 f* T$ _% B session experiences a redispatch, it may pass twice in the backend's queue,
- w' K s) O8 X- x6 Y" s and then both positions will be cumulated. A request should not pass. T8 m9 T8 m7 |- W. v+ G7 `' w
through both the server queue and the backend queue unless a redispatch
) s* u L F6 M1 s1 G7 V$ D4 ^ occurs.
2 L/ r+ L$ G4 }& F9 M
5 B7 ]4 a% a0 Z1 l - "captured_request_headers" is a list of headers captured in the request due* P/ b, r( c* x+ L$ i' g
to the presence of the "capture request header" statement in the frontend.
# `" h% Y2 \5 F$ Q K Multiple headers can be captured, they will be delimited by a vertical bar2 [" `# L1 N! R- m7 t. ?$ d
('|'). When no capture is enabled, the braces do not appear, causing a- o5 z: i0 o, ]* N3 q* Y
shift of remaining fields. It is important to note that this field may* ]6 i0 D& A2 ~( ?2 T+ L
contain spaces, and that using it requires a smarter log parser than when3 g5 W7 Y8 [4 Z
it's not used. Please consult the section "Capturing HTTP headers and
* g% A! b2 f0 t cookies" below for more details.. v: u) f' c* r' V6 C
3 C' J. L, |8 c8 H: j9 U
- "captured_response_headers" is a list of headers captured in the response
5 K B! @/ ~9 l: h) h due to the presence of the "capture response header" statement in the8 e2 M D4 }" s1 a0 w2 g
frontend. Multiple headers can be captured, they will be delimited by a3 Y! y# Y, c' R9 n6 S
vertical bar ('|'). When no capture is enabled, the braces do not appear, V3 |+ i. t4 G' A- r
causing a shift of remaining fields. It is important to note that this
% `' H! W V j% T field may contain spaces, and that using it requires a smarter log parser
* e2 f' v) X7 Q, f+ c6 ] than when it's not used. Please consult the section "Capturing HTTP headers
% }8 I8 P" N0 y and cookies" below for more details.2 R9 l j, d r
$ }) c9 X+ V7 l; ~ f0 }
- "http_request" is the complete HTTP request line, including the method,
* H4 x. ?5 X- | d+ Q0 Z request and HTTP version string. Non-printable characters are encoded (see! s9 t6 j& o8 P0 [$ T
below the section "Non-printable characters"). This is always the last
/ n* `2 i2 x* j- R) h6 L field, and it is always delimited by quotes and is the only one which can9 O2 [4 v7 f' Q, J3 j9 i
contain quotes. If new fields are added to the log format, they will be% ] k2 v% G5 Y
added before this field. This field might be truncated if the request is
8 [; t6 h& ~! W! A/ @ huge and does not fit in the standard syslog buffer (1024 characters). This+ P! T, g+ v* y, n1 B
is the reason why this field must always remain the last one.+ T* r7 ]! x1 o! y; Z8 X
6 J; P6 o1 z$ }/ P5 K8 `6 b+ B+ Q: a3 j; p
8.3. Advanced logging options
5 w4 z- ~. I, Z# @5 d-----------------------------2 r( X# g \1 h3 Z8 g g
B1 V% e8 C2 O$ nSome advanced logging options are often looked for but are not easy to find out
2 L6 e' C1 }# ^+ @% hjust by looking at the various options. Here is an entry point for the few) n7 Q1 H5 q3 g; A; O. W3 y+ b- v
options which can enable better logging. Please refer to the keywords reference( ^; |* F. k% m1 p: I6 j
for more information about their usage.
# Z* E/ }& C6 j! o6 j3 Y+ g% h& A7 V9 S
% O6 }1 A- u/ J8.3.1. Disabling logging of external tests2 }1 X1 V+ F& \% F, {! ^1 N# N4 d
------------------------------------------
6 h1 d$ L1 r/ A' e& F
8 a9 w- U1 }! [1 O5 k5 F9 x: pIt is quite common to have some monitoring tools perform health checks on A2 U: G" H2 f. V' L
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any
. y% h3 G! C( W* S% Zcommercial load-balancer, and sometimes it will simply be a more complete d, s/ V; ?6 \1 }' [3 k4 l
monitoring system such as Nagios. When the tests are very frequent, users often
4 n7 m) M- m6 Y! M5 n: h: \ask how to disable logging for those checks. There are three possibilities :
G. ^! g6 y3 p
9 q! I ^9 w3 D! e - if connections come from everywhere and are just TCP probes, it is often
: ]& [2 P; }; @, j `( Q' s' H desired to simply disable logging of connections without data exchange, by n5 g6 ^) W K
setting "option dontlognull" in the frontend. It also disables logging of0 e( ~9 r; j' j: V0 ]$ R
port scans, which may or may not be desired.
* N4 y$ }2 o: \# I, R6 ~
+ T$ Q6 j2 S5 q$ M6 H/ U; t7 l - if the connection come from a known source network, use "monitor-net" to
# R% I) M$ T. h9 X" { declare this network as monitoring only. Any host in this network will then7 N) b% d* T5 ~# |2 |/ F
only be able to perform health checks, and their requests will not be
% A% d1 g' A; b! S logged. This is generally appropriate to designate a list of equipments
0 j) [; a& r+ J4 r4 M* d such as other load-balancers.1 S& E. Y) Y7 X9 O3 i
4 g. A9 J* R1 P4 c! L8 g7 v L. G7 o - if the tests are performed on a known URI, use "monitor-uri" to declare
5 N+ Y/ m. b2 K0 e/ M; h* y% t this URI as dedicated to monitoring. Any host sending this request will
$ E% i* w, ~0 J6 M3 A- f: c only get the result of a health-check, and the request will not be logged.- s- \/ G# l5 g! b7 \
% ^7 \/ L0 X/ g( G8 k# e6 g3 d; ]5 v) Y J
8.3.2. Logging before waiting for the session to terminate2 j% q% `! b, p7 j
----------------------------------------------------------
$ r/ M* O9 l0 l1 z/ ~% t, Z4 R" F0 h7 K4 ? d
The problem with logging at end of connection is that you have no clue about( W9 N! d* |- N% `1 B
what is happening during very long sessions, such as remote terminal sessions
# T' C3 z7 k3 f8 \or large file downloads. This problem can be worked around by specifying. R* Y* w3 P# N! m
"option logasap" in the frontend. Haproxy will then log as soon as possible,) o6 d9 [( ^" ^$ }, z T
just before data transfer begins. This means that in case of TCP, it will still0 D1 \6 I. r0 @# K) D: M2 S
log the connection status to the server, and in case of HTTP, it will log just0 w, N8 _% j8 W+ G1 i2 o- i8 L) i
after processing the server headers. In this case, the number of bytes reported
8 ^" n1 T* f% M' his the number of header bytes sent to the client. In order to avoid confusion
& j8 g" z0 q, vwith normal logs, the total time field and the number of bytes are prefixed5 [# G+ a' D% |
with a '+' sign which means that real numbers are certainly larger.
( b P& d. |- w I6 `& a/ x
3 X5 ^0 l5 X2 ]( Y; I
( l, l, j, c" L) }8.3.3. Raising log level upon errors2 o8 W a4 s- G) ?$ R* p
------------------------------------4 N3 x6 O0 v* [7 }7 I! f
! o U1 m$ O: b$ J4 ]' ]
Sometimes it is more convenient to separate normal traffic from errors logs,
7 v7 M& U4 V/ u5 T v& d7 E; ^for instance in order to ease error monitoring from log files. When the option
v+ c/ }) K. t2 s+ u6 M3 _"log-separate-errors" is used, connections which experience errors, timeouts,$ H2 J' S0 [) ^2 e' I
retries, redispatches or HTTP status codes 5xx will see their syslog level0 G( Y2 g' v" t. ^
raised from "info" to "err". This will help a syslog daemon store the log in
! u( H# q. z8 T4 I) [a separate file. It is very important to keep the errors in the normal traffic
2 o0 E& L7 ^9 G( Lfile too, so that log ordering is not altered. You should also be careful if; m: S' d. Y2 e! M* z
you already have configured your syslog daemon to store all logs higher than0 i! `7 E5 `+ {2 E& }0 H
"notice" in an "admin" file, because the "err" level is higher than "notice".
( \$ q% U4 Y, b* D2 Q) ]3 q& b9 m; D4 m- B @- U
$ H x6 s( C; W8 M% M9 U4 C# d' G: V8.3.4. Disabling logging of successful connections
3 e/ H% b% W8 d. G( f9 q3 t6 Z--------------------------------------------------* w; L7 Z) V5 C
0 n- b; M2 R4 t, L% x6 \; V) v5 NAlthough this may sound strange at first, some large sites have to deal with
& x. ^' a' m0 d. m7 ~3 ^, emultiple thousands of logs per second and are experiencing difficulties keeping% Z5 b+ }2 s* w
them intact for a long time or detecting errors within them. If the option8 _* o8 E- j5 H( |& b/ x
"dontlog-normal" is set on the frontend, all normal connections will not be, H( h" t5 X1 G* ^; a
logged. In this regard, a normal connection is defined as one without any
. c8 k5 ]! g# t% ^' e2 T+ a. x' n+ rerror, timeout, retry nor redispatch. In HTTP, the status code is checked too,
% e! K# p6 m# R7 }7 u# zand a response with a status 5xx is not considered normal and will be logged
* ?% _3 x4 R- T T. L1 c. `: r9 L# T) htoo. Of course, doing is is really discouraged as it will remove most of the) B6 f8 s `, s8 @" _' K4 ?
useful information from the logs. Do this only if you have no other
; y7 m0 ?) J! P' |alternative.( M9 n* L% h& e+ d8 c
1 j6 }" ?: q! z% E$ G9 X9 Z
0 j$ J0 }' Q! e( Q
8.4. Timing events4 Q! s) c2 C: u* M
------------------
2 V) q) O1 x. {* x9 Z
: o# p6 ]1 v0 h2 D) u3 Y W- }Timers provide a great help in troubleshooting network problems. All values are( i) ^, h# l+ O$ a" c9 L; }! S
reported in milliseconds (ms). These timers should be used in conjunction with* Y$ |1 N) C0 l1 d8 l
the session termination flags. In TCP mode with "option tcplog" set on the
- ^' u6 I# r. S4 p9 z5 l( N; vfrontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP6 u `2 u4 A3 T$ Q4 n$ Z- X
mode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :
# t/ }; R" F: c) S: [) y2 g" ?$ T, R" r
- Tq: total time to get the client request (HTTP mode only). It's the time0 ], H0 c1 Y4 n1 n2 o
elapsed between the moment the client connection was accepted and the
( v& h X. u7 \: c# z moment the proxy received the last HTTP header. The value "-1" indicates
! z4 c$ N. Z) x4 c( H! Y1 ^ that the end of headers (empty line) has never been seen. This happens when
6 ]# X3 ^* o* I' I& T, a/ l; o# r the client closes prematurely or times out.
& Z# E, m- w4 \& E7 G% v5 Y: a# o1 n5 ^, Y+ i+ h. f
- Tw: total time spent in the queues waiting for a connection slot. It, x+ l- n+ ~- b y# g
accounts for backend queue as well as the server queues, and depends on the
" u9 j `" Y; a3 l, T) ^ queue size, and the time needed for the server to complete previous
2 P/ W2 }. Q$ `0 a( V! f requests. The value "-1" means that the request was killed before reaching
1 r+ m% X) L8 m. S& e" n the queue, which is generally what happens with invalid or denied requests.. @1 p. s& d9 u
8 w! w* S, d" U& F* J - Tc: total time to establish the TCP connection to the server. It's the time
h3 p& @% j3 h; A" U elapsed between the moment the proxy sent the connection request, and the
- b" [, V* d" Q0 G7 G d$ P, Q$ }8 ? moment it was acknowledged by the server, or between the TCP SYN packet and
' K6 j: I) B1 I+ x& P8 s the matching SYN/ACK packet in return. The value "-1" means that the
" g8 e! s! @* i3 L l }6 v connection never established.
3 @5 _9 }$ N: N( r9 r# f. A
( T: N1 j5 [4 i+ A& u - Tr: server response time (HTTP mode only). It's the time elapsed between# Z4 m3 W/ L; i
the moment the TCP connection was established to the server and the moment
2 t) X3 d! c4 X9 ` the server sent its complete response headers. It purely shows its request
2 w: W8 x. H9 n9 I7 R/ I processing time, without the network overhead due to the data transmission.
2 I4 z3 k; g) S2 I* h It is worth noting that when the client has data to send to the server, for* N5 g% g5 B, q% Z; u
instance during a POST request, the time already runs, and this can distort( f0 l) ]9 v0 n9 [/ L, H
apparent response time. For this reason, it's generally wise not to trust
( n2 V* ?& f' q7 D2 } c too much this field for POST requests initiated from clients behind an
. V1 _( {6 _" _. \2 @ y untrusted network. A value of "-1" here means that the last the response( k6 S" F7 j' U" B6 L$ e! F6 ^ Q
header (empty line) was never seen, most likely because the server timeout. i8 b" ]/ [5 ], z! F* J- o
stroke before the server managed to process the request.
+ d. j3 i+ C2 V! N/ F1 L$ U4 |( K, ?6 U% x D( _) s9 I
- Tt: total session duration time, between the moment the proxy accepted it
( Z- [& |& p# l( l, O and the moment both ends were closed. The exception is when the "logasap"- U% V4 |+ P% |# ~) \. [
option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is
+ e; y2 L; g0 b2 M7 c% g( L prefixed with a '+' sign. From this field, we can deduce "Td", the data0 ?* L5 Q3 S3 `: [; h6 J" a0 ^
transmission time, by substracting other timers when valid :3 P/ M6 s0 ?, I. D* w
4 f5 W; g# j! h8 a; N `( m
Td = Tt - (Tq + Tw + Tc + Tr)
4 s! b g8 Y7 L8 r+ W* a: C; G1 T# O5 N, W# J2 X3 s/ B
Timers with "-1" values have to be excluded from this equation. In TCP8 E) s* P3 L3 O) g
mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be
& }3 p1 A A) o8 f0 e1 M" K negative.
8 n$ q: W5 M4 Y$ z4 P2 K- Y
9 p8 O( U1 G- L. N5 S9 zThese timers provide precious indications on trouble causes. Since the TCP
0 V/ z% F3 s' T+ z3 L* }, ~* Hprotocol defines retransmit delays of 3, 6, 12... seconds, we know for sure/ C6 L0 z# _. J2 u' e
that timers close to multiples of 3s are nearly always related to lost packets3 S- B0 N/ H0 i) U
due to network problems (wires, negotiation, congestion). Moreover, if "Tt" is
( p+ T6 C0 T5 T4 ?$ o' _) `close to a timeout value specified in the configuration, it often means that a
; Q, G2 n7 O& |7 O" |session has been aborted on timeout.
4 r4 Z. v( V; d/ @# k# h/ g3 k
6 t& y8 p$ N. M( X. Y0 O8 h- GMost common cases :
, w; i2 r# b9 _. }4 b/ w4 F: d. T2 k& S* `$ ~$ i4 C1 w, K. N
- If "Tq" is close to 3000, a packet has probably been lost between the) y' w7 u) b ?5 Y! }
client and the proxy. This is very rare on local networks but might happen% Y* u/ `* D E
when clients are on far remote networks and send large requests. It may- R U* h) N: `3 b
happen that values larger than usual appear here without any network cause.
! V: h0 I# N G( j' O1 P& r2 r Sometimes, during an attack or just after a resource starvation has ended,
' V1 }3 N9 a+ A+ C haproxy may accept thousands of connections in a few milliseconds. The time5 ]) J- [) s/ P9 m3 A
spent accepting these connections will inevitably slightly delay processing- J' @0 i6 L; C
of other connections, and it can happen that request times in the order of( Z% G h( N: J7 ` k. _/ N$ g8 |
a few tens of milliseconds are measured after a few thousands of new
* u3 o: h, w1 e connections have been accepted at once. Setting "option http-server-close"6 m9 k% O) w# I9 d
may display larger request times since "Tq" also measures the time spent
8 W0 ?. {% U0 m5 ?/ u b waiting for additional requests.
7 x& j) Q( L1 j3 f1 G' \4 C3 h$ C& ?5 c4 A$ a
- If "Tc" is close to 3000, a packet has probably been lost between the5 o( A, a: W" H4 @
server and the proxy during the server connection phase. This value should
1 \1 r P% H. [) a, z/ c2 q always be very low, such as 1 ms on local networks and less than a few tens. K$ a( ?$ z/ r. ?7 S* y
of ms on remote networks.
9 N' Z, |7 I& R, X7 A6 d
- M7 J9 \7 h; y; M3 g1 r7 P0 g* I - If "Tr" is nearly always lower than 3000 except some rare values which seem/ A5 L' W8 @' c' |3 S+ K
to be the average majored by 3000, there are probably some packets lost! ~# b- R% T1 q0 E
between the proxy and the server.9 T" d9 |- v! A. c) A5 \9 Y
( a9 ]" \" T ~( o \
- If "Tt" is large even for small byte counts, it generally is because% Z/ [8 O8 R5 y' ^. S
neither the client nor the server decides to close the connection, for
6 Y7 x, X' U- V9 M instance because both have agreed on a keep-alive connection mode. In order
8 J5 b" b) I# s- n2 O- [$ z2 R to solve this issue, it will be needed to specify "option httpclose" on
+ a/ g& r& C; [! a2 \* x either the frontend or the backend. If the problem persists, it means that% {8 r, C6 j }
the server ignores the "close" connection mode and expects the client to! ^ z! q) u, W) ^, D
close. Then it will be required to use "option forceclose". Having the% |" ?( q( s+ N9 a1 Q o5 J$ A
smallest possible 'Tt' is important when connection regulation is used with0 V9 e: P C- x
the "maxconn" option on the servers, since no new connection will be sent
: {2 B7 w) G z* @5 b to the server until another one is released.
# B7 Q0 {' n; x N, y2 W
/ C7 }" n# z9 H+ OOther noticeable HTTP log cases ('xx' means any value to be ignored) :/ i+ e1 l+ F f( z; ^2 E. m
R/ L8 X% S) K* P' Y& `* `. b
Tq/Tw/Tc/Tr/+Tt The "option logasap" is present on the frontend and the log: ?/ v# i2 K" G6 ]
was emitted before the data phase. All the timers are valid& h& v; f- y4 M
except "Tt" which is shorter than reality.. l# M/ `* m& Z4 l5 E% r
( c/ \- O6 _# @5 y4 R -1/xx/xx/xx/Tt The client was not able to send a complete request in time( Z5 C& k% Y4 E5 @1 g# }+ @! s0 f
or it aborted too early. Check the session termination flags
8 A7 f6 B7 h' `0 L then "timeout http-request" and "timeout client" settings.
# k; J2 ?; K! U5 T2 U6 v) q% G; k8 x
7 B- ^ K0 H' \+ g4 \* p Tq/-1/xx/xx/Tt It was not possible to process the request, maybe because3 A( ~) q8 p& r K* m& Z' Y6 E
servers were out of order, because the request was invalid
4 M; x& a N9 i or forbidden by ACL rules. Check the session termination
) t0 C+ T/ k9 A7 E' R$ A! e- I0 d% g flags.
% q2 I2 L9 D0 p8 ?) x
7 D* Y9 x- J0 [$ F* w Tq/Tw/-1/xx/Tt The connection could not establish on the server. Either it
" a) R, d/ r5 `, _7 K7 o actively refused it or it timed out after Tt-(Tq+Tw) ms.
& \5 r% e8 O" X0 ` \3 I K Check the session termination flags, then check the
& I. ] E. d' A9 t "timeout connect" setting. Note that the tarpit action might
. I+ m6 s1 @6 W ]' W3 S1 t return similar-looking patterns, with "Tw" equal to the time7 }9 z7 a0 Y- A3 d* r$ p
the client connection was maintained open.
9 M; Y3 }+ @+ v6 f1 n
4 o4 s) p: P o2 v0 m: X, { Tq/Tw/Tc/-1/Tt The server has accepted the connection but did not return
+ [$ }1 o% E' z( ~; k1 k9 S9 O! V a complete response in time, or it closed its connexion7 I8 p) l0 h+ \- {0 q% J; \
unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session: j. T' s. c& V6 v% A7 M* R) B; W; A
termination flags, then check the "timeout server" setting.
' z! k, ?4 D7 g3 a2 A# l0 _) ^& E N/ O* |: z% \. U$ v/ n% f/ w% |( C3 L
' k4 Z: t# ]7 l
8.5. Session state at disconnection" p5 g2 f& u7 M: d- X+ l1 J
-----------------------------------4 U+ m0 {9 M3 g e
$ m& b- X u2 m
TCP and HTTP logs provide a session termination indicator in the9 ]# f2 ?+ }; H+ l% @
"termination_state" field, just before the number of active connections. It is1 ~/ g+ n& @: ]( O* C
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,- ^8 A5 T" ?; i/ ?+ P! B6 \
each of which has a special meaning :* Q5 u( e) `/ N2 `: b1 a& h
, G$ j6 U: Q$ r8 n0 p+ I$ G: Q# U, ?
- On the first character, a code reporting the first event which caused the
X( z6 g1 Z; U' z& o/ Q session to terminate :0 r2 J c l/ Z4 R1 \/ X1 b- _+ M) d
# y* b6 M e; q+ |% ]3 O) g2 a
C : the TCP session was unexpectedly aborted by the client.# V" Z9 L# C$ _
( R! d) F9 T# T S : the TCP session was unexpectedly aborted by the server, or the
( G l7 ~% f& d5 Q( |9 J server explicitly refused it.% B. v0 x; e0 @- M% p h
3 p& R/ n# s4 f P : the session was prematurely aborted by the proxy, because of a6 D; l" U- x2 V' ^" I) i3 X
connection limit enforcement, because a DENY filter was matched,0 E N* T. n6 j3 a) I
because of a security check which detected and blocked a dangerous; N# y" V* p5 R
error in server response which might have caused information leak, m3 u2 o6 z. t/ l; w2 K
(eg: cacheable cookie), or because the response was processed by& d! c) ]5 x' m7 q7 v- M0 C
the proxy (redirect, stats, etc...).
9 U5 c7 k1 |8 v! `9 B1 b7 A5 V1 [0 L- l, W/ ~# i4 j. _2 `
R : a resource on the proxy has been exhausted (memory, sockets, source2 g2 u; }4 \. V5 ]9 a6 Z
ports, ...). Usually, this appears during the connection phase, and! d0 r/ A" H2 |% \
system logs should contain a copy of the precise error. If this
& f/ Q! r9 `' W$ `# p happens, it must be considered as a very serious anomaly which) J0 X; S. U6 ?: t0 a
should be fixed as soon as possible by any means. k3 d1 U" z; p& C0 N
/ v. T" S S: |$ n5 b
I : an internal error was identified by the proxy during a self-check.
8 _' ~2 C0 @! I/ q% ^! M5 U This should NEVER happen, and you are encouraged to report any log* Y4 ?! _( `3 p" S5 {
containing this, because this would almost certainly be a bug. It5 }9 ?) i7 E2 B" N
would be wise to preventively restart the process after such an
; k0 D* h" H+ l' n event too, in case it would be caused by memory corruption.( ?# O0 d& N+ Q, s5 o) b
+ {' C. a& Y' Y c : the client-side timeout expired while waiting for the client to |9 I' u% i! N( ^
send or receive data.) l# n8 X6 U1 c5 L% c) W1 [
6 b( q( }: j/ q) n# M
s : the server-side timeout expired while waiting for the server to+ |2 ]; V0 v8 a+ p4 W
send or receive data.% q; E" z' c5 `. \! z
' c* g& ^5 ^5 f2 L. C0 P3 r z - : normal session completion, both the client and the server closed. x5 m. `+ o6 N8 F0 W( G
with nothing left in the buffers.; Q5 n5 y7 ^. J! L9 f
; g9 T0 a( }! j& ~& [
- on the second character, the TCP or HTTP session state when it was closed :3 w! U+ L" H9 Y
6 ], T( j5 J8 J: K! `0 u0 ]
R : the proxy was waiting for a complete, valid REQUEST from the client' Z0 o% v! Y% w
(HTTP mode only). Nothing was sent to any server.3 S0 ?3 }4 S4 [+ m# r8 a
! s% R$ d$ [& s/ E" f& V8 {
Q : the proxy was waiting in the QUEUE for a connection slot. This can6 }9 Q6 r, U; |3 E" Q
only happen when servers have a 'maxconn' parameter set. It can
" A9 e( z2 c. B3 H) _" T* Z also happen in the global queue after a redispatch consecutive to
& o4 c) x) O7 ~9 I) a, }& Y/ y a failed attempt to connect to a dying server. If no redispatch is# J4 p* }0 q3 r# ~4 n6 v+ d, }
reported, then no connection attempt was made to any server.# w, t, e4 c7 y9 }- U# L C
% l# l9 W' B3 T( F' F
C : the proxy was waiting for the CONNECTION to establish on the
' O4 p7 T2 j4 v5 n server. The server might at most have noticed a connection attempt.# Z) R5 O1 l) e$ e6 z9 B$ ~
, D) s6 x" ~, l8 n, k* ^' \1 ?6 |; g$ F H : the proxy was waiting for complete, valid response HEADERS from the% D t! m9 V8 ?$ }" q7 ?
server (HTTP only)., m/ H/ B5 \$ w! k0 V" ~
! J" M; e. _# M3 _1 |; T
D : the session was in the DATA phase.4 ?4 w6 H' T9 M. L5 E
9 z# U( y2 P a8 I* U% l) h L : the proxy was still transmitting LAST data to the client while the" N4 Z1 ?8 ], f* w" K
server had already finished. This one is very rare as it can only
% }! L' u# O' X happen when the client dies while receiving the last packets.
+ j! i8 i& G1 P5 ~4 A$ c+ R
) }! b4 D8 x- _6 a5 R. R( h6 Z T : the request was tarpitted. It has been held open with the client
7 }' l3 V4 U# i. x7 X during the whole "timeout tarpit" duration or until the client& V$ w2 `5 l8 ~6 _, e( i
closed, both of which will be reported in the "Tw" timer.
6 u% k3 v7 J3 y+ t5 V" ^# I
9 T. [$ A) C8 `, B9 d/ a - : normal session completion after end of data transfer.5 k' o5 b$ P& F4 y# n! m
, i' s1 l2 k+ ?" k" J ?
- the third character tells whether the persistence cookie was provided by
q# u/ l/ _# l X- y& | e" Y the client (only in HTTP mode) :- v7 e9 S$ e: \' q
( r9 x$ r8 j& f6 d' V8 j3 { N : the client provided NO cookie. This is usually the case for new
% L% t5 B; `! \ visitors, so counting the number of occurrences of this flag in the
1 c% I7 J5 w: e3 k1 t) k+ g6 i logs generally indicate a valid trend for the site frequentation.' b4 @& p8 m" i; m
8 ~! g7 R! V, ~9 t" S* X I : the client provided an INVALID cookie matching no known server.6 @0 ^7 s/ A' \. O [& n6 X
This might be caused by a recent configuration change, mixed
9 u5 B. d* o. b) v1 c; Y cookies between HTTP/HTTPS sites, persistence conditionally# h4 v, ]4 s: T7 J9 ~
ignored, or an attack.
* ?# V$ |" o& Z0 [ y% U' E) I
! V# _) \3 ], l; z* c D : the client provided a cookie designating a server which was DOWN,
, W: i. d! @! t" n9 t' b2 F+ q so either "option persist" was used and the client was sent to
0 N8 m" [# U8 C5 }1 K C this server, or it was not set and the client was redispatched to, h" {" M# n3 p4 @4 A8 c8 ]7 R
another server.5 l; T! P: u2 S9 ^! z% v- Y4 O% G
/ M3 m3 c! R- k; \3 k4 u
V : the client provided a VALID cookie, and was sent to the associated1 j+ f2 H. B& M p! T- R. y
server.' w4 L' t0 a7 W+ o7 @5 s: w
" i; t# F6 K4 \% h! r( r3 O
E : the client provided a valid cookie, but with a last date which was
1 ~- T/ c' e2 [9 S# d older than what is allowed by the "maxidle" cookie parameter, so
5 J& s5 ^! m* M. @* Z the cookie is consider EXPIRED and is ignored. The request will be
7 U. }" _; X4 W& S$ F" M% `1 d6 u redispatched just as if there was no cookie.
0 ^; v. z2 k4 T2 w6 E# G; x
8 A/ T6 e) Z z+ ~" G4 { O : the client provided a valid cookie, but with a first date which was
) P# M+ D! g$ A older than what is allowed by the "maxlife" cookie parameter, so
- M. O! V2 _- b the cookie is consider too OLD and is ignored. The request will be
7 O; y F- B, @5 [7 n }3 n4 i* t redispatched just as if there was no cookie.4 i& t/ G( f4 u7 ^+ {. V
1 \8 z `7 @5 Z+ M
- : does not apply (no cookie set in configuration)./ M) H* G V5 a6 J" n8 @- p
" [; g8 N/ y1 E0 N o: _ - the last character reports what operations were performed on the persistence: y; {% G% w% g# f
cookie returned by the server (only in HTTP mode) :
F8 O& z" h! n% J3 S Y0 O8 {$ G1 ^9 I3 R1 e. p% k( s; c
N : NO cookie was provided by the server, and none was inserted either.8 H0 b8 A* e6 L4 D
7 ~9 z! F- `. A& b I : no cookie was provided by the server, and the proxy INSERTED one.
' P7 a( a: E3 X Note that in "cookie insert" mode, if the server provides a cookie,
" L) X0 u7 K+ f, s it will still be overwritten and reported as "I" here.
/ k' H, ]5 H7 J' j
4 c( n/ V- z! L: { U : the proxy UPDATED the last date in the cookie that was presented by2 }' D! Z3 I& `* U! P8 J
the client. This can only happen in insert mode with "maxidle". It
) D4 L0 G6 |9 r happens everytime there is activity at a different date than the
1 p8 H# A7 \0 S- \- z, w* W5 Y date indicated in the cookie. If any other change happens, such as
* j) [5 b5 n3 @! X. j a redispatch, then the cookie will be marked as inserted instead.
' K3 h: V$ Z: b4 f, o3 g% A3 B$ y5 O3 x
P : a cookie was PROVIDED by the server and transmitted as-is.
4 z8 Y% Q' Z& Y1 a: @. `# U# ^9 R' t' H
R : the cookie provided by the server was REWRITTEN by the proxy, which
2 V" T+ p h3 O& Q+ q happens in "cookie rewrite" or "cookie prefix" modes.
U- C) o) D8 m& X" W+ f$ a3 `# Y$ s) u$ j) @5 j- X, j2 Y: j
D : the cookie provided by the server was DELETED by the proxy.
) ^8 w; } s7 M. ?7 T% P u, f# d1 ^) m% g3 a" z' O% n# u v
- : does not apply (no cookie set in configuration).+ B7 {$ Y2 @6 p& {; `" m" v& s2 H
2 f& ?' k. ^; L. [. T
The combination of the two first flags gives a lot of information about what( s0 `& g4 a) m U8 z1 b4 ?9 ?
was happening when the session terminated, and why it did terminate. It can be9 s- ] _+ ?: l( D e2 S; X+ K2 e
helpful to detect server saturation, network troubles, local system resource
, V! w- ^& v n$ t# b5 w$ M" a- x2 Istarvation, attacks, etc...
4 O3 `5 `) ?! j& y8 v
! M8 F9 K5 e! l( JThe most common termination flags combinations are indicated below. They are
1 r' W4 ?- o$ ]& `5 Lalphabetically sorted, with the lowercase set just after the upper case for" j: ]& b0 L! R
easier finding and understanding.0 N8 u; J7 c8 H/ a
6 {* ^9 ]# P, s0 k0 R( B1 ` Flags Reason2 G+ L$ }! p1 N' @/ `' |! Y
% Y' L- K j7 W/ x: S! d9 K& v
-- Normal termination.1 S1 S B3 Y1 y: |" w
& e% u$ G' w' N CC The client aborted before the connection could be established to the' m, x# _: @% d; ]# F) G9 E8 }: O5 Y
server. This can happen when haproxy tries to connect to a recently
8 w1 I+ G8 }* p8 g, ^ dead (or unchecked) server, and the client aborts while haproxy is
6 [( e& [. c( H; } waiting for the server to respond or for "timeout connect" to expire.
( {3 r* t( y* n9 i5 G* h/ G8 q
' ]* [' |5 C0 |9 ] B* o# I CD The client unexpectedly aborted during data transfer. This can be! }3 w# T" E3 B1 k! K( G
caused by a browser crash, by an intermediate equipment between the* J5 f2 \6 P, b- w0 A d
client and haproxy which decided to actively break the connection,
& Q' T3 _/ {. f by network routing issues between the client and haproxy, or by a, h$ ~" {. t8 J$ y- D6 }" X
keep-alive session between the server and the client terminated first- O8 S# {( I9 w7 k {
by the client.# O0 D: G# ?" D- Q6 E8 d
9 c* k5 I% q! x7 ?+ [2 s
cD The client did not send nor acknowledge any data for as long as the& x1 r% I, r j( j7 k# k6 `- Y
"timeout client" delay. This is often caused by network failures on
; S& N. Y& Z. q the client side, or the client simply leaving the net uncleanly. B- z: w4 O1 R0 p
+ d; X; H4 f/ I9 P CH The client aborted while waiting for the server to start responding.
, \9 U; \& G6 U3 i4 j, ?' g It might be the server taking too long to respond or the client" r, }2 n) n8 w
clicking the 'Stop' button too fast.+ ?0 b+ L: a' ]' z( J: Y' F/ _7 U
+ ?2 L4 e2 {$ \: {2 J
cH The "timeout client" stroke while waiting for client data during a# G& Q5 F: [9 A/ I x
POST request. This is sometimes caused by too large TCP MSS values
& {% S, J X6 B/ m5 n for PPPoE networks which cannot transport full-sized packets. It can
7 ]# H: y) W: o5 s: Q* } also happen when client timeout is smaller than server timeout and) q3 d6 ?) Q. G4 x/ }9 |
the server takes too long to respond.' E% N2 m' N' c
9 F6 c6 G% k# l
CQ The client aborted while its session was queued, waiting for a server& P I- S* ?5 V
with enough empty slots to accept it. It might be that either all the( [7 u% m9 X* u' Y
servers were saturated or that the assigned server was taking too b! c. W8 Q0 l& L6 i; H) T8 e% ^
long a time to respond.- u% D2 ], }, c; I' C
7 H" _0 A% `3 R0 O8 F CR The client aborted before sending a full HTTP request. Most likely
, A- A% m+ V2 f: S r0 X the request was typed by hand using a telnet client, and aborted
" A" B0 w# l; b3 l# |6 M8 D9 ~0 e too early. The HTTP status code is likely a 400 here. Sometimes this
& k3 h# Q4 p$ c& | might also be caused by an IDS killing the connection between haproxy
/ `7 \& a2 u5 u F" K( w and the client.
_7 C/ S) \: b$ r( ? d, K
( d' ]6 F# j7 ] cR The "timeout http-request" stroke before the client sent a full HTTP% i$ Z( P3 Q2 k; }, q- T7 L7 F6 N
request. This is sometimes caused by too large TCP MSS values on the) J y9 p! K7 P# b
client side for PPPoE networks which cannot transport full-sized/ j9 e1 V8 u) R1 G2 k6 j+ u
packets, or by clients sending requests by hand and not typing fast" I( L8 y& U, m: a! D" Q( I
enough, or forgetting to enter the empty line at the end of the0 @% [1 T7 Z6 m, {1 Z& W
request. The HTTP status code is likely a 408 here.
2 E3 q8 ~. p/ V A- i- \9 j# @ l3 I" _
CT The client aborted while its session was tarpitted. It is important to
" T, i8 d. I' l& p check if this happens on valid requests, in order to be sure that no
9 `! s+ }; N$ L2 c; e" N wrong tarpit rules have been written. If a lot of them happen, it+ p1 B5 p# y+ x+ a& ^$ _! P5 W: N
might make sense to lower the "timeout tarpit" value to something* M$ e% q7 P$ I3 ^) _. d
closer to the average reported "Tw" timer, in order not to consume
- s, K& i, U: j. k6 H resources for just a few attackers.
2 N2 e0 E: C& Y5 s, d Q3 V P, l6 K$ r+ n; X6 X. k- B x
SC The server or an equipment between it and haproxy explicitly refused2 J7 p7 @" C$ v
the TCP connection (the proxy received a TCP RST or an ICMP message
1 A3 t3 k, M. b. J8 q5 A5 [/ s9 W in return). Under some circumstances, it can also be the network
0 V/ e/ v2 S7 i. W- A5 M$ L. T( w stack telling the proxy that the server is unreachable (eg: no route,
2 f; g: G; f, N or no ARP response on local network). When this happens in HTTP mode,- K" T1 O8 c5 @1 P
the status code is likely a 502 or 503 here.) L" e0 ~8 v6 e) l- M8 W
. |1 ?- N. ~& n0 T8 N; X sC The "timeout connect" stroke before a connection to the server could" J7 B% \; W8 F# [0 {6 p
complete. When this happens in HTTP mode, the status code is likely a
4 p7 w4 M2 S7 w }. t! s 503 or 504 here.! {( Z8 s0 v9 ~: n+ F v
* k4 {1 R. T" o' v. q" A$ Q SD The connection to the server died with an error during the data
`5 E6 i9 S- [. x. M, |$ l" }/ }* L transfer. This usually means that haproxy has received an RST from
" x; a9 c; G2 q- ?7 Z, @' y the server or an ICMP message from an intermediate equipment while
# v4 x3 d2 a" T b c exchanging data with the server. This can be caused by a server crash# d* @/ O4 S# ]
or by a network issue on an intermediate equipment., k& r* E7 g! Y" q
. E3 |: q; S1 e* k7 X G sD The server did not send nor acknowledge any data for as long as the
4 ^& l+ k, Z4 U& ~9 K: y "timeout server" setting during the data phase. This is often caused
/ e l3 H' e& i by too short timeouts on L4 equipments before the server (firewalls,
3 v8 Q" L& {7 A+ v- f0 }' N load-balancers, ...), as well as keep-alive sessions maintained
9 E' P1 z& y* Y between the client and the server expiring first on haproxy.& @# u; Q2 F8 S
2 L! b+ p# Y% f- d/ S2 q- n" | g2 X SH The server aborted before sending its full HTTP response headers, or
4 X# ^9 K2 B# b/ Y* U# ^ it crashed while processing the request. Since a server aborting at; o: l6 `7 \+ m: \, l
this moment is very rare, it would be wise to inspect its logs to* f3 B. F* E. b% c
control whether it crashed and why. The logged request may indicate a0 H: h- F0 I B
small set of faulty requests, demonstrating bugs in the application.
$ h( s9 Z: l' Q# G% D# H } w- H4 E Sometimes this might also be caused by an IDS killing the connection
, g* W/ M' v! L( D5 \ between haproxy and the server.
3 e6 d! S9 |+ W) K( ]; b0 B" N+ \9 C" b
sH The "timeout server" stroke before the server could return its% i, L- V) m% B# [4 u6 k
response headers. This is the most common anomaly, indicating too; @% F5 q- @- ]* \* ]7 q
long transactions, probably caused by server or database saturation.
& W" g0 Z. K/ P0 R& P- ^3 n The immediate workaround consists in increasing the "timeout server"
; w! r/ f5 Y, L$ B9 g setting, but it is important to keep in mind that the user experience
: [+ h' v# m P0 d will suffer from these long response times. The only long term
9 W2 G. S' ?: N" B solution is to fix the application.
+ [" q/ B7 A- I3 m! ]8 e- e: Q; x) K0 w2 t. X
sQ The session spent too much time in queue and has been expired. See
# X0 S: A; ~- D$ b& R the "timeout queue" and "timeout connect" settings to find out how to5 s, k! z/ n# N# Z! u' _$ v
fix this if it happens too often. If it often happens massively in$ ^: V5 X* `7 H3 X, t7 Z0 G3 P! L
short periods, it may indicate general problems on the affected
( t1 J) U4 j4 g1 s/ Z9 s# v, i servers due to I/O or database congestion, or saturation caused by5 `- y0 d5 ^' P4 T+ ^- x
external attacks.
; `0 m6 c( }" r% \; q& ^& c3 `8 t8 R) E. l9 b. G. C
PC The proxy refused to establish a connection to the server because the
. I5 k" |0 x) s process' socket limit has been reached while attempting to connect.- m/ Q0 H2 d) Y8 f0 a: ~
The global "maxconn" parameter may be increased in the configuration2 c$ [2 f+ {, C1 [2 d" s' x
so that it does not happen anymore. This status is very rare and
9 ?! w* }% c7 n& a8 @! O might happen when the global "ulimit-n" parameter is forced by hand.
5 q2 z1 Y; U% @9 t, Y, A$ S5 I$ Y) V6 f
PD The proxy blocked an incorrectly formatted chunked encoded message in7 E7 x' `# [7 z# ~
a request or a response, after the server has emitted its headers. In
8 {6 o: \5 v) d5 Q. Q* ? most cases, this will indicate an invalid message from the server to' s% d2 z) ~4 S
the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647
& h- R: v" o, o5 y& Y% x% Q4 S bytes). Any larger size will be considered as an error.
! u1 X% P. T2 h x
$ w% I( ^& u6 M$ {# m# A PH The proxy blocked the server's response, because it was invalid,% {6 V l9 L9 s+ u$ D$ @3 d9 U
incomplete, dangerous (cache control), or matched a security filter.
{+ O5 S* D, S In any case, an HTTP 502 error is sent to the client. One possible
" }' U, V4 P( x9 U3 f" W cause for this error is an invalid syntax in an HTTP header name4 t) N0 B, g% I! A) k
containing unauthorized characters. It is also possible but quite9 H* Q. ~- f) G% I
rare, that the proxy blocked a chunked-encoding request from the
! J( ~5 ~, |" c! O% e' W0 u client due to an invalid syntax, before the server responded. In this
% ^3 f8 c0 N0 H- H6 a case, an HTTP 400 error is sent to the client and reported in the( u; Z% w, L% H' O) v% F& t
logs.. J% _6 g1 d; F6 J; s, ]1 m3 G
; J; d3 {* M- l7 `' ]0 I PR The proxy blocked the client's HTTP request, either because of an$ }+ a. Z7 r& S$ M' O/ j$ x
invalid HTTP syntax, in which case it returned an HTTP 400 error to
1 R1 l7 w+ N0 V. D) y the client, or because a deny filter matched, in which case it
! p! ?. P3 j# c$ {+ B returned an HTTP 403 error.; T' ?% i2 H6 ]) J+ T2 q* Z
+ \. A6 F! K+ F3 t PT The proxy blocked the client's request and has tarpitted its8 `' W/ ?7 l4 L5 s
connection before returning it a 500 server error. Nothing was sent$ @# A& e% }) u) o4 ]; W- l7 J
to the server. The connection was maintained open for as long as
7 a; ]- S1 w( g7 X reported by the "Tw" timer field.
8 P9 ~$ j" M) L M4 s5 t+ m+ ?) S8 Z
/ \$ d1 o ]1 N, Y/ v+ a RC A local resource has been exhausted (memory, sockets, source ports)( M! p, C' M1 u, a0 P' H
preventing the connection to the server from establishing. The error6 U0 V* {+ p& m
logs will tell precisely what was missing. This is very rare and can+ y0 r; f/ J' H h0 w; _( [
only be solved by proper system tuning.& A: y/ E) _( J, d$ \
9 P' E9 w, W. U7 j% q( LThe combination of the two last flags gives a lot of information about how9 }' s# l t0 I2 i( D% X
persistence was handled by the client, the server and by haproxy. This is very
, _. _( s' {' E! p5 k! T2 simportant to troubleshoot disconnections, when users complain they have to
; s3 f- U. g. |re-authenticate. The commonly encountered flags are :7 g% y/ {# `5 ]! R
! \( n1 ^( h7 }- U- O0 `
-- Persistence cookie is not enabled.. s7 n+ [; A/ v4 B9 b O
$ ?3 ]( e2 f+ }9 w: T: Z6 v
NN No cookie was provided by the client, none was inserted in the, Y a- Q( B. w0 y. t' @
response. For instance, this can be in insert mode with "postonly"
3 U: d* B) f" i1 s set on a GET request.
8 k6 o, j0 v) [1 c. X& X% r
" }* B6 L0 x9 s& R R1 x8 y8 L6 y II A cookie designating an invalid server was provided by the client,
9 d% k& q! m: _$ g( b; o a valid one was inserted in the response. This typically happens when
& n. |3 Q" r/ Y! E8 c" k3 d a "server" entry is removed from the configuraton, since its cookie
/ C; @5 j+ G0 @- }/ p# F1 I value can be presented by a client when no other server knows it., x; H5 M" k5 }/ l3 a
, i6 k T7 s+ B7 }) x6 Y
NI No cookie was provided by the client, one was inserted in the9 [/ u. F% q$ `0 P( e! R# q
response. This typically happens for first requests from every user" P7 C6 a1 ?7 X4 i9 y
in "insert" mode, which makes it an easy way to count real users.
1 z0 Q3 T+ _, V+ @3 R, S% ]+ C
4 d z+ b! k+ h/ \; e3 R VN A cookie was provided by the client, none was inserted in the3 }4 s2 U3 Q A4 ` K4 k7 c/ z
response. This happens for most responses for which the client has) {- J9 l7 u8 Y0 Q6 w9 l) d
already got a cookie.
% U2 J4 i! p6 k# j( }% _7 ?% [ t# p( F0 ?5 T; v ~2 f; A+ G! C
VU A cookie was provided by the client, with a last visit date which is, }4 l6 y3 p4 P. H. v' d ?
not completely up-to-date, so an updated cookie was provided in
) q7 Q$ U# s% ?/ U response. This can also happen if there was no date at all, or if
/ m4 k w5 l1 l/ n there was a date but the "maxidle" parameter was not set, so that the. P7 g5 Y: I0 H D' i
cookie can be switched to unlimited time., r0 P( ^" s0 w# S }
4 f$ f6 P5 m2 z+ r% t! t, A, N EI A cookie was provided by the client, with a last visit date which is3 \3 P) O" n8 ^, I3 k
too old for the "maxidle" parameter, so the cookie was ignored and a0 ~( N, z% W) h! e# ?( Q6 L
new cookie was inserted in the response.0 u+ y* g5 @" Y) K# `' ?
- G& j, I! E5 ]; ^) E
OI A cookie was provided by the client, with a first visit date which is
4 p0 B/ } D& w: i2 r5 X- O too old for the "maxlife" parameter, so the cookie was ignored and a
. G8 n" i" P, X9 ~7 K+ L6 \" e new cookie was inserted in the response.
1 l) c: w0 r3 m6 \6 J3 R; N* L A b3 Y t
DI The server designated by the cookie was down, a new server was. _$ l( F0 ~. j- v, j& @) o7 }4 c" S
selected and a new cookie was emitted in the response.: R/ k k$ m: {8 C0 F
" P( q! O9 x# e VI The server designated by the cookie was not marked dead but could not
" b2 F9 Z3 u3 S% F" m/ b+ M ` be reached. A redispatch happened and selected another one, which was
& O3 ?" n0 ?$ {" m! T+ a then advertised in the response.: j' Q) T" j4 l, P
- e5 t) W! y. M: \( W9 W J2 h; h9 h/ s2 n3 P$ y+ a6 v" T
8.6. Non-printable characters
; l1 l4 K! ]% C; M) ~-----------------------------
& X$ F* w+ u5 Y( J0 q* [, `, s; g6 r
* `9 t- N n' x) wIn order not to cause trouble to log analysis tools or terminals during log4 w( }% R' j/ A1 X1 J
consulting, non-printable characters are not sent as-is into log files, but are
) y3 {0 Z; \, d' C; i- M3 Kconverted to the two-digits hexadecimal representation of their ASCII code,' w4 ~; h7 \$ q
prefixed by the character '#'. The only characters that can be logged without& w! l, e! ~" q9 H' j
being escaped are comprised between 32 and 126 (inclusive). Obviously, the
) B0 D$ k1 b5 ^% B$ x, y( Y6 qescape character '#' itself is also encoded to avoid any ambiguity ("#23"). It! g/ t" q6 \ A: |, j
is the same for the character '"' which becomes "#22", as well as '{', '|' and
, ?2 O! T. f G/ s- |'}' when logging headers.
; w7 A" Z8 O! E8 ?% h F
+ o1 R; |% K. x1 GNote that the space character (' ') is not encoded in headers, which can cause% L( [1 K* B) h0 v7 [) q
issues for tools relying on space count to locate fields. A typical header$ |0 J; v5 x4 G0 P0 @5 ^6 j( O
containing spaces is "User-Agent".4 x/ \6 F6 I0 v, g
5 S9 P) N; Y7 ]. l( J, tLast, it has been observed that some syslog daemons such as syslog-ng escape
) ~3 G4 P) m4 G; Q) f# Q- uthe quote ('"') with a backslash ('\'). The reverse operation can safely be' B6 ~4 p( k- h( s# W' p
performed since no quote may appear anywhere else in the logs.6 y, V0 x0 j2 b1 m
4 }5 E, F4 n) J" X3 z* S, s
$ f/ F% a( C+ Y o
8.7. Capturing HTTP cookies0 u7 }, b$ K) T" z
---------------------------
1 R, [) M3 t" L$ [2 T
0 H: b- ?+ k& ]6 M3 k' U3 jCookie capture simplifies the tracking a complete user session. This can be2 b/ T" Y+ g! e3 g
achieved using the "capture cookie" statement in the frontend. Please refer to- O% R; Q7 m7 ~' y/ C2 @& a
section 4.2 for more details. Only one cookie can be captured, and the same
2 O' a, g0 y P' b9 Wcookie will simultaneously be checked in the request ("Cookie:" header) and in
8 Q: T9 o0 D7 Sthe response ("Set-Cookie:" header). The respective values will be reported in7 H# o" }/ i, ?! T! q
the HTTP logs at the "captured_request_cookie" and "captured_response_cookie"2 l$ M' S& Z" G5 X
locations (see section 8.2.3 about HTTP log format). When either cookie is8 I( ?% F2 {; o+ @
not seen, a dash ('-') replaces the value. This way, it's easy to detect when a( J/ S6 q# v/ i( J5 M7 B3 {" _! y/ Y5 h
user switches to a new session for example, because the server will reassign it
6 B$ _+ j7 s1 R1 R5 l. `: m ma new cookie. It is also possible to detect if a server unexpectedly sets a
- X- ^# K1 x f( @" U( I# g3 cwrong cookie to a client, leading to session crossing.& d% [! L7 u! B7 P% S
5 j: \) X, X2 a: `: ^ Examples :& n( m |, Q1 Y7 `7 Q
# capture the first cookie whose name starts with "ASPSESSION"# [! [. O0 ^4 i; M
capture cookie ASPSESSION len 32
; B7 b P' t9 g+ }6 w" B. U0 F% t# ?% w' {( n
# capture the first cookie whose name is exactly "vgnvisitor"1 Z2 Q; R" O6 \0 n9 v9 ~
capture cookie vgnvisitor= len 32, ~% N: @- z) d- L# {* G
3 e* U. R/ B: H/ \- P& `( D- `" K7 Z
8.8. Capturing HTTP headers
* N' j# l5 j6 h$ V( h( U---------------------------! I* E" `( ?( k# K( M. d3 w
0 X' G$ I$ V8 U, F: F, oHeader captures are useful to track unique request identifiers set by an upper
+ d; O4 j- T: A0 z0 `# Wproxy, virtual host names, user-agents, POST content-length, referrers, etc. In/ b5 Z4 y! t: r, F, A9 D
the response, one can search for information about the response length, how the# O/ @1 b+ H( o; _6 H S/ L/ I! m
server asked the cache to behave, or an object location during a redirection., a: j# T; D: v7 I( |$ ^/ B
- p) X) c3 C& j/ U! f( RHeader captures are performed using the "capture request header" and "capture' ]' c7 ]" R: t- g' L( g
response header" statements in the frontend. Please consult their definition in5 P% G: F8 }9 r- l; Z
section 4.2 for more details.
8 F. _, l9 o" X1 ], M1 ~
$ \6 G7 @$ r* j$ {' |It is possible to include both request headers and response headers at the same
$ ?) e& j- H% `- Wtime. Non-existent headers are logged as empty strings, and if one header' |5 Z7 b ~: }
appears more than once, only its last occurrence will be logged. Request headers) G; k& ^4 {) |2 ^, X y n, b8 ~
are grouped within braces '{' and '}' in the same order as they were declared,$ y5 u8 c% T8 [7 l$ l* D5 l6 {
and delimited with a vertical bar '|' without any space. Response headers
5 Y( k6 j C0 l2 B4 Mfollow the same representation, but are displayed after a space following the1 T0 F: ?2 x4 N8 H. [/ x) G4 P D$ ^
request headers block. These blocks are displayed just before the HTTP request- ?0 x: Y% w5 m8 {3 {% ], A
in the logs.: ^2 }9 Z7 H+ B8 x3 z% G
" m8 q6 _ h3 O r$ ] Example :
. Q$ z5 C; k9 `# K2 \! I Y, N # This instance chains to the outgoing proxy4 O# D) H4 `* J8 K- i
listen proxy-out
) }0 a+ u! l. j" ^, J3 ]2 |* H mode http* K# [) c: a3 E9 t: i3 Z
option httplog
% o5 `4 n9 E% l6 X2 v option logasap
& T1 Y7 k9 b Q7 y; }( ` log global0 o* e2 i0 y! [, I
server cache1 192.168.1.1:3128
0 G7 n1 X& A. P# N/ O! [+ w! T* O4 u4 {6 I( m, ]
# log the name of the virtual server
: v& s! ^! P6 D K% v% O capture request header Host len 208 N4 C' c k" ]7 E
3 K/ e0 _( H3 c2 {9 ~8 Q: F; k # log the amount of data uploaded during a POST D) x8 F0 V) q
capture request header Content-Length len 10
/ }6 a1 ~# _& L. J
( o x: p0 \1 c! t- y # log the beginning of the referrer3 t+ I. I. `/ d/ s
capture request header Referer len 20
& w. x _3 k& o0 {( v- J |. s6 T# b- X
# server name (useful for outgoing proxies only)
' c6 X$ j% _& g U6 k+ ~' I" c! h7 ~ capture response header Server len 20# d R3 I( [* W1 O; f! N
$ L+ c4 H' n- D: N& K0 ` # logging the content-length is useful with "option logasap"
& Y% W; [* @2 \. G" C g! k5 w0 g7 U/ { capture response header Content-Length len 10$ X9 f( p. T. V; d0 b4 m4 f w
6 O ~- ~! X: o5 ~" G$ [ # log the expected cache behaviour on the response
# [" t. @+ p* I$ i" s# ]6 B+ M: t capture response header Cache-Control len 8
2 t# g! W. r2 P6 S9 b* b( M* g7 k9 v0 O
# the Via header will report the next proxy's name+ S+ p( k1 A( E5 f: Z( g& w
capture response header Via len 201 L1 a$ Y2 ?. D- i7 d
, Y. M: e. i/ u3 Z/ G; F$ y # log the URL location during a redirection
5 R) f1 m9 L$ \- L7 ` capture response header Location len 20
9 \% [' h: a! D8 z5 s2 i. X( P& c3 i" N$ W7 D7 n
>>> Aug 9 20:26:09 localhost \
0 ^7 A, U! U- @9 A8 T0 v* D; ^# m haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \& s# B: l0 y1 E3 k& d) l
proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \( s- d+ o- A+ {* d! i% {3 B; B
{fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \& u& d7 \- b6 f4 T u2 P
"GET http://fr.adserver.yahoo.com/"
# S) P! e# r: w) \$ N% F4 m# H' W, M) E
>>> Aug 9 20:30:46 localhost \
; \, Y) c3 M0 s% C( O haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \, `' ~, \& R9 u: v! o
proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \5 w/ V* B4 O# c$ |
{w.ods.org||} {Formilux/0.1.8|3495|||} \
9 w% _. M* b% ]9 J "GET http://trafic.1wt.eu/ HTTP/1.1"
1 C& ~# [* W5 n) j0 D% U
5 `2 t/ e* V( k& T P >>> Aug 9 20:30:46 localhost \" ^) W7 S" H& n4 b+ {
haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \$ R5 a# p" l; b, f; @
proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \( _/ x' e- Z/ t
{www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \& `( F/ _- ?# B% T2 B( y/ [% {
{Apache|230|||http://www.sytadin.} \5 [& |' g4 O2 h( e- k+ z8 A
"GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
1 P- U9 O8 Z- b. v. ^$ X3 F( e; d' m" D+ |" q* `* G8 a! C
6 X3 _, C! D, }5 x+ ~
8.9. Examples of logs! I6 D0 h- j9 c3 b) u# X, s
---------------------
6 f+ O/ n0 P! R7 u
/ k- Z: V- W' y* S6 t* ] yThese are real-world examples of logs accompanied with an explanation. Some of+ J' I% V* o6 @# G; L
them have been made up by hand. The syslog part has been removed for better
. L! C' O; R) }4 J+ v$ @9 H3 Areading. Their sole purpose is to explain how to decipher them.0 e+ U) k5 ?$ [0 e: a* `# \; W# V
/ E% O, n* h! @7 n1 ` >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \" L: E' N6 z2 W2 v
px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \- b8 U/ I1 B! F) A, V7 d3 X
"HEAD / HTTP/1.0"
" E3 N8 n& c# [/ z# ~
" Y e5 _7 h* ? => long request (6.5s) entered by hand through 'telnet'. The server replied
% x7 J# F0 z8 I2 q; X in 147 ms, and the session ended normally ('----')- d8 v+ a4 l$ S$ [# I& T# C
1 B* Z; R% [3 g3 Y9 X' N, D4 l >>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \& ^8 D* ?) c6 {0 E5 `4 S* D
px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \
" Q8 `0 F; H; Q" n4 T3 _% ~7 f 0/9 "HEAD / HTTP/1.0"
( \8 n& c' H5 J- i6 y! @- O
0 L, j Y5 S0 @& k1 v => Idem, but the request was queued in the global queue behind 9 other
7 i3 `! j& o5 R. V6 T# Z* T requests, and waited there for 1230 ms.! j! B( D7 ~2 f/ a" E H; I
) j4 M9 s$ I* ]3 t >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \6 ~$ j$ u; Q" o7 D8 h- F4 F
px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \
# [0 Y- ]1 t. H "GET /image.iso HTTP/1.0"
" i* H8 Y: s$ I5 `* u4 V- d1 f3 V D7 b" N
=> request for a long data transfer. The "logasap" option was specified, so: R" e& K4 E. n9 K% q( C
the log was produced just before transferring data. The server replied in7 f7 `) O: ?0 \. S
14 ms, 243 bytes of headers were sent to the client, and total time from8 l- _7 s/ L# C& w1 e4 s" w& M
accept to first data byte is 30 ms.9 Y8 a- T% p# R& }
& {2 A K, ^. v$ o5 }- v1 H >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
7 u# t) P8 d- n+ c: u px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \# z) ^6 \! l# a1 W4 s% F5 p( u
"GET /cgi-bin/bug.cgi? HTTP/1.0". S9 j' {! w$ f# W% t
6 C. ?# z Q* F1 Y" O/ w' C => the proxy blocked a server response either because of an "rspdeny" or: a9 ?& ]; A8 r B2 y, u# D& c
"rspideny" filter, or because the response was improperly formatted and! z ?# K' q: f% `/ v
not HTTP-compliant, or because it blocked sensitive information which' s u% w' r2 Q
risked being cached. In this case, the response is replaced with a "502
+ i1 E' [/ k. c bad gateway". The flags ("PH--") tell us that it was haproxy who decided
( t/ g$ L |9 R+ a; ?' a to return the 502 and not the server.% {$ H' Z1 O9 \) ~& o( ^
1 D, K9 l+ d! m0 [1 h$ {
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \/ w e- |4 M6 _6 j7 G
px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""
7 o5 z' Q8 e9 |4 L& j) F( I8 P) W
: P7 j# p' n1 Z( u% x => the client never completed its request and aborted itself ("C---") after
+ @# Z% h* p( w( w w 8.5s, while the proxy was waiting for the request headers ("-R--").) L! J3 `" v! H6 }' J& D" C/ o0 j
Nothing was sent to any server.5 G: r8 `9 L* P
0 m% ^, y b( h, x >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \. s! Z, m1 X- n# U: Y+ B7 {
px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""
- P/ ~5 A( f& A$ f9 J0 k, b4 i: P* Z# ^/ z" M
=> The client never completed its request, which was aborted by the
/ y% ]7 u+ o. V7 Y" @1 b! _& f! x time-out ("c---") after 50s, while the proxy was waiting for the request- W# t, e; D( l6 b; a% }0 Q
headers ("-R--"). Nothing was sent to any server, but the proxy could! W& `* M/ ]# n2 e, w! O! Y
send a 408 return code to the client.7 a l& [% L5 I2 Y
1 o3 j- X H( [- W5 I& u0 S) h
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \' R/ B# |$ ?% e$ i
px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
2 O- n, m: A! w5 t" N' i' O0 _; O2 g3 @ r7 D
=> This log was produced with "option tcplog". The client timed out after. V) B U3 W8 t! U4 w
5 seconds ("c----").( X+ d# o: U( r, p3 ^9 _
0 g6 [0 B" ~/ _
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
0 n9 W ^9 g1 c/ ]2 p px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \: `( j* K. B0 `3 G+ `. {
0/0 "HEAD / HTTP/1.0"
9 k$ Z$ r( v2 q b# f0 \# F8 E) a8 ^
=> The request took 3s to complete (probably a network problem), and the
& ^8 K m! l+ A9 c: i connection to the server failed ('SC--') after 4 attempts of 2 seconds
5 }9 Q: u: I7 a (config says 'retries 3'), and no redispatch (otherwise we would have# e7 M. G, l" d$ ~7 x
seen "/+3"). Status code 503 was returned to the client. There were 115
' v+ V; }4 A2 q) N- U7 \" }( H connections on this server, 202 connections on this proxy, and 205 on
( X) w: P# Q6 \7 e the global process. It is possible that the server refused the
' R7 N% z3 S1 f( o2 ~ connection because of too many already established.
! I* v: L* g& s/ T
+ t* f" P" s( A8 t' ], U6 a; j9 v6 z5 d) z
9. Statistics and monitoring$ P9 m- p0 @$ {$ |) \0 s
----------------------------
- I r; s% O3 j2 Z$ d/ R
4 ^% f1 g5 x5 l& G: x( QIt is possible to query HAProxy about its status. The most commonly used
' d3 A1 I: ]7 g w# emechanism is the HTTP statistics page. This page also exposes an alternative7 @3 K; A% v; R* N- b
CSV output format for monitoring tools. The same format is provided on the
9 ]9 k& ]2 \, ~2 a3 h2 p' ~Unix socket.. _9 x0 q+ Z6 ~
5 d a7 v6 g l B+ l
; C! [, _( u$ P* q
9.1. CSV format
* T( g# Y; w, w+ O. m+ s R V, ~---------------
' m1 O/ H; x9 Q4 Q" z
V) @. r( _& l" I; u! U x9 [The statistics may be consulted either from the unix socket or from the HTTP. G9 e. l. @# H: Y2 A- Z
page. Both means provide a CSV format whose fields follow.
* p |% ?5 G" g
% l! b/ [7 n$ c 0. pxname: proxy name: }' M \1 ~8 M3 s
1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name3 |* n" A; S: d
for server)
" D- t/ d _, q# p! d 2. qcur: current queued requests
# A- E7 l1 ?2 r$ o 3. qmax: max queued requests
( |5 Q( E4 b+ \9 `6 Y) D( o 4. scur: current sessions$ [* e8 C W9 a% k
5. smax: max sessions9 W1 R( y& x( `# c% `. v0 ?9 @1 R
6. slim: sessions limit; K2 m2 u1 H5 K
7. stot: total sessions& n) M. p/ j0 a3 K2 J
8. bin: bytes in
; R6 `) }- f5 l* r) i* F3 ^ 9. bout: bytes out
# P. W" D! u* C3 F. S$ z1 y 10. dreq: denied requests4 j1 x# D& {7 w' U" Y
11. dresp: denied responses6 F5 n% C6 h' [0 w1 [" j
12. ereq: request errors" q+ w/ M* K' Y. {
13. econ: connection errors
+ A2 @: v4 j1 `* \& Y! u 14. eresp: response errors (among which srv_abrt)
& a, k* i$ T5 E! _ 15. wretr: retries (warning)
) W/ n# }- I" H' r3 \ 16. wredis: redispatches (warning)& R; w. ]( v% F {
17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)# |# o8 b. F$ H8 {% X9 i4 O
18. weight: server weight (server), total weight (backend)
8 z+ @) g+ a+ F6 i 19. act: server is active (server), number of active servers (backend)8 H: A6 Z: N$ [1 ~; Q# |
20. bck: server is backup (server), number of backup servers (backend)
3 a' n. k+ o! x0 ^8 j' z1 R 21. chkfail: number of failed checks
; L; U- V' I) P* D0 h 22. chkdown: number of UP->DOWN transitions6 o$ r+ K* y; _3 I
23. lastchg: last status change (in seconds)
6 h3 K$ l: x4 F9 T: m+ d 24. downtime: total downtime (in seconds)7 R& O& `7 q. e. P( @1 z
25. qlimit: queue limit, ^! } j4 H1 Z9 o, K
26. pid: process id (0 for first instance, 1 for second, ...)
+ i9 K6 g3 \# `& g& s# E! P8 ]" C 27. iid: unique proxy id0 ]3 P) F9 m$ N8 F
28. sid: service id (unique inside a proxy)
6 u4 Y( n) d' ?' O' O5 J0 J# R 29. throttle: warm up status/ v; M5 l( L" ~$ z1 S
30. lbtot: total number of times a server was selected* Q, Z4 G8 k0 Q0 K# S1 c9 K' t; d
31. tracked: id of proxy/server if tracking is enabled
7 \: j& x5 w( B# @: ~ 32. type (0=frontend, 1=backend, 2=server, 3=socket)
0 i) ~& i6 l0 N4 z2 i" p. O. ~ 33. rate: number of sessions per second over last elapsed second/ B5 q4 j" j! l6 f$ E
34. rate_lim: limit on new sessions per second) D7 i' K' e9 o7 P3 f
35. rate_max: max number of new sessions per second
" C6 A( M2 V( `- ]7 s7 e9 V 36. check_status: status of last health check, one of:
; G9 Z/ p! M1 {2 i8 s UNK -> unknown
3 ~% B1 d$ i3 k" i7 K INI -> initializing
+ k, k, E6 b. k SOCKERR -> socket error
0 E3 a* T7 P- I2 \% @7 X L4OK -> check passed on layer 4, no upper layers testing enabled
/ W! X: P3 S+ C Y) e9 Y) y L4TOUT -> layer 1-4 timeout6 S; G: H Y$ k$ q. T5 O( s; K) {+ x
L4CON -> layer 1-4 connection problem, for example
# ]+ F+ r: O6 z6 j& b "Connection refused" (tcp rst) or "No route to host" (icmp)
- f& P' |$ @3 {. p L6OK -> check passed on layer 6
O6 I" s, p( h- c" K! c7 m L6TOUT -> layer 6 (SSL) timeout
; [: `2 i4 u7 |0 f4 s/ \ L6RSP -> layer 6 invalid response - protocol error' J B, j9 E/ u0 V
L7OK -> check passed on layer 79 b) W# q7 D7 _' d% G/ o
L7OKC -> check conditionally passed on layer 7, for example 404 with& D7 y$ X! f) F3 q2 p& S7 T
disable-on-404
( r8 Y8 r$ Y) [ L7TOUT -> layer 7 (HTTP/SMTP) timeout
) ]5 ]. E; H2 B0 b" Y, B' b L7RSP -> layer 7 invalid response - protocol error/ k+ `- k8 z5 L0 x, A" n/ ]
L7STS -> layer 7 response error, for example HTTP 5xx& U w$ N: Y) m. y& [. K5 ]: w
37. check_code: layer5-7 code, if available
. b s# b& H/ [/ P e. @8 y3 L 38. check_duration: time in ms took to finish last health check
2 ~2 P5 z: b1 p2 u- B1 d7 R 39. hrsp_1xx: http responses with 1xx code
/ U$ B+ S6 D) \. ~2 G7 z 40. hrsp_2xx: http responses with 2xx code7 J/ ^; L7 b3 i; Q8 M3 ]0 x- ^1 V3 W( q
41. hrsp_3xx: http responses with 3xx code
6 t5 H0 {& w: B 42. hrsp_4xx: http responses with 4xx code
' K! h# D. d$ E2 X' Y8 ^% \ 43. hrsp_5xx: http responses with 5xx code: x' b, a3 Z: Q3 x% e- f. \6 I
44. hrsp_other: http responses with other codes (protocol error)
$ C" d" f. N- G& q4 p) R6 e 45. hanafail: failed health checks details
" l/ ]& H9 i$ X" ~0 U 46. req_rate: HTTP requests per second over last elapsed second- g2 ]# g2 v5 U& k$ F
47. req_rate_max: max number of HTTP requests per second observed5 j- [7 y# H) k/ r
48. req_tot: total number of HTTP requests received$ e. V; O( I7 G$ B' H4 L; d
49. cli_abrt: number of data transfers aborted by the client
# Q) I, e# _ ]: W- N: D( x! X: @7 ` 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)& K1 U3 a8 N) J% h' i/ ]$ z; D
' t( H" L* C/ K4 A
- R0 X9 [$ ~+ q' _8 b9.2. Unix Socket commands
n w0 l& m% G' E/ Y-------------------------
9 `3 A$ k3 F3 @2 R% W- H
7 a0 W7 x; \3 cThe following commands are supported on the UNIX stats socket ; all of them& k7 ?9 M, Z8 `: }: p2 P6 F
must be terminated by a line feed. The socket supports pipelining, so that it. M; T* i! Q q5 D; F, x7 |7 J* P
is possible to chain multiple commands at once provided they are delimited by5 P( e2 E; ^. y: Y3 c; t
a semi-colon or a line feed, although the former is more reliable as it has no
( @. u6 B2 z; {: h% H, O* i, Frisk of being truncated over the network. The responses themselves will each be
% i8 n, e% U( k. J& N8 ~ |% Wfollowed by an empty line, so it will be easy for an external script to match a
% n: ^$ u* j$ E, d. O! rgiven response with a given request. By default one command line is processed' i; [- m' l- b' a+ |
then the connection closes, but there is an interactive allowing multiple lines
; q. u/ I. ]' T2 H7 z" Uto be issued one at a time.6 Q: b9 u# I) D9 X7 L
* g* ?9 F$ m4 p3 h. Q# z8 q
It is important to understand that when multiple haproxy processes are started
4 @6 \# C4 ~ n9 V o( x5 eon the same sockets, any process may pick up the request and will output its6 R3 Y$ L+ V6 Y2 c7 ?
own stats.1 i. r0 ~! F9 \' `2 a
1 F, c6 T; X' `% R+ I1 Q# T* u
clear counters) S6 F$ O: o' w+ Z$ O9 l8 W
Clear the max values of the statistics counters in each proxy (frontend &/ b6 H% o' @ `- j( f: _* e
backend) and in each server. The cumulated counters are not affected. This% k* s& I+ p# O0 [6 \& \
can be used to get clean counters after an incident, without having to
3 f. ?7 f$ ^& R9 {% P: f8 }. Y) V2 f restart nor to clear traffic counters. This command is restricted and can* b! j! s$ z4 i# w: o% e4 b
only be issued on sockets configured for levels "operator" or "admin".
& |0 V3 r9 c0 b6 O: U
1 w* C& J& f+ Pclear counters all. S/ Z$ |6 c9 {, |+ Z0 u/ N
Clear all statistics counters in each proxy (frontend & backend) and in each
" w' i% E; R a$ J server. This has the same effect as restarting. This command is restricted- [( m, u% @( z
and can only be issued on sockets configured for level "admin".& l3 o+ a1 O' L q/ }4 e$ p: ~
# e5 Q: D* ^0 a% e3 A) n# z) j9 Tdisable server <backend>/<server>, |- f0 T( ~; \2 L! n: E) b! i
Mark the server DOWN for maintenance. In this mode, no more checks will be3 ]' _4 [ y/ k$ h7 V. s9 g
performed on the server until it leaves maintenance.
# |$ D6 }( K# r0 @ If the server is tracked by other servers, those servers will be set to DOWN
( ~% [+ T- v9 R" Z N during the maintenance.6 A) X5 R, ?3 }
v7 l2 n* s2 k$ d In the statistics page, a server DOWN for maintenance will appear with a
2 M5 n- S- |2 {* W& V "MAINT" status, its tracking servers with the "MAINT(via)" one.& ~) t: O( v5 [0 B6 h. F9 K
/ n# ]3 Y$ P2 J: B
Both the backend and the server may be specified either by their name or by- h7 |- ^# a# o& h7 K- @3 \6 Z
their numeric ID, prefixed with a sharp ('#').) i. ]3 X' s5 ?* w2 Z' V% O8 |0 w
4 E; n6 ]5 D+ w: M3 Y3 E: p' q This command is restricted and can only be issued on sockets configured for) t( ^3 \' k/ U7 q
level "admin".
8 p- A" U: t0 K8 T- z
) @+ t, y# O ?5 D ?0 N5 G- m# Venable server <backend>/<server>' n& O s: m$ {! [
If the server was previously marked as DOWN for maintenance, this marks the
& f7 p3 Z* @; R7 D6 ~9 J% W server UP and checks are re-enabled.# ^3 S; D _9 t9 E' W8 v% @4 f
) z9 O$ X' P; O H g) i
Both the backend and the server may be specified either by their name or by
* C# H, F" J6 H9 K/ C, m their numeric ID, prefixed with a sharp ('#').
0 G. X1 w8 y. y9 D( X/ T) C* \2 I8 {4 r3 j
This command is restricted and can only be issued on sockets configured for+ n5 n9 g$ _# t- q& \2 W6 V1 ]) v
level "admin".6 c, `4 W% k( E1 y
# G& `9 W1 d! u( H- ^get weight <backend>/<server>2 }$ x9 {* U {& j* s6 A( F. \
Report the current weight and the initial weight of server <server> in
; E6 v/ k8 g9 @ backend <backend> or an error if either doesn't exist. The initial weight is
* Y- S" N" p' N+ c/ H) n1 M the one that appears in the configuration file. Both are normally equal% E( L/ z% T7 h
unless the current weight has been changed. Both the backend and the server
, E9 s5 F2 G' K' x! f may be specified either by their name or by their numeric ID, prefixed with a& s! }4 Y, M7 |: D L- l
sharp ('#').
2 I5 C1 _" k' i% W- A
6 R7 s+ x* v$ j; |help8 f: p: P% R3 ^% \. z% h% ?* t
Print the list of known keywords and their basic usage. The same help screen# j: j0 ^: [2 h: K4 Z6 W
is also displayed for unknown commands.
+ Y7 M, D7 |+ z- v
; H: w5 _& G! jprompt* d [! H. H: j; a2 x
Toggle the prompt at the beginning of the line and enter or leave interactive Z C3 w- R" i/ K+ |
mode. In interactive mode, the connection is not closed after a command" f$ f& l* w0 {( s% C* Y
completes. Instead, the prompt will appear again, indicating the user that5 Y( y' h7 s' ^$ O' ]: G- n
the interpreter is waiting for a new command. The prompt consists in a right9 \1 G- u: s) S
angle bracket followed by a space "> ". This mode is particularly convenient
3 j, i% U$ `3 K4 J, S when one wants to periodically check information such as stats or errors.# e, U+ n8 c- o5 p; V/ [3 y
It is also a good idea to enter interactive mode before issuing a "help"& e5 j) K3 D6 e% b* l8 A* Z
command.* r7 b2 z: N+ w+ _# ^5 Y
; k6 Q0 U$ T; c- E( K6 dquit2 V& G) G0 q! M" z$ b$ X- j, F
Close the connection when in interactive mode.8 U. ]' o& i/ l# f0 O% I6 i
8 y3 B! b( a I: e' ~5 Z Fset timeout cli <delay>/ i' F7 O0 w/ v& T- v1 X) L
Change the CLI interface timeout for current connection. This can be useful
: _- y; h+ f% ~* F9 x, x( g during long debugging sessions where the user needs to constantly inspect
; q0 W: ?+ r& f1 M1 A some indicators without being disconnected. The delay is passed in seconds.! o0 s: u+ K& c* W
( }2 V$ ~7 o7 V& d4 [
set weight <backend>/<server> <weight>[%]
. z$ E9 t! Y; Z1 i9 e# J! E Change a server's weight to the value passed in argument. If the value ends+ j3 v. t: i# D( m. Z
with the '%' sign, then the new weight will be relative to the initially1 L) |. S. P$ T4 _( t5 O
configured weight. Relative weights are only permitted between 0 and 100%,$ a/ v% f9 f( `; a. l+ M8 G' U
and absolute weights are permitted between 0 and 256. Servers which are part
. M; t& Z3 ~( P: t of a farm running a static load-balancing algorithm have stricter limitations
2 J, ?5 t0 c) X) f u+ V because the weight cannot change once set. Thus for these servers, the only
" J2 _, _3 L- q. p T8 j. F7 C6 z) o accepted values are 0 and 100% (or 0 and the initial weight). Changes take
1 I6 ?) F: A2 i4 Q" x; [6 s5 a2 p effect immediately, though certain LB algorithms require a certain amount of
; {5 h, ~0 z; V0 a requests to consider changes. A typical usage of this command is to disable
; p5 W/ D B' }- D& _$ {- `) c) }7 } a server during an update by setting its weight to zero, then to enable it
: R3 e4 x4 {6 f i again after the update by setting it back to 100%. This command is restricted" z0 \3 T5 }% k$ {8 X
and can only be issued on sockets configured for level "admin". Both the
7 G, y; t: n9 j; Y+ ^ backend and the server may be specified either by their name or by their" O m8 Y7 _$ h# b
numeric ID, prefixed with a sharp ('#').. Z; x" B( A' R- F3 h
/ _4 O, h Z6 c5 @% m% \/ cshow errors [<iid>]
- B0 o/ ^4 F7 A3 |/ \ Dump last known request and response errors collected by frontends and/ b$ d+ z, B: L# B, O8 q4 x; z
backends. If <iid> is specified, the limit the dump to errors concerning
- Q) n0 v: ]0 n either frontend or backend whose ID is <iid>. This command is restricted
; n2 q) g, o: o2 x* h' ? and can only be issued on sockets configured for levels "operator" or4 o' c+ ]- u4 [7 b
"admin".& X4 Y# B1 k- R" X k0 \ a$ j
0 }/ ~8 P! O% E! @ The errors which may be collected are the last request and response errors
7 u5 R Q* m7 Z1 D7 E caused by protocol violations, often due to invalid characters in header
: n4 K7 h: a# E names. The report precisely indicates what exact character violated the
! s) T9 w; E3 w9 ^2 m/ T Y protocol. Other important information such as the exact date the error was* T. k+ }. P: s7 }2 V& S8 Q P
detected, frontend and backend names, the server name (when known), the, F. r6 H& G& a' F8 Z% W. c+ ]* K
internal session ID and the source address which has initiated the session3 n6 |* a+ E% U: x2 p+ g
are reported too.7 \$ q2 G( A! n2 w# G0 f
0 {! E. u8 {! L3 ] All characters are returned, and non-printable characters are encoded. The. H" y: c9 }: P; c
most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one
: s. i$ L$ z( P9 K2 W5 _ letter following a backslash. The backslash itself is encoded as '\\' to
. K9 u* e% D6 i6 x i! S avoid confusion. Other non-printable characters are encoded '\xNN' where* s$ h% u4 T0 v( G+ [( w
NN is the two-digits hexadecimal representation of the character's ASCII. U# G/ M( M$ x, I& ^6 B
code.
* R9 B( n, s( U7 D, w$ M' V6 i2 H; z. [
Lines are prefixed with the position of their first character, starting at 0; G$ H4 a( }' N+ H% L8 C2 [. u
for the beginning of the buffer. At most one input line is printed per line,
! |' `# J7 I5 A and large lines will be broken into multiple consecutive output lines so that% W8 Z1 w$ V0 A; J* l2 n% A+ |/ v
the output never goes beyond 79 characters wide. It is easy to detect if a
: @- d/ c6 M2 U. A! d' ] line was broken, because it will not end with '\n' and the next line's offset
* v( C" T* p" Y# W/ N will be followed by a '+' sign, indicating it is a continuation of previous
2 l! s4 C+ {. ^2 ]9 K line.
- Z2 I" |$ H: O0 U$ A3 J) I w) w1 ?: r h) O6 B9 q# P7 v
Example :3 f. V' J r* o8 A' I
>>> $ echo "show errors" | socat stdio /tmp/sock1$ ]. E; ]8 F& S3 a# n, c' d0 v4 d1 c8 `
[04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response; g: n2 e' w) N/ z* [3 L4 Q
src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)4 z0 A2 h, A& B4 L2 h8 d
response length 213 bytes, error at position 23:4 q9 N9 P+ g& W; S5 G, O! ?0 z$ j
% C+ R8 Z9 e |; V' ]9 b7 q
00000 HTTP/1.0 200 OK\r\n
4 N/ s+ c5 A! E 00017 header/bizarre:blah\r\n
: s' |5 p$ s1 \" U0 l 00038 Location: blah\r\n% T: a; V* N# g R7 b9 w0 T+ y
00054 Long-line: this is a very long line which should b" X* w A; Z! w7 [) [
00104+ e broken into multiple lines on the output buffer,# b: G+ S: z: I( [ _
00154+ otherwise it would be too large to print in a ter
2 M$ Z+ M" O, x) X 00204+ minal\r\n/ L5 g, t9 z9 G* p+ P
00211 \r\n/ Y: N6 ~9 h9 e7 m' Y1 `
7 u/ U( D& C' G1 s& W( u
In the example above, we see that the backend "http-in" which has internal
9 p, Q3 C# L& E* f6 f ID 2 has blocked an invalid response from its server s2 which has internal" }9 b( _3 Z6 ^5 \+ ?' m$ f0 q4 [
ID 1. The request was on session 54 initiated by source 127.0.0.1 and
9 J0 [1 q# N3 @* m6 F# _# W received by frontend fe-eth0 whose ID is 1. The total response length was; o2 H( s) K( N+ h2 A T
213 bytes when the error was detected, and the error was at byte 23. This6 @8 d" Y% R& C
is the slash ('/') in header name "header/bizarre", which is not a valid
4 a& N3 Y9 t5 V$ g( V$ ]* C HTTP character for a header name.% L( z+ B6 h$ g
. A9 k4 T7 I3 v. a8 gshow info: g2 G' [. r- `- d S" J3 u: P5 B
Dump info about haproxy status on current process.2 n' g8 Z2 [8 T& g2 ]
: ~9 k1 k6 c: t1 u* z1 h$ Zshow sess/ B" z1 J7 G' G9 [$ o. j% z
Dump all known sessions. Avoid doing this on slow connections as this can
9 M; y# V, R% g8 _+ J# ~1 P+ x( q be huge. This command is restricted and can only be issued on sockets
: A3 S) s# S( M$ e$ R J configured for levels "operator" or "admin".
+ O. n2 \- e+ l& ?2 p8 C9 D- ]: W4 {1 H$ Q+ P9 b
show sess <id>' @7 @* \% g4 \- g( c5 Q7 I* g
Display a lot of internal information about the specified session identifier.
s2 }- L$ v+ p3 X6 f2 H7 } This identifier is the first field at the beginning of the lines in the dumps# G. l3 b% u8 a5 K# j
of "show sess" (it corresponds to the session pointer). Those information are' m( k+ b* ]; p. |
useless to most users but may be used by haproxy developers to troubleshoot a
( W# n' D9 [( F6 [8 Z3 r: M" ? complex bug. The output format is intentionally not documented so that it can
$ e5 _/ U3 K+ B: C freely evolve depending on demands.
3 ~8 F9 C' K% o4 U$ m, z) m
! f" m+ k; j- U3 y6 Rshow stat [<iid> <type> <sid>]
0 Z: T# J9 F# Q! C' v+ `0 o5 R* S Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
2 u. U X: @. b" ?6 T7 J9 z possible to dump only selected items :) k' @& `0 T8 c4 {# h
- <iid> is a proxy ID, -1 to dump everything
% m2 X+ b# s2 M F# ~5 U. c A - <type> selects the type of dumpable objects : 1 for frontends, 2 for
; X6 v; g1 p$ N: j9 C1 ] backends, 4 for servers, -1 for everything. These values can be ORed,
$ ?0 N- I0 H1 k$ V9 p; t for example:; N) U s$ p& L7 s
1 + 2 = 3 -> frontend + backend.
3 h* m7 n2 u" W3 [# a `2 j- k 1 + 2 + 4 = 7 -> frontend + backend + server.# b- p# h( t2 V4 k( J
- <sid> is a server ID, -1 to dump everything from the selected proxy.0 Y1 c& `/ o6 @/ I8 G a* k
& |8 `) g t$ q9 {# a8 {1 [5 S Example :% w4 b" ]0 Q3 r# M- a# X+ s/ _
>>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock15 @4 l$ E- l5 Y6 V [
Name: HAProxy
0 L+ B2 n- ^+ ? Version: 1.4-dev2-49
: R! Z) d$ [- ]* Y Release_date: 2009/09/233 K+ k, e# q. e, t7 y
Nbproc: 1- X4 E- a" z8 a* g
Process_num: 1 L; C' g; {9 `
(...)3 a, q) |0 @, F# ]/ i
. h* e Z, S% ]% {, A
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq, (...)
; ^+ e4 H. x4 I& { O3 @/ o stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
}/ ~ [0 a- }* U stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...). r: } b% d9 q( }4 y8 m
(...)9 [; x- A- G8 `9 t. V+ H4 T" m
www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)
9 w& A4 r8 A! \3 x; f/ }; K" \! z! d1 T+ c; A
$
# ?( S# t8 B, c2 Q$ ~8 c. U7 g: S
7 D p) ~5 q5 s/ S$ Z/ y Here, two commands have been issued at once. That way it's easy to find
Z! _4 C' j# e7 _ which process the stats apply to in multi-process mode. Notice the empty. D, `# p* w+ x9 S8 x Q3 K! N7 t
line after the information output which marks the end of the first block.1 M9 |7 y5 _# e! F
A similar empty line appears at the end of the second block (stats) so that
0 d( k6 ]3 X$ P# e# h G% k the reader knows the output has not been truncated.$ ?- O$ R2 s3 J, [" T+ w
: p, ~; @0 V; L$ C6 n7 T0 ~
4 b0 ~" |8 z" Q) @
/*+ w8 u" S7 J+ l9 ~" e. U
* Local variables:5 U3 D/ c6 _& b" w/ F% x
* fill-column: 79$ T- f! }8 q# b# _0 d( t# F$ a
* End:
9 K' {% A$ v5 V, W */
$ Q: |$ v/ }% e+ p2 C0 S/ Q. f" U5 W$ _6 H/ O9 B
8 V9 T7 T. n2 t
|
|