易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 6034|回复: 0
收起左侧

configuration

[复制链接]
发表于 2016-8-17 21:51:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
                         ----------------------
6 X7 M% a1 j9 ?: i7 q4 g( s                                 HAProxy' J4 E( O4 x& C& }
                          Configuration Manual
  d4 x+ [% A$ ~+ M2 \$ S: X1 g2 ?                         ----------------------% L% R& g8 _0 R  T# I+ q" j2 o
                             version 1.4.27
8 \. w7 L7 \; |6 M1 U: U7 b( B                             willy tarreau" P# O' e% p: e! V8 H
                               2016/03/13
) M$ h4 t3 j' s- B8 l. |) U, Y

) `5 a1 X  q: u$ {5 g, D, SThis document covers the configuration language as implemented in the version
9 M+ z" }1 r2 ^% H5 k% Pspecified above. It does not provide any hint, example or advice. For such5 L4 V1 P) a' _5 G9 r
documentation, please refer to the Reference Manual or the Architecture Manual.9 R' m# ^  M! [' |1 L
The summary below is meant to help you search sections by name and navigate  d' o5 S3 M2 d* S2 H
through the document.* `$ K! ]. E0 p$ Z

, K8 d  J( X1 N- |Note to documentation contributors :
2 G; m, d* O$ h' Z8 x# }+ D    This document is formated with 80 columns per line, with even number of
0 n! }% v8 |9 f    spaces for indentation and without tabs. Please follow these rules strictly0 k$ \9 E, O' g+ c, D7 k3 X
    so that it remains easily printable everywhere. If a line needs to be  t% r# r' l" l. b) `1 v5 M
    printed verbatim and does not fit, please end each line with a backslash
4 c/ n# a: I" ^! Q* c    ('\') and continue on next line. If you add sections, please update the( n  r8 B1 h( Q+ Z' Q
    summary below for easier searching.4 {8 D, `1 r, Z: b
* `" r2 i3 a1 u4 {; v
9 X8 m0 Y" d) P9 K
Summary" b! V" W3 A# p, }" m& _' s% S
-------0 p6 X* S$ m2 c) z4 P
' p( W# t( r# I0 O. |2 Y
1.    Quick reminder about HTTP: z) l# k! q: G
1.1.      The HTTP transaction model8 y: h% e3 e0 _6 n) k
1.2.      HTTP request
% e/ @( X. Z8 b- D. E1.2.1.        The Request line* h+ Q* a% [& ?6 o4 e2 j5 ^
1.2.2.        The request headers/ x. t0 D; C6 L$ J
1.3.      HTTP response9 A/ e* b# E2 T) Y1 a3 m$ m, N
1.3.1.        The Response line3 T" W! }9 \+ Z; S# G% t1 F8 e
1.3.2.        The response headers
' ]! j/ n% N+ L9 B) ]3 D* n+ q0 k9 O  |3 Y- v1 g3 g0 U
2.    Configuring HAProxy
' D; k9 b% O' j. d* ]: {. C: z- M' }2.1.      Configuration file format0 q+ }+ T- j, Y8 u: v0 r& N/ }
2.2.      Time format# P0 k2 F# a1 e5 ^) R. U# p
2.3.      Examples& [% O8 K7 D7 @
( \! j1 ?& y9 v( o* g: A
3.    Global parameters
7 z5 D5 D1 A- q2 ~3.1.      Process management and security
) G4 k, A) [' J4 o- j4 o# U3.2.      Performance tuning% V9 H5 O! p+ w( D
3.3.      Debugging
8 J9 l8 `4 |" k3 F" X* k$ q3.4.      Userlists- Q2 m& w8 B' H5 V9 S: A
2 }+ ^! f# B" o/ E/ L4 `* y+ F
4.    Proxies' e  c, J: z# r: Y) r' c/ G
4.1.      Proxy keywords matrix
: {& z5 S0 w3 {* F4.2.      Alphabetically sorted keywords reference
' C2 W' b. L. F) }" |4 ~1 G7 |& U0 g6 i3 B, Q# r
5.    Server and default-server options
6 l  t7 ~6 T1 T8 i
" h7 P* I# e6 M' ^) B6.    HTTP header manipulation
, H8 @6 j* j* G& f. f. E! a( t! |* Y+ r8 h
7.    Using ACLs and pattern extraction
) K; T1 L$ a- p9 V2 x+ i7 C7.1.      Matching integers
& M, R% _: S% O# S7.2.      Matching strings9 F8 m) @& ~! a* e6 D7 V) ^4 F
7.3.      Matching regular expressions (regexes)- K5 {, T' w6 z$ G. y
7.4.      Matching IPv4 addresses
% T# H9 P! R5 M6 d8 l+ k  A' p7.5.      Available matching criteria8 i0 K# v; o3 r) K+ r& F, N6 e2 D
7.5.1.        Matching at Layer 4 and below
9 c2 v5 E. s* ]. p+ d7.5.2.        Matching contents at Layer 43 c% N4 B! |7 Y3 M9 X7 [! `4 U
7.5.3.        Matching at Layer 7
1 e* h4 w. G1 W7.6.      Pre-defined ACLs3 D6 `0 I$ {6 w% G
7.7.      Using ACLs to form conditions% j2 p, Z" r8 Q& E
7.8.      Pattern extraction
# y; x9 d3 l5 S
) O/ Z+ y( {, B, s8.    Logging7 e4 w. A' J+ ?
8.1.      Log levels
0 e, G% S, e4 \$ e8.2.      Log formats. l0 c6 L) b; Z
8.2.1.        Default log format. S2 p, x7 h% r6 t- A% m
8.2.2.        TCP log format
6 O; ^) E5 f2 m. w9 Z8.2.3.        HTTP log format/ K; k" c  v+ q9 _" L5 s& w
8.3.      Advanced logging options6 E$ I$ k0 `4 |3 @1 w7 W
8.3.1.        Disabling logging of external tests
. W) q5 X  s1 }$ K. i3 c2 l% Y# N8.3.2.        Logging before waiting for the session to terminate' p! G# c& ~/ V; D; Y
8.3.3.        Raising log level upon errors
2 p1 `6 g" e6 e6 }+ S( F8.3.4.        Disabling logging of successful connections
& O1 ^/ I$ M* \* m* E6 `0 u, p8.4.      Timing events
- m! k, ?+ e* G8.5.      Session state at disconnection8 H9 z2 J2 \, P/ B) f" I" _2 h' @
8.6.      Non-printable characters
1 r" F! C$ Z  ^: |3 P1 O& K7 |: o+ P/ D8.7.      Capturing HTTP cookies6 S( l7 \6 B8 C& ]) U) m4 x/ Z9 T
8.8.      Capturing HTTP headers
+ p% B4 z3 y2 V/ e" \. H8.9.      Examples of logs0 r7 f) f) H- S, @& R& u/ Y

8 ~1 z2 W2 a! ]( T9.    Statistics and monitoring5 K2 B) J. i" j5 E7 ]
9.1.      CSV format
) O$ c2 @) A& R% ~, k9.2.      Unix Socket commands0 Z3 F: C* ?: q/ |$ [6 o
! T) n7 y6 i; Z
* d2 }- n2 p5 a- m2 f1 o
1. Quick reminder about HTTP  j  l, r; I5 F
----------------------------3 p$ v: F0 b2 @3 S1 v: M
9 A4 I4 M& R* K, s: A
When haproxy is running in HTTP mode, both the request and the response are1 D3 ~3 J- Q: e8 f) }9 k
fully analyzed and indexed, thus it becomes possible to build matching criteria4 [. y5 f7 V' J6 `, I$ I5 ^- i6 a, A
on almost anything found in the contents.
4 x9 T' Q% R, E9 u) O6 M* ^0 t! U, C
3 Q* v/ _5 Q. N) e% wHowever, it is important to understand how HTTP requests and responses are
4 i4 {* T6 q1 u7 b9 w; [& ~formed, and how HAProxy decomposes them. It will then become easier to write4 Z/ F, ]/ q- }4 v" i* p
correct rules and to debug existing configurations.
$ H, s2 m. d( f' ^, |* W6 J# l9 n( H% U: {

' S0 F2 z4 y$ [4 U  D1.1. The HTTP transaction model
3 |- y% H' n  A  x-------------------------------
$ e4 X' k9 ~3 L# M
" \! g0 `8 k# w$ t) K/ y3 PThe HTTP protocol is transaction-driven. This means that each request will lead
2 v* U0 [" T4 Q) V7 ?/ xto one and only one response. Traditionally, a TCP connection is established
, b. d* v& E  w' H* I* n+ ?2 Hfrom the client to the server, a request is sent by the client on the
2 ]# g6 Z) ^! U* Vconnection, the server responds and the connection is closed. A new request
2 l& l- k) u1 ^will involve a new connection :! N3 f9 _* k: O& I5 s0 T
9 l9 O0 z: W  W
  [CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ...( D6 {: o0 I- j, f& F; X3 a; D
- _; Q4 U0 T( D3 ^% r+ u
In this mode, called the "HTTP close" mode, there are as many connection
$ {, K, U( b' J) l# d  d( mestablishments as there are HTTP transactions. Since the connection is closed
+ \5 s/ a  y. R% v, `by the server after the response, the client does not need to know the content0 Z) K( z: X2 w" V2 O: s# @) Y1 w
length.( w5 s# j* b* m

( i, d9 D* j& }) k' X2 aDue to the transactional nature of the protocol, it was possible to improve it
$ @# q( Y# z; ito avoid closing a connection between two subsequent transactions. In this mode
7 X2 |; H  F7 S% U$ [, I8 P# Ehowever, it is mandatory that the server indicates the content length for each
3 o' f0 F  {9 c! g! [& B0 jresponse so that the client does not wait indefinitely. For this, a special$ o) O5 ^- b2 k* E* M
header is used: "Content-length". This mode is called the "keep-alive" mode :
. ?* ^: X5 [* i7 X6 V) A
' t7 T8 r' h6 q  [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ...
, o- |1 Q, P# }* s, y
- R  m+ t2 [' ~5 r+ {9 E0 P! DIts advantages are a reduced latency between transactions, and less processing
! W" l/ ]" w( `6 ~/ Hpower required on the server side. It is generally better than the close mode,
! b7 v) X2 k# u8 gbut not always because the clients often limit their concurrent connections to. P( A9 w, c* Y) @( t- e
a smaller value.
2 c" S( v' F; g  c( b; ]- B+ v
A last improvement in the communications is the pipelining mode. It still uses0 N8 D* o( |, d$ h; G* m, x
keep-alive, but the client does not wait for the first response to send the* `$ Z/ g, l# j# g0 ~4 N
second request. This is useful for fetching large number of images composing a5 _5 K. Z7 g( j0 A: k
page :/ p  ?$ d( g) K! r+ W

% L- O) S0 e. E! a# g& m  [CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ...
! f$ B9 t: B, A* Y4 A) J: l$ Z# X3 h# L
This can obviously have a tremendous benefit on performance because the network. v) R9 ?6 W9 D$ X% q/ c, ~
latency is eliminated between subsequent requests. Many HTTP agents do not2 U+ @4 l+ X# X( o% e
correctly support pipelining since there is no way to associate a response with
9 y* }  l7 g2 b* D6 t' }: Kthe corresponding request in HTTP. For this reason, it is mandatory for the  P: O% W8 {# Q8 c+ Y
server to reply in the exact same order as the requests were received./ @3 M% x4 G  K" r; A
+ C' S7 [4 v: `) s- @0 I
By default HAProxy operates in a tunnel-like mode with regards to persistent1 p' Q* N6 m; ?8 T
connections: for each connection it processes the first request and forwards; a  S$ H# {/ M: |% z. {% j
everything else (including additional requests) to selected server. Once3 L1 I$ C& f) K$ r# S6 o! d
established, the connection is persisted both on the client and server9 D, w  _( I- M& j7 N/ m: S# U
sides. Use "option http-server-close" to preserve client persistent connections
2 B. F+ ]1 I9 y0 P8 e+ |while handling every incoming request individually, dispatching them one after
6 i2 U5 g# `% K! Hanother to servers, in HTTP close mode. Use "option httpclose" to switch both1 P) i0 U0 N& i7 }" r7 ?4 x* F
sides to HTTP close mode. "option forceclose" and "option- W1 z( T) U+ H. ^
http-pretend-keepalive" help working around servers misbehaving in HTTP close
- v5 I% U$ V$ {mode.
; t$ B8 g$ r" H: \2 J$ t. M3 C  U2 D" `; k4 \/ F) z

3 S  e' b  q+ D* o4 a6 @1.2. HTTP request
4 t# d# }) F* }-----------------; A- @$ b: F) i; u- q

( N* m( r. n9 u4 ]! T/ J% b' c/ bFirst, let's consider this HTTP request :+ e2 }7 ]3 R& \, H
1 ?1 s3 ~1 U/ w6 L( m/ Q: x
  Line     Contents! C" G. u. f( l& Z4 {1 c
  number/ A  U5 h, h% b; @7 ~2 T. t# q
     1     GET /serv/login.php?lang=en&profile=2 HTTP/1.1( V! C9 R* q. J
     2     Host: www.mydomain.com
2 l! g' @" c- o5 Z" B     3     User-agent: my small browser
1 Z) ?/ ?9 \9 [     4     Accept: image/jpeg, image/gif
5 _+ u5 K* X5 R$ M5 _+ a" c* I. w9 V- R     5     Accept: image/png
# H: h$ e# V9 R% {9 o9 m- u9 b; q. c, ?6 W

* P! Y4 R9 {# }8 H0 V, }1.2.1. The Request line
+ {& q: m( V4 S: Q% [/ ^/ ~-----------------------; \* D/ u" k. H' Y
+ C) d. N. I) i7 h
Line 1 is the "request line". It is always composed of 3 fields :+ B! l- U5 h9 g9 V$ {3 P6 F* C5 m

3 Q& W4 y$ }' ?: r: R4 j) S# c2 A  - a METHOD      : GET
% Z; d& G0 r. D+ d6 d% K, v  W5 k  - a URI         : /serv/login.php?lang=en&profile=2$ W; w& J- m; R( I3 [" }- q
  - a version tag : HTTP/1.1
* X7 a0 v( U; e! v+ H! _
$ e: w- Q8 ?* l) \5 i  i1 K! xAll of them are delimited by what the standard calls LWS (linear white spaces),
) }" t( y$ f2 O& B. F' n. D9 Dwhich are commonly spaces, but can also be tabs or line feeds/carriage returns
. H( F0 a! [! K  |4 O' y3 t! Jfollowed by spaces/tabs. The method itself cannot contain any colon (':') and
) ]% ?' A' U7 {( x$ ]! \is limited to alphabetic letters. All those various combinations make it. X& M, a2 E/ t5 o, B. k3 F9 j
desirable that HAProxy performs the splitting itself rather than leaving it to
' d5 Z1 E/ n) m# o8 x) bthe user to write a complex or inaccurate regular expression.8 T( K5 J& A) Q7 y* E

: _& ^2 [; ~$ p2 @! }  z* kThe URI itself can have several forms :) }" o5 {1 F+ `3 S; _* v) X, c
; e$ s2 D: C, c1 k
  - A "relative URI" :8 l  N9 }# `: U. e, g

' ?, j+ t) u$ {3 j, {" C8 o- b      /serv/login.php?lang=en&profile=2+ |# G; H% h, U& o4 U$ C3 A; w
' B. i* S6 t4 j( f
    It is a complete URL without the host part. This is generally what is
8 S1 A! j4 \* u! U    received by servers, reverse proxies and transparent proxies.8 B" h, Z  O: ^. w
( }  a- `# h6 Q) s' X4 t  ^8 A. C" ~
  - An "absolute URI", also called a "URL" :
- r6 p# }4 M1 Y2 o- l
- T6 c" N6 s5 _) v      http://192.168.0.12:8080/serv/login.php?lang=en&profile=29 Y6 c; m- F# v

5 f1 v# v3 z5 a4 l9 O- P1 a    It is composed of a "scheme" (the protocol name followed by '://'), a host! O* A8 g" U  `, j0 @
    name or address, optionally a colon (':') followed by a port number, then
9 W* @5 X, p* \' ]    a relative URI beginning at the first slash ('/') after the address part.
# ~2 T1 |) g2 i' Q* ?- e4 C    This is generally what proxies receive, but a server supporting HTTP/1.1
" H  I5 ~3 k6 \9 F    must accept this form too.
! o* O, s: b+ E0 J/ N, e; ^  ^
  - a star ('*') : this form is only accepted in association with the OPTIONS
/ Z: S3 `" \7 }+ s  ^+ Y% r: [4 J% F    method and is not relayable. It is used to inquiry a next hop's- L$ S/ o4 K$ s) g
    capabilities.
0 q+ t; b" @% _" W# E7 X! S( p0 p0 q0 r. \+ V* \2 V. J. y
  - an address:port combination : 192.168.0.12:80, @. T3 r  k% ~8 V4 P+ H
    This is used with the CONNECT method, which is used to establish TCP# a& [* g( b+ I, p" |: f
    tunnels through HTTP proxies, generally for HTTPS, but sometimes for
: i- I" ?/ Z( d+ m; l    other protocols too., R3 j4 w- p, |5 a" {1 x& x; _
% W; r. V; G% M9 q
In a relative URI, two sub-parts are identified. The part before the question) |" E# @. b1 u/ M
mark is called the "path". It is typically the relative path to static objects3 v1 I$ s3 V: d+ i, o% p
on the server. The part after the question mark is called the "query string".  V' v9 K, ^2 M6 {
It is mostly used with GET requests sent to dynamic scripts and is very
; @9 A8 \/ `! ~6 D; a1 ^specific to the language, framework or application in use.
: b% o" @! M/ w7 i! l8 W9 o- O7 M( D# @: {1 \

1 B- \. o4 U* Z. i* n: V1.2.2. The request headers
* j. [6 \. r; ^, g- S--------------------------& V  d* L: \8 A% V( ~  I' J* P
2 x' q* m1 ?- l9 ^* E7 u2 T) l& I
The headers start at the second line. They are composed of a name at the7 M8 ?% Q+ g. O; H2 j5 B
beginning of the line, immediately followed by a colon (':'). Traditionally,+ A9 M/ H5 {$ V6 i2 ?1 e# X- |
an LWS is added after the colon but that's not required. Then come the values.0 z( R: x' I% U$ ~1 h, m; `
Multiple identical headers may be folded into one single line, delimiting the4 L  {# R4 x6 E* e' w" H. T
values with commas, provided that their order is respected. This is commonly
7 A$ @! `6 o% k3 m! b# k1 Xencountered in the "Cookie:" field. A header may span over multiple lines if
& B: v7 }* c$ a! y* A0 wthe subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 54 A0 n  r! ]3 r1 Y4 v3 H# I
define a total of 3 values for the "Accept:" header.
+ A" E) U9 n# _: w! Q3 b! N( x" k* I: I& s' h2 t" q& w1 `
Contrary to a common mis-conception, header names are not case-sensitive, and8 x! n8 m7 b5 I* \* G6 @: W8 D
their values are not either if they refer to other header names (such as the
& o6 ^4 B# ]! [9 y"Connection:" header).
4 \& W- U* Y, @( l2 x: K
/ f7 a4 ^- N4 e$ W& r+ MThe end of the headers is indicated by the first empty line. People often say4 v( `* T9 l' n( A" g7 s- g5 N3 Y
that it's a double line feed, which is not exact, even if a double line feed
0 x/ \9 K+ j* j6 X& m. Lis one valid form of empty line.  l4 ]8 J6 B  E7 u: F9 N
6 O6 F: ]. j7 P2 x
Fortunately, HAProxy takes care of all these complex combinations when indexing8 R: f% ^: d. W9 ~
headers, checking values and counting them, so there is no reason to worry% ?' O. S$ H7 F
about the way they could be written, but it is important not to accuse an
! y' }, a7 {+ A) B+ c: bapplication of being buggy if it does unusual, valid things.
% J4 z2 p5 G% i- y2 z1 M( L% t0 x0 [6 ]3 H% B$ {1 M
Important note:
% O  [8 Z& H+ N2 |   As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks
5 ]9 H. i  M. s; I, M; o   in the middle of headers by LWS in order to join multi-line headers. This; F7 U# z, j- T% R' ]7 P% v, S
   is necessary for proper analysis and helps less capable HTTP parsers to work
: ^7 h& P4 O$ A# E7 f   correctly and not to be fooled by such complex constructs.
; }& \, l) r( ^2 C! L. b  O& d  G- I2 i

3 T8 r5 d  L1 r5 n; ]1.3. HTTP response
* v1 {. Q# U" f5 s6 C$ ]------------------3 \( n2 c( n9 T2 c( F
6 x; B8 `) j' d& w2 g& F0 t. W
An HTTP response looks very much like an HTTP request. Both are called HTTP% O7 |- |' X0 ]7 Q+ t+ t
messages. Let's consider this HTTP response :
" n' m/ E2 Q2 I' h+ t( t4 w( w, g7 e4 {
  Line     Contents
1 h9 M  e9 z* h) F: f! o  number1 t& U: z/ ^8 ]' A$ }# b
     1     HTTP/1.1 200 OK
- t% J  z9 K# }5 ]     2     Content-length: 3506 ?& P) q2 l" _8 @" G
     3     Content-Type: text/html$ ]% D& [! w; x3 J- V
; E$ N! [8 ]: O" L$ H
As a special case, HTTP supports so called "Informational responses" as status3 Y  L7 B  ?4 M' G; g1 H" V
codes 1xx. These messages are special in that they don't convey any part of the
' ]: W8 c' v# h6 Rresponse, they're just used as sort of a signaling message to ask a client to$ t5 k/ q( j) J# G6 ~+ O0 l
continue to post its request for instance. In the case of a status 100 response9 S% J2 g% g: p: T# l7 y# P
the requested information will be carried by the next non-100 response message1 P$ q) C9 x" s1 w8 b* \
following the informational one. This implies that multiple responses may be6 h8 O( y3 t& ?* h/ x3 [
sent to a single request, and that this only works when keep-alive is enabled
3 ?  H! j0 q; M4 c5 i0 |8 p  R(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to2 P0 V. Y, a- q- d$ V: i3 B
correctly forward and skip them, and only process the next non-100 response. As
! K4 b& O3 w& psuch, these messages are neither logged nor transformed, unless explicitly
( Q# B0 q. H, Ostate otherwise. Status 101 messages indicate that the protocol is changing3 B- b* n- `1 N' ?/ z  T3 D2 G- g
over the same connection and that haproxy must switch to tunnel mode, just as
! m* c4 Z. o& n4 aif a CONNECT had occurred. Then the Upgrade header would contain additional
, s' t* Y% Q2 i$ W3 \information about the type of protocol the connection is switching to.
" U* M; l+ j' T- i
- ~8 W2 G1 }3 s$ @( w  d  C, N+ J2 K3 G! j! u& a- f
1.3.1. The Response line
0 ?* h, w8 J/ R* j9 v& X------------------------
. {- J  ]% ^4 I+ T1 Q' N+ k+ a3 a, U: m7 }
Line 1 is the "response line". It is always composed of 3 fields :
4 b7 J' Y) M  E' ^
* j, b" v. |/ Y- I7 w# k/ \  - a version tag : HTTP/1.1
5 I8 ^2 Y# ]4 I) H' @7 k  - a status code : 200
/ v$ U" o/ Q6 C/ s0 C0 t  - a reason      : OK, V0 [0 N" C  a& O" a
. d1 I/ A# }! l, c6 w& O
The status code is always 3-digit. The first digit indicates a general status :) w" F% B  f& X: O( B
- 1xx = informational message to be skipped (eg: 100, 101)
8 [8 ]; J( S0 n) N - 2xx = OK, content is following   (eg: 200, 206)- @  q0 l" O0 Q1 w, H* W! o5 [
- 3xx = OK, no content following   (eg: 302, 304)
1 t# \/ n9 {: K& R8 j1 O - 4xx = error caused by the client (eg: 401, 403, 404)
' R( F- ?* j3 t - 5xx = error caused by the server (eg: 500, 502, 503)0 H8 x0 i' Q5 w

5 o: D+ F6 ?$ S' ^Please refer to RFC2616 for the detailed meaning of all such codes. The
1 Q( j, P4 E' A"reason" field is just a hint, but is not parsed by clients. Anything can be
% M% `& b) E* H; C  ufound there, but it's a common practice to respect the well-established8 K; q* @- ?1 \+ P; R' u5 ]
messages. It can be composed of one or multiple words, such as "OK", "Found",
9 |' m, u* R, W  f; u  ~5 jor "Authentication Required".4 r0 K9 C; c5 \4 D2 p# j
2 c9 s# ^0 K7 l( A" N. k
Haproxy may emit the following status codes by itself :# @: j* }7 Y2 J1 ^. G
& c5 k+ f1 B: W1 q) ~
  Code  When / reason
/ l& h: C6 S$ v- X- R   200  access to stats page, and when replying to monitoring requests
' x9 R. p$ f( F/ D2 c   301  when performing a redirection, depending on the configured code
1 p" F+ m6 d0 W$ D# j   302  when performing a redirection, depending on the configured code
3 A$ E4 x! m% X- r# I0 t, }   303  when performing a redirection, depending on the configured code
1 }8 D5 r7 {8 Y& W" f- V& I* g   307  when performing a redirection, depending on the configured code
2 F9 i# w9 I! G9 D1 ^0 e2 q   308  when performing a redirection, depending on the configured code0 N9 l. N" R) t: A0 T
   400  for an invalid or too large request6 r; j/ B# D/ N- w5 A
   401  when an authentication is required to perform the action (when  H$ G" \; D. v% a  v' b* u3 q
        accessing the stats page)0 x  w# e9 Z1 N$ L* m( w; M! s  L
   403  when a request is forbidden by a "block" ACL or "reqdeny" filter' ?5 f1 g/ L0 M; r/ K, D" G* e
   408  when the request timeout strikes before the request is complete
9 L. `" B4 s# z   500  when haproxy encounters an unrecoverable internal error, such as a% g) K, b/ Q& M( y# Z6 T' _- f
        memory allocation failure, which should never happen
- ?$ q3 }, }5 y- d# H8 s0 h4 B! C   502  when the server returns an empty, invalid or incomplete response, or4 _6 P( H  s' g( n- y
        when an "rspdeny" filter blocks the response.
5 X# z- C# R7 k7 M( u9 f  X: F   503  when no server was available to handle the request, or in response to8 Z# f* _# H5 q/ i) E2 ?
        monitoring requests which match the "monitor fail" condition
# g& _3 G$ O/ u9 N% |   504  when the response timeout strikes before the server responds
' s4 [7 h+ \; \$ W! w- l! O8 W# z, }; p* }. ~; m& w
The error 4xx and 5xx codes above may be customized (see "errorloc" in section" r3 B3 `5 j) f
4.2).9 i) p& z7 r: f# I# \! {5 q
" ?' g/ z$ f6 @% @; N7 k

" T3 e( R! a/ k, s3 Q1.3.2. The response headers; J! J; I) ]. A! w* \
---------------------------
" j; V  h- D/ G3 L7 O( b
7 f+ n4 G& _4 e6 X$ N8 jResponse headers work exactly like request headers, and as such, HAProxy uses1 j+ z/ ?8 C+ T
the same parsing function for both. Please refer to paragraph 1.2.2 for more
2 |3 E+ f6 B/ m" fdetails.
  m+ E' F9 z3 @7 j2 r0 a; b1 T' h( |
. M0 p- b$ a, y5 j+ _
2. Configuring HAProxy  I* K5 T) D5 Q1 C/ G5 l
----------------------
) P7 C7 o5 a% t/ I
! G5 Z6 i/ P1 f; {. {2.1. Configuration file format
. y3 f5 G8 N7 }: A; Z( ^------------------------------
! C3 k% U: U3 A6 w3 d
3 E# C3 i4 L: @) ^# q2 AHAProxy's configuration process involves 3 major sources of parameters :5 r# c8 K, X2 ]3 Z
7 s( A* q( f# J7 w7 m! {
  - the arguments from the command-line, which always take precedence# y) ~0 ~1 o  J, H) R
  - the "global" section, which sets process-wide parameters& h$ o: D6 m9 l" c# w: O5 ]
  - the proxies sections which can take form of "defaults", "listen",
$ d6 A1 X8 {3 f9 y    "frontend" and "backend".
2 ?& D! j" X9 k$ P( @, i/ _$ p/ G. m+ e$ d  `+ v7 {, `
The configuration file syntax consists in lines beginning with a keyword* ~7 _# P5 l) B1 T; }
referenced in this manual, optionally followed by one or several parameters2 P7 w# M$ E4 J0 e
delimited by spaces. If spaces have to be entered in strings, then they must be5 D- _7 B$ d  L7 B
preceded by a backslash ('\') to be escaped. Backslashes also have to be5 v! C1 J( k- ~7 U
escaped by doubling them.3 F. n/ Y" k$ i8 V. G- U; B
7 S0 s; s% J$ @  A" m5 C8 f' ]
# K+ |1 m, K! P
2.2. Time format
/ \* A: J' M- I) F: C" p* R; `7 j----------------
- |# F( n9 C' l, V5 N1 f8 |; \1 ~4 @* z: e
Some parameters involve values representing time, such as timeouts. These/ z+ t- l; I& d7 g
values are generally expressed in milliseconds (unless explicitly stated
8 _3 [7 z- H) O6 ^4 h7 N) T0 sotherwise) but may be expressed in any other unit by suffixing the unit to the2 l- j; |7 T- A) B1 v
numeric value. It is important to consider this because it will not be repeated  N: j1 L& h% @
for every keyword. Supported units are :, a7 K- p  p5 l6 o, z: B

- k. l" S' v0 T. g. _- N7 z  - us : microseconds. 1 microsecond = 1/1000000 second0 s1 E! s9 L- E8 C
  - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.) @. _: l6 b) ^' t" I% Q
  - s  : seconds. 1s = 1000ms
' R; j1 H3 P! B  - m  : minutes. 1m = 60s = 60000ms' g$ I' B  }$ c
  - h  : hours.   1h = 60m = 3600s = 3600000ms
) x9 O& C4 o# C) i. O+ X: |  - d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
; F6 |) L# |2 X" q+ C* |2 a
- T9 K% l' c9 x, j
: o6 x  x5 R5 P2 D' h, e3 I6 C2.3. Examples0 M1 H  {1 I( y) N1 @% j7 R) x
-------------
" \% o; a7 _" G& @; g" h* v' \  k; ?4 D# L8 v( H& W9 S% r
    # Simple configuration for an HTTP proxy listening on port 80 on all
2 {1 l0 w* s* h' P. e& H: f    # interfaces and forwarding requests to a single backend "servers" with a7 J6 Q8 N/ h. N) X8 _
    # single server "server1" listening on 127.0.0.1:8000$ R* }/ D5 d1 |8 }3 e" ]$ \- c
    global
8 `* {! C  F7 K3 h. U        daemon" \5 I2 ~( ~; ~" V6 f  i
        maxconn 256
$ p# v/ I3 F. K* l# R' V- G, f* @
: e7 T* i! M( W) o    defaults  j7 i; V% G6 I; b$ N* t
        mode http
' Q5 G5 q- o0 y% m        timeout connect 5000ms1 v, m; u9 U2 O& H/ i# s1 \
        timeout client 50000ms
" I0 a* i6 S8 N/ y        timeout server 50000ms2 Y: `4 z2 e+ t% }: w+ x6 M0 X0 v3 c' @
7 I: E$ U6 F0 p/ D
    frontend http-in
# V+ b: _) V/ U8 _) z        bind *:80) R) e! n8 D7 d" b4 U6 s6 t
        default_backend servers1 @1 {- @3 v7 b7 G1 V" t6 z/ q5 T
0 H7 k, o) Q! n) D; A
    backend servers
2 p; M, C* u* B; r0 Q, }6 P9 @        server server1 127.0.0.1:8000 maxconn 32
2 n& B6 s/ t+ q/ S# E/ ~* @' t7 }) Z' L0 ~; v
6 e- {9 r5 M: R6 K" q$ @
    # The same configuration defined with a single listen block. Shorter but! Q( S/ k9 I8 f( M/ U& x) c4 ~. E
    # less expressive, especially in HTTP mode.
8 Q6 s$ n5 {1 e; J9 q* P    global6 F* Q/ Q" D7 {
        daemon
9 @$ K- F+ l( `& [- t. ?# [1 N        maxconn 256. T4 ?1 k# m  J
1 i) \* a! `  F/ V7 v
    defaults0 e- z5 Q5 q* g; g( ]8 ~
        mode http# U" Q9 P/ K) H8 ]
        timeout connect 5000ms
/ [2 c1 e3 E) N- W1 S        timeout client 50000ms
; @6 c( j0 S1 A4 W; J' e% L6 w# V& n        timeout server 50000ms
+ t5 ], {' G2 T+ ]5 \4 w3 A
8 D7 s4 W7 H) t4 {; t2 g0 c    listen http-in
% L! Q% v$ o( c7 V" w        bind *:80
% ?. n& J& _* m% S8 C' d        server server1 127.0.0.1:8000 maxconn 32
, S8 n. r) f! `8 p5 n& L4 `
' ?& v2 U0 u2 p; U
5 t; S) K* b- W6 M4 R& VAssuming haproxy is in $PATH, test these configurations in a shell with:$ b% q# ^% a: k' b$ m: [' u

7 \, u. i3 P* o8 T: _    $ sudo haproxy -f configuration.conf -c( {; }8 A8 ^5 K: V% p) R

0 P6 l8 Y7 ]( Y+ Q0 c
& ?  w0 F" B1 w4 y6 j, g3. Global parameters5 b4 ^# f1 o7 F9 k% c
--------------------
7 q* m0 L! h; Y5 u" J. F
- a% Q( I) o" T/ S9 ^Parameters in the "global" section are process-wide and often OS-specific. They
5 k- D6 L5 Q/ ?+ x; j- x; L* Vare generally set once for all and do not need being changed once correct. Some
% f$ V/ ?7 b/ |) V- {' `) Aof them have command-line equivalents.
8 b' E! b, ~( G+ T! }+ g& C9 A
The following keywords are supported in the "global" section :
! C- c+ u+ ^0 {) |
* g: q: a" ]/ c6 r; k( f' b! l0 L * Process management and security. i. o8 T% f2 s$ t7 v5 H, ~1 r
   - chroot7 u3 X! b5 r; n/ ^: y# Z
   - daemon
. h8 W/ F+ r* ~: |   - gid1 [' I5 a( p  K' O+ f" l
   - group: S: o* {9 K# O4 N1 s  ~8 i
   - log
3 L- T1 U3 I7 H% S; q   - log-send-hostname: \% p  X# Y9 E! m
   - nbproc! R/ i! [! f! ^# O) ^& r! h3 w6 k
   - pidfile' j% l3 _/ L" K7 C6 E) U
   - uid* N0 z  A( K4 K
   - ulimit-n
( l: [7 O, h% Q. |  a   - user
; U6 G* p* G9 _: @  K   - stats1 r1 z0 i( l& x) F2 f% k* P
   - node
2 a! O, P. K( K   - description/ b" W  [. K! Y$ }! |: ^0 k0 u5 N: S; A

5 s5 P( v) X) y- a9 s; y( v * Performance tuning  U3 b  N4 ^; ]. ]# a
   - maxconn, w* y5 F9 A$ j& L' I) r
   - maxpipes6 n& Q$ T# Q+ d, i0 F' P4 F
   - noepoll
  B: W: R$ i/ H   - nokqueue* a6 a6 K7 ^  }3 \, C
   - nopoll
* A% t! h9 Z/ u. n. U! o. i   - nosepoll9 j  k( @2 u& w, f
   - nosplice$ x4 {5 e0 }: J& ~( c8 H5 X  u
   - spread-checks
; `" u3 @. E7 m5 ]) T   - tune.bufsize- Z5 O+ U6 P4 G+ c  F2 _
   - tune.chksize
. z3 }. u3 X; y/ o; V! {8 f3 \   - tune.maxaccept( t, q" W2 R) P/ G5 Y
   - tune.maxpollevents
/ A1 S, L) M  H9 r   - tune.maxrewrite
5 ]8 I2 Z& a* [: L+ c5 d) D8 B- `   - tune.rcvbuf.client
6 F1 f$ D9 O1 b# J( r! o6 v   - tune.rcvbuf.server9 A, `* {) T0 y) e- g
   - tune.sndbuf.client
( B7 X- N& H7 K6 E" w   - tune.sndbuf.server1 F' c3 s/ F. B- O$ _* R
6 Y0 |: z. [8 @- \9 w
* Debugging
" v+ Q4 D7 D& ^. g* {, s5 j- E: {   - debug9 Y" {( X: g1 e0 U
   - quiet
4 U0 j. N& |$ }
/ R' ^  \& }% O: i6 y' u# K# X! w
3.1. Process management and security
# n- P" ^9 u2 [------------------------------------- V5 e; u3 b& c* M% h

9 J+ g# v" |7 ?* Y1 x4 ?* O) Uchroot <jail dir>
& w( e8 I6 T( F& m  Changes current directory to <jail dir> and performs a chroot() there before
7 \" e' ~9 u+ x* b- v4 J- R6 J! \  dropping privileges. This increases the security level in case an unknown" F. a& M; W4 C: E, u9 U, e! `6 J
  vulnerability would be exploited, since it would make it very hard for the
: M/ a3 F4 r. Y( b/ q9 {  attacker to exploit the system. This only works when the process is started
9 x% H. d; o8 a& M  with superuser privileges. It is important to ensure that <jail_dir> is both& p7 z8 A3 [! C2 \' I/ F; h; F4 q
  empty and unwritable to anyone.. `- q2 T% v. E8 m/ g0 `1 w& b. Z7 E

9 q$ M" f& \- [, x) r9 [/ adaemon
( ^" c5 N' v3 A$ l) c  Makes the process fork into background. This is the recommended mode of" X7 R9 S0 M) f) r# g
  operation. It is equivalent to the command line "-D" argument. It can be
: ?, f7 O! J  S$ l  disabled by the command line "-db" argument.! _6 ~% @" M/ D% Z- s% }

, A( {- O3 ?0 C" I- Igid <number>' X$ u0 d1 K0 c, j! J0 a/ ?1 f# J
  Changes the process' group ID to <number>. It is recommended that the group
2 N- j+ x) w3 [$ y. ^1 x# b  ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must2 R1 \. O( D) p7 J9 M# N+ a! {
  be started with a user belonging to this group, or with superuser privileges.
/ c# n8 u8 i' N" F) A  Note that if haproxy is started from a user having supplementary groups, it
- A- I" M; c1 E) X  will only be able to drop these groups if started with superuser privileges.  q- n) c2 m% p& E3 [+ K, v9 n
  See also "group" and "uid".3 U3 l% D! U) W% Z/ v+ @

- C- N* [& e  c) Ggroup <group name>5 I& V7 W$ y1 w' l
  Similar to "gid" but uses the GID of group name <group name> from /etc/group.
* O  g5 G% t( ^  See also "gid" and "user".
* Z) f' p1 O) d2 c; O, }4 F# Z
% ?" q$ T/ a, r6 c0 J! ~log <address> <facility> [max level [min level]]; B6 d% I' G* Z# e) P  M
  Adds a global syslog server. Up to two global servers can be defined. They
5 Q8 [" W3 u; N- p9 m  will receive logs for startups and exits, as well as all logs from proxies
8 m( Y8 m+ i( r' @3 D$ T  configured with "log global".3 M) f" t0 v* E' f$ t: \9 M& u
  r9 G7 H, y9 C6 C5 j
  <address> can be one of:: |7 e) a+ h: V- P1 c

; b; Z& w5 ^. B5 y; E: k- K        - An IPv4 address optionally followed by a colon and a UDP port. If; f$ ]7 A# F: x& X
          no port is specified, 514 is used by default (the standard syslog
8 W$ |7 A. r) ?          port).0 E/ }, S/ w0 }6 [9 E7 X
0 d% E0 T( u6 d; m
        - A filesystem path to a UNIX domain socket, keeping in mind# P( h7 k  l7 |$ v
          considerations for chroot (be sure the path is accessible inside
' H. k0 T& n3 a2 Y$ @          the chroot) and uid/gid (be sure the path is appropriately# u& C+ q6 ?* A, A, S& K& {
          writeable).$ D, e2 P$ R" {8 u; J

, z" E# H0 B) E0 O, Q5 v  <facility> must be one of the 24 standard syslog facilities :
; f& x" M  [) h; K5 ]; W' c$ g% [- \) V
          kern   user   mail   daemon auth   syslog lpr    news- ]- r7 Z% R/ z( d/ e
          uucp   cron   auth2  ftp    ntp    audit  alert  cron2
" L7 x1 h1 G& p& p! t          local0 local1 local2 local3 local4 local5 local6 local7
/ S7 }: n9 s3 x( [) l# I& a# w+ S+ B- R( o# N& l
  An optional level can be specified to filter outgoing messages. By default,% r- `& E$ F7 V7 U
  all messages are sent. If a maximum level is specified, only messages with a
! g  e7 |5 A: X) o  severity at least as important as this level will be sent. An optional minimum, s5 a& R* ]. p, `% m
  level can be specified. If it is set, logs emitted with a more severe level5 ?' N+ V7 _2 ?6 Q& y* N% i
  than this one will be capped to this level. This is used to avoid sending4 Q0 R* w; O+ f( w1 }  Z
  "emerg" messages on all terminals on some default syslog configurations.0 }, K; t, B$ s. m9 ~  U+ F
  Eight levels are known :
/ g( J# g  X: o4 q# ^$ K( v# q  [5 W3 C1 i# i+ y
          emerg  alert  crit   err    warning notice info  debug
- i% O9 q; ?$ H9 V/ N6 A& I6 z, L; f% A
log-send-hostname [<string>]
: L3 ]# l! b6 b5 X9 K  Sets the hostname field in the syslog header. If optional "string" parameter
" {/ ~4 s0 Q0 Q* G  is set the header is set to the string contents, otherwise uses the hostname) ?) E/ A% V- o# x7 e, q
  of the system. Generally used if one is not relaying logs through an8 k+ U; A% b% |" ^8 O0 \2 X! }
  intermediate syslog server or for simply customizing the hostname printed in
( ^* r( k2 a; P. A  the logs.
4 H# `; C" I8 N" e6 s4 P1 ?, B
2 b0 K6 L+ `' e( Z3 F8 Rlog-tag <string>6 s% c! L  G3 M1 i, O$ p& w" @
  Sets the tag field in the syslog header to this string. It defaults to the- x: u' Y' ~% A3 Y' c9 F
  program name as launched from the command line, which usually is "haproxy".0 I: Y$ `- D6 R
  Sometimes it can be useful to differentiate between multiple processes
3 E. k( t' @- V/ r7 |8 ]7 K' L  running on the same host.
- e' c. b9 L% p! U& K# c! e
* l" Z$ k+ M8 p" n% jnbproc <number>6 k* }5 n( ?+ x. T- f
  Creates <number> processes when going daemon. This requires the "daemon"
  N$ z6 M  e2 @# B- }6 q  mode. By default, only one process is created, which is the recommended mode
$ _" n' d, T$ ?5 V  of operation. For systems limited to small sets of file descriptors per& p( `! b0 a! f" o+ w5 [
  process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES9 l+ s: y* M8 E" R$ y, x
  IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also "daemon".0 }( v: t  ~- e/ [, f% N0 v
$ f  C! M. L" h& R
pidfile <pidfile>
9 B- W( v* V& Y3 p+ S  Writes pids of all daemons into file <pidfile>. This option is equivalent to
6 W& a- r; ?  _8 k; E9 Z  the "-p" command line argument. The file must be accessible to the user
* c2 Q5 w" z; J& x' L% e2 [" h  starting the process. See also "daemon".
) F" A/ I6 \! o6 M! ?  v% @( O
stats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]
6 {/ P" S8 u8 r1 ?0 \/ F* a) x% Y, X" I- D             [level <level>]- l% L4 p, Q6 v" ?3 B/ {  m
! |) [+ D: `( G% C
  Creates a UNIX socket in stream mode at location <path>. Any previously5 X- L8 u4 h5 x3 w. l. ^
  existing socket will be backed up then replaced. Connections to this socket, x5 ^% S& H. D7 [1 \% D# P
  will return various statistics outputs and even allow some commands to be
+ p4 B: E$ I/ a: U6 x  issued. Please consult section 9.2 "Unix Socket commands" for more details.. r; J! X- L- O2 U( Z8 D! ^
& \( N; o8 K5 G# k- M
  An optional "level" parameter can be specified to restrict the nature of+ ]( [2 N6 s) G& |* n$ M
  the commands that can be issued on the socket :
( v) H1 x0 t" ^" z    - "user" is the least privileged level ; only non-sensitive stats can be
+ O  y# T* E9 z) @      read, and no change is allowed. It would make sense on systems where it
# ?$ m! o2 p1 S      is not easy to restrict access to the socket.9 s) y. |* u) C8 ?

/ o* C+ r) Y: O3 E. |% L" w+ ?    - "operator" is the default level and fits most common uses. All data can
) I' I4 Z' [, [5 B  v      be read, and only non-sensitive changes are permitted (eg: clear max
; A0 o. ?/ e3 \( Z      counters)./ d9 V0 K( r/ j+ h
5 O) f2 f. }, q6 N
    - "admin" should be used with care, as everything is permitted (eg: clear5 O0 d' P) r" g7 i8 G
      all counters).
/ D% }" \) t% ^- R* ^$ ^: H- o0 g
9 `9 G: B, g, j1 X1 E  P/ P  On platforms which support it, it is possible to restrict access to this
. L6 H/ g7 G$ z  socket by specifying numerical IDs after "uid" and "gid", or valid user and& E9 o  e) P: C! B
  group names after the "user" and "group" keywords. It is also possible to
! w3 S& s0 w) l- U& T  restrict permissions on the socket by passing an octal value after the "mode"
7 |: r6 g5 D' ?& p  keyword (same syntax as chmod). Depending on the platform, the permissions on' a1 g7 j* P9 l! k
  the socket will be inherited from the directory which hosts it, or from the
$ I/ K3 O8 B" D, A& D- h  user the process is started with.2 j7 u1 ?3 j" ~' N  R+ \! _
7 n" ^% A% d: L2 @7 P) @9 U' {, m
stats timeout <timeout, in milliseconds>
! ?) w& x( _9 f" q7 M- ^  The default timeout on the stats socket is set to 10 seconds. It is possible, K+ x+ }  L; E- @
  to change this value with "stats timeout". The value must be passed in
. _8 E2 T8 @$ o. n7 W% w6 G  milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }.- g) |9 U  Q4 E. [

! l& f1 C" R6 G! Jstats maxconn <connections>
2 j; F0 H$ C& }% V3 a  By default, the stats socket is limited to 10 concurrent connections. It is* R7 j) }1 w7 w6 R
  possible to change this value with "stats maxconn".
  W/ D, C# }8 z# x1 f6 Y
- w+ V1 ?* I  a9 c, Duid <number>
. [# o9 F8 K5 k# w  o( c  Changes the process' user ID to <number>. It is recommended that the user ID. ?  i4 k: \. X) q- ~! T' Q7 S- @) D
  is dedicated to HAProxy or to a small set of similar daemons. HAProxy must
/ Q, n5 q- |. n$ A' D9 |1 i+ L  be started with superuser privileges in order to be able to switch to another
2 I0 J& j% y' [6 G4 r. @  one. See also "gid" and "user".- I# t8 v7 b! s! W" F8 O
& C9 R- z2 Z; q' s) y
ulimit-n <number>
/ W2 }2 W) n3 l' X2 ?- ?  Sets the maximum number of per-process file-descriptors to <number>. By
! _( O' L" p& z; v0 V2 q0 R6 W3 c  default, it is automatically computed, so it is recommended not to use this4 R4 H, ~8 q- c& @/ a$ h2 S# ?
  option.
2 h8 {! a' |0 K+ P
: d, x! u* O) ]0 J# J) S+ a8 q1 Kuser <user name>
& O2 A! Q! w$ \( e$ G: O& o  Similar to "uid" but uses the UID of user name <user name> from /etc/passwd.
, R2 `- _5 k+ r4 A9 U7 l' E% x  See also "uid" and "group".
# c! ~, r& `( P- f2 w0 f# m% o7 U" u( y' x) c6 x
node <name>
& ^/ I) `( s; E4 Q+ s  Only letters, digits, hyphen and underscore are allowed, like in DNS names.
( u* f2 ^. S" M% w) d$ @) E  L) n; T6 d( D2 {. C, P$ G+ _5 P) A, [
  This statement is useful in HA configurations where two or more processes or
& r8 F8 J2 U3 H% }  servers share the same IP address. By setting a different node-name on all
0 r/ ~6 {  j7 I) b4 B  nodes, it becomes easy to immediately spot what server is handling the
# C5 _. h5 s$ t* K7 D  traffic.9 ?9 K. Z2 K2 m6 i6 ~9 \
$ Z! }8 w/ [- n7 a/ I6 g
description <text>
! [6 d' B# ?  I! \8 h: w/ I5 G  Add a text that describes the instance.) H+ i  c- J+ W

; i! g% u( c  y0 ?; l  Please note that it is required to escape certain characters (# for example)  p( N1 P5 i6 W. x
  and this text is inserted into a html page so you should avoid using
) x- F5 }6 w9 N. Q7 n: x  "<" and ">" characters.6 u5 p' ]1 L& I+ E0 N/ j( a- m8 N
. s! q! B$ G# u5 R

1 i0 Z, C6 E/ M1 a+ D  c3.2. Performance tuning# q7 Y' b  f. h
-----------------------
2 p2 g4 C- C8 P# z$ E% E! @' a
7 s1 `, O, w' q! ?! q: Rmaxconn <number>
* c1 p% K, y; H/ w$ E4 \/ Y+ V! o9 y  Sets the maximum per-process number of concurrent connections to <number>. It
: m4 n, O4 d( Y" y6 c  is equivalent to the command-line argument "-n". Proxies will stop accepting, K; O! L2 k' X  x3 ?/ N- V) S7 z
  connections when this limit is reached. The "ulimit-n" parameter is+ q: G9 q$ U; \- S" v; S5 F9 G
  automatically adjusted according to this value. See also "ulimit-n".4 P# L. R0 c" g6 t$ V+ Q7 o0 N: Y6 z% l" Z

4 h* P) u6 P# h2 S# S  ]; l! b' gmaxpipes <number>
/ C* v+ h: J3 y" q% z4 f# _% t  Sets the maximum per-process number of pipes to <number>. Currently, pipes- W+ G, D. }- N
  are only used by kernel-based tcp splicing. Since a pipe contains two file
" h( v/ P; i+ _8 P" \  descriptors, the "ulimit-n" value will be increased accordingly. The default
( e$ x, u; L! u( y% y% c  value is maxconn/4, which seems to be more than enough for most heavy usages.# J( i! N4 [  H' p
  The splice code dynamically allocates and releases pipes, and can fall back
7 H& k) L. P- C4 B1 P: S  to standard copy, so setting this value too low may only impact performance.4 U% T0 w) N' _! ^5 s/ q3 i9 w. x# [
' G# \8 z' I) G8 K+ k* P3 e( N& U
noepoll
* n$ E* r5 V* G5 H  Disables the use of the "epoll" event polling system on Linux. It is
8 t& ^% o/ B6 p  equivalent to the command-line argument "-de". The next polling system
9 C; D. T3 Z# ^  used will generally be "poll". See also "nosepoll", and "nopoll".2 j- g3 P' l5 F; ~  y* N; x

2 M4 k4 s+ E8 e- Unokqueue$ [' Y9 J7 N" S* H( a* W7 Y. i
  Disables the use of the "kqueue" event polling system on BSD. It is
+ G# ~4 W  E: p! S% o% F+ l  equivalent to the command-line argument "-dk". The next polling system
/ }2 Y& K% j0 [! U  used will generally be "poll". See also "nopoll".$ L2 i4 g) X/ p1 C! T
  e2 ^9 A) N, |! x' U) a
nopoll/ [! K+ ]- p) O; ~0 K* R; j* g
  Disables the use of the "poll" event polling system. It is equivalent to the
. T; G2 p- Z% c# c1 x  command-line argument "-dp". The next polling system used will be "select".) D; i& Y: D5 N# b% T! V& a
  It should never be needed to disable "poll" since it's available on all; x9 `9 m" `, e7 V! e$ g- b7 b
  platforms supported by HAProxy. See also "nosepoll", and "nopoll" and
" ~) \6 q3 S9 q( {. }  "nokqueue".
% H! N5 M6 W* j& n6 Y
' C2 W5 N) s1 L% i" qnosepoll& N: ]$ r2 Q  W1 Q& j
  Disables the use of the "speculative epoll" event polling system on Linux. It9 b7 L% b) y$ ]3 \( r% Y2 z
  is equivalent to the command-line argument "-ds". The next polling system
+ q# C' h( B) O! @% P5 {) b  used will generally be "epoll". See also "noepoll", and "nopoll".
8 b8 V! M9 r8 `3 N2 ^$ [# d' Q  o# w
" S: I) n0 ^- d: Z4 fnosplice  i! |& m  k, z5 W5 ?' u
  Disables the use of kernel tcp splicing between sockets on Linux. It is# S3 y& |( H; G# v. @. h/ Q# i
  equivalent to the command line argument "-dS".  Data will then be copied
5 ^- f. o& h  f, G7 G# ^7 t  using conventional and more portable recv/send calls. Kernel tcp splicing is
( Q% T' p/ I7 M  limited to some very recent instances of kernel 2.6. Most versions between4 L+ a% r' c, X" Z5 V3 F, K$ O
  2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not: P5 E: [& j- t- q7 O3 ?' @
  be used. This option makes it easier to globally disable kernel splicing in
  q9 \0 f& k, i( D1 o9 i! M+ L! r  case of doubt. See also "option splice-auto", "option splice-request" and$ c8 j. N8 t3 \
  "option splice-response".
- G2 k' u! q. f' A5 U7 I# a1 @' z" h$ R5 _8 L. k( T9 y: v
spread-checks <0..50, in percent>
& l2 H# E' o9 D$ ?1 `* j7 w  Sometimes it is desirable to avoid sending health checks to servers at exact7 L5 d/ a1 [2 T2 S  E4 \
  intervals, for instance when many logical servers are located on the same/ V% }0 S' o; w( s% C% h
  physical server. With the help of this parameter, it becomes possible to add4 {1 n- o/ i- _6 w  X7 K5 Y, J
  some randomness in the check interval between 0 and +/- 50%. A value between0 o# w1 m) }+ C* r9 Q3 p
  2 and 5 seems to show good results. The default value remains at 0.
* }" j! Z  Y' _$ R- |# Y0 C2 `# c& ~$ P- S- Y/ X; u6 g
tune.bufsize <number>1 }5 }1 W- r  N  `: R0 |! o
  Sets the buffer size to this size (in bytes). Lower values allow more
5 k& }6 ?) w# Q# j* c2 t8 f  sessions to coexist in the same amount of RAM, and higher values allow some
  c; j5 {: {4 N( p$ D! S  applications with very large cookies to work. The default value is 16384 and
& s1 Q! b4 |3 C. R6 k2 P  can be changed at build time. It is strongly recommended not to change this
! ~7 n6 u' O) E( l  from the default value, as very low values will break some services such as
+ y! S% z0 f, q$ C! {, a  statistics, and values larger than default size will increase memory usage,
5 D8 W/ ]+ F2 a' {) m8 ?  possibly causing the system to run out of memory. At least the global maxconn) y6 d' n; j3 Y1 r% k, _4 t
  parameter should be decreased by the same factor as this one is increased.1 H: m4 h; O4 B# K; I4 o

  D: X/ o+ X0 y: y8 V3 Itune.chksize <number>, D7 g1 P7 d4 g6 R- l" h7 H
  Sets the check buffer size to this size (in bytes). Higher values may help
- X+ G  s& m7 ~1 N$ s* t  find string or regex patterns in very large pages, though doing so may imply
9 Z2 e) |$ E& D) u  more memory and CPU usage. The default value is 16384 and can be changed at, @- |6 b8 N5 F3 f2 U0 _
  build time. It is not recommended to change this value, but to use better8 b& U& F9 o! e$ j+ W
  checks whenever possible.( U2 N- ?# y; g( A9 v* {6 y- F. l
0 L; y; e# ~% y: M2 m: a
tune.maxaccept <number>
4 l4 `9 N; b6 Q  Sets the maximum number of consecutive accepts that a process may perform on9 k& M2 d, g9 Z5 }# _
  a single wake up. High values give higher priority to high connection rates,: O! N, o- X) Y. b
  while lower values give higher priority to already established connections.
# U  E+ |. ^$ t- N  This value is limited to 100 by default in single process mode. However, in
9 r. w5 ?+ r3 _. s2 l  multi-process mode (nbproc > 1), it defaults to 8 so that when one process
- ~9 B: U" a/ b  F  wakes up, it does not take all incoming connections for itself and leaves a- W* U% [! _+ p- ?5 q1 R# C
  part of them to other processes. Setting this value to -1 completely disables3 S2 j6 `' B0 F( E) f# T2 c
  the limitation. It should normally not be needed to tweak this value.
( i9 @. H8 g5 X. Q* L4 k5 }* i! B, |; \6 [# \+ w$ s5 Z; e
tune.maxpollevents <number>
8 a5 ~( K+ S2 D4 q- y. K/ p  Sets the maximum amount of events that can be processed at once in a call to( y3 S- O/ p7 h
  the polling system. The default value is adapted to the operating system. It8 [$ a+ a$ l( K4 `+ `
  has been noticed that reducing it below 200 tends to slightly decrease% \$ Z& _0 ~" n
  latency at the expense of network bandwidth, and increasing it above 2002 \6 ]8 N4 D6 e3 ?* _+ t5 M
  tends to trade latency for slightly increased bandwidth.
+ w2 j! [9 G6 b3 I9 L
$ e$ q# G) T0 g, B0 vtune.maxrewrite <number>5 e6 J6 E" |1 G- r8 ~# \( `
  Sets the reserved buffer space to this size in bytes. The reserved space is$ `1 l8 s3 ^8 r1 ]3 O, s
  used for header rewriting or appending. The first reads on sockets will never
& _* e) D, I4 _# U6 F8 ]! E  fill more than bufsize-maxrewrite. Historically it has defaulted to half of
1 h) r1 C! _4 |! P2 s/ v  bufsize, though that does not make much sense since there are rarely large
$ I0 F& _# T  U7 S; ]* S% m7 a  numbers of headers to add. Setting it too high prevents processing of large/ J3 G' @; m8 t+ e; ]
  requests or responses. Setting it too low prevents addition of new headers
" B. r' t/ `8 T3 B  to already large requests or to POST requests. It is generally wise to set it
( |/ @6 G/ W! e2 c9 N  to about 1024. It is automatically readjusted to half of bufsize if it is2 z& t+ g, G& w
  larger than that. This means you don't have to worry about it when changing( o" N$ y* E2 o4 ^5 C# r9 J
  bufsize.& y7 H0 ]& h% p5 s# k% t& n9 K
$ n) G' f$ e( F' D5 @) ^1 l
tune.rcvbuf.client <number>3 U/ d# P5 ?; y
tune.rcvbuf.server <number>
5 p" L' I# L9 L  Forces the kernel socket receive buffer size on the client or the server side
# I. H# X2 }* c, y" f  to the specified value in bytes. This value applies to all TCP/HTTP frontends5 j; q: u9 @. ]1 _/ {4 g2 A
  and backends. It should normally never be set, and the default size (0) lets
% Y8 ^, ?% w6 e0 `  the kernel autotune this value depending on the amount of available memory.! d; a% D$ ~; {# I' \! ^# }! @
  However it can sometimes help to set it to very low values (eg: 4096) in
/ T* K& _. v: w& K  order to save kernel memory by preventing it from buffering too large amounts
0 q; L# n. j4 `, Z$ N  of received data. Lower values will significantly increase CPU usage though.
9 F7 ~: a9 F/ Z$ g% @1 T
; S) T; e* W. htune.sndbuf.client <number>
' W* i* X0 e9 q( Atune.sndbuf.server <number>
9 A9 H/ V1 @4 G9 _  Forces the kernel socket send buffer size on the client or the server side to6 Y* ]% Y* I: t$ Q6 ~
  the specified value in bytes. This value applies to all TCP/HTTP frontends
: t) g6 j& \0 u) q  and backends. It should normally never be set, and the default size (0) lets
; e! k2 c: H8 j% N  the kernel autotune this value depending on the amount of available memory.8 S0 V1 z" Z! y
  However it can sometimes help to set it to very low values (eg: 4096) in
) Q7 L4 X+ v* L8 J& G' |  order to save kernel memory by preventing it from buffering too large amounts
" i* P, _4 @% S: ]' f1 e+ x  of received data. Lower values will significantly increase CPU usage though.8 P. Q4 s- H. D$ k3 ?7 c) J
  Another use case is to prevent write timeouts with extremely slow clients due- L& b4 ]' \/ o/ _5 {' G# k
  to the kernel waiting for a large part of the buffer to be read before
9 ~) `; z* f8 G  j  notifying haproxy again.( n! B3 v$ t8 p2 a4 r6 N/ t
/ n1 N' o) l) H: {+ T
: O- e+ P3 ]) d; A
3.3. Debugging) z" @& h% W! L; b. @/ {6 M* D" @
--------------
- t$ D, g" U- Z& |% o, ]$ v' L0 l" Z9 h; U0 A% W* G5 l, ~( S6 @
debug
" M. P0 }- R& U6 p# P$ [  Enables debug mode which dumps to stdout all exchanges, and disables forking" {/ ^: V+ z; a, O/ w. T
  into background. It is the equivalent of the command-line argument "-d". It2 V/ B! b$ k: r# d
  should never be used in a production configuration since it may prevent full
8 M# l/ T/ b% Y) @9 q. Q  system startup.
  `" x& W, v: J: p6 N, t- l; e2 k' s! J# Y1 T1 R
quiet' l1 b8 X7 G/ K: B
  Do not display any message during startup. It is equivalent to the command-
4 u. N3 Z/ V. I9 `- s; k  line argument "-q".
# f7 V% Z6 i6 O9 @8 X) v5 w4 G) m% j" _: S+ z3 t
3.4. Userlists0 L# Z8 l5 ]+ A8 T
--------------: u8 E3 G- f$ h9 E* t- y, ]
It is possible to control access to frontend/backend/listen sections or to
1 o; z4 {( v1 m5 whttp stats by allowing only authenticated and authorized users. To do this,
# e! D. s" j4 t2 m  q, e; tit is required to create at least one userlist and to define users." u9 h: ]0 w  R& k+ O" R; j6 D
" P" c! S9 q2 P9 }& |$ ^  c" u& c2 k
userlist <listname>
  I3 Y1 }6 J; X: C  m  Creates new userlist with name <listname>. Many independent userlists can be4 r4 a/ I4 W4 v  [' Y, g/ B+ k
  used to store authentication & authorization data for independent customers.! @& E3 P' |# t7 ]$ ?& C( p
( B5 [2 t, E1 j+ p
group <groupname> [users <user>,<user>,(...)]
' i& B, S$ f" z: r: v2 R  Adds group <groupname> to the current userlist. It is also possible to* L& i5 Y2 U1 j  A: l# Q1 b
  attach users to this group by using a comma separated list of names6 r8 r  O, ^- n8 s, t
  proceeded by "users" keyword.
3 p; ^) t5 q. c2 I- \9 f3 w" ?% g7 a4 N7 j2 E
user <username> [password|insecure-password <password>]( T5 F4 Z/ h# s. p
                [groups <group>,<group>,(...)]5 K  x- K: h. \% y3 R* ]
  Adds user <username> to the current userlist. Both secure (encrypted) and
: @1 V) q9 P! ?5 v$ W  insecure (unencrypted) passwords can be used. Encrypted passwords are# P) s+ _" S+ I+ m( _( z/ y
  evaluated using the crypt(3) function so depending of the system's0 {. B; x& j6 k9 i1 d* ]5 D0 `
  capabilities, different algorithms are supported. For example modern Glibc7 ]/ J. X8 c2 O/ c# q
  based Linux system supports MD5, SHA-256, SHA-512 and of course classic,8 M: c! d" y& U3 r1 g
  DES-based method of crypting passwords.# t- `, H8 _$ c7 Y# ~
4 O9 X4 }* i) S/ R% C  F7 C: D

* r7 y) {" `5 L4 E/ }  Example:8 Q2 [+ b+ \# p) M! h
        userlist L1
* z- d8 K) [2 \) `$ w          group G1 users tiger,scott
# ]2 S/ F6 a5 \0 c+ N7 I" W/ M" ?          group G2 users xdb,scott
9 v# U3 B! ~' f; n6 q; F+ ^. S
          user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91, t+ H" d& V5 M: E
          user scott insecure-password elgato
5 c/ N( [, w5 x# `0 w          user xdb insecure-password hello- ~5 O! m. B  J
( K: O0 b$ m+ I( F8 b
        userlist L2
% X  i: V2 j8 G. m          group G1. u  g6 ?8 p6 O$ M- s; N5 \
          group G2. N+ D  ^* c+ S. E8 T! Q

) u0 p$ `+ O8 r5 s2 u          user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1$ _1 z2 o+ g- G6 H  u
          user scott insecure-password elgato groups G1,G2% f4 `) d4 m7 a. F/ B/ w5 }
          user xdb insecure-password hello groups G2
* |1 q* I% ~+ }4 }, r6 g2 Y9 N- l/ e1 L2 n1 P5 ^4 i2 |$ t
  Please note that both lists are functionally identical.
- `6 U' o# n* K' e
5 V+ p# r1 s% S/ ^( R8 S: R4. Proxies
3 \, g! g! m: P0 u----------
0 B* y* D/ r) W8 @* ]; u" e
0 @, t! S. S. V- k. |$ ]Proxy configuration can be located in a set of sections :; q! c  t3 B& J& W' I
- defaults <name>& Z) c8 p0 c$ @3 R. |
- frontend <name>
, `" X& z# J7 O2 I - backend  <name>' w. f0 c% K+ A9 n, g& O" Y$ c6 d
- listen   <name>" Q  G+ w8 T4 d$ K0 H- S3 g

1 V$ O: d0 R  Q: D  l: P. ~8 XA "defaults" section sets default parameters for all other sections following; ]1 ~% y% {+ P# Y5 z
its declaration. Those default parameters are reset by the next "defaults"+ Y1 l$ E& {0 I
section. See below for the list of parameters which can be set in a "defaults"3 g' F9 a3 e& T9 V2 v2 c4 s% |* V, p0 {
section. The name is optional but its use is encouraged for better readability.3 C% |$ N! P  M5 S* b$ O
- |# u4 D7 ~# P/ L1 N& ^
A "frontend" section describes a set of listening sockets accepting client4 ^, N( L2 O, w4 E+ x: t" g1 Z+ U
connections.
6 k1 v8 z" W& u% F9 b3 a. |9 y
/ @- _6 w4 N0 i  R5 u3 B+ N7 HA "backend" section describes a set of servers to which the proxy will connect
6 a) H' }+ Y' N; |* f" W2 Eto forward incoming connections.! ^4 A* J, n, `0 M6 ~( _4 N

1 w+ ?2 Y0 K* o* Q2 eA "listen" section defines a complete proxy with its frontend and backend
* U+ o' h( ^1 n! I* [/ Y, Tparts combined in one section. It is generally useful for TCP-only traffic.
% R5 e3 ?6 }7 d2 a! H( `9 j2 ^& Z8 J2 f9 `* H0 q8 w" J7 f- @7 t
All proxy names must be formed from upper and lower case letters, digits,( F/ t# v% @! g# d. E
'-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are
# N2 S, ]$ c' ~0 T# N0 h5 T# M* Dcase-sensitive, which means that "www" and "WWW" are two different proxies.! d( g' \% p7 Y

& c& c: ?9 ?; Z4 v/ q' z! {0 lHistorically, all proxy names could overlap, it just caused troubles in the
! g, C  u# Y, P" w! S- {$ Mlogs. Since the introduction of content switching, it is mandatory that two
* f, t1 z- O) ]/ I$ H- K9 Mproxies with overlapping capabilities (frontend/backend) have different names.
% {) n+ c/ ~$ hHowever, it is still permitted that a frontend and a backend share the same- K5 l3 u' M, a. ]0 i( O
name, as this configuration seems to be commonly encountered.0 V% l6 M& E. w0 t/ S$ d
1 u9 l3 W: D. g
Right now, two major proxy modes are supported : "tcp", also known as layer 4,
5 j( U! E6 w# q; v! \7 h* rand "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards
% A  I9 e3 w( Cbidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the
. ~/ v  `7 a6 lprotocol, and can interact with it by allowing, blocking, switching, adding,
8 T. U% C, i# [4 N! K; F/ d# Imodifying, or removing arbitrary contents in requests or responses, based on
- @  K0 d" L2 T: z9 qarbitrary criteria.% v1 n. b6 G2 D& w

! H( _) S- J; D/ d7 v4 ]/ Z/ ^$ i% H3 r2 o
4.1. Proxy keywords matrix! C* }  z3 V+ b7 l& l7 K
--------------------------# m( ~' e. y: N; h' K) F

1 f! H7 p8 Y, ~6 U* l) S3 b5 ~The following list of keywords is supported. Most of them may only be used in a
$ i) N3 G# j- ?' J0 ~% W& Vlimited set of section types. Some of them are marked as "deprecated" because
( W8 M- Q# M& }( W! nthey are inherited from an old syntax which may be confusing or functionally9 A0 s; r* u8 q0 X# H3 _; p
limited, and there are new recommended keywords to replace them. Keywords
- O; U. |( y- C1 u! Nmarked with "(*)" can be optionally inverted using the "no" prefix, eg. "no
% U8 J7 B8 `6 W# moption contstats". This makes sense when the option has been enabled by default
% D( K2 W4 [' `8 v9 C+ f6 T4 ^and must be disabled for a specific instance. Such options may also be prefixed  }% H$ ^( l- R8 Y! L" ?* F3 b( p% t  R
with "default" in order to restore default settings regardless of what has been
# R/ F+ g( u; p: K! p4 ^8 tspecified in a previous "defaults" section.
' d8 ~6 O" G6 F  O  y( S& e1 G6 v7 }. x7 G$ p: F3 r/ @
2 m- z4 s# r* r# @) k
keyword                              defaults   frontend   listen    backend
, c- \% N1 j7 E/ }+ R, ~1 S  Y------------------------------------+----------+----------+---------+---------9 q0 j, A9 v3 D2 f) t  r4 B5 Q
acl                                       -          X         X         X
6 O2 k$ _/ M: e0 o+ G6 A- c, vappsession                                -          -         X         X
- }- ^# G7 W6 G/ D7 c& fbacklog                                   X          X         X         -3 e: s, p' H! U/ [
balance                                   X          -         X         X
& h/ T+ T- |  k; O) S1 n) |! fbind                                      -          X         X         -6 g* `  U" n- g4 r1 i: {) T9 }
bind-process                              X          X         X         X
5 J; T! |" T! K/ Yblock                                     -          X         X         X' F: J" ^( j, v+ w, w4 p+ [  }
capture cookie                            -          X         X         -
- e$ K. y. r: rcapture request header                    -          X         X         -
4 S) h# N0 Y+ W) M$ j9 S5 Fcapture response header                   -          X         X         -2 ^% f! `( Z# I8 M; M! m2 c
clitimeout                  (deprecated)  X          X         X         -) w. W( k( d0 I
contimeout                  (deprecated)  X          -         X         X6 \# `! [' c7 K% O! w8 V) T* @
cookie                                    X          -         X         X
- t  G6 }3 D$ h* h; Kdefault-server                            X          -         X         X
1 @1 C7 v" A* C6 E) ^5 g4 |default_backend                           X          X         X         -
% U* q2 x, q+ S' tdescription                               -          X         X         X
4 M% n6 E! F- u  o- {disabled                                  X          X         X         X7 V) [" v* D' P4 D( U5 N
dispatch                                  -          -         X         X( H2 v: ~% S, E) D0 m  K  ~2 r
enabled                                   X          X         X         X" O8 |% K+ C) I8 f* U; P4 l1 k
errorfile                                 X          X         X         X( c) ^, @- s# B1 Y) b0 V9 L
errorloc                                  X          X         X         X8 l! [( G+ Y/ }' C2 I  ^0 U" c
errorloc302                               X          X         X         X- y# _8 [3 ^6 [& X
-- keyword -------------------------- defaults - frontend - listen -- backend -2 [, p( _7 t; w1 [/ _
errorloc303                               X          X         X         X$ `( d/ V* l. g1 M( W. y
force-persist                             -          X         X         X7 i! _! \8 x1 X4 e# I* {
fullconn                                  X          -         X         X; V& k. n- v( F( N: o( ~' ]
grace                                     X          X         X         X8 l% _4 D& {/ P( f6 S8 G, n
hash-type                                 X          -         X         X  b2 M+ K! q% T3 B, d
http-check disable-on-404                 X          -         X         X
! F0 N  l% ?: x. S; S  I0 i; Jhttp-check expect                         -          -         X         X
: `3 k9 B  F3 z; q. H6 [http-check send-state                     X          -         X         X
* u6 ?/ E1 Y; z  X0 Y! g$ H  d9 p+ Qhttp-request                              -          X         X         X
2 ]0 D/ H6 |- r2 ?, did                                        -          X         X         X
4 f* X# j3 k: D0 F  U, K/ A/ [ignore-persist                            -          X         X         X
/ F3 }. ^% n! g' d# _* N6 elog                                       X          X         X         X! _- C3 `( {) T3 c. @
maxconn                                   X          X         X         -" U  O$ `; B! ?
mode                                      X          X         X         X" I6 J+ F6 J9 S  n. e
monitor fail                              -          X         X         -- @# w/ {  {" h% @
monitor-net                               X          X         X         -
8 @6 a1 g; X8 a1 Omonitor-uri                               X          X         X         -
# v- g" f0 `1 A; [  L# p5 ?option abortonclose                  (*)  X          -         X         X; B0 k* Z+ Y0 E5 R. |' t# h
option accept-invalid-http-request   (*)  X          X         X         -
3 T$ Y4 t3 g* Q* ?option accept-invalid-http-response  (*)  X          -         X         X0 G$ d% _; y' l; A6 |/ [$ `7 w
option allbackups                    (*)  X          -         X         X3 M9 f. Z# W9 u; c
option checkcache                    (*)  X          -         X         X6 ~2 d. l; K9 y- v5 @
option clitcpka                      (*)  X          X         X         -$ |; T7 P9 R* F  e* t, B
option contstats                     (*)  X          X         X         -
6 }2 V& O+ A. @3 \option dontlog-normal                (*)  X          X         X         -
4 u, }! T2 V( q( j1 Joption dontlognull                   (*)  X          X         X         -7 w$ a5 ~' i! _* ]: ^- F4 ?
option forceclose                    (*)  X          X         X         X: N3 V! w! A3 O' z; ?
-- keyword -------------------------- defaults - frontend - listen -- backend -
" U& b+ F- P9 H8 f# }3 r; y! aoption forwardfor                         X          X         X         X
4 x! a! u. L. `option http-no-delay                 (*)  X          X         X         X. ^: |6 L( Y1 I+ G+ t+ i9 h
option http-pretend-keepalive        (*)  X          X         X         X
. b7 K# Q! n0 s7 Z( H3 W( Zoption http-server-close             (*)  X          X         X         X
2 [4 U: c8 b8 j; `option http-use-proxy-header         (*)  X          X         X         -
5 U% `4 N8 j' G& N- \. `option httpchk                            X          -         X         X- a  F8 \$ L! V3 ]% W% `8 \2 p
option httpclose                     (*)  X          X         X         X
9 E9 W! v3 M+ V$ V" X' \; Z8 `6 S! [option httplog                            X          X         X         X5 S' C/ ?) E/ H+ r
option http_proxy                    (*)  X          X         X         X
+ @$ }0 d3 i  D( c  {1 poption independant-streams           (*)  X          X         X         X
8 X0 D6 |" k# V$ ioption ldap-check                         X          -         X         X
' I2 p2 j9 l* s9 _% Q. s4 h% t9 coption log-health-checks             (*)  X          -         X         X  j( R( \- p3 K- u% h+ i
option log-separate-errors           (*)  X          X         X         -; U# L. W6 E/ k0 l
option logasap                       (*)  X          X         X         -
3 Y7 Q. @1 a3 b. Q, d8 hoption mysql-check                        X          -         X         X
0 K' r$ j' n7 k2 X& C0 j; i/ D# voption nolinger                      (*)  X          X         X         X
$ E& ^3 q' @0 Y( o6 Toption originalto                         X          X         X         X) K: P4 e3 K: w) g
option persist                       (*)  X          -         X         X  G! }# X7 |( @
option redispatch                    (*)  X          -         X         X/ m8 Y* Y+ t- [
option smtpchk                            X          -         X         X3 H* b, a/ {3 }, G* {
option socket-stats                  (*)  X          X         X         -
- n, r% }& h5 b3 a& M+ g6 E6 ^) coption splice-auto                   (*)  X          X         X         X
: A1 g7 A* M* w& Q; P5 _option splice-request                (*)  X          X         X         X
  c3 N+ y  `+ h$ ^, Zoption splice-response               (*)  X          X         X         X
# L: `% r; x# f: t3 p9 C2 i6 xoption srvtcpka                      (*)  X          -         X         X
6 y* ~" \$ g4 x( W3 Xoption ssl-hello-chk                      X          -         X         X6 |8 w7 D  @2 F# E, `
-- keyword -------------------------- defaults - frontend - listen -- backend -
  I2 h, H& {9 O, q8 Q+ }4 doption tcp-smart-accept              (*)  X          X         X         -
. ^1 i, Q- m* \. z1 J) moption tcp-smart-connect             (*)  X          -         X         X4 H: d5 c6 E1 q9 O' ]+ l* z
option tcpka                              X          X         X         X8 C1 r2 W4 W; O- A9 G# L9 X
option tcplog                             X          X         X         X: B) t6 {( W! j: b# Z( ]
option transparent                   (*)  X          -         X         X
" J3 R( Y  b, r4 @persist rdp-cookie                        X          -         X         X
  f* J- \& ]% r9 Q7 @, a  {3 Q  k( prate-limit sessions                       X          X         X         -* p5 R2 ]: L- B# l# E! d0 {
redirect                                  -          X         X         X9 y' K) g/ v7 J) a/ r: P: j. `
redisp                      (deprecated)  X          -         X         X% ?! ?' ]  e: g1 K2 ~+ g
redispatch                  (deprecated)  X          -         X         X
' B6 H- u% d3 {9 Ureqadd                                    -          X         X         X
! Z% I9 m# j2 [: S6 g) Yreqallow                                  -          X         X         X
+ f+ c0 ?& I' i& Rreqdel                                    -          X         X         X3 B' O5 u' @3 u: @+ V+ B  u
reqdeny                                   -          X         X         X
6 G# T6 M* U6 P8 a  freqiallow                                 -          X         X         X: l7 }* `9 Y  i/ t9 s' Z
reqidel                                   -          X         X         X5 J6 r  n% h0 E" h: U
reqideny                                  -          X         X         X
- Z- y0 b! i3 ?- Creqipass                                  -          X         X         X
- E3 ~, w3 H7 b( \6 M9 ^reqirep                                   -          X         X         X7 S/ o% q7 _' }9 E# C
reqisetbe                                 -          X         X         X
4 O) C+ m, }3 K5 b/ a+ J- nreqitarpit                                -          X         X         X6 v. E1 C" g9 `/ N: u2 g& @1 ]
reqpass                                   -          X         X         X
9 R& N8 |1 d: l( j  \( v( x' w8 u! _reqrep                                    -          X         X         X
2 Z8 E6 s9 M1 e# K/ Q! C$ f# j-- keyword -------------------------- defaults - frontend - listen -- backend -
$ f9 `9 m  d8 U7 _' x/ rreqsetbe                                  -          X         X         X4 n! e  V7 Z+ b0 x% l1 e( N; U# d
reqtarpit                                 -          X         X         X4 j: m& G- v- c+ W5 W2 {& F
retries                                   X          -         X         X
' N1 W; s+ r# X; h' Erspadd                                    -          X         X         X
, w" Y( K2 W* v) ]# E* @  ?1 mrspdel                                    -          X         X         X7 z! n9 \% `, L
rspdeny                                   -          X         X         X
0 x3 u5 s4 i6 w7 vrspidel                                   -          X         X         X- p4 O+ b# L9 v
rspideny                                  -          X         X         X, o/ Y0 |5 p7 V; j+ D9 _7 n
rspirep                                   -          X         X         X; W3 N- h! r" [3 g3 Q
rsprep                                    -          X         X         X
2 i+ h5 E, m2 ~: f9 I; G5 kserver                                    -          -         X         X
# `, q6 q+ H4 P" S& Xsource                                    X          -         X         X
. v# e7 c/ {+ B* D3 Y$ D: c. o! usrvtimeout                  (deprecated)  X          -         X         X
9 Y2 C: T4 F$ v. d, W; i/ Kstats admin                               -          -         X         X
" H0 B8 m7 N5 o5 wstats auth                                X          -         X         X
& Y# p8 a3 G/ k( [stats enable                              X          -         X         X
. Q) |: C/ B" zstats hide-version                        X          -         X         X; D# e% ]% {% g! C& e, `% A* N
stats http-request                        -          -         X         X+ s" V3 Q& b* v/ z: {) U( {
stats realm                               X          -         X         X
+ o7 m& R* V( x& j' Nstats refresh                             X          -         X         X
  j9 \$ X8 v7 T, R4 istats scope                               X          -         X         X. m* b1 Z( ~7 ]' j, B
stats show-desc                           X          -         X         X  ~6 l0 p; }) G) K( {
stats show-legends                        X          -         X         X  G5 B- E+ G2 f7 V8 h5 b+ F  t( s$ U
stats show-node                           X          -         X         X
) B3 K6 g4 i& s, V  Jstats uri                                 X          -         X         X& I, {4 _2 h: t6 T
-- keyword -------------------------- defaults - frontend - listen -- backend -
) l6 [4 ?) N9 [0 S& p+ @stick match                               -          -         X         X
5 H  ?, Q2 N  V0 c  }! Hstick on                                  -          -         X         X& i9 d4 d8 n) P
stick store-request                       -          -         X         X
" @6 R( ]: X' b. ~5 V! vstick-table                               -          -         X         X) L; t. k# a8 U0 o& s
tcp-request content accept                -          X         X         -
- c3 J, i( [& ~; O4 {( Itcp-request content reject                -          X         X         -0 s, K" N( b' w8 B# m  u
tcp-request inspect-delay                 -          X         X         -
0 Y; ?$ z, H+ [$ ^5 ptimeout check                             X          -         X         X: v$ w$ A0 P0 f  ]
timeout client                            X          X         X         -+ u7 \' n6 I0 z7 x: T2 b
timeout clitimeout          (deprecated)  X          X         X         -5 `/ j) W+ Q- v9 k4 I" G' u( v5 I/ b
timeout connect                           X          -         X         X
+ z2 {, h4 ~/ h5 e" {" vtimeout contimeout          (deprecated)  X          -         X         X
5 L* M7 }( G" n' C, o# J8 Y1 |8 y+ Ztimeout http-keep-alive                   X          X         X         X; p+ w3 _7 G( V( s& I! K" n8 B( W
timeout http-request                      X          X         X         X2 C% _( [( d, k5 j8 Y
timeout queue                             X          -         X         X
' {+ S! x' Y+ ~+ m7 d$ ^6 w% R+ w/ {5 Htimeout server                            X          -         X         X
; q( j. J3 M  M3 qtimeout srvtimeout          (deprecated)  X          -         X         X2 V( ^+ s4 G; {+ q: w' w
timeout tarpit                            X          X         X         X
  J8 t( ^. `- [' u1 M7 ~/ T9 ntransparent                 (deprecated)  X          -         X         X2 l9 V, G" R& F7 U( d1 _8 L
use_backend                               -          X         X         -/ I6 n. _6 R/ B# Q. b5 V# B
------------------------------------+----------+----------+---------+---------! p; J: R$ U  K2 F8 b* ~' c
keyword                              defaults   frontend   listen    backend
* F4 h0 w2 o3 D" |6 w! N& f3 j3 o
, c! }$ G, |/ e' ~
; R9 ^6 P) y' `, K$ M3 v4.2. Alphabetically sorted keywords reference  f1 o3 C% Z4 n! x6 X% [/ i
---------------------------------------------
! E( G( [& @+ n1 h$ Z8 f4 q+ ]- d- A( s5 T
This section provides a description of each keyword and its usage.
% P2 \+ Y: [2 V" R: |
* i9 e; P6 u$ Y- h2 b' e
2 l7 Q+ o% b$ H& Q' Oacl <aclname> <criterion> [flags] [operator] <value> ...5 X- l. J% L3 b# v8 q2 c
  Declare or complete an access list.- P! C/ n0 l- _0 V
  May be used in sections :   defaults | frontend | listen | backend+ N; g, g  z  w. ~9 D- j
                                 no    |    yes   |   yes  |   yes, \9 S, s% n; z6 Z  F
  Example:" b6 V$ S+ \  P$ o- u4 z% H2 I6 B3 K
        acl invalid_src  src          0.0.0.0/7 224.0.0.0/38 @( y! R& o% D1 i$ N/ k
        acl invalid_src  src_port     0:1023
1 B9 U+ I+ M3 C- A& ]        acl local_dst    hdr(host) -i localhost
1 p8 y# z6 h; Y2 T3 T/ Y( F* I
: p2 t6 Q0 P2 M$ v, r, {0 f  See section 7 about ACL usage.
) q2 ]" R6 V  V8 N
3 I8 v2 ]% Y) `
' {3 b! A% M# t9 p5 B# `3 Bappsession <cookie> len <length> timeout <holdtime>
& {: d" [+ i7 D4 y           [request-learn] [prefix] [mode <path-parameters|query-string>]
9 b3 }3 b* O  g. {8 x3 m; Y5 W  Define session stickiness on an existing application cookie.
3 m/ p# `: x2 K  May be used in sections :   defaults | frontend | listen | backend
& b2 B' _6 W, P' ^0 E- }- Y                                 no    |    no    |   yes  |   yes
; b* ?4 y6 ]# j4 Q! K0 X2 K  Arguments :
# U$ V2 X7 O0 ^    <cookie>   this is the name of the cookie used by the application and which! A7 W0 K) f+ ?( s0 g- |
               HAProxy will have to learn for each new session.
% Z- f. _+ y$ n! U# e
4 g' C& W( n+ I/ q8 ^2 q    <length>   this is the max number of characters that will be memorized and
% {% q! U, ~' h1 O# e; a: ?% V               checked in each cookie value.
4 c0 a3 x9 O6 I% X
7 c+ q& p6 u, f  I    <holdtime> this is the time after which the cookie will be removed from" k/ \( F' u0 U
               memory if unused. If no unit is specified, this time is in- b3 o2 y; W; n0 |$ c0 k
               milliseconds.' ^7 ?; h: Y7 x2 _
4 o5 p, n9 {1 ^1 x& H% Q4 O- l
    request-learn! X. U, k3 J* R% Z
               If this option is specified, then haproxy will be able to learn
* H/ Q- `4 O% g               the cookie found in the request in case the server does not
* U" V% o2 A2 W+ |( `               specify any in response. This is typically what happens with
( N. q) {, Y: f1 X9 e4 g3 @! @& n2 ~               PHPSESSID cookies, or when haproxy's session expires before! {3 u% {* M8 M' q, H, T8 x
               the application's session and the correct server is selected." G, j: o' ^  s  s2 t7 X/ e# L3 s& v
               It is recommended to specify this option to improve reliability.
& j/ M4 o1 ~2 `* [8 f, M# Y! w3 C" d
    prefix     When this option is specified, haproxy will match on the cookie
* @( m! c1 l7 S7 o               prefix (or URL parameter prefix). The appsession value is the
6 p, Y0 Z! C; q; W) f6 w2 r: }               data following this prefix.
1 r  B2 `9 P+ W, c9 M- P2 F
0 R# x/ l5 r* F- w+ W               Example :
8 R: t: H4 Y! H& ?( V. J' M               appsession ASPSESSIONID len 64 timeout 3h prefix& p* H2 q3 A6 _, q3 i' c0 W( z' u

: p5 E. x/ d% n; s. n5 V% o               This will match the cookie ASPSESSIONIDXXXX=XXXXX,
) X; C) K6 b& E, S2 d" ~: z) T               the appsession value will be XXXX=XXXXX.* j# N0 ^2 H4 m- F* I! Q

$ y1 v# K) A5 A8 k* I" W    mode       This option allows to change the URL parser mode.
4 t, e- J! {+ P# p$ E& I               2 modes are currently supported :( `4 V9 H- R! q5 M$ T( d
               - path-parameters :  u1 \2 f1 i; x. w
                 The parser looks for the appsession in the path parameters
! Z- ~& B$ y* p                 part (each parameter is separated by a semi-colon), which is
6 y% ~" L/ O( W- U+ y! D% c                 convenient for JSESSIONID for example.
' y; s3 }# S5 b! F                 This is the default mode if the option is not set.1 y) V1 T5 I2 M/ p) z
               - query-string :
& W% r' R: Z! b' Z: b- l                 In this mode, the parser will look for the appsession in the+ u' @9 d1 u" e% {8 u
                 query string.2 F+ I! b2 u/ l3 ~6 S9 n
& d) w! `' i1 r- U& ^2 K$ j3 e" V1 e
  When an application cookie is defined in a backend, HAProxy will check when
( J6 d. r4 p9 K5 ?  the server sets such a cookie, and will store its value in a table, and5 H+ [# G& a& c. D* y
  associate it with the server's identifier. Up to <length> characters from
1 `; {/ P( X& j: I' @5 s, _  the value will be retained. On each connection, haproxy will look for this* S. @; ~& |4 [: d  J& B
  cookie both in the "Cookie:" headers, and as a URL parameter (depending on% p6 H% f- b/ _  b: U: U
  the mode used). If a known value is found, the client will be directed to the
/ H! e8 v# F, P5 K4 e( Q  server associated with this value. Otherwise, the load balancing algorithm is
- [! X+ x6 h# k8 z! p  applied. Cookies are automatically removed from memory when they have been: B. N  U5 {6 J. K
  unused for a duration longer than <holdtime>.( p1 l' p( @9 W! ?4 m

4 o! W* s8 \9 k/ @8 s/ T6 Q  The definition of an application cookie is limited to one per backend.# X! Y0 S/ ]/ |0 x; P/ P

) N2 K$ t2 p" ?* ^: `  Note : Consider not using this feature in multi-process mode (nbproc > 1)
" L3 A+ u. \6 X         unless you know what you do : memory is not shared between the& \, S' t5 p1 L0 w, T1 `5 [
         processes, which can result in random behaviours.! I$ l/ c0 o( `% J# K5 W3 H

' J+ u8 Q2 G( z' D9 h; ]$ \2 C( M  Example :
' Z: ~0 C0 B# r7 l" K        appsession JSESSIONID len 52 timeout 3h
# i7 G: u/ v' G+ N3 A& r: ^/ m. u1 W# n/ Q
  See also : "cookie", "capture cookie", "balance", "stick", "stick-table",
( m! r% r- l* C6 ~. \" H3 I             "ignore-persist", "nbproc" and "bind-process".
2 Y5 h/ P% A- q% L4 j/ p$ m% _* |# f3 @6 r" s! J" n5 J: K  C1 B

8 ^4 K5 ~: N0 T: S" `7 x/ bbacklog <conns>9 h6 l$ a( U0 t! V( v9 E# c
  Give hints to the system about the approximate listen backlog desired size( V( e2 Q5 n4 t+ F5 t
  May be used in sections :   defaults | frontend | listen | backend5 a# f2 n$ O8 V* f
                                 yes   |    yes   |   yes  |   no0 Q0 [$ u* J. _$ [. \+ i+ G1 |
  Arguments :, v" N: a, Z# u  W
    <conns>   is the number of pending connections. Depending on the operating2 O0 g: C, @3 r# P' |' e' J& |% n
              system, it may represent the number of already acknowledged
- p0 U, ~' I( M4 L              connections, of non-acknowledged ones, or both.* P* g, E( B: I
' b8 c2 f! U, ]
  In order to protect against SYN flood attacks, one solution is to increase
" ]9 I6 T: f, s; Z9 i7 _  the system's SYN backlog size. Depending on the system, sometimes it is just
& a/ |( B+ x# u6 Z4 \; {' _) g  tunable via a system parameter, sometimes it is not adjustable at all, and) o) v- b4 v5 r/ ^7 ]* U4 c. {
  sometimes the system relies on hints given by the application at the time of
$ _2 _8 ]$ P4 \2 e6 S: u  the listen() syscall. By default, HAProxy passes the frontend's maxconn value
: ^2 T+ S# p$ N: p7 H  to the listen() syscall. On systems which can make use of this value, it can9 ]/ N2 A$ `. x5 S8 o
  sometimes be useful to be able to specify a different value, hence this6 L0 x+ r+ L+ d  O% i5 P
  backlog parameter.9 ]+ C: X. f$ c  Q4 J

4 x1 p: E6 Y0 V* Y( q7 u  On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is
* J; J' q2 w, e. ^) Z: B  used as a hint and the system accepts up to the smallest greater power of: F$ Q  H6 \! r8 j: t% S  N
  two, and never more than some limits (usually 32768)." H& e9 N- ~/ T  [. X5 u

6 H( V) w- h# ^1 w7 }  See also : "maxconn" and the target operating system's tuning guide.
1 A7 p6 J# H+ C" b- v9 t! @* d4 y+ Z0 F; W3 a6 R- W- S( ], S& z% @

) N! Y! g. O+ Hbalance <algorithm> [ <arguments> ]
  c  U: A* y" |$ c8 _  jbalance url_param <param> [check_post [<max_wait>]]0 Z. ~. g2 w. Y3 n7 _
  Define the load balancing algorithm to be used in a backend.
0 d) V5 F2 F; X% T8 S  May be used in sections :   defaults | frontend | listen | backend4 L7 M: @, W3 x6 w
                                 yes   |    no    |   yes  |   yes
, L0 E: @! P0 v6 H  x5 b: {/ B% u  Arguments :
# C/ r" l$ N# V    <algorithm> is the algorithm used to select a server when doing load: q6 j4 m& ?0 r: N- v, l5 g
                balancing. This only applies when no persistence information/ v3 O7 y& b7 p  M. h
                is available, or when a connection is redispatched to another
  h) k# A/ u$ q  \- ?                server. <algorithm> may be one of the following :
8 P# m  _6 A- R- I. }0 E. @+ p7 N, ]
      roundrobin  Each server is used in turns, according to their weights.8 T& m. @4 {& Y5 |. m
                  This is the smoothest and fairest algorithm when the server's- s) w3 S8 S  j5 W! E
                  processing time remains equally distributed. This algorithm
; R( g4 f; o' S                  is dynamic, which means that server weights may be adjusted
* B. S: E. p9 u9 _                  on the fly for slow starts for instance. It is limited by; A7 B' L' j) ^( r: E4 B1 B8 s5 n
                  design to 4095 active servers per backend. Note that in some
5 g* c  O# f' F% ?0 m                  large farms, when a server becomes up after having been down
9 ^* o) `& a3 n( e1 I                  for a very short time, it may sometimes take a few hundreds# T' A( F) z0 g7 e- o
                  requests for it to be re-integrated into the farm and start
0 V  R; M# Y9 g) w7 c                  receiving traffic. This is normal, though very rare. It is( V) s5 @: L& f) ^1 i0 D
                  indicated here in case you would have the chance to observe
* l6 s" m8 l0 S7 j                  it, so that you don't worry.8 ]" w1 n* H% b: e* N, N
5 A8 ^4 W5 c0 u$ n5 g
      static-rr   Each server is used in turns, according to their weights.- |. |$ I/ d: w
                  This algorithm is as similar to roundrobin except that it is0 y" {( S$ `4 M+ P' B, U" ~- U
                  static, which means that changing a server's weight on the
' T$ O$ o. e* `' Q: _5 y6 r                  fly will have no effect. On the other hand, it has no design
$ C% L1 {% v' w3 f. ^7 B, U                  limitation on the number of servers, and when a server goes
9 x! `( Y# G6 G7 L" B                  up, it is always immediately reintroduced into the farm, once
' W) Z+ }, {% U$ a$ u2 k/ v                  the full map is recomputed. It also uses slightly less CPU to1 l9 f" ^' h! E) l. y' }: a
                  run (around -1%).
# O; @3 Z- U- L) O! x2 j0 F5 C+ D4 `5 ^
      leastconn   The server with the lowest number of connections receives the  I% O6 x# l6 J+ e" Q# Z& t+ h
                  connection. Round-robin is performed within groups of servers
2 o- y7 C; o0 n" m. l                  of the same load to ensure that all servers will be used. Use6 u2 B; c- l5 k& q3 G- ~* M
                  of this algorithm is recommended where very long sessions are
8 R! m  C$ @* D; ?                  expected, such as LDAP, SQL, TSE, etc... but is not very well
9 C# x) o+ s4 n$ W; Y+ T) y                  suited for protocols using short sessions such as HTTP. This- Y. a# _2 t+ y. }7 k8 D0 o$ z
                  algorithm is dynamic, which means that server weights may be
% y5 A4 u$ t2 ?: {/ d                  adjusted on the fly for slow starts for instance.; ~0 h2 f5 ?  T

  i4 p! ?; d9 D0 M4 y8 V: h  ~      source      The source IP address is hashed and divided by the total4 v0 \3 F, U' }% _& p
                  weight of the running servers to designate which server will. k. R; v; b2 }4 w1 i: @" a
                  receive the request. This ensures that the same client IP
3 k& \5 J9 D4 z# d2 \                  address will always reach the same server as long as no% @. n+ ^: ?" |/ u; t- i& [0 r
                  server goes down or up. If the hash result changes due to the5 \% v+ [# d/ L: a2 |8 B% Q
                  number of running servers changing, many clients will be
9 o; Z' e  T" _3 U8 Y% N                  directed to a different server. This algorithm is generally# y1 V/ f4 A8 |
                  used in TCP mode where no cookie may be inserted. It may also1 I* j3 \9 N; l1 w
                  be used on the Internet to provide a best-effort stickiness
0 u) P8 v4 {/ q& Q* f- J6 G                  to clients which refuse session cookies. This algorithm is
% h4 H( H' n, g* @1 {+ e/ G                  static by default, which means that changing a server's
+ ]2 T* V5 ~- \5 K; v/ M+ L3 o9 h                  weight on the fly will have no effect, but this can be4 m3 N" N" k. B" M& D
                  changed using "hash-type".
8 J, \1 x2 t* G3 \* u$ M# R2 I1 M% f; H
      uri         This algorithm hashes either the left part of the URI (before) J1 B: G( p- I7 t! t9 H
                  the question mark) or the whole URI (if the "whole" parameter7 I# _" T9 A  ^9 {" [
                  is present) and divides the hash value by the total weight of6 ?, y* L6 v7 M* o6 I
                  the running servers. The result designates which server will) @4 h2 M$ c4 k; K9 c0 y
                  receive the request. This ensures that the same URI will2 T6 ?  Y" `% `% }3 D
                  always be directed to the same server as long as no server
% ]1 v1 E1 L- V, }6 {. z8 B                  goes up or down. This is used with proxy caches and; L5 N" f. f' o5 O5 w( e
                  anti-virus proxies in order to maximize the cache hit rate.
4 I! N$ T6 C) ~6 m  \                  Note that this algorithm may only be used in an HTTP backend.# E  x8 E9 s- }' k7 b8 [1 m/ Z
                  This algorithm is static by default, which means that
1 y6 p' o7 _4 F7 ^4 {) d3 b                  changing a server's weight on the fly will have no effect,7 f: w& }. @$ Z! i7 m- [
                  but this can be changed using "hash-type".  A! T5 Z( a/ p2 H
1 }" B/ ~0 c) U' h9 @# A/ H; y
                  This algorithm supports two optional parameters "len" and
6 ?2 q% i$ |7 d# C( Z# Z                  "depth", both followed by a positive integer number. These8 R# c, u$ V2 W7 P$ b) b3 Q
                  options may be helpful when it is needed to balance servers1 u. C$ c8 l4 e: n8 }; B
                  based on the beginning of the URI only. The "len" parameter
5 d" W! @% [; Z# o! Z: i- q                  indicates that the algorithm should only consider that many8 B- G5 I2 P; I# L+ D
                  characters at the beginning of the URI to compute the hash.
4 `: o: H+ _* Z1 x                  Note that having "len" set to 1 rarely makes sense since most1 u7 }7 Q  Y% x& R( `% T3 j6 o" T$ b
                  URIs start with a leading "/".
. w3 o6 B7 X# J! C  @, h  Z& F& c
. U) {1 a0 i4 p0 K( C                  The "depth" parameter indicates the maximum directory depth, x" M: Q: ~0 _! E5 H2 N" x9 n( \
                  to be used to compute the hash. One level is counted for each
! a6 w3 F: H6 W: M( J& D# g                  slash in the request. If both parameters are specified, the5 [$ U/ O" Y+ {
                  evaluation stops when either is reached.. h3 M% B  a4 R5 |! K0 [' o2 c, F
4 _3 J6 V7 @4 _
      url_param   The URL parameter specified in argument will be looked up in
# j7 n  ]) `! J7 P2 u- \5 W& x                  the query string of each HTTP GET request.
( F1 u3 x! f( q1 }5 w# A4 ]; p
# j/ ~# n: K( z0 d% @. ^                  If the modifier "check_post" is used, then an HTTP POST
- M$ t" C& x' C, g6 h                  request entity will be searched for the parameter argument,8 O- g) i9 u' u' H& C) J
                  when it is not found in a query string after a question mark
) @' f5 h7 \' G# A+ T2 G; d                  ('?') in the URL. Optionally, specify a number of octets to; ~& h9 r; |1 V& I& D! N% N% G
                  wait for before attempting to search the message body. If the
2 J7 K9 {5 {; R+ _% L                  entity can not be searched, then round robin is used for each; R2 X) I( x9 }# F% A. P# B
                  request. For instance, if your clients always send the LB
2 e% s' B& J% k- }                  parameter in the first 128 bytes, then specify that. The
) T! P4 ?8 i0 L" o                  default is 48. The entity data will not be scanned until the1 ?+ n9 Y( l" E0 h  J7 _
                  required number of octets have arrived at the gateway, this5 _( ?5 ]: `6 `  ^# r
                  is the minimum of: (default/max_wait, Content-Length or first% q8 \& C: Y5 ~/ S. \6 z& i
                  chunk length). If Content-Length is missing or zero, it does+ n; @9 L  u( S0 X( ^
                  not need to wait for more data than the client promised to
5 K9 G% J, E: M, E4 C6 V! K                  send. When Content-Length is present and larger than
3 f& X/ s9 ]+ ~                  <max_wait>, then waiting is limited to <max_wait> and it is  X; l0 M6 m$ d! c0 I- a
                  assumed that this will be enough data to search for the, v+ ]4 r9 ?6 k" ~$ v- ^7 d4 S: [
                  presence of the parameter. In the unlikely event that5 ^* i$ G1 b$ Z
                  Transfer-Encoding: chunked is used, only the first chunk is
3 x* p* j: S5 h" M; G                  scanned. Parameter values separated by a chunk boundary, may+ G. ^$ c# G: |. Z; I9 U4 X
                  be randomly balanced if at all.
6 n/ f6 B& ]: E: f' l; C5 Z4 C. _" w$ d8 e' }& H* e
                  If the parameter is found followed by an equal sign ('=') and
3 X* J. a' d$ g; v. B8 [0 |                  a value, then the value is hashed and divided by the total
+ M, ^$ B$ w1 h3 u+ T' [" M                  weight of the running servers. The result designates which
8 e, @; B# l* A  Z                  server will receive the request.4 Z2 C* O1 I$ z" z# Y" s! D8 {4 A

8 c# [( ?7 Y* k  y% e, Z& O( l: w, f                  This is used to track user identifiers in requests and ensure) w- s5 m: }6 Z, p5 @0 i6 Z6 \
                  that a same user ID will always be sent to the same server as
9 t# g' `2 Y) L9 L2 D                  long as no server goes up or down. If no value is found or if
7 w$ A- Q0 f* S9 J                  the parameter is not found, then a round robin algorithm is# s1 w& a+ I  W# C; @2 \$ O, @
                  applied. Note that this algorithm may only be used in an HTTP9 X4 ~9 J. M! t. E- p: E
                  backend. This algorithm is static by default, which means- f0 J& @' |9 \4 o* V, x' U6 r
                  that changing a server's weight on the fly will have no
0 B1 Q" X2 G0 T5 K                  effect, but this can be changed using "hash-type"., x# c# Z( |) D( \0 j; [5 H

& R9 P& j  g6 x; L! Q; G& c! @      hdr(<name>) The HTTP header <name> will be looked up in each HTTP request.
" I$ W* H" b  G1 r/ `+ X, ~                  Just as with the equivalent ACL 'hdr()' function, the header1 {6 {, t* `4 ?9 Q
                  name in parenthesis is not case sensitive. If the header is1 ^. t5 }4 G( J4 i+ b+ Z3 y
                  absent or if it does not contain any value, the roundrobin% q# B% V" T" A4 p* Y: r8 a) H
                  algorithm is applied instead.2 \* e, P. `- k! \5 }+ e
! D  ^. f% B$ |
                  An optional 'use_domain_only' parameter is available, for
% m7 s" r5 g' u3 d4 d2 @                  reducing the hash algorithm to the main domain part with some: ~0 J+ C1 e% n/ ]- q
                  specific headers such as 'Host'. For instance, in the Host
. x# h4 b% _4 ?% H& P& R2 D* D                  value "haproxy.1wt.eu", only "1wt" will be considered.$ S2 g: X7 [+ e, [9 E" Z) D* t
$ ~& {: _$ J  X
                  This algorithm is static by default, which means that; Q8 N0 S, v4 P( [! g: k8 g2 m
                  changing a server's weight on the fly will have no effect,
- ?& Z6 g. r, f# q                  but this can be changed using "hash-type"./ I7 o1 K! I" A2 L6 L/ }3 }
* p+ g3 x2 d, @! j- A- ^: V; {4 y
      rdp-cookie! p! r/ \4 t" \' z+ B& O. k# ]
      rdp-cookie(name)6 g7 z; t4 f2 U6 W; u4 [* Y# p. z. K- |
                  The RDP cookie <name> (or "mstshash" if omitted) will be2 |9 B( n( k) V* m) _9 d7 D
                  looked up and hashed for each incoming TCP request. Just as* H, C) P! ?7 G" i+ F
                  with the equivalent ACL 'req_rdp_cookie()' function, the name
( ]% `1 f1 M0 X2 w5 J1 z                  is not case-sensitive. This mechanism is useful as a degraded2 k! u7 j( R0 ]5 `; e; O! f0 ^0 ^
                  persistence mode, as it makes it possible to always send the) K* l- _% u: g/ O. \* I
                  same user (or the same session ID) to the same server. If the+ D2 `1 G5 J7 r8 A2 f7 b
                  cookie is not found, the normal roundrobin algorithm is$ E$ V; V9 e" [4 m! S; d$ V* t
                  used instead.* E+ c1 X3 i6 {8 g0 D4 E+ i

) K# p/ P) p# i" ?# \6 q. L                  Note that for this to work, the frontend must ensure that an( u* U9 d' [& }: W$ d; I' C1 T
                  RDP cookie is already present in the request buffer. For this/ l8 I% R$ j+ v' j/ R  k6 n
                  you must use 'tcp-request content accept' rule combined with! ^8 x% C; d5 Z; K; M) y/ d2 z
                  a 'req_rdp_cookie_cnt' ACL.3 B% C2 m  \( Q- T2 n

. \. o8 I# J9 j1 c, i* n) m( o                  This algorithm is static by default, which means that/ T8 |/ W1 a  o! Z4 U( O6 v9 }' Z
                  changing a server's weight on the fly will have no effect,
4 a( V+ d1 [3 \5 d; {                  but this can be changed using "hash-type".  D5 Z& h! h/ \8 c9 E9 L1 o
7 ]' q4 O" x2 @) D3 p
    <arguments> is an optional list of arguments which may be needed by some
6 ~$ A- Y- t. x                algorithms. Right now, only "url_param" and "uri" support an
3 }& u' D4 h. W1 f: g% t                optional argument.
5 e9 x, A3 f; W+ a- f2 j
/ ^; H. C1 t5 C( m$ h) M                balance uri [len <len>] [depth <depth>]  w* Q+ d; }8 `! W! u% j, N  Q& _
                balance url_param <param> [check_post [<max_wait>]]
$ \/ N* b# U& P& F
8 ?. i. o4 k5 Q) L  The load balancing algorithm of a backend is set to roundrobin when no other
/ k) @' t" _% F8 S- A+ k  algorithm, mode nor option have been set. The algorithm may only be set once" d# ^+ d0 `) ^  }- x
  for each backend.7 o5 s# I' H2 w

8 I5 n6 h# |! i# ?3 J  Examples :
% D2 m2 [. d, F2 S6 b0 ?1 i0 [7 G        balance roundrobin* k  a4 |1 v5 P! n
        balance url_param userid
2 e/ b! o1 W8 _        balance url_param session_id check_post 64
. H7 y: z8 X- I        balance hdr(User-Agent)
' X, D  j  |  Y7 a' D        balance hdr(host)& ]+ F+ Q2 Y; w9 i& c4 Z+ ]3 \
        balance hdr(Host) use_domain_only; C0 t2 j% c- n1 r1 F
, \# b8 H9 e% v% n& W. S
  Note: the following caveats and limitations on using the "check_post"
5 s' m, D/ c# j# S; r: X6 _  extension with "url_param" must be considered :% k. w! J: y  v& _, p4 `- V: ], j

2 e5 e  s6 P( ~9 Q$ g    - all POST requests are eligible for consideration, because there is no way
" L4 B# X  }  `# d  `6 B: d" _8 B# M      to determine if the parameters will be found in the body or entity which
4 U# ?( g. U- ~) J+ o      may contain binary data. Therefore another method may be required to
  |$ n& ~1 V$ Z: z4 M      restrict consideration of POST requests that have no URL parameters in
) j7 u6 Q: q9 K! i5 T) B      the body. (see acl reqideny http_end)
' I# f8 Q& T' T9 f) \9 y. o* m
    - using a <max_wait> value larger than the request buffer size does not0 T5 |/ g. X3 Q4 s% z
      make sense and is useless. The buffer size is set at build time, and6 w( S# t  S7 Y
      defaults to 16 kB.( E/ r; Q0 H  W
; a" f( B  Z" {6 c4 l+ ^
    - Content-Encoding is not supported, the parameter search will probably
, E" e7 S' Y1 s+ L9 r; V/ H      fail; and load balancing will fall back to Round Robin.: ^! p, A5 G& a: Z, B5 I+ N

4 g1 g7 h2 Z9 T6 c# z& O! @, P. c    - Expect: 100-continue is not supported, load balancing will fall back to
) I5 a8 l# y; m$ Y$ x      Round Robin.8 Y, w1 y% v  o$ }
% D. K; D- ?9 a" }5 u! H- g
    - Transfer-Encoding (RFC2616 3.6.1) is only supported in the first chunk.- r  t7 O4 |2 y9 A3 q$ t
      If the entire parameter value is not present in the first chunk, the
: E; s1 F5 [( |% W( N1 |/ ^      selection of server is undefined (actually, defined by how little0 @7 |; V2 S# f# i
      actually appeared in the first chunk).
0 D, O! g9 X1 y' Q9 _  K+ K2 P' {2 O/ u/ Q
    - This feature does not support generation of a 100, 411 or 501 response.: e! T( T. Q! X5 f' r4 v( @
' V1 M4 z" @/ }9 n# D: t) h
    - In some cases, requesting "check_post" MAY attempt to scan the entire( x( P9 H) ^& h" p, T
      contents of a message body. Scanning normally terminates when linear
- j4 H# A' n5 T1 m/ b      white space or control characters are found, indicating the end of what
9 i9 o3 T" t9 [5 i+ V      might be a URL parameter list. This is probably not a concern with SGML8 }6 S6 e9 r6 T+ N
      type message bodies." A& F( _1 ?( [, |) Z" A" c

2 x5 g, b# B0 K: [  See also : "dispatch", "cookie", "appsession", "transparent", "hash-type" and" E9 _# M+ c9 _
             "http_proxy".
6 y: T9 k: E. ]3 x. m
/ Z" d  O8 S0 B  f2 T
* @6 b% C  x! `" Ubind [<address>]:<port_range> [, ...]! F7 @  R0 q' a, W2 r' h
bind [<address>]:<port_range> [, ...] interface <interface>
  M$ ~% p  D7 j# ebind [<address>]:<port_range> [, ...] mss <maxseg>+ Z9 s( s/ u/ d6 Q
bind [<address>]:<port_range> [, ...] transparent' f7 e- [6 X6 N  p. i: J
bind [<address>]:<port_range> [, ...] id <id>
4 k1 k- C& z# e2 F/ R) Qbind [<address>]:<port_range> [, ...] name <name>9 `6 m3 N& m( `* T7 a7 D
bind [<address>]:<port_range> [, ...] defer-accept
% d( v( q* J# m0 R# C' _5 L; X: J/ ^  Define one or several listening addresses and/or ports in a frontend.5 A! o, G' D4 L
  May be used in sections :   defaults | frontend | listen | backend8 a0 l. X- ^) k
                                  no   |    yes   |   yes  |   no
' _5 N, e+ R3 D5 A  Arguments :: z3 {% X6 e# v, P, R
    <address>     is optional and can be a host name, an IPv4 address, an IPv6
# p- D8 H2 [; F/ y& @- R4 r* Z                  address, or '*'. It designates the address the frontend will
1 E3 d2 l* _/ l& O                  listen on. If unset, all IPv4 addresses of the system will be
, z* Y0 ~; _! X/ g" Q8 y                  listened on. The same will apply for '*' or the system's
- [0 w' a6 [* n0 j+ S4 y                  special address "0.0.0.0".( A1 r. Z! \! d
4 {% |: F6 J' \: l. X
    <port_range>  is either a unique TCP port, or a port range for which the7 r* i6 Y1 L4 Y/ x0 `
                  proxy will accept connections for the IP address specified
- [% Y3 A  H6 s$ f7 J2 U' B- q. v. q                  above. The port is mandatory. Note that in the case of an
# z1 R' e9 D8 I9 s                  IPv6 address, the port is always the number after the last
% {- ^1 F0 B$ ?( O; j2 I                  colon (':'). A range can either be :  {: g' S" q$ Z+ ?' r, \) U9 K
                   - a numerical port (ex: '80')
, @3 p# s( e# Y1 x  x3 [) M! x, ^                   - a dash-delimited ports range explicitly stating the lower
/ x( l2 Z- Y* ]5 F                     and upper bounds (ex: '2000-2100') which are included in
" \( {4 e4 [9 e, {& M( f                     the range.# L4 a. F3 o) s5 l% B
  S! j. q$ ]+ w0 @  C6 P; L+ R5 ~
                  Particular care must be taken against port ranges, because7 \9 }* O3 P1 }" _3 e
                  every <address:port> couple consumes one socket (= a file
( G6 Y. h# Y; ~& V9 k                  descriptor), so it's easy to consume lots of descriptors
2 u, B  h0 Q7 X0 A* {* ~                  with a simple range, and to run out of sockets. Also, each( h2 p: W: A+ M0 j6 [) b3 u
                  <address:port> couple must be used only once among all
* V( s4 M2 I( v1 Q4 `2 z2 g  _                  instances running on a same system. Please note that binding
3 M+ s1 k7 ?' L  e                  to ports lower than 1024 generally require particular  S$ o+ |3 l* H1 |
                  privileges to start the program, which are independant of7 a! \8 F5 }3 v3 I
                  the 'uid' parameter.
) _! ?. a! N/ A) t) L3 ~
0 `# U! \' l9 Y: }6 s7 {' n5 F    <interface>   is an optional physical interface name. This is currently  w2 J, d3 k; I1 w
                  only supported on Linux. The interface must be a physical" u' \6 T; Q* J' X
                  interface, not an aliased interface. When specified, all
  ]" M0 P% Y- L' M- ~                  addresses on the same line will only be accepted if the! A, _- N7 K/ w# H) V
                  incoming packet physically come through the designated; z2 p2 e$ Y3 H- z4 U/ g5 X! P4 f! A
                  interface. It is also possible to bind multiple frontends to, q+ y7 @! N( _2 {
                  the same address if they are bound to different interfaces.' r- m# z8 |% U, P/ m% t1 r
                  Note that binding to a physical interface requires root
- L( B/ P" n7 F4 @7 `" f                  privileges.
) a0 V; m% V7 J9 T. j& N
$ \( _, q2 Q' q- W9 L    <maxseg>      is an optional TCP Maximum Segment Size (MSS) value to be
: l2 `' L5 `7 ?$ H. ~! a5 ]. V2 H                  advertised on incoming connections. This can be used to force
) q  \& |0 I& z& k5 L: l/ `  ]( z                  a lower MSS for certain specific ports, for instance for
1 @2 A4 r/ V* N" T/ H3 n6 D$ t0 K0 \3 x                  connections passing through a VPN. Note that this relies on a
/ z' w; m6 t; h8 _; A" f6 {" L; j                  kernel feature which is theorically supported under Linux but
* P. u) `0 J, Q5 a* X+ z- N/ {0 [                  was buggy in all versions prior to 2.6.28. It may or may not
7 [$ N6 B: g9 P                  work on other operating systems. The commonly advertised
6 ?9 }9 O2 F" O8 l4 b  _                  value on Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP).
4 A* \- E" T% @% \
; @- @$ @6 i0 \+ j) [3 B4 F    <id>          is a persistent value for socket ID. Must be positive and4 l& \. k8 `3 I0 i4 h* s" c, @( C
                  unique in the proxy. An unused value will automatically be. g% a# L; U& `, L- R0 K1 _, _& z' L
                  assigned if unset. Can only be used when defining only a
! X: }  W* E) A* Q/ k                  single socket.3 U4 D& W3 |8 I" y+ |9 V
4 k. L$ z( z! ^( n; J
    <name>        is an optional name provided for stats
4 _4 Q, C4 u! M0 u$ M
  }, H# E: V/ D2 W. B' e    transparent   is an optional keyword which is supported only on certain
" a6 I/ p7 r) Z% J                  Linux kernels. It indicates that the addresses will be bound2 Q/ e* Z( A1 v: p; N/ }7 v
                  even if they do not belong to the local machine. Any packet
) g  `. _6 v& l; p4 ?5 W$ O                  targeting any of these addresses will be caught just as if
) j6 z: Y6 `5 V& R                  the address was locally configured. This normally requires  T9 W) x. H# w" @8 y+ Q: z
                  that IP forwarding is enabled. Caution! do not use this with: |6 l$ Z( g; M2 l  I, ^
                  the default address '*', as it would redirect any traffic for
! n7 o: j' {! q& H- u$ i2 R                  the specified port. This keyword is available only when
" n' m3 H2 r* E( M4 i2 f: K8 T                  HAProxy is built with USE_LINUX_TPROXY=1.
8 |( Z, X+ b9 y: K8 c" g% G( j( C6 \$ B2 ]4 N/ b8 _
    defer-accept  is an optional keyword which is supported only on certain
! H# x7 C6 J7 ^5 ~; {  J) ^3 N# o$ b                  Linux kernels. It states that a connection will only be/ ~, u0 m! s+ H5 C
                  accepted once some data arrive on it, or at worst after the
7 v- h8 i+ H: W6 |( l                  first retransmit. This should be used only on protocols for' [4 l/ u0 _4 P
                  which the client talks first (eg: HTTP). It can slightly" C, T1 d- A' y0 p3 m+ K
                  improve performance by ensuring that most of the request is2 V  Z* k5 f9 R) e. O. d9 ~! x
                  already available when the connection is accepted. On the% M3 X7 ^2 L- H  ^
                  other hand, it will not be able to detect connections which) T$ U6 W+ n: u  T6 k, ~
                  don't talk. It is important to note that this option is9 f2 c8 P& B# ^3 U, ?" M5 a" u0 k
                  broken in all kernels up to 2.6.31, as the connection is
( Z  @' G0 M0 \9 |7 a/ t9 v0 D, ]! o                  never accepted until the client talks. This can cause issues  S) @" A6 d/ k, N$ u/ B
                  with front firewalls which would see an established; y3 k) w; p: ~6 [+ l
                  connection while the proxy will only see it in SYN_RECV.. f2 P" r; Y0 V& y5 ~, [

$ h5 I7 Y4 E6 C+ z0 J4 P8 H; V- w  It is possible to specify a list of address:port combinations delimited by
* k  A. [9 x& ^) Q) u8 U  commas. The frontend will then listen on all of these addresses. There is no
1 \6 [  Z! w) p  fixed limit to the number of addresses and ports which can be listened on in
  f, E! z0 r2 {' a0 E  a frontend, as well as there is no limit to the number of "bind" statements) I' g* D+ i4 I2 X* q
  in a frontend.
9 d# C0 T! g2 L% ^
- o$ w# p# V: N$ T  Example :
0 r3 _9 F* @) ^$ y        listen http_proxy3 u/ @" U" T; `8 _% x% a" }
            bind :80,:443
6 B1 Q% `' p3 z. `; a. W4 |            bind 10.0.0.1:10080,10.0.0.1:104430 {( V# r) P, q

, `5 O, y6 Y6 B* e: w; ]  See also : "source".
" b6 R; H# }; r* ^% w, O$ p5 D: Q: ^9 p5 A, x' i9 D
* T* s3 C2 @6 X; l+ |" l
bind-process [ all | odd | even | <number 1-32> ] ...
0 }) e$ m4 {( c' H$ ^* o# }, _  Limit visibility of an instance to a certain set of processes numbers.
9 R# q* @# C2 r  May be used in sections :   defaults | frontend | listen | backend- ?$ B  [) a4 _5 ?( P& E/ P3 u! O* V
                                 yes   |    yes   |   yes  |   yes
" y# U( v4 o+ l  Arguments :& O$ I6 Z( x8 ~, J  q/ Y
    all           All process will see this instance. This is the default. It
& [- z# L6 i& S$ B' C$ X3 B                  may be used to override a default value.$ ]; q( C1 G) R0 m' O( C

2 p# R" S; J, h    odd           This instance will be enabled on processes 1,3,5,...31. This
- M7 b& t9 B( j. w4 z3 r                  option may be combined with other numbers.1 @/ D& Y- s" s. A/ ~" N# N7 A
  l& M; }# o! E6 I2 t6 {7 m
    even          This instance will be enabled on processes 2,4,6,...32. This  ?7 B4 c5 e2 s* r
                  option may be combined with other numbers. Do not use it6 \* x: C/ r; s2 c
                  with less than 2 processes otherwise some instances might be/ l- b& q/ G  w3 s. d
                  missing from all processes.+ F) l6 P* ^% c6 T
) X. E$ A: ?0 O: ]' Y% U& H2 s
    number        The instance will be enabled on this process number, between
2 g% V# C! Q3 l- I1 A                  1 and 32. You must be careful not to reference a process
7 S5 ~% \. y5 s4 F. E* {9 Q                  number greater than the configured global.nbproc, otherwise3 V- u* X' g+ _5 H* n% R! }, u6 Z! o$ Y
                  some instances might be missing from all processes.5 g7 P% d$ v& @! ^2 M2 Q

& T0 ?; _" ^6 o  This keyword limits binding of certain instances to certain processes. This: e$ A! L5 _6 ?* r
  is useful in order not to have too many processes listening to the same' [% R) p, U% z
  ports. For instance, on a dual-core machine, it might make sense to set
( [; l+ o* j$ @5 \  'nbproc 2' in the global section, then distributes the listeners among 'odd'4 C( U! O( q( y3 i9 s5 r
  and 'even' instances.
6 w  w0 ]3 `6 e$ v6 B
; ^$ d; x5 o+ ~1 g; \  T  At the moment, it is not possible to reference more than 32 processes using1 q% I( O% j& e$ `4 a, s" ~
  this keyword, but this should be more than enough for most setups. Please0 T, }. F  T. W/ `. y$ Y& T/ t
  note that 'all' really means all processes and is not limited to the first, y/ ~- w$ ]& a) g; p5 ~& Y4 w& x, U
  32.
$ ~5 g& B8 b, ]$ y' P3 {4 l/ M+ G0 G. Z4 h
  If some backends are referenced by frontends bound to other processes, the$ V8 [6 Y( _5 O) {6 p) C/ |
  backend automatically inherits the frontend's processes.: n# V; D/ E) p  \9 T1 ]& m! ~2 B
" Y% }# l) G, u) k+ ]! S
  Example :
+ y5 ^2 @6 R$ n' d, Y3 d9 C        listen app_ip1
4 K0 c" x; m2 s6 O9 u  f0 u7 K            bind 10.0.0.1:80
* ?4 o; q. X1 l) z            bind-process odd$ V  {7 y3 {% n+ @$ \, z. }
3 D2 O* X$ m7 [5 ]
        listen app_ip2- ?) h2 M* }- ^- W" ?# K
            bind 10.0.0.2:80. S5 X/ l4 J# R9 j3 u6 E; v8 }6 L/ F
            bind-process even. B5 H" c6 Y# y4 u1 w8 d

  n# _$ y* o2 c; R3 w* J4 B        listen management
( i, W* S, y& h6 d" c4 ~            bind 10.0.0.3:80
! I, ^% y7 e& U: X" a            bind-process 1 2 3 41 l: Y: }8 K' M; s+ T0 {
7 ?, B& ~" x6 U; M5 \" p7 o
  See also : "nbproc" in global section.
/ x: g! m% ^& F9 d. `$ k3 [3 B" c  b8 G5 [6 B0 U: Q3 h
3 E7 d$ Z7 a* v/ I4 R: }: g) ]! _
block { if | unless } <condition>2 ~' p  {) R' }
  Block a layer 7 request if/unless a condition is matched$ F8 W; Z4 [0 B  ^
  May be used in sections :   defaults | frontend | listen | backend+ Q& |. N( M1 ?3 s8 Y
                                 no    |    yes   |   yes  |   yes
8 E: Y) {- d3 @9 F+ N9 S: \( y8 R. q6 j' w& j
  The HTTP request will be blocked very early in the layer 7 processing; A; N' U: f; p( x: ?7 o8 J
  if/unless <condition> is matched. A 403 error will be returned if the request* M; f( R# M$ w$ ^5 A, ~* R  d
  is blocked. The condition has to reference ACLs (see section 7). This is) ]' F9 t3 F0 ^- D! N
  typically used to deny access to certain sensitive resources if some# e# T) R& t  ^# i: i- t
  conditions are met or not met. There is no fixed limit to the number of
( P% b: g* G) H3 ?3 ?! S" ?  "block" statements per instance./ \6 V4 ]8 ]) ]& V9 F2 z

3 W8 `! d! r: _8 y  S8 @, i  Example:) c$ A- H" C1 X; I) S$ g
        acl invalid_src  src          0.0.0.0/7 224.0.0.0/3
; c6 f# w1 x6 u: M6 E2 h        acl invalid_src  src_port     0:1023
8 D/ ^. h! |; Z/ d9 @; D        acl local_dst    hdr(host) -i localhost, P3 p$ [2 O5 F( j
        block if invalid_src || local_dst
0 r. |: [4 X; ?' R5 j! M6 @; E
7 O2 o9 @; N! i6 K  See section 7 about ACL usage.
/ }% O9 s, m. `- v3 l0 T
5 a% _2 A1 B$ \' F% i4 [; [7 m
) O( ?8 E% q1 k; ^capture cookie <name> len <length>; K5 r, e0 X, w* S
  Capture and log a cookie in the request and in the response.
% o9 ^  F6 `! t( m1 c: @  May be used in sections :   defaults | frontend | listen | backend. N" y, x6 M- s. f* _
                                  no   |    yes   |   yes  |   no5 y' N8 e4 O! K$ W
  Arguments :
3 c/ H/ i  o; o' O& N    <name>    is the beginning of the name of the cookie to capture. In order- [) f5 t  i9 M* M
              to match the exact name, simply suffix the name with an equal$ A) ~( C5 F( X3 X/ w9 u; \
              sign ('='). The full name will appear in the logs, which is# q* o# a7 P1 Y) a4 O: K- s
              useful with application servers which adjust both the cookie name
" ?4 J4 W; a! V              and value (eg: ASPSESSIONXXXXX).
; l( x7 R. K' Z( y8 N$ e
& }% X/ B& b$ V    <length>  is the maximum number of characters to report in the logs, which9 k2 i( l( P- y) |! u; P
              include the cookie name, the equal sign and the value, all in the2 o# d$ Z+ q( z$ @
              standard "name=value" form. The string will be truncated on the! j- m( v' v( y) {
              right if it exceeds <length>.
6 v' g+ d3 C3 U( R8 w3 w* C
! ?# c. O, ?3 W  Only the first cookie is captured. Both the "cookie" request headers and the
2 J. p" X; X, H3 y8 D  "set-cookie" response headers are monitored. This is particularly useful to* |0 l( Z( C- I* U  t
  check for application bugs causing session crossing or stealing between
! L2 H/ z  p5 C- @& i. ~  users, because generally the user's cookies can only change on a login page.+ Q6 v  z4 H$ S* p, t9 y
9 p2 G! G/ [/ _7 l! \8 g& N
  When the cookie was not presented by the client, the associated log column
. ~) r: c" F6 ?) [  will report "-". When a request does not cause a cookie to be assigned by the* u. ]1 _1 T, x
  server, a "-" is reported in the response column.
9 p' }& V1 ]- {* z1 E2 k
; l/ l  H/ p% Z9 f+ p% {, k3 G' V  The capture is performed in the frontend only because it is necessary that" ^! M. o9 ^. q& ?' M0 \
  the log format does not change for a given frontend depending on the4 N5 l" g% P  o& T6 r9 s
  backends. This may change in the future. Note that there can be only one
# Y$ n0 @! B$ m  "capture cookie" statement in a frontend. The maximum capture length is
! R2 F: O7 |% I4 k5 n2 F$ F  configured in the sources by default to 64 characters. It is not possible to
! Z, r7 N6 d- C2 W; P! C  specify a capture in a "defaults" section.
) l+ Y+ Q; l& e) t8 K9 u
9 o5 x$ \. B1 D+ R' Z0 u  Example:
" Z, g* S) i; D4 ?+ _  z4 t7 V        capture cookie ASPSESSION len 32' w# S, U2 @( Z) r2 h) Y
( k: M; c1 D, ]9 K+ R) |
  See also : "capture request header", "capture response header" as well as' a3 i& A' F- S0 u
            section 8 about logging.
9 N6 W' a1 z& @+ n
0 a  i0 V3 ?+ j( R* P
+ ~2 a$ H" `7 @8 u' J/ k4 z  wcapture request header <name> len <length>
# F9 }* F) D) S  K. M- m  Capture and log the first occurrence of the specified request header.4 h2 \2 P5 t4 \4 R
  May be used in sections :   defaults | frontend | listen | backend
+ o& H6 y/ b; X4 w4 H                                  no   |    yes   |   yes  |   no
0 L6 v# n# m- @4 p# [+ F  Arguments :
4 H8 f3 v: ]$ P1 p- E+ T1 p6 a    <name>    is the name of the header to capture. The header names are not
6 l+ @2 X) D( K: ?              case-sensitive, but it is a common practice to write them as they
; ^5 `5 |- R9 T. f$ j5 J& I) i              appear in the requests, with the first letter of each word in
$ h- P3 i" i0 y              upper case. The header name will not appear in the logs, only the: l; b( u3 B1 R0 j6 O% T- J; j$ Q
              value is reported, but the position in the logs is respected.
4 ~+ j. r( |' g
6 K" R* `4 W7 }/ x6 v7 A    <length>  is the maximum number of characters to extract from the value and& ?- |$ h; h3 P  w
              report in the logs. The string will be truncated on the right if" ?) o, _( `) A9 l
              it exceeds <length>.
- e0 z1 [& C7 }4 n% R8 e
& H% H4 P3 v0 ]; [  Only the first value of the last occurrence of the header is captured. The  w; B3 {9 Q$ B  h, \9 L; y/ g. t
  value will be added to the logs between braces ('{}'). If multiple headers0 |# i# X9 h: X6 ^3 X
  are captured, they will be delimited by a vertical bar ('|') and will appear# |5 J- h' c0 u/ {' o8 ?9 \  l
  in the same order they were declared in the configuration. Non-existent
7 i# x5 A- K& b  N  X% l% u4 \  headers will be logged just as an empty string. Common uses for request
# x/ e9 S$ U' z# `" Q+ @  K+ u5 w  header captures include the "Host" field in virtual hosting environments, the5 U# I  U2 p7 E' m- B/ e
  "Content-length" when uploads are supported, "User-agent" to quickly
( W6 |) }% a) i6 C3 J. J' ~/ Q  differentiate between real users and robots, and "X-Forwarded-For" in proxied5 f9 B0 p0 K8 x% j
  environments to find where the request came from.! q/ S2 P  o1 `8 }. _

% u; I: s  B1 P4 i3 c  Note that when capturing headers such as "User-agent", some spaces may be& T  J( l1 V3 s4 h: ]2 ?. n, s1 F
  logged, making the log analysis more difficult. Thus be careful about what
5 F' U! x2 j8 _9 ~' y" M; |4 L( @, m  you log if you know your log parser is not smart enough to rely on the
# G4 V& D' ^, \! b9 f  braces.+ P3 V$ M$ c& G. j$ R$ F7 X
- x5 |2 a! R( Y  ^: f
  There is no limit to the number of captured request headers, but each capture
' G, u  f. c( C  is limited to 64 characters. In order to keep log format consistent for a
/ y  D0 O7 k8 i% n! K5 Q  same frontend, header captures can only be declared in a frontend. It is not
' E( X% A& u& W7 H% J0 N' Z  possible to specify a capture in a "defaults" section.9 u/ W, E: l. n; i, d7 J
2 U3 j- S. s, J) {# w) o, V
  Example:
% P8 ?5 I% W  D2 e) R        capture request header Host len 15
! T: n! i  f1 v$ i3 e1 I        capture request header X-Forwarded-For len 156 m- q% e4 ]# e3 l) f% `" U
        capture request header Referer len 15
* j5 B+ y$ i7 d' ^& I# k* s# v2 n/ F; q% m) o4 V, z
  See also : "capture cookie", "capture response header" as well as section 87 ?- q% p! m/ G. A" Q
             about logging.; H  B' ?6 v( z# `+ K3 Z: k4 b& b

7 l3 `' k' x! d* N: C. k% L
6 n, u# B- v, q, b) {# c7 Dcapture response header <name> len <length>6 R8 u6 B* r( F0 ^1 v
  Capture and log the first occurrence of the specified response header.
$ D1 b' z# }) e5 R& g8 b* o; c  May be used in sections :   defaults | frontend | listen | backend: p- J' R* Y' ]; ~
                                  no   |    yes   |   yes  |   no
& a* z8 O6 o0 E) V% C' R+ b  Arguments :/ C" o2 L% S5 R; ~
    <name>    is the name of the header to capture. The header names are not! I) b: c1 z) f) ~! Y$ T; P) I$ I
              case-sensitive, but it is a common practice to write them as they4 S7 {) j0 O1 @& y' i, \
              appear in the response, with the first letter of each word in
, z: P2 [) _1 S+ }1 J2 K              upper case. The header name will not appear in the logs, only the
& _/ O+ f0 ?- l3 ?1 H              value is reported, but the position in the logs is respected.
: m8 j' Q0 {- P0 H& u; {" x5 E6 o5 }) J' h. I, ~, t8 H
    <length>  is the maximum number of characters to extract from the value and* U9 @! v$ x  {/ R9 U0 t
              report in the logs. The string will be truncated on the right if
* g. h. ]. i- A* Q* H; J  P8 ^# E( Y              it exceeds <length>.  }% y% \( m% ^1 I
5 z1 n. J. d# x2 y# p1 m$ C
  Only the first value of the last occurrence of the header is captured. The
5 ?5 Q$ c5 U* }. M; o" ?  result will be added to the logs between braces ('{}') after the captured
- Y0 B! W- M$ }4 R2 v# u3 r  request headers. If multiple headers are captured, they will be delimited by
) I! o) M- S4 A  a vertical bar ('|') and will appear in the same order they were declared in! w( m2 c2 ^( {2 K1 \* r  {
  the configuration. Non-existent headers will be logged just as an empty
8 D$ H: u9 \* F; ]* H. |  string. Common uses for response header captures include the "Content-length"
( k7 f+ {9 r  N2 {6 z1 u7 {  header which indicates how many bytes are expected to be returned, the
: g# ~" }# m: z& z5 d& Y  "Location" header to track redirections.  D4 r: x) r  {

! U0 \5 }& N& }& ]& q) V  There is no limit to the number of captured response headers, but each) h! b4 g: B' \9 m! }0 [3 ?/ L( e
  capture is limited to 64 characters. In order to keep log format consistent  l! S7 U. H* M" d; h" l- G
  for a same frontend, header captures can only be declared in a frontend. It
* H, ^8 }* c5 I+ U! d6 X/ v2 U  is not possible to specify a capture in a "defaults" section.1 Z2 `; V. e- [$ M

1 d0 x6 C7 A1 n5 s& S. x" R. u, y  Example:$ Z! Y7 v$ m" P4 H' }$ |; n
        capture response header Content-length len 9
8 U# M- `" H6 Q$ |. N8 u        capture response header Location len 15) J& p* |' V2 ]/ V3 |
( A: P. G7 A7 K& \& w
  See also : "capture cookie", "capture request header" as well as section 8
) v, a( S& Y; j             about logging.2 S+ W* p! c; p' d$ i
$ q( r  m5 I+ U

* o% \! j6 I: ]  x/ K5 I& ]* tclitimeout <timeout> (deprecated)
7 P/ [; O, R* B% @1 B+ ^7 `# x  Set the maximum inactivity time on the client side.
5 W' H7 l6 w# o  b: d/ C  May be used in sections :   defaults | frontend | listen | backend% A0 }2 i: J- c! ~6 c' f
                                 yes   |    yes   |   yes  |   no
$ b! j: W+ o. ^4 p  Arguments :0 \- F0 M' H% k* a' \: T
    <timeout> is the timeout value is specified in milliseconds by default, but. Q- x" E% [1 o. r, S
              can be in any other unit if the number is suffixed by the unit,
7 v9 J& G8 V% w8 s# ~# M8 R              as explained at the top of this document.. S. F$ n, T0 k' y

/ {2 {. {2 f3 |" h  The inactivity timeout applies when the client is expected to acknowledge or
" [4 S- K2 n$ k6 _( z. d+ w# Q% j  send data. In HTTP mode, this timeout is particularly important to consider
! R; R  U% T& I6 D+ D0 d  [- W  during the first phase, when the client sends the request, and during the5 I. O& S+ }; P9 ]* G2 M: F$ b( ~
  response while it is reading data sent by the server. The value is specified* K8 ~# i; F# }2 x2 O: s2 e8 ^; k
  in milliseconds by default, but can be in any other unit if the number is
% q- l* J. @" G; P. D  suffixed by the unit, as specified at the top of this document. In TCP mode5 ^- j3 b$ s5 l
  (and to a lesser extent, in HTTP mode), it is highly recommended that the& [4 n" x: W& ^0 u6 f% X  N4 T/ L
  client timeout remains equal to the server timeout in order to avoid complex
6 y, s' v3 C( a0 T9 T! b2 |* [6 A0 T  situations to debug. It is a good practice to cover one or several TCP packet( r  h! ~* \, A* ~' U( r2 y* k
  losses by specifying timeouts that are slightly above multiples of 3 seconds6 P3 z8 R2 H; D
  (eg: 4 or 5 seconds).
: P* S" b1 U$ D) {
& v) L! R& F! a  This parameter is specific to frontends, but can be specified once for all in2 `) S" I% O/ A
  "defaults" sections. This is in fact one of the easiest solutions not to* R* ]2 b5 r; I1 G5 q6 [. o! N( w
  forget about it. An unspecified timeout results in an infinite timeout, which
: L5 Z+ D+ G3 D+ z% p  is not recommended. Such a usage is accepted and works but reports a warning
1 A' H; c# A+ u) I% E/ b  @  during startup because it may results in accumulation of expired sessions in3 o" ^3 ~0 N! v' e% r/ M/ m
  the system if the system's timeouts are not configured either.
  T' ~; {, C: _" D# A3 O3 S8 X0 I4 R, ]5 ~
  This parameter is provided for compatibility but is currently deprecated.
$ ~; i. \1 e+ d) k! N% I  Please use "timeout client" instead.1 r! V: {! w4 }5 J2 B, ?

# K8 x: I# U/ y. Q+ f4 _0 ~0 S  See also : "timeout client", "timeout http-request", "timeout server", and9 v  N! ^" x- G0 h' Y
             "srvtimeout".
  o" J6 K& f/ e& I; s& ?
( N" n1 E7 B; z2 k' Z2 ]5 T3 V/ {% g2 s6 @# R( E. ]- y. @
contimeout <timeout> (deprecated)
. c' E8 T( `7 i+ l5 h4 [* U' ~  Set the maximum time to wait for a connection attempt to a server to succeed.
. @  p7 R; h, P( h  May be used in sections :   defaults | frontend | listen | backend
. [, O6 r9 \7 a9 q                                 yes   |    no    |   yes  |   yes
7 U/ P5 A& L6 ?  w* A' Z/ x  Arguments :
: s; j9 I, Q5 k% B' x2 k: Q+ T" I    <timeout> is the timeout value is specified in milliseconds by default, but
- d/ O) l7 B! J; a4 U+ x  @0 Z- F8 t              can be in any other unit if the number is suffixed by the unit,
7 {9 J/ o$ d9 A; `$ r              as explained at the top of this document.
4 x$ y; i$ |$ m' {; `8 }; j! ~% Y6 U8 L# Q- u+ K$ Z! K
  If the server is located on the same LAN as haproxy, the connection should be  n$ o; A9 V  H. Q
  immediate (less than a few milliseconds). Anyway, it is a good practice to+ ~: j9 c- q5 D; Z& Y
  cover one or several TCP packet losses by specifying timeouts that are
2 P  k. Q$ o2 h4 M/ r8 V  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the  O! ~/ I  |6 ^2 q4 n! i
  connect timeout also presets the queue timeout to the same value if this one
5 l1 h8 `5 ?6 n: A: }: `. `4 I  has not been specified. Historically, the contimeout was also used to set the5 i. ]: Y( S) P) C, N# L* Y7 y
  tarpit timeout in a listen section, which is not possible in a pure frontend.
* d- M( ?! C- W/ N. `
; d, @  |) {' |  This parameter is specific to backends, but can be specified once for all in" B, o* {& @3 @/ p
  "defaults" sections. This is in fact one of the easiest solutions not to: K+ m8 h) t" Q/ n" h9 @
  forget about it. An unspecified timeout results in an infinite timeout, which. B5 V( r8 P1 F* w; T
  is not recommended. Such a usage is accepted and works but reports a warning
/ S' {4 \8 o* T7 e: c  }  during startup because it may results in accumulation of failed sessions in
2 Q4 \% Y- _; p: ^+ a  the system if the system's timeouts are not configured either.) x( k4 i5 }6 N" \9 T9 P
& Y( P# \0 x: T5 f
  This parameter is provided for backwards compatibility but is currently- ]) y! z5 k! }2 p; K5 G0 p8 s
  deprecated. Please use "timeout connect", "timeout queue" or "timeout tarpit": @1 \" ]9 `) n9 u/ P
  instead./ o- H9 R# W2 U" z# G; M6 m
5 ~2 c+ ]( c/ F6 K
  See also : "timeout connect", "timeout queue", "timeout tarpit",
  r! {5 y- {  d' K. R             "timeout server", "contimeout".5 a( I- x( F1 Q  ]! {5 p$ n

) P' N8 ^4 }7 Z+ d- J& R4 `" A9 q4 b  g) {' R; x( v3 o
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]# B7 W7 F# v* e( e8 S  p, g+ Y
              [ postonly ] [ preserve ] [ httponly ] [ secure ]6 i0 _$ E' o  b8 ^
              [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
9 H# V9 H* b8 b. ^& a  Enable cookie-based persistence in a backend.  N5 O' w& n# U* [& H
  May be used in sections :   defaults | frontend | listen | backend
+ A( p# Y; C  D8 c. g2 R5 ?: |0 w                                 yes   |    no    |   yes  |   yes" W: f) `6 c  b; [4 m( `/ U) P
  Arguments :' }$ Q9 U! ~1 a* m1 i
    <name>    is the name of the cookie which will be monitored, modified or
' W" z7 j; }: N2 J              inserted in order to bring persistence. This cookie is sent to& }+ M+ \% ?: W6 S% B; a' F8 Y
              the client via a "Set-Cookie" header in the response, and is0 R) U. G0 ?4 ]; q
              brought back by the client in a "Cookie" header in all requests.
) s  K% a; K" D# d7 G* d6 c              Special care should be taken to choose a name which does not) ~, M7 N2 T; K+ r8 U- t
              conflict with any likely application cookie. Also, if the same; G* u" u( h( O1 d: w
              backends are subject to be used by the same clients (eg:
& F( U3 ~- b' g! s' h/ ~- L              HTTP/HTTPS), care should be taken to use different cookie names
3 ~+ y! H' k; m              between all backends if persistence between them is not desired.; }7 Q1 n, z% H+ _  A3 W( X

# r6 R' C( g$ O    rewrite   This keyword indicates that the cookie will be provided by the: ?! Q- k/ f  h$ b, }% ?
              server and that haproxy will have to modify its value to set the
; i6 G+ \( e1 S5 c9 B/ c! a              server's identifier in it. This mode is handy when the management0 I  p. ^- |1 H& w  O4 L
              of complex combinations of "Set-cookie" and "Cache-control"4 q3 E8 I3 x, \5 @
              headers is left to the application. The application can then% {" {$ c: f, }
              decide whether or not it is appropriate to emit a persistence! p5 U% @2 h5 k- M' q- z
              cookie. Since all responses should be monitored, this mode only
3 B, X2 v+ m3 V3 q              works in HTTP close mode. Unless the application behaviour is
1 [7 Y3 q* L2 f4 j( {              very complex and/or broken, it is advised not to start with this6 r( B! x% _8 @# a# L$ J
              mode for new deployments. This keyword is incompatible with
! s; H2 x) h$ n  h              "insert" and "prefix".
3 j+ S  G$ X8 G4 z6 ~; Q% R: Q+ k( E6 J9 U8 s6 w0 W- [" T9 g
    insert    This keyword indicates that the persistence cookie will have to
# H: J; j! c% s: @) P9 ^              be inserted by haproxy in server responses if the client did not: y; z0 @5 @* {( z+ F; o, ~

) w4 _% ]. A, `0 h+ Q3 X              already have a cookie that would have permitted it to access this
4 T0 I9 z$ c+ c' ~              server. When used without the "preserve" option, if the server
* t, \+ j: j1 [1 T4 }9 _; {              emits a cookie with the same name, it will be remove before( K8 k" u9 Q$ Q+ i, }7 j5 C
              processing.  For this reason, this mode can be used to upgrade# p# f% [' V1 t2 ?* i1 b! W1 Q- r
              existing configurations running in the "rewrite" mode. The cookie8 a. \0 U. m2 F& t, d# R
              will only be a session cookie and will not be stored on the7 V& j; L" o9 J0 B6 g
              client's disk. By default, unless the "indirect" option is added,
5 ]1 v8 s) n( [1 H) R" ]              the server will see the cookies emitted by the client. Due to
  R( K2 r  H6 s: Q4 z              caching effects, it is generally wise to add the "nocache" or
: C' w* t; L# r( B* A, R6 b" v              "postonly" keywords (see below). The "insert" keyword is not
" _  t  |0 P4 U6 ?. L. A+ u( F              compatible with "rewrite" and "prefix".
% K* [8 ~6 ?$ z2 J1 c- V4 S8 ~+ c0 s0 e; }
    prefix    This keyword indicates that instead of relying on a dedicated
0 g6 [. ^% {8 E% z- |4 Y& Y* o              cookie for the persistence, an existing one will be completed.
% q: d! k. V9 C              This may be needed in some specific environments where the client
# d5 G; J: T! X2 M9 W              does not support more than one single cookie and the application0 \: T. B3 ?1 O; N
              already needs it. In this case, whenever the server sets a cookie+ |; ~2 q3 n) Q- O; M
              named <name>, it will be prefixed with the server's identifier
+ m9 ?1 i0 m/ |& X: w; ~              and a delimiter. The prefix will be removed from all client: X+ k* W& S. p% V* k
              requests so that the server still finds the cookie it emitted.! S" ]1 x: f. N3 z
              Since all requests and responses are subject to being modified,# a, l& X2 P$ N0 ^$ L
              this mode requires the HTTP close mode. The "prefix" keyword is( R3 k' K+ I& b6 p6 s
              not compatible with "rewrite" and "insert".
" a/ K- W  x0 G7 ~" S9 M! O$ l; u
( v7 [6 B+ Y# z& d' g    indirect  When this option is specified, no cookie will be emitted to a
; ^0 Z2 i# B$ _, q              client which already has a valid one for the server which has- \9 w/ F4 L* q3 X/ x6 n
              processed the request. If the server sets such a cookie itself,: D6 C, m& }* N7 [, c+ s( p; d. v
              it will be removed, unless the "preserve" option is also set. In
  ~& o0 T' b4 T8 ]2 \* O- A              "insert" mode, this will additionally remove cookies from the
$ z8 z8 \+ z( k+ O$ k1 A              requests transmitted to the server, making the persistence4 Q' y" ~9 B; n: z2 v
              mechanism totally transparent from an application point of view.
8 s+ o- C. A! ?5 X: k' s4 l
; z, }) _1 }% T! W3 [    nocache   This option is recommended in conjunction with the insert mode, u- u' u+ [# ]7 z$ n
              when there is a cache between the client and HAProxy, as it7 A& |, z. B2 B
              ensures that a cacheable response will be tagged non-cacheable if, U$ R- H$ n) |9 `2 i
              a cookie needs to be inserted. This is important because if all* H5 c0 d- ~$ g1 p* G% Z5 z
              persistence cookies are added on a cacheable home page for( B( z6 S+ K5 w1 z4 a  F8 z  e
              instance, then all customers will then fetch the page from an
7 I: f+ n7 W9 f* f, F7 g5 \              outer cache and will all share the same persistence cookie,
9 R- h# D7 k, X1 W  \              leading to one server receiving much more traffic than others.- ^. W' u9 P& G5 \4 |& k
              See also the "insert" and "postonly" options.8 L5 P9 s/ o, T

7 v: q3 h0 u( R0 {; Y6 w    postonly  This option ensures that cookie insertion will only be performed8 @7 W  i& Z0 t1 R- H% ?. a: |
              on responses to POST requests. It is an alternative to the
: l0 i: x1 f6 M) `              "nocache" option, because POST responses are not cacheable, so
( c4 D- t% i  N- {; y9 n$ m+ l! [* ^              this ensures that the persistence cookie will never get cached.3 L% S8 L: Y: g# n- m% F& O+ `
              Since most sites do not need any sort of persistence before the
. Z( @1 r- X# f) p- L2 e1 s% g( H              first POST which generally is a login request, this is a very8 ~4 [0 Q0 n2 |6 D/ N/ f. J* Q
              efficient method to optimize caching without risking to find a. T  T1 o, O: ]3 j- ]! F
              persistence cookie in the cache.' \  _) Y0 e% k8 w, z0 W8 m
              See also the "insert" and "nocache" options.& M$ T; e- I; @# f/ P6 A

8 l5 V# F+ x+ `2 D  x* J; E: ]    preserve  This option may only be used with "insert" and/or "indirect". It+ t; \% P% g0 M' B; [
              allows the server to emit the persistence cookie itself. In this
7 n, W. ^1 A( P7 c2 F# p              case, if a cookie is found in the response, haproxy will leave it/ |4 d: w1 u8 X6 [% A6 i6 a+ o
              untouched. This is useful in order to end persistence after a
$ @5 m6 N5 @2 V  Q0 l; v$ Q7 R              logout request for instance. For this, the server just has to
; G1 D- @: L% X+ w/ t              emit a cookie with an invalid value (eg: empty) or with a date in
0 y0 C: N" l/ ?$ J- b3 X/ ]3 f* V              the past. By combining this mechanism with the "disable-on-404"
( z& W/ p+ u/ c/ |              check option, it is possible to perform a completely graceful
$ W: m$ |! A1 w8 Y" V, \- W              shutdown because users will definitely leave the server after
$ a/ v9 t% k; h. G* I              they logout.6 `  \  \- ?# Q% D" y3 @
9 v% n" m: Y# C  I* D- u6 I. s. h
    httponly  This option tells haproxy to add an "HttpOnly" cookie attribute" k2 g+ l% T  t/ O8 s1 d1 Y
              when a cookie is inserted. This attribute is used so that a
, I  i2 x- F; F4 m0 g              user agent doesn't share the cookie with non-HTTP components.
( a9 G$ M+ t& b1 z' v2 n              Please check RFC6265 for more information on this attribute.
; d- {  W* [% t) u- ], P- u+ V" o; {
" w' J, R. L( w) M) {4 a    secure    This option tells haproxy to add a "Secure" cookie attribute when
" V0 q7 V; ^+ [. R              a cookie is inserted. This attribute is used so that a user agent
; t$ ?% M4 z/ r: t7 `+ T6 L. I* Q7 S" l              never emits this cookie over non-secure channels, which means* _$ c$ I: g2 B2 }  C* E" T
              that a cookie learned with this flag will be presented only over
4 {, C  E& G5 P" {: \              SSL/TLS connections. Please check RFC6265 for more information on6 B: N3 ^, {5 m) q! S
              this attribute.4 O! B- Y2 R/ w2 ~+ J" \

% L2 ~4 M1 R9 q; l; d    domain    This option allows to specify the domain at which a cookie is
9 b5 h- b9 a0 y9 A- u4 j) ]              inserted. It requires exactly one parameter: a valid domain
( O2 c" j9 o, Q1 a              name. If the domain begins with a dot, the browser is allowed to
; U' ^7 p/ q! U              use it for any host ending with that name. It is also possible to5 R6 @, k5 F/ ?5 b0 }, \; @# b" }2 T
              specify several domain names by invoking this option multiple
: e2 C& U8 U9 d0 x              times. Some browsers might have small limits on the number of- \% Q; i4 l/ W9 f9 G2 P
              domains, so be careful when doing that. For the record, sending
( ~4 E; W7 l! l! e              10 domains to MSIE 6 or Firefox 2 works as expected.# H; H! n  W/ M( s, B! R, A  L! h
$ k5 Y$ t) v0 L3 o
    maxidle   This option allows inserted cookies to be ignored after some idle, e% ]- l* o- G
              time. It only works with insert-mode cookies. When a cookie is
% a" x* r% Y: s  C5 k. s' m              sent to the client, the date this cookie was emitted is sent too.; M4 g2 c) f4 a+ f
              Upon further presentations of this cookie, if the date is older
% v( \! f6 ~5 b7 {0 C3 k2 F0 g              than the delay indicated by the parameter (in seconds), it will9 p$ U& d) m- w$ E+ Q% C2 t
              be ignored. Otherwise, it will be refreshed if needed when the! b9 ^4 t' V) f8 o5 ?6 n  E
              response is sent to the client. This is particularly useful to
1 d/ L! z  F% o3 U              prevent users who never close their browsers from remaining for6 Q4 Y& t5 Z/ U' V" T: c$ [
              too long on the same server (eg: after a farm size change). When
, n4 G2 c3 G; K* m8 @* A8 S              this option is set and a cookie has no date, it is always
- p8 V! y: y% F5 F! A; C              accepted, but gets refreshed in the response. This maintains the
" t% ]& q$ G: I- Z0 q              ability for admins to access their sites. Cookies that have a
  D% j& A- P$ @" m: \              date in the future further than 24 hours are ignored. Doing so
  Y. ]$ [5 }5 g              lets admins fix timezone issues without risking kicking users off
' o8 n; H. F3 {              the site.
1 y" {7 b' v1 ]) m) t
; c; p3 C0 m$ O1 L# s    maxlife   This option allows inserted cookies to be ignored after some life) g2 C+ f" ~2 x& U1 A0 l5 x
              time, whether they're in use or not. It only works with insert
* u7 U. j9 v! }" Y4 {: H              mode cookies. When a cookie is first sent to the client, the date
) M' U; O. X! u" ~              this cookie was emitted is sent too. Upon further presentations
+ m2 x5 {) a* E3 S              of this cookie, if the date is older than the delay indicated by* d2 A$ y3 }7 T; Z; b* r7 o: L
              the parameter (in seconds), it will be ignored. If the cookie in0 f3 O* v2 ?% h6 ?$ Q
              the request has no date, it is accepted and a date will be set./ a9 n* j6 E  T1 \, X- L
              Cookies that have a date in the future further than 24 hours are" _+ D5 d$ x5 ?: _6 y
              ignored. Doing so lets admins fix timezone issues without risking0 s7 q: }/ k. E/ {: N: V9 d
              kicking users off the site. Contrary to maxidle, this value is
! I1 ]# U/ L! P              not refreshed, only the first visit date counts. Both maxidle and
4 J8 J; \, P' Q+ b+ [* Z: J# E" r              maxlife may be used at the time. This is particularly useful to
+ r; h8 I0 ~; E) z  `: u              prevent users who never close their browsers from remaining for
$ R; W+ I2 V1 Q2 h. d2 `              too long on the same server (eg: after a farm size change). This) }/ b1 o/ `( W+ X0 D3 L7 x6 w
              is stronger than the maxidle method in that it forces a3 r; n3 c" @+ c1 i
              redispatch after some absolute delay.
  b3 m6 t. y9 {  |# G# N4 q9 s
9 E% ^6 ]. c( f( Z: C- N  There can be only one persistence cookie per HTTP backend, and it can be
3 d3 K# J9 e) D" y& j1 _  declared in a defaults section. The value of the cookie will be the value6 g- C  `; ^: S0 P. A
  indicated after the "cookie" keyword in a "server" statement. If no cookie, C3 T; [1 T' l+ P8 z
  is declared for a given server, the cookie is not set.
( N) O% p+ N3 P
- c* q0 u2 \( F0 @# h  Examples :- L6 K$ e- Y3 S  l7 W* P
        cookie JSESSIONID prefix
' G) E  s  u  d5 d& J- b        cookie SRV insert indirect nocache1 ~1 s) y6 }/ y9 O' a; e
        cookie SRV insert postonly indirect
0 U+ t& I: {1 v4 U" E        cookie SRV insert indirect nocache maxidle 30m maxlife 8h
2 ?( t9 M3 L/ w( C: ^" r5 m1 e8 O+ o& f2 N1 c
  See also : "appsession", "balance source", "capture cookie", "server"
$ m* F3 s, l/ x+ ~  C             and "ignore-persist".) u4 \( O" i4 z9 C) N! F5 v0 l

3 Z% C! T9 I) h1 U) i
! p" f; h6 M7 s5 ~6 |6 @default-server [param*]
1 A# y' u/ r4 Z2 x# N" [% K5 k4 _  Change default options for a server in a backend4 I( y7 F$ K  O: o) ~% R
  May be used in sections :   defaults | frontend | listen | backend! w! \) P+ K' ^& ]; J
                                 yes   |    no    |   yes  |   yes
6 b5 t3 E8 q3 m  Arguments:
% O) q5 [9 t" X, F3 @    <param*>  is a list of parameters for this server. The "default-server"3 f. D: R+ d. ]7 `9 T
              keyword accepts an important number of options and has a complete
3 A! Y1 p- a- b+ t) w              section dedicated to it. Please refer to section 5 for more9 w* }; q3 B2 {  m# w8 T4 T
              details.
* c: N$ L4 Z* [# A" ?( Z! h$ ?9 o9 [1 M
  Example :/ [" \1 n( c& q  m( [
        default-server inter 1000 weight 13
* W; U8 _+ l3 }- j5 A
* a+ r* A$ g; f1 t3 X  See also: "server" and section 5 about server options
0 F3 H$ ?/ W# r6 L& y6 C/ ]# l
; s$ X* S) L' n$ k( r( \4 d! v/ @5 a/ {! p5 E% A
default_backend <backend>3 p1 `. ?! P3 i0 w" ?- e7 J
  Specify the backend to use when no "use_backend" rule has been matched.* G' s( [% G3 m% V
  May be used in sections :   defaults | frontend | listen | backend% y5 a3 F. [: [. `3 g& z7 v
                                 yes   |    yes   |   yes  |   no# A8 M9 ~% Y  x1 q# ^
  Arguments :( G! V( c$ U" m  }' W6 ]
    <backend> is the name of the backend to use.9 B+ e: U4 B8 V$ M+ W6 z. l7 v. @% s

6 g: u6 L& _$ N  When doing content-switching between frontend and backends using the( D' C8 w- \( `0 q
  "use_backend" keyword, it is often useful to indicate which backend will be" D- v: I- ?) x6 T# m4 o4 r. [
  used when no rule has matched. It generally is the dynamic backend which; v2 ^3 [/ Y: u+ _! m$ w0 ~
  will catch all undetermined requests.
3 z* c" U5 G: @0 |/ S7 \# s
* \* d$ A, [* Q) w( A: e  Example :
. H  V% h/ X0 O! _
+ P3 `6 B- r  T        use_backend     dynamic  if  url_dyn
% L8 g4 V7 e% e( P8 p        use_backend     static   if  url_css url_img extension_img
$ L8 P4 k2 q* r5 z' L8 P        default_backend dynamic
4 b2 ]8 ~5 Y7 U! U7 C8 C+ K. ?0 v  i
  See also : "use_backend", "reqsetbe", "reqisetbe"2 u, t5 ^; K! R! @' Q( u1 v( }- W! N/ D

% e  m2 w  T. ^  T: R
' S; @5 v" @9 L) |. M  h; G# q# xdisabled
* `! j! O5 y* x& R' E( Q  Disable a proxy, frontend or backend.
4 e- V& h! X6 V  May be used in sections :   defaults | frontend | listen | backend
  T+ f4 b4 r% T! V- b5 f+ M2 n) v                                 yes   |    yes   |   yes  |   yes
$ }+ H' P9 P8 d! N, v+ B5 J; {  H  Arguments :
. z" ]0 j# r3 ~* I  W4 Y* J7 Y- u8 N" c) }% L2 i
  The "disabled" keyword is used to disable an instance, mainly in order to: j& Q! U. W/ y, B2 L+ T7 q
  liberate a listening port or to temporarily disable a service. The instance
$ z1 J8 J" ]2 h0 ], \- y  will still be created and its configuration will be checked, but it will be
( V5 p8 t- g6 L; y' [. ^! c$ ~# n  created in the "stopped" state and will appear as such in the statistics. It3 @* X; ?5 V$ C( s
  will not receive any traffic nor will it send any health-checks or logs. It( L9 B$ ^! G2 m- z" ]- }( `
  is possible to disable many instances at once by adding the "disabled"( s, t, {3 r# y
  keyword in a "defaults" section.
: w- S/ g, }; l/ E4 L3 F5 E( I8 n$ X  W( E4 ]% g; B, F
  See also : "enabled"
9 u% r0 V2 F0 V4 Y6 w* E( \! v! l( G
: d: t) B( g: s5 y9 J
dispatch <address>:<port>
+ v, k- [& y: j6 r2 ?2 v- z  Set a default server address
5 T! y5 I2 t5 k& R9 U( `  May be used in sections :   defaults | frontend | listen | backend( N4 e. n% n+ I8 s0 |2 t
                                 no    |    no    |   yes  |   yes/ Q9 J/ v" z. x7 {: \' W
  Arguments : none2 u" N- U( N& X
1 Z# B8 n: X& d
    <address> is the IPv4 address of the default server. Alternatively, a2 u$ H  f. S/ A
              resolvable hostname is supported, but this name will be resolved
8 p1 B: }6 Y8 W              during start-up.* T* F/ y& Z  M7 e! \* q# X# W1 W) S
; V5 |; s) y2 L" {  A
    <ports>   is a mandatory port specification. All connections will be sent
' Y# d, Y- T4 m5 _              to this port, and it is not permitted to use port offsets as is
/ `- ?- V0 U# \3 I  e+ r              possible with normal servers.
6 e5 e  H8 _/ W* _0 Q& h3 a
( o+ ]3 T; h3 |1 x5 e+ L  The "dispatch" keyword designates a default server for use when no other
  k0 X  I1 h( B* b( `, y0 }2 D  server can take the connection. In the past it was used to forward non/ o( V% U# F1 m" u6 w
  persistent connections to an auxiliary load balancer. Due to its simple
5 e3 Y& f3 w7 [" ]  syntax, it has also been used for simple TCP relays. It is recommended not to/ E- ^' ?7 h: ?: `
  use it for more clarity, and to use the "server" directive instead.
# L& G& k% Y- ~* P& |6 R
4 q6 E$ l. o( ]* x: |6 W* k: @$ i  See also : "server"
; e2 V* T# }8 {. F' A/ l/ A! Q( s9 }; w

6 O' ?' _5 {. O. _% a' `enabled" l( ^5 C) K0 Z' d) }7 `* H
  Enable a proxy, frontend or backend.
, r7 p( x: ~$ c. G6 N2 e  May be used in sections :   defaults | frontend | listen | backend9 y! n1 J4 _$ {! C1 k: z
                                 yes   |    yes   |   yes  |   yes! I6 _$ L  A6 y( g. T
  Arguments : none3 ^: n- s2 P! i4 |' @& O

+ i% N( l+ @; i& S6 ^  The "enabled" keyword is used to explicitly enable an instance, when the" [( b) c1 n- W
  defaults has been set to "disabled". This is very rarely used.
* s$ r4 z' h9 F) I% x1 b
, s5 Q" Z+ c% B7 D0 b  See also : "disabled"; G3 T$ `3 _4 Z
. d8 x( c. ^: G5 x0 h$ F

: i, `" P* @; B7 v( X7 Oerrorfile <code> <file>
2 |* {1 f: r7 F# g2 b$ L  Return a file contents instead of errors generated by HAProxy
' s' I. o0 J" W# g6 w# c  May be used in sections :   defaults | frontend | listen | backend# |5 q& L$ x- W/ w3 S
                                 yes   |    yes   |   yes  |   yes
% S; Q( p3 M9 s5 U  Arguments :
& i" f) \' w% ~- S; G5 g  G/ @    <code>    is the HTTP status code. Currently, HAProxy is capable of
  k# e7 u$ J% D9 V0 q              generating codes 200, 400, 403, 408, 500, 502, 503, and 504.
: \$ }+ I& ^  W% z- o# h5 M5 l4 w( [1 S
1 i0 H9 j; {) T( S. g: p9 x    <file>    designates a file containing the full HTTP response. It is8 E' g. v: U7 s$ c; N' v
              recommended to follow the common practice of appending ".http" to( y1 _/ |% s. n' w
              the filename so that people do not confuse the response with HTML
5 ~+ U  t6 W+ E2 s8 X              error pages, and to use absolute paths, since files are read
# i. N( s2 n8 N# Y9 A) p              before any chroot is performed.
- x! f8 H4 r9 Q, U& r' g7 b5 u1 R. i& L( }* h7 J
  It is important to understand that this keyword is not meant to rewrite
* f  x! {/ ^" e  errors returned by the server, but errors detected and returned by HAProxy.+ X  M) l: q% ~3 C4 D0 ^% j
  This is why the list of supported errors is limited to a small set." r: A# O- c: f. u( X$ i: u

+ B, |% P( w- N5 L  q: l  Code 200 is emitted in response to requests matching a "monitor-uri" rule.( Z4 `- Y- V1 f/ s! q% T

. M. k' |- l) [' Q/ l3 H5 w  The files are returned verbatim on the TCP socket. This allows any trick such
  J" u% |2 _9 O6 G  as redirections to another URL or site, as well as tricks to clean cookies,! b& G( P- p2 [" k8 I
  force enable or disable caching, etc... The package provides default error. _2 S6 s- u1 m2 H: m2 Y# K8 U
  files returning the same contents as default errors.
5 [6 b/ P3 P" I# }- y+ v! @: Y3 L) }- ^3 e* y! H2 @  l1 }3 Y4 ?% p: i
  The files should not exceed the configured buffer size (BUFSIZE), which
: |3 `- a: ]1 ]5 d  generally is 8 or 16 kB, otherwise they will be truncated. It is also wise
9 F& b6 P. D0 |% O: z% s1 C  not to put any reference to local contents (eg: images) in order to avoid
# p6 }5 B% _( T0 e7 z  loops between the client and HAProxy when all servers are down, causing an
2 ^8 u( R, e. a) O" C; l% g  error to be returned instead of an image. For better HTTP compliance, it is
( j2 Q8 N, ]9 d; r6 O/ Q. v, b  recommended that all header lines end with CR-LF and not LF alone.
( W' ^0 u0 C4 o- A3 M- G  U! J3 L/ j& e
  The files are read at the same time as the configuration and kept in memory.' a5 v9 y  Z; |  s* ?
  For this reason, the errors continue to be returned even when the process is
$ }$ z) @& N) x  chrooted, and no file change is considered while the process is running. A
8 q, A# X. l$ i# O9 E  simple method for developing those files consists in associating them to the
' \9 \) K$ N1 `8 g! j% T  403 status code and interrogating a blocked URL.1 T  M; b8 m7 t7 G6 T
% Q3 N  O/ f2 o9 H, ~
  See also : "errorloc", "errorloc302", "errorloc303"% T1 Z0 C1 ^/ X: K$ s8 Z

8 Z6 f: ]+ v% Z4 Q* K* x  m  Example :6 @7 }- _4 k7 w9 [3 H
        errorfile 400 /etc/haproxy/errorfiles/400badreq.http
4 `4 f6 s6 m7 T        errorfile 403 /etc/haproxy/errorfiles/403forbid.http
( m5 {* l- t: V' D. ?/ g/ a' |        errorfile 503 /etc/haproxy/errorfiles/503sorry.http+ h2 [8 f: S, E4 y- R

# S5 L& K  C) d/ F7 y* u  K& y9 K+ F9 R. q) Y# y4 L
errorloc <code> <url>
6 q( d' Z4 H# K% @errorloc302 <code> <url>
7 o5 L: @) h' n$ B% W: l  Return an HTTP redirection to a URL instead of errors generated by HAProxy
0 x, J8 n) ^: T1 A+ O$ o" ^  May be used in sections :   defaults | frontend | listen | backend
$ q  F! ]  t; C2 W5 N5 G                                 yes   |    yes   |   yes  |   yes: G' ^0 M- B, M$ w! \
  Arguments :  I2 m) [' q( |. k2 _8 C' d
    <code>    is the HTTP status code. Currently, HAProxy is capable of7 t- G! b, {) x# N/ g# b8 ?
              generating codes 200, 400, 403, 408, 500, 502, 503, and 504.% [8 N. N: P* r+ }' U: n
/ @8 O6 q9 h9 E+ C9 D  t2 w4 F+ ]
    <url>     it is the exact contents of the "Location" header. It may contain
$ C, ~1 S4 x6 ?* G# R0 U# v3 K              either a relative URI to an error page hosted on the same site,
$ w; h; `2 B% ]8 r' {4 F- h              or an absolute URI designating an error page on another site.0 J- i6 ?, K6 ]6 W/ @
              Special care should be given to relative URIs to avoid redirect* D1 I5 G/ r, c) X+ f: V
              loops if the URI itself may generate the same error (eg: 500).0 Z0 e3 Z: ]) a4 Q, m

$ D( B9 W& o: L  It is important to understand that this keyword is not meant to rewrite
& _2 c) ]' k3 F4 e. M5 Q  errors returned by the server, but errors detected and returned by HAProxy.3 _9 ~2 N2 M4 j# D
  This is why the list of supported errors is limited to a small set.
$ E) ?. j9 G+ h! s; k9 j7 M/ B: ^4 y4 ]3 L$ d
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.& X7 y- x# B8 U

- N& a8 C7 _: e# H! t  Note that both keyword return the HTTP 302 status code, which tells the
" W, \9 B- [# ?* j% C7 c  client to fetch the designated URL using the same HTTP method. This can be8 w! @- e$ y! m* y- W/ f
  quite problematic in case of non-GET methods such as POST, because the URL
' S$ N5 ^4 C2 _) g$ p  sent to the client might not be allowed for something other than GET. To
- @5 i# `! Y5 h! i1 f, ^7 Z! `$ ~  workaround this problem, please use "errorloc303" which send the HTTP 3031 I# {8 A7 N( l+ i' f
  status code, indicating to the client that the URL must be fetched with a GET9 K  s# u' o4 {2 h% _9 o) t
  request.7 J1 e+ `. X# i4 a2 K+ R, _8 @3 L
0 r9 e* g5 k" J' H
  See also : "errorfile", "errorloc303"7 c9 W! v6 [; v5 v/ {5 n' @+ g

! r& @# T# r. r! v# c" ?! d' C, g# W
errorloc303 <code> <url>+ B) l9 V! X# ]* M
  Return an HTTP redirection to a URL instead of errors generated by HAProxy/ _0 A; ~8 c2 H/ f
  May be used in sections :   defaults | frontend | listen | backend, E  D/ [1 A1 X% e8 `2 i
                                 yes   |    yes   |   yes  |   yes
; H6 p* z1 z" g- K% H  Arguments :4 e  d' d9 \! y% b6 G+ o
    <code>    is the HTTP status code. Currently, HAProxy is capable of8 s6 |. b1 M1 |& V! b8 n1 R% l
              generating codes 400, 403, 408, 500, 502, 503, and 504.
6 x6 }' g5 Y  z6 g6 d. \& S6 Q+ [3 V$ n2 M2 Q
    <url>     it is the exact contents of the "Location" header. It may contain5 v6 ?2 }$ J0 a+ u2 f; Z
              either a relative URI to an error page hosted on the same site,
$ q% n* k7 ?8 |+ S              or an absolute URI designating an error page on another site.
! X* N9 Y" O8 Q' Z              Special care should be given to relative URIs to avoid redirect7 ~5 L9 G2 q, z8 o3 D- x; z6 W) U
              loops if the URI itself may generate the same error (eg: 500).* `, z; y/ h2 x5 E- P
% l, R# Z/ w1 P3 h. _  A
  It is important to understand that this keyword is not meant to rewrite/ B. v, c. i' ^( i
  errors returned by the server, but errors detected and returned by HAProxy.
6 t# |2 L$ S& ]" U) ^" ~! ~/ T( c4 C  This is why the list of supported errors is limited to a small set.
. ^9 s" p5 q% F3 @. \' k: x1 b3 R; X% T! i, ~2 g; F# V- `: x9 R9 z7 j, O" e
  Code 200 is emitted in response to requests matching a "monitor-uri" rule.$ U# k/ Z7 b$ G0 z) x) _( @

# O: \# Z& ?9 U( h* N9 A  Note that both keyword return the HTTP 303 status code, which tells the+ J1 N% Y, a2 o. K7 x/ |
  client to fetch the designated URL using the same HTTP GET method. This
& H0 [" R7 e7 D( I: U" k& ~& l2 i  solves the usual problems associated with "errorloc" and the 302 code. It is# U8 f3 M) o' _/ l* y
  possible that some very old browsers designed before HTTP/1.1 do not support7 }3 r; M( k2 l+ |
  it, but no such problem has been reported till now.$ T5 B/ Z2 I$ R
+ h1 u3 h' k( V' u
  See also : "errorfile", "errorloc", "errorloc302", a* s7 c( g: ~+ [) m4 ?$ K' f2 h  M

9 D% q& S0 x( ]. o! w/ ?+ M0 C) D* A+ E
force-persist { if | unless } <condition>' t3 a; b" T( V1 g4 H
  Declare a condition to force persistence on down servers3 m! n3 I6 K- r0 w' E: e3 [
  May be used in sections:    defaults | frontend | listen | backend
! C/ @+ P1 e  ]                                  no   |    yes   |   yes  |   yes
/ P: B2 z1 D$ X( }6 Z3 {, m) R6 e. Z1 X" h* z5 m" O
  By default, requests are not dispatched to down servers. It is possible to
/ F9 ~  W1 b- h3 k# [  force this using "option persist", but it is unconditional and redispatches
1 J3 W  j9 l8 u  [! v  to a valid server if "option redispatch" is set. That leaves with very little- c, i; E  b  F# ?" V
  possibilities to force some requests to reach a server which is artificially
; u* W0 k# K6 i3 V& ~+ o. f! _  marked down for maintenance operations.
) b1 _; j1 Q7 S4 ~6 N: X
8 R; r4 Y: x6 W4 c* M! c  The "force-persist" statement allows one to declare various ACL-based  g7 D, @, {+ W1 U
  conditions which, when met, will cause a request to ignore the down status of
* b$ G4 x/ q( ], Z2 M* z  a server and still try to connect to it. That makes it possible to start a
1 z* o; ~6 z) R3 ?  server, still replying an error to the health checks, and run a specially, r: X9 J) R3 f7 `& p6 u( F
  configured browser to test the service. Among the handy methods, one could- s' ^/ Y/ i; c: h( k/ G
  use a specific source IP address, or a specific cookie. The cookie also has
. T; Z; G7 H5 p7 Z3 p) P  the advantage that it can easily be added/removed on the browser from a test
4 N8 O% u, ~. p  page. Once the service is validated, it is then possible to open the service
7 M0 L6 E4 I1 E  to the world by returning a valid response to health checks.- ?- }1 f) X: j! L1 v2 |+ E

% G8 C) r  a7 ?  i- j# z  The forced persistence is enabled when an "if" condition is met, or unless an0 K8 U! I% @4 p% y
  "unless" condition is met. The final redispatch is always disabled when this3 r' B* S4 b9 z. P
  is used.
% i6 Y+ f3 n1 r9 c. g9 X1 u, Y
! w# m! `$ o5 }# o  See also : "option redispatch", "ignore-persist", "persist",
% d" ^& c$ e, Q4 N             and section 7 about ACL usage.' }# A& ^% D! O4 u. Z

0 A1 o( L7 }$ i; B( u9 V9 {
% K! A+ O7 ^0 Q8 Z* A  z' mfullconn <conns>
4 v: M0 h6 a7 \, Y  Specify at what backend load the servers will reach their maxconn
; S8 x  W5 K" [0 \9 H& l/ Y  May be used in sections :   defaults | frontend | listen | backend+ b* H. m: s% q4 j
                                 yes   |    no    |   yes  |   yes
$ f6 d* V) H) n! U( `( ~  Arguments :+ b3 G# u# u1 x# u
    <conns>   is the number of connections on the backend which will make the
! z; [1 P) r( f" ^- G; d  G1 o              servers use the maximal number of connections.
! s* G, H( p; @' Z+ E) {% h5 y* Q* r. u. A/ w* G, s+ b/ S
  When a server has a "maxconn" parameter specified, it means that its number$ U% H5 }: m% d' Q* N" ^
  of concurrent connections will never go higher. Additionally, if it has a
  M. B' p1 k5 f1 |7 f8 ^; c  "minconn" parameter, it indicates a dynamic limit following the backend's
' A7 c, J4 T2 I5 j7 S  load. The server will then always accept at least <minconn> connections,
- ]  f6 X: `  h  never more than <maxconn>, and the limit will be on the ramp between both
  d$ y7 t/ Y* y6 E  values when the backend has less than <conns> concurrent connections. This& N* f& e8 L+ p3 Y
  makes it possible to limit the load on the servers during normal loads, but& L) J" {6 w5 P0 K5 x7 C
  push it further for important loads without overloading the servers during* G7 N  J+ e/ k3 ?* S* r  q7 g/ h
  exceptional loads.
' \2 Q' g1 G$ q( k4 x# s5 L6 D! h6 x4 E& m8 R
  Example :
/ t: `& K& o; w+ s4 ~& q     # The servers will accept between 100 and 1000 concurrent connections each
* E" o6 i3 I  Z: v% k     # and the maximum of 1000 will be reached when the backend reaches 10000
3 @5 h) h; S# r: E     # connections.
" L5 _% s+ o( x$ I1 `+ i     backend dynamic
9 Y  T' H" B5 W& u( |% N$ J        fullconn   10000$ Z5 G% d$ C" N4 T7 y
        server     srv1   dyn1:80 minconn 100 maxconn 1000
* B" Z0 V4 \! f7 S# a        server     srv2   dyn2:80 minconn 100 maxconn 1000
3 [  g$ S) N. Q  o+ x8 z* g
0 F! c- C. c# z. V, J5 s0 T  See also : "maxconn", "server"4 D: `/ t. @2 f+ p

0 x$ V& C& R% K1 |% ^7 A$ j
6 U: _4 S1 [6 s% q+ w) Sgrace <time>
; X) v: {# h+ Y1 w) c  Maintain a proxy operational for some time after a soft stop7 H% A$ f+ D# `- O" V" a; S+ U
  May be used in sections :   defaults | frontend | listen | backend9 U3 O( S; [9 ^# G8 j
                                 yes   |    yes   |   yes  |   yes+ q, d. N3 u0 n: X
  Arguments :
3 G4 {' ~# I, |    <time>    is the time (by default in milliseconds) for which the instance
1 b* j+ u. P% F; P) O              will remain operational with the frontend sockets still listening6 {. P3 z6 \! M6 `
              when a soft-stop is received via the SIGUSR1 signal.+ B$ V/ B4 n& S) L. T+ k1 k4 D
# C' W$ W4 Y# N0 A
  This may be used to ensure that the services disappear in a certain order.
8 K% e, E. [5 n" k  This was designed so that frontends which are dedicated to monitoring by an3 R' W* J  r3 k) E
  external equipment fail immediately while other ones remain up for the time6 E6 L9 I2 z" s. B; J" |) Y6 I! ?; }
  needed by the equipment to detect the failure.. x. r; }2 Y0 o! ]
: \* E6 k# i3 r9 i
  Note that currently, there is very little benefit in using this parameter,
/ L# |# w" l/ ^$ ^! I2 h( h  and it may in fact complicate the soft-reconfiguration process more than% L1 H$ `' M5 d: o( `+ i
  simplify it.
2 |& ?0 I. x) G  ^
2 }. @, ~1 t4 r2 h  R
, S9 U6 O% w- ]hash-type <method>
. ^  m+ v; b5 p' M  L% P  Specify a method to use for mapping hashes to servers
3 Q; a: i3 E5 i( Y' z6 B  May be used in sections :   defaults | frontend | listen | backend
# }# D( \4 g- L7 u$ l% D: ^                                 yes   |    no    |   yes  |   yes' H: s' u8 Z1 D3 n, k* E
  Arguments :
4 N  {5 e4 J% B% H4 A    map-based   the hash table is a static array containing all alive servers.( C1 ]6 z8 k# w4 d7 N- U
                The hashes will be very smooth, will consider weights, but will
  P+ L0 r4 r# n: w/ m2 P1 k                be static in that weight changes while a server is up will be
' Z, j" ~0 N3 Y+ g7 h: y                ignored. This means that there will be no slow start. Also,
) i. p* z9 A2 j# q2 H                since a server is selected by its position in the array, most
: y/ J: A) `8 ^2 h/ f  H                mappings are changed when the server count changes. This means
) @$ m" s" Z, c" q7 w. L/ R                that when a server goes up or down, or when a server is added% r5 d" l& w* A4 Q( Y) @3 o9 ]0 T. @. ^
                to a farm, most connections will be redistributed to different
+ T; P8 q( {5 U5 Y: V% X9 \. [                servers. This can be inconvenient with caches for instance.
  B. i% V9 j+ L& Q% ~0 e7 ]2 V
# G4 w' \2 _" A6 K# l1 ?6 V) L" |7 h    consistent  the hash table is a tree filled with many occurrences of each
" G7 |, ~, C: d' q                server. The hash key is looked up in the tree and the closest# A8 y" u8 g% R( `
                server is chosen. This hash is dynamic, it supports changing
/ k. x  {' A' ^6 T                weights while the servers are up, so it is compatible with the, C9 q7 D5 P/ }. o7 k$ c  w4 W
                slow start feature. It has the advantage that when a server
; C0 R( d5 }: [3 |/ p                goes up or down, only its associations are moved. When a server0 W3 \" V9 |1 l
                is added to the farm, only a few part of the mappings are
. m" R  F0 v6 h- j' J& a                redistributed, making it an ideal algorithm for caches.
* a9 }- S9 ]2 T5 [4 f, m3 L  c                However, due to its principle, the algorithm will never be very( o5 d: c3 F8 ]1 _$ C6 _1 O
                smooth and it may sometimes be necessary to adjust a server's
$ t- A9 R. U5 Z; o# o                weight or its ID to get a more balanced distribution. In order* i; K: ?, w: w8 \2 J$ }' J3 Z
                to get the same distribution on multiple load balancers, it is
; r" I7 b1 k, v! d# g" U                important that all servers have the same IDs.
; @. o2 B& {  I& I! i; F% v
5 f/ v  ~$ `( ?% W% v  The default hash type is "map-based" and is recommended for most usages.
, C: V1 f7 B- p6 s$ |6 y% a% L) N0 n. m
  See also : "balance", "server"; c8 t. {  E0 T3 ]- b7 a
$ I. Q. W0 S6 l: ]) L2 \0 p* ]
1 W7 R! S" r, T! @
http-check disable-on-404
0 J% u/ |! N; o! o' B  Enable a maintenance mode upon HTTP/404 response to health-checks
/ q( Y7 G' A8 F: |  May be used in sections :   defaults | frontend | listen | backend
: y/ p% n0 J" g! }                                 yes   |    no    |   yes  |   yes5 C0 w# n2 L7 d5 n9 l! T' Q+ N% S3 }
  Arguments : none
! Y2 ^& ^& s) j
/ Q; |$ ^" E" p' F  When this option is set, a server which returns an HTTP code 404 will be
6 W7 \, Q" K% y* J$ b  excluded from further load-balancing, but will still receive persistent7 [. m& c% I# }! _3 s+ L
  connections. This provides a very convenient method for Web administrators
! h" A0 q9 x0 ~  to perform a graceful shutdown of their servers. It is also important to note
  i5 e4 S/ ~$ I5 t& L* O  that a server which is detected as failed while it was in this mode will not9 N% H% Z5 B- }; z- n
  generate an alert, just a notice. If the server responds 2xx or 3xx again, it( S: A2 c2 e8 I7 P: g5 \" B
  will immediately be reinserted into the farm. The status on the stats page$ Z5 y' W0 B2 F3 u: \, W: ^0 H3 J
  reports "NOLB" for a server in this mode. It is important to note that this  ~6 ^' y* ]/ _# x* K
  option only works in conjunction with the "httpchk" option. If this option
8 k* q! ~5 p" A  is used with "http-check expect", then it has precedence over it so that 404
  @& Y6 P* s  x$ j/ @# J/ Z  responses will still be considered as soft-stop.
$ d3 [. {6 N) {( I' T+ d4 W/ t, D# m, r
  See also : "option httpchk", "http-check expect"
$ e/ S8 p5 p* X3 a" e4 p; E4 j2 q5 L. O) D/ {

/ o3 Z/ L+ d- ~% e! r3 A& uhttp-check expect [!] <match> <pattern>: z, V& B5 W$ i( @7 L; u6 n
  Make HTTP health checks consider reponse contents or specific status codes- Y$ |. N! `1 _1 E' x. ~
  May be used in sections :   defaults | frontend | listen | backend1 D' K) Y5 ], w
                                 yes   |    no    |   yes  |   yes
* W- Q& h, d9 s  Arguments :
$ h+ h0 r5 N: w& t    <match>   is a keyword indicating how to look for a specific pattern in the7 q# v7 z. Z) h) A8 g$ w" P
              response. The keyword may be one of "status", "rstatus",1 L# \( W0 n+ B) ]) p: V
              "string", or "rstring". The keyword may be preceeded by an
7 F: ~1 x. }* M/ D2 {- c2 S              exclamation mark ("!") to negate the match. Spaces are allowed0 `1 h# b$ @) g5 t6 y' s+ Y9 N
              between the exclamation mark and the keyword. See below for more$ R! w. L' L) K8 ^! g
              details on the supported keywords.: _, Y" C* K8 A3 Q, g& X% T" p
/ @0 @& a, _% W) @
    <pattern> is the pattern to look for. It may be a string or a regular; C9 X. I7 p) ^+ o5 {& r
              expression. If the pattern contains spaces, they must be escaped( ]" g; s; D2 S! D9 L9 k5 J# T" I+ `
              with the usual backslash ('\').* J3 E4 e+ m5 Y% w/ h

' k- g& m# n6 J0 k4 k/ J0 s. e  By default, "option httpchk" considers that response statuses 2xx and 3xx* q8 P5 M! k* ?
  are valid, and that others are invalid. When "http-check expect" is used,
* e* ]1 m+ s' |' j  it defines what is considered valid or invalid. Only one "http-check"! D, k6 [7 j5 H" H$ Y3 f
  statement is supported in a backend. If a server fails to respond or times" K4 K. [1 o& X/ X. [! G0 {, _" p
  out, the check obviously fails. The available matches are :
8 K( m: I; m9 N% n- |- M8 D0 i. q/ O, d, k6 g% {  n$ g9 i" S
    status <string> : test the exact string match for the HTTP status code.7 A, W1 w% d. N# N2 F
                      A health check respose will be considered valid if the
5 `/ R% m* r) u' h9 Q( |3 b; q                      response's status code is exactly this string. If the
. K* C" s3 L, V, p! [$ [3 h                      "status" keyword is prefixed with "!", then the response
. _) R1 c3 Q# M9 p" t! a) O                      will be considered invalid if the status code matches.& z6 E% W) A3 j$ S  p- C

: j* P6 n3 ^3 z5 t: @: s4 P5 n$ g    rstatus <regex> : test a regular expression for the HTTP status code.# ]4 ~- X: b$ E, s
                      A health check respose will be considered valid if the+ w9 a* R/ T% n) ~% b% A
                      response's status code matches the expression. If the4 m2 c' j5 o' }4 K  Z# k
                      "rstatus" keyword is prefixed with "!", then the response
& o7 P; d6 |; m& L. ]% G1 }1 I8 z7 u                      will be considered invalid if the status code matches.
6 i. X$ }4 O; i6 k; P- Z( l# h                      This is mostly used to check for multiple codes.) X' Z  ~% H! ]2 Q1 {1 V$ e6 H

  A- r# y8 y/ i3 ]( D$ c, W    string <string> : test the exact string match in the HTTP response body.) D" k9 m! P, L- @
                      A health check respose will be considered valid if the
3 ^: e+ j4 k( c& E' r. ]                      response's body contains this exact string. If the
+ x* R% H' \* U, y0 D                      "string" keyword is prefixed with "!", then the response
, n) [) _. l5 R7 o0 f                      will be considered invalid if the body contains this* P, A9 T) e/ y0 L* @9 U7 O* M
                      string. This can be used to look for a mandatory word at' {9 Y* l4 Y+ @% H+ P- o9 \% l
                      the end of a dynamic page, or to detect a failure when a
) ?0 H, |  W9 I                      specific error appears on the check page (eg: a stack7 w1 _  `% x4 U: u& p4 {2 Q) h
                      trace).
. S* M1 d2 |2 d" V% @, C8 M  V! Q3 G! k4 f. F  w, D
    rstring <regex> : test a regular expression on the HTTP response body.
# Y& D8 b9 {; O9 H8 R                      A health check respose will be considered valid if the* G* V7 a$ Y# R# p9 h
                      response's body matches this expression. If the "rstring"
4 o# \; J2 s9 V3 |                      keyword is prefixed with "!", then the response will be( d* q/ N1 v- a/ o" Y. O6 M
                      considered invalid if the body matches the expression.4 n, |! y( ~9 r$ Z6 f" w8 H
                      This can be used to look for a mandatory word at the end
# T# |/ A1 h) K  v3 p" r& F: Y, r                      of a dynamic page, or to detect a failure when a specific* e9 S( B+ Z: K9 I* X
                      error appears on the check page (eg: a stack trace).' S$ @  V; Z; y* }5 v$ r  |2 B

9 b( ?4 U  h& _0 m7 O9 F" s  It is important to note that the responses will be limited to a certain size
% w9 `* T' l! B3 m" b  defined by the global "tune.chksize" option, which defaults to 16384 bytes.! j4 S- }9 C# y
  Thus, too large responses may not contain the mandatory pattern when using" b; d& ]* o) R- l# t6 i
  "string" or "rstring". If a large response is absolutely required, it is4 N5 M3 c& Y* I  C/ E
  possible to change the default max size by setting the global variable.
/ t: W* Q/ S" B0 x6 U  However, it is worth keeping in mind that parsing very large responses can
( N/ O4 g" V1 r' O. i4 t# g  waste some CPU cycles, especially when regular expressions are used, and that3 @+ `1 c, b1 L/ i* \- L
  it is always better to focus the checks on smaller resources.
- D& Z" {/ S" e, O) x) _; C- Z* N
& e! ?, p' w7 u/ \2 C( q  Also "http-check expect" doesn't support HTTP keep-alive. Keep in mind that it; |8 o1 A  }: |: I# ^
  will automatically append a "Connection: close" header, meaning that this
2 Z$ E4 i3 K3 d- t2 u7 U1 _  header should not be present in the request provided by "option httpchk".
+ V' F( a" T4 F5 u5 `) r5 }6 j6 O) ^4 |3 V
  Last, if "http-check expect" is combined with "http-check disable-on-404",( h  f# |/ ]* D+ }
  then this last one has precedence when the server responds with 404.
; @2 y' }0 X7 R. U" C6 ^+ l' I* a5 o, ?& F: W7 g! v. S, o
  Examples :
' j2 b1 e5 M9 J7 s3 D         # only accept status 200 as valid
" q* l/ d1 E0 J         http-check expect status 200
- p$ F* i5 L0 P- x1 ~, Q9 E: L1 C1 R( E" j$ V
         # consider SQL errors as errors5 ^  H3 U% k0 S  H" q4 Z) C1 k
         http-check expect ! string SQL\ Error2 h4 a0 i% x2 w1 S/ l
4 }' D" e# p0 A; x$ X
         # consider status 5xx only as errors
4 |+ ~% b" E8 }3 e         http-check expect ! rstatus ^5
/ E4 n* g9 F$ N# `. H
7 M! _3 ~7 {+ u, E         # check that we have a correct hexadecimal tag before /html5 H* Z, |  v2 ]
         http-check expect rstring <!--tag:[0-9a-f]*</html>
" E- E3 p0 }" Q& i$ l; U4 }
% w0 ^# [: p7 F% r# ?- j  See also : "option httpchk", "http-check disable-on-404"
, r; M6 X1 i; n! t8 F; Y# H2 F
) K1 f: H% m: v4 \6 H$ T  s5 W! ]1 S: J
http-check send-state9 ~7 H( u+ l- E  [4 }5 u
  Enable emission of a state header with HTTP health checks" Y: ]; Y) C2 c5 d  J4 Q
  May be used in sections :   defaults | frontend | listen | backend
/ [3 |  |( |6 V                                 yes   |    no    |   yes  |   yes6 K- M2 k1 v" \
  Arguments : none) g( u, o$ q+ I6 @0 ^) `; L

/ a  _2 p9 s1 r3 W. }  When this option is set, haproxy will systematically send a special header* P3 o3 l% o, q) T0 H
  "X-Haproxy-Server-State" with a list of parameters indicating to each server7 V# p5 A8 b9 b5 B
  how they are seen by haproxy. This can be used for instance when a server is
( I4 d4 @8 K4 |9 O* T  m  manipulated without access to haproxy and the operator needs to know whether
4 m9 h, i* T5 `  haproxy still sees it up or not, or if the server is the last one in a farm.$ j# D5 M/ b: D) V3 y
$ b( g; T/ @4 ?; S
  The header is composed of fields delimited by semi-colons, the first of which
% K9 a3 j5 K/ D+ T( x  is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid1 V+ h( V+ i5 W
  checks on the total number before transition, just as appears in the stats
2 g" [- I& c/ p' l  interface. Next headers are in the form "<variable>=<value>", indicating in
) p0 @( w1 O4 X  no specific order some values available in the stats interface :" q: D: m  @4 i5 B8 ?
    - a variable "name", containing the name of the backend followed by a slash0 L5 ~& u  j! E! `
      ("/") then the name of the server. This can be used when a server is. I3 _* z1 v2 V! O8 [
      checked in multiple backends.
- D/ d7 `8 V0 ~/ u% y$ @" M
. ~3 K! x+ b) ]' G9 S0 _    - a variable "node" containing the name of the haproxy node, as set in the4 I8 u7 j  r6 f$ I
      global "node" variable, otherwise the system's hostname if unspecified.
6 G( K" ]4 n) j/ x  K
* w5 ?: K: N" h9 c    - a variable "weight" indicating the weight of the server, a slash ("/")
$ ?: N' M7 [$ F3 d- o# i1 `      and the total weight of the farm (just counting usable servers). This- V* c3 t6 Q" v
      helps to know if other servers are available to handle the load when this
' J' v0 M0 {2 K      one fails.9 H+ v* G1 @  \) a- M+ @

, H& y# D) E; x' [: g* ]% R    - a variable "scur" indicating the current number of concurrent connections
* {4 ]& }& O- l7 h3 I      on the server, followed by a slash ("/") then the total number of) l! i2 c+ m7 i5 `# |5 P9 |0 i
      connections on all servers of the same backend.0 U* E( `7 p5 M3 k# [8 Z! O

" N, V& b. V# b    - a variable "qcur" indicating the current number of requests in the
- t5 a, h: M6 J' c/ `      server's queue.1 f* i" L$ [' e' R& A$ \

. L% {0 o# ^9 d7 K  Example of a header received by the application server :1 {6 Q& j8 y, D& Z
    >>>  X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \
/ r- h5 o, z/ V. Z           scur=13/22; qcur=09 F+ Z6 D, f5 T, ~/ e
7 L4 L0 v6 R% K
  See also : "option httpchk", "http-check disable-on-404"
1 L" q- }' x4 ], J" a& t; M7 r1 v) ~8 j
http-request { allow | deny | auth [realm <realm>] }6 K4 s" u4 N" `: @8 v2 l
             [ { if | unless } <condition> ]
; q, K# K5 A. [: I- a  Access control for Layer 7 requests
* i  `3 M$ ]7 A0 l6 d/ O
0 q# y( ], l& ?  May be used in sections:   defaults | frontend | listen | backend* m4 U4 E1 t2 z" q4 C' X
                                no    |    yes   |   yes  |   yes
) l; Q% l0 J+ ^* W, z4 G3 z8 O) Y$ C$ d
  These set of options allow to fine control access to a0 @+ K, A  y2 @! T& V
  frontend/listen/backend. Each option may be followed by if/unless and acl.
6 V' ]) C: |# f: z( b5 @) R" ~  First option with matched condition (or option without condition) is final.0 o1 ?6 F" g' `* k+ B- Z" S( {
  For "deny" a 403 error will be returned, for "allow" normal processing is3 J; c! \, [9 m! n" T5 z5 S
  performed, for "auth" a 401/407 error code is returned so the client
* y* `5 Z; O- i2 m  should be asked to enter a username and password.
! a3 h0 [+ ]% N$ C( ^1 M' d+ j6 i$ Z
  There is no fixed limit to the number of http-request statements per/ o6 k& l' f: f
  instance.1 D) ~, ^( X1 K2 U3 }( J8 O$ c

0 Q2 M3 l, e+ w) y6 L7 q  Example:6 P+ X/ D! q+ U2 V3 O/ y
        acl nagios src 192.168.129.3
; S& {2 o2 X) L0 |; j- ]* o4 `        acl local_net src 192.168.0.0/16, k6 A( T( g7 a4 S) M: p: L1 W
        acl auth_ok http_auth(L1)  Y5 o. H% Z2 P4 i$ A% v
! T, O. C& E+ C9 H3 l
        http-request allow if nagios7 Z2 n" p: W3 B. u# I
        http-request allow if local_net auth_ok: b: A1 {' S, \6 r
        http-request auth realm Gimme if local_net auth_ok2 i2 ~& a2 \/ _! f  n: x
        http-request deny
) g$ {0 M' ]8 A# |
6 P- o7 z/ c+ B, U" L* r" l+ h  Example:
, F* ?( u/ n/ P, W' Z% \$ r0 P        acl auth_ok http_auth_group(L1) G1
) ?6 Q7 u% I: d6 r
# s, _8 ^' Z/ t; K" T        http-request auth unless auth_ok7 ~( ]9 C% @6 R- m; L' W
0 u4 v* U+ E" v8 M5 a
  See also : "stats http-request", section 3.4 about userlists and section 7
1 S7 O5 @1 |  z) `5 |. a             about ACL usage.! _# Q5 l9 V; R5 a$ r0 t

; h; |, i" _/ q  G2 Yhttp-send-name-header [<header>]
! Q1 k" R: Z% I$ F  Add the server name to a request. Use the header string given by <header>' ?) r* r) j7 f

- C* Y# @, U: _+ |& f  v7 T% c& i  May be used in sections:   defaults | frontend | listen | backend
' }  S1 u& r! Q1 }$ J6 H                               yes    |    no    |   yes  |   yes) n4 _" |, G% f- H
% Q' s; _4 G% x+ @; w
  Arguments :
  w4 F: e9 |5 ?0 l9 m! _# \' G
! W; L- L. d2 r* E    <header>  The header string to use to send the server name
! B% S5 d8 B$ E1 t' K3 R5 b* P' L
. U4 W& V! n4 \  The "http-send-name-header" statement causes the name of the target: \8 Z! ~5 _% K" k: E
  server to be added to the headers of an HTTP request.  The name, d: w2 l( R! F' c
  is added with the header string proved.6 c$ m$ g; r5 {( x- I, _6 L! R
( k0 K; G4 d0 E
  See also : "server"+ h. F9 U1 d) r: L0 o) g- d
+ T' N8 R! a6 D& X8 K
id <value>
" r, K: b  r; |  Set a persistent ID to a proxy.
1 D8 o  x/ Z0 E' s  May be used in sections :   defaults | frontend | listen | backend
4 B; t& R. H2 V                                  no   |    yes   |   yes  |   yes0 F8 }  z: J9 t0 t3 p& J
  Arguments : none( m* r% O; D7 B! M4 K8 e4 B, A0 q2 n

6 N' d* h; N6 u6 E$ S8 Q2 Z4 Z  Set a persistent ID for the proxy. This ID must be unique and positive.
4 t! x$ P3 D+ x7 I# C, [, U) }  An unused ID will automatically be assigned if unset. The first assigned
* b# l: _% F# A3 m" P  value will be 1. This ID is currently only returned in statistics.8 C/ `# Z! T8 P
# j8 b. x" p( o3 L, q0 W9 h6 W

; j/ C9 N5 h" O0 W; g% v$ p3 `ignore-persist { if | unless } <condition>
/ j6 M7 @, ^& @# @" [  Declare a condition to ignore persistence
4 e) N5 c+ k1 W& k# M0 q. H  May be used in sections:    defaults | frontend | listen | backend
0 n8 G! N2 u4 c                                  no   |    yes   |   yes  |   yes
+ r) }* Z% j& _( U2 c
) M, |5 w2 s$ z  U2 H2 [  By default, when cookie persistence is enabled, every requests containing
" B( }, y! j& @, R, k: M& M  the cookie are unconditionally persistent (assuming the target server is up" f& ~# r( @6 c1 g# l- ]
  and running).
6 @) [) g) x2 E. p9 E& r4 F0 Q* d3 K* B3 N+ y) Z
  The "ignore-persist" statement allows one to declare various ACL-based% g  v  L5 h# J6 j  v
  conditions which, when met, will cause a request to ignore persistence." P& V2 d) v7 d; \( N4 _( C& K- m
  This is sometimes useful to load balance requests for static files, which
9 Z8 d# p+ m; v0 Q/ l  oftenly don't require persistence. This can also be used to fully disable
, b/ d! M& G% M9 Q/ `4 x8 e3 v  persistence for a specific User-Agent (for example, some web crawler bots).* g& W7 M+ E8 _3 ]& O7 {7 }

8 Q- M: i' m; l/ @7 Y6 O8 j4 j+ [  Combined with "appsession", it can also help reduce HAProxy memory usage, as5 {5 }' t/ y0 d# z% s* Y4 u& E
  the appsession table won't grow if persistence is ignored.1 r( ?# E. \7 Q6 Q
- T- D4 K7 i' r9 x0 X$ x
  The persistence is ignored when an "if" condition is met, or unless an2 [+ c% u. i# c, L
  "unless" condition is met.' ~6 C  P4 [7 T* f! }) }

, Q/ d* @  }7 \. S+ u  See also : "force-persist", "cookie", and section 7 about ACL usage.
$ Q9 ?0 ^) q) i0 w! a$ c+ `6 T7 z+ {0 E0 i2 d

, G! w9 M& @! U% P' dlog global4 k, ]8 F  @3 d4 @
log <address> <facility> [<level> [<minlevel>]]1 k3 e5 u! _" ]2 t! ]
  Enable per-instance logging of events and traffic.7 j7 @5 D2 y& Q/ I' Z
  May be used in sections :   defaults | frontend | listen | backend' a1 I; d4 U& g8 Z0 [
                                 yes   |    yes   |   yes  |   yes
1 d) c' a! W, g6 A7 D  Arguments :) P& r/ a7 K+ ~$ `9 W) }3 N5 q
    global     should be used when the instance's logging parameters are the5 s4 t  g4 o( w( I. [
               same as the global ones. This is the most common usage. "global"0 `6 o/ A- n  I6 p) `& E* K
               replaces <address>, <facility> and <level> with those of the log2 u. G( T- b0 T
               entries found in the "global" section. Only one "log global"" r% o- `& A5 r' o, O7 w
               statement may be used per instance, and this form takes no other# b6 r) U& W1 @
               parameter.
- @! e8 f/ j/ s& K% h- G5 ]' f0 a2 e4 J
    <address>  indicates where to send the logs. It takes the same format as6 o! c: p2 g9 [# |* j0 l
               for the "global" section's logs, and can be one of :
: a" m6 X6 p; C9 ]' C- l
% G- ?+ c0 I' o! _. N) G* H8 z- ~               - An IPv4 address optionally followed by a colon (':') and a UDP3 J# M5 l+ P% y( F2 {- {
                 port. If no port is specified, 514 is used by default (the
, R; ^. x  `+ h0 |4 R                 standard syslog port).
! T  x( F# x: f8 a
5 o4 q" y9 O7 H6 ]) {& f               - A filesystem path to a UNIX domain socket, keeping in mind
* p6 h9 n2 ]5 ^5 {  M7 |                 considerations for chroot (be sure the path is accessible
# c6 C7 E  Y" E6 [                 inside the chroot) and uid/gid (be sure the path is
% s+ E; M& t) @- u1 Q+ ?                 appropriately writeable).; e  \& g# U9 d2 l1 Z" d$ f/ Z

+ V6 Q1 b2 d5 h) j4 F    <facility> must be one of the 24 standard syslog facilities :/ b9 k% o- ]8 a( v. i5 J# g
4 Z1 `! `$ y, T% w3 W  X
                 kern   user   mail   daemon auth   syslog lpr    news
9 ]/ _* ?, j$ f8 E2 }% J                 uucp   cron   auth2  ftp    ntp    audit  alert  cron2
6 P! F0 m- n+ l: `                 local0 local1 local2 local3 local4 local5 local6 local74 X  k3 I; i! r8 V" ]

' c& E) N' b0 r9 G& g& m  X4 ?8 c    <level>    is optional and can be specified to filter outgoing messages. By
" z! V9 [+ v0 N% y0 O               default, all messages are sent. If a level is specified, only
: {( |# C" R- Z; e4 F               messages with a severity at least as important as this level
) {9 X  R) {; L$ |, D               will be sent. An optional minimum level can be specified. If it) o8 Y2 K8 D7 J; _- n) A1 k1 @/ ]+ r& J
               is set, logs emitted with a more severe level than this one will
" h) b/ ~8 r6 T  [               be capped to this level. This is used to avoid sending "emerg"
" _6 }3 x" j& X) F0 O) B               messages on all terminals on some default syslog configurations./ L4 K1 p4 Z) d6 M- ?' m0 K
               Eight levels are known :, i2 Q7 }9 ^, H6 k- Z! l. C. B7 A$ L
  g5 j; R% |  N- G+ G! j
                 emerg  alert  crit   err    warning notice info  debug
4 Q9 k0 d; f; l/ l
! n4 I6 G; B9 c9 ~* V  Note that up to two "log" entries may be specified per instance. However, if
% A8 `# N2 H% o' `0 B/ H  "log global" is used and if the "global" section already contains 2 log' C+ z: h; b. |0 N/ u' a
  entries, then additional log entries will be ignored.' ~7 G# u$ ]. T: h9 O. a0 Q
+ r- n* o. R8 ~) L- I
  Also, it is important to keep in mind that it is the frontend which decides
. }8 [9 D2 @! v* }  what to log from a connection, and that in case of content switching, the log5 ?" ~: b4 D* T* Q. `
  entries from the backend will be ignored. Connections are logged at level, s9 [4 A& V3 e! D
  "info".( s2 p) H+ Q' B/ M- {8 c
# I) D6 U4 I4 ~
  However, backend log declaration define how and where servers status changes
* F2 g* U  E. G  will be logged. Level "notice" will be used to indicate a server going up,* |2 B. o5 d9 l0 g6 t- B% b5 O3 _
  "warning" will be used for termination signals and definitive service
" k& D  S3 K! Z- ?  termination, and "alert" will be used for when a server goes down.
0 `# \4 h* W! o8 i4 n2 _0 G4 f( }( C
* h+ {7 a* a& D& h4 ?+ I  Note : According to RFC3164, messages are truncated to 1024 bytes before
; a8 m% p  ~) p; I4 c% y         being emitted./ m1 z9 @. L0 H
8 m+ l4 x7 C) A" U8 b! t9 f# t
  Example :
* S& z& M+ A9 m    log global  l9 W  O5 S1 W. d! ~8 h/ I: p. u- l
    log 127.0.0.1:514 local0 notice         # only send important events
6 n/ k& V: K" H6 t# R3 }" X  N6 e    log 127.0.0.1:514 local0 notice notice  # same but limit output level1 ~! x; _) k+ P/ S
3 b- l+ h  g- [& D

0 M  h) {' ]8 t$ q: g" W) x  ymaxconn <conns>
3 F* j  y1 K0 F1 m8 U0 q  Fix the maximum number of concurrent connections on a frontend  V8 a( O0 |# \# m+ ~$ ~
  May be used in sections :   defaults | frontend | listen | backend# \$ C' Q2 F$ g' w2 I
                                 yes   |    yes   |   yes  |   no
5 O' Y2 f! N$ K  Arguments :* H6 M( |' Y7 j; l
    <conns>   is the maximum number of concurrent connections the frontend will" M, H! a. R- ]8 [2 l
              accept to serve. Excess connections will be queued by the system
' A; V3 R0 p# y- n              in the socket's listen queue and will be served once a connection! D: o& P+ ~) j7 x6 m5 ^* \
              closes.
8 {8 _) J6 ?( p5 n) D/ r4 U
$ f" M6 ~5 n/ ?; k  If the system supports it, it can be useful on big sites to raise this limit* U9 t4 j, t' t) u# g! ^
  very high so that haproxy manages connection queues, instead of leaving the% N" x  C; H9 S; k
  clients with unanswered connection attempts. This value should not exceed the7 c+ Z1 O# J* a" E" Y1 o0 F
  global maxconn. Also, keep in mind that a connection contains two buffers5 H7 V1 q7 v! X  T) E1 @# O# B
  of 8kB each, as well as some other data resulting in about 17 kB of RAM being
' A3 F2 [7 b+ _& h: E' ~5 P! f  consumed per established connection. That means that a medium system equipped
4 y5 n9 I- N! R; [. Y9 O0 i1 Q+ ^0 W  with 1GB of RAM can withstand around 40000-50000 concurrent connections if
0 p5 L1 @0 w. V0 i" g- q  properly tuned.
. }6 R7 n' X5 `* }  D5 z" X
* \1 O0 D" D7 K1 j  Also, when <conns> is set to large values, it is possible that the servers  e- X9 C. Q) _( C/ y0 F" N4 n
  are not sized to accept such loads, and for this reason it is generally wise. g) }0 ~. f' @. C- S
  to assign them some reasonable connection limits.
' D, u7 q8 _  h* c. ^+ J
7 b9 h" m1 p! R0 {8 l7 i4 Z  By default, this value is set to 2000.
- S! w/ h4 v. M: l+ k$ U) D* u! M3 j
  See also : "server", global section's "maxconn", "fullconn"
: X3 \0 a( Z0 v
# m% C0 H( m6 F: _/ [/ D% v5 @3 x, S6 \* J
mode { tcp|http|health }
9 l4 S5 ^* }- _  w! w  Set the running mode or protocol of the instance; e" t* u$ [; k$ z
  May be used in sections :   defaults | frontend | listen | backend) q. \* c  Q; J- y/ Y% O
                                 yes   |    yes   |   yes  |   yes
) s9 M* ^2 a  l4 D8 q) i4 n! k  Arguments :* M. Z, Y4 f4 q7 ~7 B/ |$ @
    tcp       The instance will work in pure TCP mode. A full-duplex connection* u& j* n, v" U  y. S
              will be established between clients and servers, and no layer 7
9 B! \) O7 l: ~0 {5 D4 P# W              examination will be performed. This is the default mode. It  s- P2 W4 `' V. }# {$ M$ y7 o
              should be used for SSL, SSH, SMTP, ...
2 w( Z( J; I$ N0 h9 f7 E1 j( g9 \" ]8 z& v6 r
    http      The instance will work in HTTP mode. The client request will be9 G; P; K! o; n5 ^$ k- D
              analyzed in depth before connecting to any server. Any request
( E" s6 m, h3 a; S              which is not RFC-compliant will be rejected. Layer 7 filtering,3 C, F2 Q1 U7 l- E) V6 O) f
              processing and switching will be possible. This is the mode which
8 s, M6 I, N1 I# V4 D$ ^4 q& w& {              brings HAProxy most of its value.
$ n8 @1 B4 [' [5 d
: c. T3 h# I  J& J7 y7 y    health    The instance will work in "health" mode. It will just reply "OK". u  {' M1 |% {4 f
              to incoming connections and close the connection. Nothing will be
. ^" V9 u1 ~5 C1 z; d: |  u* M              logged. This mode is used to reply to external components health  n8 Z/ i# y. g: p9 I" q  G! b
              checks. This mode is deprecated and should not be used anymore as: O( y% J' e6 @. d3 p& O
              it is possible to do the same and even better by combining TCP or+ u. S/ C; a2 w6 Q
              HTTP modes with the "monitor" keyword.
$ `" g1 t2 h1 m& V) L
0 y8 p7 V2 Y6 j. s' `! h/ B# n  When doing content switching, it is mandatory that the frontend and the; f2 x  u% Y  `1 j/ F, y1 A! ~8 C
  backend are in the same mode (generally HTTP), otherwise the configuration
. T. X) i' q2 f" D! `0 K  will be refused.* l. N$ n* o' t9 _; j; t0 J: r! c' J
* d4 s9 q2 ?. g/ F
  Example :0 y; w) |* [- @3 k8 }& }8 i
     defaults http_instances: K4 R1 V2 r# |, q& l0 y) A
         mode http. t% D: @) s" c* ?- L$ s

$ w7 V( J) Q( c# ~1 m! u  See also : "monitor", "monitor-net", R% y. z6 b4 Q5 r
. i' v# B3 w- L0 E" w2 A
) F2 ^( X. m2 z( |4 E. S8 }
monitor fail { if | unless } <condition>3 `4 O- A5 C- U# S; o
  Add a condition to report a failure to a monitor HTTP request.8 }+ ?  U) o8 V9 E
  May be used in sections :   defaults | frontend | listen | backend# `+ X. V: c6 v  i  M) ?
                                 no    |    yes   |   yes  |   no
; e& d- }( e2 w- p  Arguments :. ]- q# v6 N: U; c# S+ z' A- Q
    if <cond>     the monitor request will fail if the condition is satisfied,* [6 x. ]7 `, [2 E2 X$ c1 \, c% o0 F
                  and will succeed otherwise. The condition should describe a; {1 y+ ]7 l: P# C8 }6 b
                  combined test which must induce a failure if all conditions: t9 W$ H- W& R
                  are met, for instance a low number of servers both in a
1 D  _. C- v! h7 R                  backend and its backup.5 y; E) s' d: N& L+ l
3 t: F+ Z7 G! t6 w& u
    unless <cond> the monitor request will succeed only if the condition is9 f- X0 C- U$ ~
                  satisfied, and will fail otherwise. Such a condition may be
3 t3 R+ a: c, {$ ~0 _2 F: e                  based on a test on the presence of a minimum number of active
% }5 p& z6 @1 ?7 _                  servers in a list of backends.1 n) ^* m# H' x. D' {; y
& c1 ]  Y8 Q9 g/ m
  This statement adds a condition which can force the response to a monitor6 f  ^) h  z% @( F" }
  request to report a failure. By default, when an external component queries
, P2 ~; V" V( V+ M$ U  the URI dedicated to monitoring, a 200 response is returned. When one of the! z/ c2 v; A7 ?  F3 C4 k( L
  conditions above is met, haproxy will return 503 instead of 200. This is
7 r, |7 Y+ J' x: V- _/ \# {  very useful to report a site failure to an external component which may base
  T7 q. U- f# S& i+ Y  routing advertisements between multiple sites on the availability reported by3 _% [# n( N/ m: J9 Q5 H8 Y- n
  haproxy. In this case, one would rely on an ACL involving the "nbsrv"
# h* G& s5 j8 |  criterion. Note that "monitor fail" only works in HTTP mode. Both status
$ J  X& o, y& I2 c  messages may be tweaked using "errorfile" or "errorloc" if needed.$ N- J/ l( N9 C+ J( `. I+ L

: [: \9 n* n: R. Z$ A: E4 E9 b% i  Example:' [# q  }- J9 y* |$ o
     frontend www
6 ]  a" D# M# O+ m9 x9 j        mode http" X5 s6 D6 c" o; f2 R2 Q+ I1 T
        acl site_dead nbsrv(dynamic) lt 2& `+ ~# {1 C2 m" U7 r' h
        acl site_dead nbsrv(static)  lt 2+ X5 G3 P% L8 I/ N8 f/ Z" K* ?
        monitor-uri   /site_alive
6 _$ n- S& x4 Y" m) s- x$ Q        monitor fail  if site_dead
! C3 P9 D1 i* ?6 l
- e! Q, Y2 k, H. e# Q  E2 \& L  See also : "monitor-net", "monitor-uri", "errorfile", "errorloc". q* A- k% k6 _. Y% K4 H; {
1 L2 n7 S  x7 ^; K

% D7 l7 x3 c" w( r! v4 A) imonitor-net <source>
% r- T. Q# Z! {: I  Declare a source network which is limited to monitor requests" d' i- M9 b* [, t4 W
  May be used in sections :   defaults | frontend | listen | backend
$ n& ~) L0 l1 s. S+ M; M  H# L% m9 Z' e; w                                 yes   |    yes   |   yes  |   no
9 D1 @8 Q, A; G- L$ v  Arguments :, B3 o; h6 r) v& h$ L: q
    <source>  is the source IPv4 address or network which will only be able to. g3 i5 Q1 K8 |
              get monitor responses to any request. It can be either an IPv4
4 r+ i5 Q5 v6 p. }. p              address, a host name, or an address followed by a slash ('/')
0 r: O2 \& [6 `+ q              followed by a mask.
3 z$ V4 c4 c4 Z
! d. n0 |: I- b# C  l; T! V  In TCP mode, any connection coming from a source matching <source> will cause
0 l7 b0 ?1 |0 {  the connection to be immediately closed without any log. This allows another
4 [% }4 i) G3 \  ?  equipment to probe the port and verify that it is still listening, without
8 m+ d5 M- d' l. p  forwarding the connection to a remote server.
6 [6 U, B" b+ h7 g* G0 d) y& P  z% }: F& {3 `& I% U4 w$ Z- B
  In HTTP mode, a connection coming from a source matching <source> will be
/ o0 C' c" |4 K0 `. i" Z7 _, |( y  accepted, the following response will be sent without waiting for a request,8 ?& g( x* Q+ |* H
  then the connection will be closed : "HTTP/1.0 200 OK". This is normally* l4 n5 A. r  r7 F# e- f* C
  enough for any front-end HTTP probe to detect that the service is UP and
, t4 R' R' W; `) T  running without forwarding the request to a backend server.  }% L9 a/ K- V  S

" I/ t! w( R! [  Monitor requests are processed very early. It is not possible to block nor
, m+ {& t3 b5 R& [  divert them using ACLs. They cannot be logged either, and it is the intended% [- q* D/ @" s# b! E) ~" r  n
  purpose. They are only used to report HAProxy's health to an upper component,
6 \% k# n2 k: n+ m  Y  nothing more. Right now, it is not possible to set failure conditions on$ ?- X! n) k9 i# A: s# s8 P
  requests caught by "monitor-net".
4 ?" r% R3 g2 v9 e( A' _: ?
3 X7 E1 S  f' D. p" v1 K  Last, please note that only one "monitor-net" statement can be specified in7 X6 g, H& e( @; }5 o
  a frontend. If more than one is found, only the last one will be considered.( }0 k( u3 u0 u4 q

; p9 d1 W; Z2 O  Example :
" _6 R$ W* b# I3 k  }  S    # addresses .252 and .253 are just probing us.+ i, S) m; D8 [9 E: i
    frontend www! }$ m, b* R3 r
        monitor-net 192.168.0.252/31, l2 Q  V; C' D1 S

: U: N9 t% o+ o; G/ P; |8 v  See also : "monitor fail", "monitor-uri"
5 Q1 g  N  t# {1 e* M
3 B" h$ R0 n( _+ _
7 o% |$ F# b. \# [1 s2 ~, j/ O# mmonitor-uri <uri>& y9 l4 T+ X" L- q6 a
  Intercept a URI used by external components' monitor requests
! R9 _) j+ @, z  May be used in sections :   defaults | frontend | listen | backend, K8 R4 X0 q7 h5 \# B7 G* w3 N
                                 yes   |    yes   |   yes  |   no" q' k9 ^! j5 N* G& ~: a8 z
  Arguments :# R" u8 h! z: h4 ?* x
    <uri>     is the exact URI which we want to intercept to return HAProxy's
* U3 t8 f  D0 i% a7 G              health status instead of forwarding the request.$ u  _+ O2 k9 y

0 F+ U; a% D4 y& ?9 Q  When an HTTP request referencing <uri> will be received on a frontend,
4 P8 [( ^* Q- D$ ~  HAProxy will not forward it nor log it, but instead will return either: {9 q. X( T" s& b" g( X' s% f" u
  "HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure1 a- @0 o1 C9 t: @7 ^1 B
  conditions defined with "monitor fail". This is normally enough for any
5 w5 C! _6 H& L7 p/ X( U  front-end HTTP probe to detect that the service is UP and running without6 ~# c# @2 D9 ~& _  D9 j: s, r$ h2 K
  forwarding the request to a backend server. Note that the HTTP method, the. D/ Y$ i$ t0 q5 O! j1 r3 w
  version and all headers are ignored, but the request must at least be valid5 \( ]6 q: H) ^& V' ~2 R& E2 M
  at the HTTP level. This keyword may only be used with an HTTP-mode frontend.
( J8 b2 ^" @- g4 ~5 Y% W" ^5 d6 O1 {1 i: Y; |
  Monitor requests are processed very early. It is not possible to block nor  v) }( _; F3 N7 X9 Z- v
  divert them using ACLs. They cannot be logged either, and it is the intended+ o: {1 N! e& l; j1 G
  purpose. They are only used to report HAProxy's health to an upper component,
  r% X% y: d* O. w5 F# i  nothing more. However, it is possible to add any number of conditions using
: r$ y9 `+ B$ \0 A1 I, a  "monitor fail" and ACLs so that the result can be adjusted to whatever check$ ?; F* o- b' V1 D4 C) y
  can be imagined (most often the number of available servers in a backend).* m$ p0 r2 f! ?8 L

" F" v! Q( E0 L  Example :
, o) E7 y7 h0 J. Y" l( b4 e    # Use /haproxy_test to report haproxy's status
7 k8 J  ]/ |  l2 [- I- u    frontend www' j4 `7 d" D0 e, ]
        mode http
0 w, J" p. P6 L# x) g1 _        monitor-uri /haproxy_test* r2 H  Y# ~  H

- K' c3 Y+ K/ y3 X9 q  See also : "monitor fail", "monitor-net"4 x+ u: G( p* f2 N

9 i. d! ^0 k3 F  U/ @. D) }8 J9 k. p9 q2 j9 H
option abortonclose/ k' W6 @( j7 C' T. k# ^4 \' D: x
no option abortonclose
  j& Q3 s" e7 q  Enable or disable early dropping of aborted requests pending in queues.
; U& X+ m6 F2 m2 R: j9 B  May be used in sections :   defaults | frontend | listen | backend7 A; v0 x4 K4 q0 b
                                 yes   |     no   |   yes  |   yes
/ T  a! w+ F5 l# }/ [, G' G+ J  Arguments : none
4 S, V# }4 ^) Y) Y: r0 D6 j& C. w9 o; e
  In presence of very high loads, the servers will take some time to respond.0 p6 W/ X9 {; {3 l
  The per-instance connection queue will inflate, and the response time will) C/ f( ]: |: M7 J  }% X
  increase respective to the size of the queue times the average per-session
. c( n7 H# N2 c3 m  response time. When clients will wait for more than a few seconds, they will
& H1 Z6 @0 u0 c$ s  often hit the "STOP" button on their browser, leaving a useless request in
6 @# o; U, |0 R  the queue, and slowing down other users, and the servers as well, because the
7 J9 \) O: U2 f6 @4 `  S  request will eventually be served, then aborted at the first error1 {5 q9 l* L. k7 ^6 _, l- \
  encountered while delivering the response.0 V& U2 \+ `& G2 @$ k2 W& C) d; G

5 n+ k3 z+ F; ^% E8 z# A  As there is no way to distinguish between a full STOP and a simple output/ }; W# b5 f8 l5 f" \
  close on the client side, HTTP agents should be conservative and consider
' {$ i6 d4 k$ Y! ^+ b1 H" U# o/ o4 ]  that the client might only have closed its output channel while waiting for$ ^8 O* A7 t$ K  A+ L
  the response. However, this introduces risks of congestion when lots of users7 _4 j; u, |1 d0 Q9 {) \, S2 u
  do the same, and is completely useless nowadays because probably no client at6 R* X7 s8 R. G$ A! `* Y
  all will close the session while waiting for the response. Some HTTP agents0 B2 N& F  E' G- w" q4 A1 T+ |
  support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most, _" M# b; Y3 I/ b8 m6 u  w  z
  hardware-based load balancers). So the probability for a closed input channel* `6 M- H; O/ t: K
  to represent a user hitting the "STOP" button is close to 100%, and the risk  }- T! Q, e" R! q
  of being the single component to break rare but valid traffic is extremely( D: L: t# ^4 u7 p
  low, which adds to the temptation to be able to abort a session early while
8 `) z4 `: }+ x' U  still not served and not pollute the servers.* X0 B0 g  o0 H/ a9 U3 O  r0 Q
( ~4 {5 Y" W( R) P2 Q
  In HAProxy, the user can choose the desired behaviour using the option
$ o; G; o  Y- r3 o  "abortonclose". By default (without the option) the behaviour is HTTP' s  u: ^1 F0 l% s9 `4 J
  compliant and aborted requests will be served. But when the option is
% h: q/ H' j: b$ a  G) V. i  specified, a session with an incoming channel closed will be aborted while
3 A* w. s' I$ z! s6 x  it is still possible, either pending in the queue for a connection slot, or
# \. ?; k% G+ F: R  during the connection establishment if the server has not yet acknowledged
. k, C0 X1 ?2 K  K) A% L$ e  the connection request. This considerably reduces the queue size and the load2 i8 L0 A( ~2 y' M5 J" O5 C( w- j
  on saturated servers when users are tempted to click on STOP, which in turn+ U/ Y. h- y; M' z) b
  reduces the response time for other users.6 W5 n7 X5 G9 T% w$ {4 [9 }' v

5 p# c, {9 X9 p) X' j/ U2 p  If this option has been enabled in a "defaults" section, it can be disabled* F- D! `* a- o6 r4 m
  in a specific instance by prepending the "no" keyword before it.3 f, {: ?8 M: X0 W5 T  Y# _% s
  ^& n, g& F  f/ O) C/ m2 p
  See also : "timeout queue" and server's "maxconn" and "maxqueue" parameters
/ n5 B) w" C8 `* `% N3 ^, L8 u. ~% M' w. x! @  T% t4 D

2 ]% h5 {6 c6 T) Moption accept-invalid-http-request
% t/ v: s% |, ~no option accept-invalid-http-request
: v( B/ L8 t' S! n5 x  Enable or disable relaxing of HTTP request parsing
0 H* \4 l0 H$ z& O  May be used in sections :   defaults | frontend | listen | backend$ d" B3 f5 Q. t
                                 yes   |    yes   |   yes  |   no: P+ O) Q9 a/ _2 F/ s
  Arguments : none9 V  B) y: {! p
& Y# s  q4 o" r* A4 |4 z2 {
  By default, HAProxy complies with RFC7230 in terms of message parsing. This
8 [8 T, ]( T+ F# v5 a  means that invalid characters in header names are not permitted and cause an9 Z' z" s3 Y1 l5 L% H& v- _- e( M
  error to be returned to the client. This is the desired behaviour as such) U  Q0 h: w$ o' O" m0 p, E0 s
  forbidden characters are essentially used to build attacks exploiting server  k% h, W% S$ P, x3 J% I/ F
  weaknesses, and bypass security filtering. Sometimes, a buggy browser or
+ j& W: a9 a/ @. N7 a( o  server will emit invalid header names for whatever reason (configuration,( d; t/ a" l6 Y$ o/ ?
  implementation) and the issue will not be immediately fixed. In such a case,( r  n# T& a+ d* S2 B- _/ G
  it is possible to relax HAProxy's header name parser to accept any character
' K7 k. j( B, }& h) g8 t. t* E  even if that does not make sense, by specifying this option. This option also* L) i) [1 D, V% M# z6 y5 G
  relaxes the test on the HTTP version format, it allows multiple digits for
7 ?2 D0 M# H$ _5 S' Y! Z" s0 X  both the major and the minor version.
! N/ s: l  a+ l& ~* t% `* V! ?
& b" _; ?5 I3 T7 l5 j) |2 ~: ]  This option should never be enabled by default as it hides application bugs
7 r# f7 [- n' d3 R( D  and open security breaches. It should only be deployed after a problem has
' `% }+ E9 ]$ g  been confirmed.
3 v3 `$ r+ ]4 e" ]6 \
" s# v6 Y3 G; z7 a. l# m/ v9 A0 j  When this option is enabled, erroneous header names will still be accepted in
+ |* m4 [" \; A* B  requests, but the complete request will be captured in order to permit later
, z8 X$ p/ X) p) ?1 ]; x. a3 D$ {  analysis using the "show errors" request on the UNIX stats socket. Doing this, A  D% |) `- i# r
  also helps confirming that the issue has been solved.
8 u% f- r9 o, x* I! H9 }  X
* d1 p5 K8 f7 I, y, ^$ g7 ]  If this option has been enabled in a "defaults" section, it can be disabled
4 m  [* G* }# K  Q7 O, s  in a specific instance by prepending the "no" keyword before it.
* z$ G: z- U/ v' `. l6 L8 l1 F4 |" m7 E) C2 g4 {7 C
  See also : "option accept-invalid-http-response" and "show errors" on the- O6 M1 [/ Y, H
             stats socket.3 a$ E- a0 F1 F/ E( ~$ X

9 e0 p# X. P, A5 v0 _; k
7 d* q6 Y8 i: d" ^option accept-invalid-http-response, w& ~+ i( \8 ?$ \3 v2 e- E+ @
no option accept-invalid-http-response
4 w7 ~& {+ |" z5 P' Z7 l  o  Enable or disable relaxing of HTTP response parsing! v5 ?' ]% F7 x( Y
  May be used in sections :   defaults | frontend | listen | backend
! N* Z1 n: I/ p) q! T1 m9 e  ~                                 yes   |     no   |   yes  |   yes9 [$ Y1 @5 v; O" h
  Arguments : none
1 X  ?# m) N7 O! a1 A0 a
1 U; _  E7 l/ G/ J( \, N$ }  W  By default, HAProxy complies with RFC7230 in terms of message parsing. This8 R2 ^" m/ V7 ]: d
  means that invalid characters in header names are not permitted and cause an
0 C: b$ K0 b: p; W3 Z+ K( O) u4 K  error to be returned to the client. This is the desired behaviour as such
; d" `4 f$ a+ c  a# _" I  forbidden characters are essentially used to build attacks exploiting server8 j' |$ B# e4 N/ o' g  M
  weaknesses, and bypass security filtering. Sometimes, a buggy browser or6 u8 N8 F+ {; _: L# t
  server will emit invalid header names for whatever reason (configuration,# H* `5 x) Z/ w+ c
  implementation) and the issue will not be immediately fixed. In such a case,
1 {( z3 O3 U0 A  it is possible to relax HAProxy's header name parser to accept any character
2 u- e: N9 W- d  \9 M4 e4 A3 Z; f  even if that does not make sense, by specifying this option. This option also( C/ y) v/ \- m# C5 n, y
  relaxes the test on the HTTP version format, it allows multiple digits for5 c+ f, S1 F4 N5 @& C* D6 g4 F
  both the major and the minor version.
/ b) |8 t) q+ [
* I  d8 I3 b' ?6 @, Y5 y  This option should never be enabled by default as it hides application bugs
; l2 ^! l  Z' W  and open security breaches. It should only be deployed after a problem has
: _# W6 h, e8 H4 k# s4 Z  been confirmed.8 E( c, Y# Z) k; s

) T* @+ ?9 }7 O; j$ |; j8 t  When this option is enabled, erroneous header names will still be accepted in
8 W  _5 @6 i0 S8 @  responses, but the complete response will be captured in order to permit4 f# f. @8 r* O$ Y
  later analysis using the "show errors" request on the UNIX stats socket.( c: Z; B5 j( `3 [6 M6 n
  Doing this also helps confirming that the issue has been solved.9 K6 b( C% [% _, n# g: Z, {

% r8 r# t0 ]' B0 M$ p" o! \  If this option has been enabled in a "defaults" section, it can be disabled  [: S) G$ c7 `) \
  in a specific instance by prepending the "no" keyword before it.- |& c6 {; u" a; G
& Q9 o! j: D) w) {, o0 {+ @1 i
  See also : "option accept-invalid-http-request" and "show errors" on the6 a) x1 k1 P( g. _
             stats socket., c5 L1 \# _6 ^. H% X
. i4 o% p- ~$ b1 X2 ^
  f* t# L6 Z5 y2 C, A
option allbackups
# y: V* v* B2 ]+ s+ c& K3 d  Y8 N) Qno option allbackups! s, O" R* V; n: X3 v, M+ U) I  p7 y( H
  Use either all backup servers at a time or only the first one/ e: ^$ s. R8 t
  May be used in sections :   defaults | frontend | listen | backend
1 j, C" i- C. s% I  z                                 yes   |     no   |   yes  |   yes( o2 U: g6 U$ ?9 R. @% \% w) w
  Arguments : none6 @* @1 z4 }4 P7 C; V( j7 F6 i
) N8 v9 x5 I4 z# t; ~
  By default, the first operational backup server gets all traffic when normal
; \0 ^. \3 l1 b2 Y. l3 L% c  servers are all down. Sometimes, it may be preferred to use multiple backups
$ x5 v- e$ J( y. L- B  at once, because one will not be enough. When "option allbackups" is enabled,6 M0 }0 J  g: Y! y" z5 n& E* x" q
  the load balancing will be performed among all backup servers when all normal
0 Z& \* H5 O3 A! p( @# [  ones are unavailable. The same load balancing algorithm will be used and the( Q1 _* r  c3 g9 K" C
  servers' weights will be respected. Thus, there will not be any priority. G6 q' y' F9 U+ Y, o' U
  order between the backup servers anymore.5 M- ?) {, o: Z# B" q8 N* A, [

& m" t/ d8 p* }/ y  This option is mostly used with static server farms dedicated to return a9 }' L( Q/ L" c. L/ O6 w
  "sorry" page when an application is completely offline.
4 S- C7 e$ H4 n1 Y9 C
1 s6 n6 }6 H; @6 F# t$ h# C. a' ?  If this option has been enabled in a "defaults" section, it can be disabled( _2 L$ E: ?; Q- Y5 v, y
  in a specific instance by prepending the "no" keyword before it.
! c- L; P- Z; S; g) X
; _* g1 A1 ~* I) Y
' Y  B$ @1 p9 C' l' _# Ioption checkcache
/ F- b) {9 J$ m7 j3 Fno option checkcache9 L1 i+ ?  ^8 W7 c$ m4 h; m- D& R
  Analyze all server responses and block requests with cacheable cookies3 D# J/ l- n0 O1 W4 X: Z4 M
  May be used in sections :   defaults | frontend | listen | backend
' Y7 o( j4 [+ r. C- J9 z2 d  b                                 yes   |     no   |   yes  |   yes
/ m$ |2 B: v$ O6 w$ B; g; x4 ~  Arguments : none' R9 C# c% j- J" S; W; {

7 t3 J& V# T& Q# q  Some high-level frameworks set application cookies everywhere and do not
3 Y0 Q- k' ]5 M( M  always let enough control to the developer to manage how the responses should1 t+ }( k$ V. o) r7 z9 e# F7 y2 I
  be cached. When a session cookie is returned on a cacheable object, there is a
: O$ \8 o+ [. q  high risk of session crossing or stealing between users traversing the same6 ^1 F5 W. b9 t, f% U3 \; K
  caches. In some situations, it is better to block the response than to let( z7 W$ m6 A8 u. }
  some sensitive session information go in the wild.
4 E; J. t2 c& D2 v( p( g+ ]" d+ D9 b( O3 D, s
  The option "checkcache" enables deep inspection of all server responses for0 T" @2 B) }3 G& j$ t- E# N) d8 e
  strict compliance with HTTP specification in terms of cacheability. It
8 U" w0 l6 m9 J1 G7 R% P& D7 n! `) x  carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server
0 V& e3 y& [$ }* ~# o! E  response to check if there's a risk of caching a cookie on a client-side: P- v) Y8 i8 g9 M# R
  proxy. When this option is enabled, the only responses which can be delivered: M- A2 c: {4 B5 y9 \; v) m/ F
  to the client are :. u" v* c) C; C- U; Z
    - all those without "Set-Cookie" header ;
* y* Q8 ]5 y& l" |    - all those with a return code other than 200, 203, 206, 300, 301, 410,; m$ T; ~% y; {. i# Q0 \
      provided that the server has not set a "Cache-control: public" header ;! _7 Q5 w4 O5 w# }3 w
    - all those that come from a POST request, provided that the server has not- G2 K' K) u9 z' n
      set a 'Cache-Control: public' header ;: r+ @2 C) v% z6 E& f
    - those with a 'Pragma: no-cache' header
( P! x  ?1 y  e4 V" }, k    - those with a 'Cache-control: private' header
. E8 V7 v& C7 ~+ Y( R; Q- G1 ?    - those with a 'Cache-control: no-store' header, T7 U  V7 }. K
    - those with a 'Cache-control: max-age=0' header: V: t. C4 x' L1 Y5 J2 o
    - those with a 'Cache-control: s-maxage=0' header
) A! O! z) H4 L2 Y' o$ q# N    - those with a 'Cache-control: no-cache' header$ J  w6 R' @* }9 i) g
    - those with a 'Cache-control: no-cache="set-cookie"' header5 {3 ?5 Z7 `0 T* g6 I  Z% b" F
    - those with a 'Cache-control: no-cache="set-cookie,' header
) `& |8 X% u7 l      (allowing other fields after set-cookie)2 ^) q4 _6 q0 T. T. S
1 r: V/ Y. U0 m2 y
  If a response doesn't respect these requirements, then it will be blocked
# @/ M! G: P6 W6 S* g& J5 N  just as if it was from an "rspdeny" filter, with an "HTTP 502 bad gateway".+ h& E7 J- \0 N( S/ v+ |: }$ F9 _
  The session state shows "PH--" meaning that the proxy blocked the response1 G& J3 t2 I0 U1 _( O- ~
  during headers processing. Additionally, an alert will be sent in the logs so
6 ]/ z# h: e0 B8 w9 n  that admins are informed that there's something to be fixed.
! C! U, H: J& m! W3 N) L/ i: [, |; w, ]* w2 ]6 r" {
  Due to the high impact on the application, the application should be tested
1 c( ?* S3 e5 F  in depth with the option enabled before going to production. It is also a
, X( Y7 o) H3 g/ p2 F! Q) v  good practice to always activate it during tests, even if it is not used in
* v5 X% W# G. I" t1 r' C5 e0 E  production, as it will report potentially dangerous application behaviours.! ^# D& m0 g/ w3 m7 E% \
0 U6 r$ U3 b4 Z/ ]4 o7 t" q
  If this option has been enabled in a "defaults" section, it can be disabled
) A5 x$ B9 Q& h# S; ^9 H  in a specific instance by prepending the "no" keyword before it.3 l. e. I# P" @5 W
0 C, @( W' R; K7 D2 R$ Z: N

; j  f$ Z& c: p7 Q' Y4 Ooption clitcpka
& @+ c- T4 w6 D9 T; i2 L3 `( ?no option clitcpka& y; h7 U+ o/ C" D$ K2 O
  Enable or disable the sending of TCP keepalive packets on the client side
6 {) _9 I' {) u) j; w. k; d; G' p  May be used in sections :   defaults | frontend | listen | backend) ^6 P( V4 O( q4 i7 E  I3 P
                                 yes   |    yes   |   yes  |   no  K8 T9 x# _7 C1 P5 p' v
  Arguments : none  k1 U5 _) F- I! Z2 R- }1 \' k

# L  e! _6 S1 a+ `  When there is a firewall or any session-aware component between a client and
+ m+ Q- F. ^  s" ?2 \2 y" [  a server, and when the protocol involves very long sessions with long idle
/ U  ~9 h; U4 P6 ~  periods (eg: remote desktops), there is a risk that one of the intermediate
9 w3 e- G5 ^" R7 X# I, o9 ?" W1 A  components decides to expire a session which has remained idle for too long.
- b/ W& H) C3 o& a8 B6 J- x) ^8 C- n% D3 }6 S4 N7 {
  Enabling socket-level TCP keep-alives makes the system regularly send packets! r" }, C% {  t% b. j  z1 _, b& V
  to the other end of the connection, leaving it active. The delay between, `1 F) i# i9 o  K8 C2 t
  keep-alive probes is controlled by the system only and depends both on the: A' p$ C& c, W9 l- ?" s: f+ q8 O9 v4 b
  operating system and its tuning parameters.
7 u/ C" A( O! [
! B$ ^2 J8 p: r. y7 Q4 n  It is important to understand that keep-alive packets are neither emitted nor
$ A" N4 x- T3 A1 M8 @! ?9 @( U3 Z  received at the application level. It is only the network stacks which sees
) X# \/ Q% t" ^) _" A  them. For this reason, even if one side of the proxy already uses keep-alives* e$ Z8 }! |2 [5 `! P4 c
  to maintain its connection alive, those keep-alive packets will not be2 b0 q& f' I( E9 o* h2 k" }
  forwarded to the other side of the proxy.7 w. a3 l" @1 z: e' |7 N
. R$ [; I5 l' f+ f9 o
  Please note that this has nothing to do with HTTP keep-alive.1 X' H$ }; A9 A) _$ `1 _

3 `) u( T. V( E  Using option "clitcpka" enables the emission of TCP keep-alive probes on the
1 F  o: B1 P, V1 t- A  client side of a connection, which should help when session expirations are
( x! @* @! L! s1 J" ^; I  noticed between HAProxy and a client.
: J9 l% L, M# H- p% E4 M. y# r( F9 V8 l0 V4 A
  If this option has been enabled in a "defaults" section, it can be disabled
8 ^2 Z; d0 f+ m2 y6 m+ P  in a specific instance by prepending the "no" keyword before it.5 L* H. ]2 n4 C( [: L! ?

# |! X6 |3 m$ w& _: D  See also : "option srvtcpka", "option tcpka": F2 e2 M8 d$ [& `* H
, g" s8 Y9 a. T

, A' J$ U. J9 V8 `$ s" d0 ^option contstats
% ^" U+ j& V, k6 e: Y1 R  Enable continuous traffic statistics updates
* W+ g2 S6 h, S6 b$ @9 z2 i( P  May be used in sections :   defaults | frontend | listen | backend+ P$ M8 M+ j& p, u( U1 c3 [% k( y3 @
                                 yes   |    yes   |   yes  |   no
/ N, R, x) k+ Z: Z  Arguments : none
1 l* p- u; y1 a; P6 k# l4 H3 o) F; A8 ]7 e% S% a; j3 X! g. |
  By default, counters used for statistics calculation are incremented
- V8 ~+ ?  c( j; i! M  P  only when a session finishes. It works quite well when serving small
( b$ `$ y% G$ m' S, d& {2 G6 {8 X  objects, but with big ones (for example large images or archives) or! w! K) y4 v& R# k8 s5 t
  with A/V streaming, a graph generated from haproxy counters looks like
! G8 m; Y. w- o1 c  a hedgehog. With this option enabled counters get incremented continuously,2 G  E) ~! {" }. n7 E
  during a whole session. Recounting touches a hotpath directly so
5 Q7 \, ^0 q4 q- K  I4 W  it is not enabled by default, as it has small performance impact (~0.5%).
! g0 [& q8 C, k2 {: J1 x0 D
9 U2 [' L/ ~# J* F' q
1 u3 j+ I) ~2 H: A- r. P$ H$ C; hoption dontlog-normal3 Z0 t' X5 ]% r/ Q9 B5 d7 `: n/ J
no option dontlog-normal
& d* w  X0 p( N/ m  S  Enable or disable logging of normal, successful connections
7 u/ Q% d* J% S6 P; c: P; J: \  May be used in sections :   defaults | frontend | listen | backend
# e0 A! `( b( g3 F2 V9 ^! t. G8 {. K, e                                 yes   |    yes   |   yes  |   no# Y8 X/ r3 {# h9 E' T, l& {
  Arguments : none
, S/ u7 ~, T: l* l& e4 I, X. D7 \. q1 e' ?( ^" K
  There are large sites dealing with several thousand connections per second
) j: u; p' `. ^  and for which logging is a major pain. Some of them are even forced to turn
3 T3 H) ?7 F, e  logs off and cannot debug production issues. Setting this option ensures that. k6 {; \) {+ Y' c  r" i; Z
  normal connections, those which experience no error, no timeout, no retry nor
( t: b$ x- r. {0 ]* |2 W7 W  redispatch, will not be logged. This leaves disk space for anomalies. In HTTP
# Q; m# f9 V% p( h# |* s8 a! B  mode, the response status code is checked and return codes 5xx will still be
7 ?- I  ~- c5 N% B3 q9 F& c* [  logged.2 `  ^. }2 [% [; J4 y5 M. l5 C
0 Q% q6 [" g1 `# S. I
  It is strongly discouraged to use this option as most of the time, the key to
! a, f# F' P6 P6 {5 s  complex issues is in the normal logs which will not be logged here. If you
& F# l2 D$ D3 x- `. l  need to separate logs, see the "log-separate-errors" option instead.
: `0 @, s% A0 s4 _6 {$ g! x) y. o5 p" }3 B' B* Q, J! M
  See also : "log", "dontlognull", "log-separate-errors" and section 8 about1 c& s0 W) Y/ k9 d# K8 j2 b
             logging.. E. H# h1 s, D
% t, v# |2 e; [: c$ K1 _+ `
$ F1 i! u9 [; y* p# \
option dontlognull* ~5 D! n! q6 l  w/ l- h0 @
no option dontlognull$ {3 A8 `/ m- T* p  s2 v- n/ W: Z# z
  Enable or disable logging of null connections
0 C  o$ ?% P" x- k  H- h  May be used in sections :   defaults | frontend | listen | backend
' C* C% I" ~" y7 N                                 yes   |    yes   |   yes  |   no: {6 m5 A: \; [5 R0 K2 `4 b
  Arguments : none
2 ^3 D) Y3 C1 @: r' m
7 r9 b- N( e, p/ A8 `* g  In certain environments, there are components which will regularly connect to
/ H! z2 D) k7 G2 _  various systems to ensure that they are still alive. It can be the case from" x( f& k0 D5 N* B8 d! W& g
  another load balancer as well as from monitoring systems. By default, even a
  u1 {9 F6 |  i/ {2 t  simple port probe or scan will produce a log. If those connections pollute% Q& f8 }3 C+ k
  the logs too much, it is possible to enable option "dontlognull" to indicate
( T- }6 I$ t4 m8 f  that a connection on which no data has been transferred will not be logged,
, t9 F7 e* Q5 h6 A+ {/ [- Q# `2 w1 |  which typically corresponds to those probes.
& W2 X' o/ ], Y3 ?
( U  j1 b! M- g+ K* I( F: T. ^  It is generally recommended not to use this option in uncontrolled% U) A  q+ m& x  L
  environments (eg: internet), otherwise scans and other malicious activities, f" M% ?0 e0 k# I  U/ E$ x2 S
  would not be logged.
* }) @2 `% I5 U- D7 w+ _9 ]' E" G! L$ j
  If this option has been enabled in a "defaults" section, it can be disabled
( v  D( o* h& T! o% t" Z1 K  in a specific instance by prepending the "no" keyword before it.
% {4 K3 J" t3 ~! b8 C
. I6 y* a5 T( G5 O% F  See also : "log", "monitor-net", "monitor-uri" and section 8 about logging.
) `! d: K6 A& X0 y, P: v1 Y" V6 N3 k

+ ~3 y$ |$ k. poption forceclose
9 R/ Y* H1 X' xno option forceclose5 b. _' J8 w$ C& E3 u5 Z
  Enable or disable active connection closing after response is transferred.
" @7 g+ w  q6 t) R  May be used in sections :   defaults | frontend | listen | backend
( @- C# h: m3 w- s, k4 K! n# g                                 yes   |    yes   |   yes  |   yes+ w* x1 T- c; _) J& [6 W
  Arguments : none9 g) j( Y  Z% b2 L( w9 u8 a8 m& `& e
2 e: `, S1 L5 i* D: l  T% R
  Some HTTP servers do not necessarily close the connections when they receive
* d1 o* M6 K+ K9 W+ s  the "Connection: close" set by "option httpclose", and if the client does not
$ N0 ]/ v: s, B7 n2 Y8 }/ E  close either, then the connection remains open till the timeout expires. This
# K& @6 V) ^; y7 H+ z  causes high number of simultaneous connections on the servers and shows high
5 B  M' j7 ~9 |( @- C  global session times in the logs.
0 _5 `+ E. V! ^) Q9 j
# k) l5 {" F' u2 j  When this happens, it is possible to use "option forceclose". It will
7 ^3 J; J; d( d  actively close the outgoing server channel as soon as the server has finished
, ]$ b0 o5 l7 \# Y  to respond. This option implicitly enables the "httpclose" option. Note that( k. \" \/ m: |: a# A# p( m1 I1 c4 V  K
  this option also enables the parsing of the full request and response, which
7 T6 }6 h3 A/ @! W) _  means we can close the connection to the server very quickly, releasing some4 ~1 I! Z! y1 m8 M
  resources earlier than with httpclose.
$ |: r/ a- O* T; l" b$ N  R& m3 _; e0 K/ j
  This option may also be combined with "option http-pretend-keepalive", which
' P$ U8 @5 G) E2 C  Z  will disable sending of the "Connection: close" header, but will still cause2 X. W: \) ]" u$ |8 o9 J; \1 h( B; v
  the connection to be closed once the whole response is received.) o5 Y4 q6 W- Z

/ s7 r! F4 |/ k6 F4 I, X2 k  If this option has been enabled in a "defaults" section, it can be disabled
( s' `& c$ Q8 O! H$ U; @1 W  in a specific instance by prepending the "no" keyword before it.
6 {# L8 ~) {9 l% ?% |" y# L- t+ P, Z8 f5 {. O/ J* ~0 e
  See also : "option httpclose" and "option http-pretend-keepalive"& T/ g/ C2 {6 V3 C- D5 u
) `1 ^$ z& r* s& f

; L: g1 v  h) ^8 Aoption forwardfor [ except <network> ] [ header <name> ] [ if-none ]  |$ p1 S. S- C  j3 c
  Enable insertion of the X-Forwarded-For header to requests sent to servers
9 A: ~4 J; q' x( \  May be used in sections :   defaults | frontend | listen | backend
$ @4 h6 T' P( D/ Q                                 yes   |    yes   |   yes  |   yes
/ j  R0 u, F1 ]' ~- p5 B  Arguments :
* K0 Q( X3 F0 P    <network> is an optional argument used to disable this option for sources$ Y3 W/ k, I$ }1 ^6 J
              matching <network># z$ K# f; P: |( V
    <name>    an optional argument to specify a different "X-Forwarded-For"
2 c9 G- k/ P5 v' ?8 l              header name.
$ m( Q& B! c" A$ K2 ^
5 n& b5 m4 q2 ~; V6 ~! O" U  Since HAProxy works in reverse-proxy mode, the servers see its IP address as! C; R5 r$ E% ^
  their client address. This is sometimes annoying when the client's IP address, p# n4 I$ q+ L9 O4 y3 ^
  is expected in server logs. To solve this problem, the well-known HTTP header
! h# E- x! q  R+ O  "X-Forwarded-For" may be added by HAProxy to all requests sent to the server.  j$ H. ]. T- C+ s, `! }: E5 M
  This header contains a value representing the client's IP address. Since this6 i  k# y* s% {  L3 P2 z* W! R( q
  header is always appended at the end of the existing header list, the server
# a; |, S, G  e$ d3 A% R/ w  must be configured to always use the last occurrence of this header only. See% P* F, K1 Y  ~0 T
  the server's manual to find how to enable use of this standard header. Note
' B! r1 u) J8 i  O* [, B6 r  that only the last occurrence of the header must be used, since it is really! d* Q/ [" P' E7 s: s
  possible that the client has already brought one.
8 E6 O$ V  Z+ {: }  n$ \3 @' N# z1 z: i3 e+ o
  The keyword "header" may be used to supply a different header name to replace" d  c8 Q+ w3 e1 w0 W/ S
  the default "X-Forwarded-For". This can be useful where you might already
  l8 g" R3 K, b4 A; t7 d  have a "X-Forwarded-For" header from a different application (eg: stunnel),0 E) h/ @; w) ]' d$ ?, }/ u" M5 t
  and you need preserve it. Also if your backend server doesn't use the5 H9 l# N4 j. E5 @
  "X-Forwarded-For" header and requires different one (eg: Zeus Web Servers
- R5 o& n* w  M5 S8 B  require "X-Cluster-Client-IP").
$ M  o$ g* B: K8 O) q% v
* U. ^4 d- H0 N: P& m/ X7 Y- E5 T7 Z( n4 X  Sometimes, a same HAProxy instance may be shared between a direct client
1 @% W% |* ]2 _% W0 C  access and a reverse-proxy access (for instance when an SSL reverse-proxy is. Z4 \9 ]2 U) f( m
  used to decrypt HTTPS traffic). It is possible to disable the addition of the0 h6 a( G7 J% g) Z3 J  `! Z2 t* ]4 y
  header for a known source address or network by adding the "except" keyword3 I; K$ D$ D* `9 X% _
  followed by the network address. In this case, any source IP matching the$ x: C" ?  S' {( R8 i' b3 }
  network will not cause an addition of this header. Most common uses are with5 Q+ v9 J, ]4 r* N; M, J2 o2 F
  private networks or 127.0.0.1./ W  i1 b6 U6 }; W$ q2 @2 s

; q0 y' J* J# ]4 |# L6 @0 J  Alternatively, the keyword "if-none" states that the header will only be
8 i1 k; j. N' Z0 `- u/ M3 M. T0 w  added if it is not present. This should only be used in perfectly trusted' |% I1 g2 d4 U/ {
  environment, as this might cause a security issue if headers reaching haproxy
" j( r% T( ^( V! E! [  n" X, t  are under the control of the end-user.
8 o8 N2 p( q0 [6 X' z% X0 G  J9 g8 S* Z  d
  This option may be specified either in the frontend or in the backend. If at
1 c9 F7 J1 Z1 n  least one of them uses it, the header will be added. Note that the backend's
! N0 `+ Q" q. X7 ]# |0 a  setting of the header subargument takes precedence over the frontend's if8 y6 F7 I+ p: {: x6 e
  both are defined. In the case of the "if-none" argument, if at least one of
( B" }) q6 b% J+ W  the frontend or the backend does not specify it, it wants the addition to be5 X5 i* v( P1 `7 t8 e& V$ i- S
  mandatory, so it wins.) b3 n  d. d9 u) j8 _
7 k3 P& y: |1 c3 \
  It is important to note that by default, HAProxy works in tunnel mode and1 x) i, a+ I7 X% h9 [$ E
  only inspects the first request of a connection, meaning that only the first9 y- D! j& |, t$ w! e2 H
  request will have the header appended, which is certainly not what you want.1 O& l. I! C- L/ x. i! ?
  In order to fix this, ensure that any of the "httpclose", "forceclose" or0 h8 b( w+ x7 J9 d& U! }4 b9 W
  "http-server-close" options is set when using this option./ n8 c3 T$ F7 m
0 \: ^- U9 `9 _1 s- B% s
  Examples :+ X, A/ a2 e: b% d$ @9 S9 R6 X
    # Public HTTP address also used by stunnel on the same machine1 O* e8 g) z. n) X, v$ ?
    frontend www
' x5 ?3 _: S$ b6 z        mode http
# B# v! p( n6 ^5 O" Y        option forwardfor except 127.0.0.1  # stunnel already adds the header
- N3 ~7 y2 l# @" i. @
$ r% @6 X1 H8 R' @    # Those servers want the IP Address in X-Client
! r* {5 U# H2 `' H    backend www
0 I$ `: \+ R# x( M& O( Z! G, }        mode http5 e1 ^* |8 t( b7 O
        option forwardfor header X-Client
3 x8 U/ m, U0 a4 a# q5 F
3 D7 ]2 Y8 q/ D! ?( W) H  See also : "option httpclose", "option http-server-close",; U# J/ U. x. O. Z+ `3 J
             "option forceclose"
9 a/ [8 Q, \% f3 X& Z- w
* D, E! ]" h! r( |, N1 z; G8 h# U9 S) T
option http-no-delay
$ F8 `2 ?+ s. ino option http-no-delay
: g9 G4 Y0 K% I: Y5 @; N3 W& W5 Z  Instruct the system to favor low interactive delays over performance in HTTP' ?# y% t5 h& x
  May be used in sections :   defaults | frontend | listen | backend
' M* K3 N5 H0 H" E* K: o2 ]: V" i6 S                                 yes   |    yes   |   yes  |   yes
$ o. O; J. {9 P5 }6 z- P* J& Q  Arguments : none) M+ N; A# _( q' _* _5 m. \
) C! ^/ d6 K2 n5 F3 x8 N
  In HTTP, each payload is unidirectional and has no notion of interactivity.2 ]5 M+ q1 b6 F7 p8 w) l* H% {) O3 M8 S
  Any agent is expected to queue data somewhat for a reasonably low delay.
7 J6 L$ y: F$ }$ \- ~: r1 d6 U  There are some very rare server-to-server applications that abuse the HTTP
7 P; L3 P; L& }9 V  protocol and expect the payload phase to be highly interactive, with many
, Z: ?* i2 _( X7 p& ^6 b' c  interleaved data chunks in both directions within a single request. This is+ v7 s: ~0 f8 ^* E5 R
  absolutely not supported by the HTTP specification and will not work across
5 G# O2 A7 x) F$ Q4 J  most proxies or servers. When such applications attempt to do this through
- x- G& B4 _" Z$ a: M; L! q9 ]  haproxy, it works but they will experience high delays due to the network
! T+ b5 v7 N& G) S  optimizations which favor performance by instructing the system to wait for
- P  Z, k8 [8 {0 D0 T  enough data to be available in order to only send full packets. Typical
, Y; o3 {. V% w, Q- m) W# _0 v  delays are around 200 ms per round trip. Note that this only happens with' |1 A/ g; M' ^; g+ J4 Y
  abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not! g. H" u* K  r
  affected.0 d- k/ \/ U* x; C& y
- a% G) J" J+ O: V2 z
  When "option http-no-delay" is present in either the frontend or the backend1 G( P$ u% }% |3 o
  used by a connection, all such optimizations will be disabled in order to8 {% ~# X: Z" q+ q7 }, k$ a
  make the exchanges as fast as possible. Of course this offers no guarantee on
, I8 ?  E; ~" q  W! u  the functionality, as it may break at any other place. But if it works via7 P7 F( s% h6 b0 r
  HAProxy, it will work as fast as possible. This option should never be used5 h: O5 h! F& `3 n- E7 X
  by default, and should never be used at all unless such a buggy application
/ a" ]+ F- ^: q) X+ [  is discovered. The impact of using this option is an increase of bandwidth
/ s: X. b3 \) ?+ f5 }% D* {  usage and CPU usage, which may significantly lower performance in high
; E- U: E1 m1 h; Q0 \4 I  latency environments.
$ T  \- N( S7 _3 \( m
& U3 v; P* Z& G% {" h7 r& V. c' l5 u' d; t- k8 G2 Q4 ?" @
option http-pretend-keepalive
. H$ h! _- ]2 u% Sno option http-pretend-keepalive: p; H1 h0 J$ }- T+ }
  Define whether haproxy will announce keepalive to the server or not9 z) v0 _7 k5 t8 A+ N1 u6 q3 ]
  May be used in sections :   defaults | frontend | listen | backend
5 x$ k. n0 e" L                                 yes   |    yes   |   yes  |   yes
8 N  Q! z' A! a2 }- Z$ X: G9 s  Arguments : none
  y: w8 `" E6 L4 R* p" d
1 t* d6 V" t. {( A6 J' b  When running with "option http-server-close" or "option forceclose", haproxy
# U: t+ v* `4 ]7 l; H/ D  adds a "Connection: close" header to the request forwarded to the server.
' t# K" M: V! v4 B) ?  Unfortunately, when some servers see this header, they automatically refrain' `4 S" k( t: K; u4 ~
  from using the chunked encoding for responses of unknown length, while this
% j* D( |) ?" j  is totally unrelated. The immediate effect is that this prevents haproxy from# T' m  k) H6 \* P- u; z& q
  maintaining the client connection alive. A second effect is that a client or
  E8 o! `, S. A: }' p" I  a cache could receive an incomplete response without being aware of it, and
5 ?, {3 c# I1 G% n  consider the response complete.
3 \0 i. z4 K, O2 u$ t- x+ S, M6 \: e+ T& G. u: R% J
  By setting "option http-pretend-keepalive", haproxy will make the server
$ M% N, v8 e5 F% i1 Q9 f; F5 z  believe it will keep the connection alive. The server will then not fall back6 h) N% p+ E7 V
  to the abnormal undesired above. When haproxy gets the whole response, it+ n1 d8 |# F% ]5 }8 a
  will close the connection with the server just as it would do with the
; H; F, o7 T  k; l2 l  "forceclose" option. That way the client gets a normal response and the
9 t. ?" s) D3 J5 J0 e4 b  connection is correctly closed on the server side.
. {" n4 y, u' i# Y, _; K7 o% J
* x! N6 h4 r  ~6 B$ K2 _: S4 S  It is recommended not to enable this option by default, because most servers
: D6 f; H* o' C" {  will more efficiently close the connection themselves after the last packet,
' c* c1 E7 {7 k1 E  t% e  and release its buffers slightly earlier. Also, the added packet on the
4 ?! u! P: s$ c. v  network could slightly reduce the overall peak performance. However it is
! x2 k# ]- K; F: o8 K  worth noting that when this option is enabled, haproxy will have slightly0 h! g0 Q  N7 g: A
  less work to do. So if haproxy is the bottleneck on the whole architecture,& }' {- X; s* v1 g) w, ^
  enabling this option might save a few CPU cycles.3 q$ k8 I7 A  P3 b( C$ j
2 [4 `9 @9 J) R; \
  This option may be set both in a frontend and in a backend. It is enabled if
: o4 ]( G) O4 l) p4 |: q9 q  at least one of the frontend or backend holding a connection has it enabled.9 e- K* c2 }0 z' E, k
  This option may be compbined with "option httpclose", which will cause. {9 Z9 I% a7 m' _* I/ N
  keepalive to be announced to the server and close to be announced to the
+ h( s. s2 ?" ]6 d8 d, o6 M  client. This practice is discouraged though.
% e& d0 l' ^: S/ z( P  t& z' o
. y7 c0 F% ]$ w! L. s; E  If this option has been enabled in a "defaults" section, it can be disabled
. ^' A" ~' r" x, g  in a specific instance by prepending the "no" keyword before it.
! o+ q: {; v/ B! y7 ?' _/ `  T9 ^$ z
  See also : "option forceclose" and "option http-server-close"
4 R4 A6 Z4 B0 c$ S* x& ~7 ~: X; ~" Q/ J% C
  d: g3 g  |1 O7 [  g
option http-server-close7 J7 |- h" I0 z% M8 l
no option http-server-close
# N) W. B) [: B# Z  f4 M  Enable or disable HTTP connection closing on the server side
0 j3 j7 F0 h0 f6 ?# p' U. M1 j' }  May be used in sections :   defaults | frontend | listen | backend) `, R- p/ V0 o; I8 k, i" ]
                                 yes   |    yes   |   yes  |   yes+ S+ v- g( b: C( [
  Arguments : none
5 c6 K1 \& W7 `' @
0 B* E3 U0 M9 w& g  By default, when a client communicates with a server, HAProxy will only
* \' ~% \% Z  a4 o, S  analyze, log, and process the first request of each connection. Setting
3 w+ Q8 @/ I7 V% I  "option http-server-close" enables HTTP connection-close mode on the server
+ W3 I  W9 M, c* L/ ~  side while keeping the ability to support HTTP keep-alive and pipelining on) J5 D, y3 m& _& k4 q
  the client side.  This provides the lowest latency on the client side (slow7 S& \0 _' {: O8 J
  network) and the fastest session reuse on the server side to save server
( b5 ]# j+ ?1 x& i  resources, similarly to "option forceclose". It also permits non-keepalive
7 b) L& r7 d& B( y9 j$ ^3 Q' g  capable servers to be served in keep-alive mode to the clients if they7 R' Z, @0 G; t& \
  conform to the requirements of RFC2616. Please note that some servers do not% _& f+ i$ w0 j: ]
  always conform to those requirements when they see "Connection: close" in the
$ W* ?5 m1 U. x& j2 |6 t5 N2 Y  request. The effect will be that keep-alive will never be used. A workaround
4 f: d' p1 f5 P6 V& n2 [  consists in enabling "option http-pretend-keepalive".8 P& o$ h- e+ X4 s- d7 L8 n
. E# G5 g+ q* {7 D. M( n
  At the moment, logs will not indicate whether requests came from the same  Z9 Z7 _4 ~5 q; u# a5 ^4 g
  session or not. The accept date reported in the logs corresponds to the end
) q  E5 X  G' [8 o  of the previous request, and the request time corresponds to the time spent
  o$ e1 Q0 n+ E0 F! J; O1 ^1 |+ Y  waiting for a new request. The keep-alive request time is still bound to the* T% V$ n, a+ S& l' A2 r; g/ Z3 I( |
  timeout defined by "timeout http-keep-alive" or "timeout http-request" if0 O( m3 M) a" T& ]8 y" g
  not set.( {  d0 H& F% t1 z# I

1 z, m  z6 k2 @. x7 Z" o+ y9 x8 f4 |  This option may be set both in a frontend and in a backend. It is enabled if
. ^1 |+ Q$ U: G- |/ T  at least one of the frontend or backend holding a connection has it enabled.
. V: a- b; J& }4 c& x  It is worth noting that "option forceclose" has precedence over "option# f! o# K7 N, |3 g  V9 y% u
  http-server-close" and that combining "http-server-close" with "httpclose"! n3 g, f4 [( @6 t! G* f, R
  basically achieve the same result as "forceclose".
7 Z) `$ l& K; ]  ~* `, k5 R& @6 z* F3 D1 P3 g2 C1 [* n  y
  If this option has been enabled in a "defaults" section, it can be disabled6 o8 v7 ]; l" `$ y: u3 s
  in a specific instance by prepending the "no" keyword before it.* G& x0 \$ p- a; e

$ W: ~8 I0 Z) j# c' t, p" ]  See also : "option forceclose", "option http-pretend-keepalive",
8 @9 C' o3 {! o1 r9 X4 V5 b             "option httpclose" and "1.1. The HTTP transaction model".
- Q  ^' M; Q/ Y% A4 ?" W2 P- f/ ]1 A( f. }% y2 j
6 \. u. q2 }( k  @  G
option http-use-proxy-header0 z7 I3 `! [& \! `4 ^. e7 y2 f
no option http-use-proxy-header
3 E, }% U' }0 v: Q, _: v  Make use of non-standard Proxy-Connection header instead of Connection
  _7 d# a, k& {  May be used in sections :   defaults | frontend | listen | backend
9 @5 |( f+ G$ V5 F$ R5 P/ |3 K                                 yes   |    yes   |   yes  |   no7 z3 q* S4 M  n! a& M( X
  Arguments : none
1 C7 _$ d6 {0 \- d6 R
, X+ f  X- N$ t2 [- \1 }9 w  While RFC2616 explicitly states that HTTP/1.1 agents must use the0 R+ b. h8 Q! q  _+ I2 M, I5 [
  Connection header to indicate their wish of persistent or non-persistent
$ c% U! F2 c7 n) O" E( h7 Y  connections, both browsers and proxies ignore this header for proxied
1 T0 Y* X, O) p  connections and make use of the undocumented, non-standard Proxy-Connection; Q9 e# w7 y% S% K1 z5 }
  header instead. The issue begins when trying to put a load balancer between
: o) \1 f9 f" J3 F* G5 P  browsers and such proxies, because there will be a difference between what" b; S" o* v$ D* f
  haproxy understands and what the client and the proxy agree on.
8 B) ^. G, }9 F/ y
4 V; ~  @- i- e: t6 `$ {; s6 a  By setting this option in a frontend, haproxy can automatically switch to use; P4 q" A5 _4 ?! y+ D% U( o: u
  that non-standard header if it sees proxied requests. A proxied request is; o6 n4 T+ |) c) C+ o9 @8 |) n
  defined here as one where the URI begins with neither a '/' nor a '*'. The9 r9 l: h% z, S; n: x. C8 y% X5 H
  choice of header only affects requests passing through proxies making use of
- e: u( T: X8 T. H5 E6 w  one of the "httpclose", "forceclose" and "http-server-close" options. Note6 q' H. T0 L/ {/ l+ m4 M' g
  that this option can only be specified in a frontend and will affect the
$ o3 Q  z+ b7 C! |: N9 a& c  request along its whole life.
* Z3 T2 h; E( Y/ R
: }& [8 A7 r4 f0 T+ z/ O/ W  Also, when this option is set, a request which requires authentication will) Y! x3 s/ D! |) C6 D5 z5 H
  automatically switch to use proxy authentication headers if it is itself a8 y8 N' E, T3 ^# H" ]$ C" g, W
  proxied request. That makes it possible to check or enforce authentication in
' t! y3 q+ S* U& v/ `! I  front of an existing proxy.2 \: D) Y8 G8 k: V' E, n

  K4 f; T" h7 y$ E7 v$ w  This option should normally never be used, except in front of a proxy.
4 l2 v8 a. W5 O6 {
4 w0 l: x* i) v9 u( t  See also : "option httpclose", "option forceclose" and "option
0 Y2 t0 ~& c6 ^- n9 f             http-server-close".
* ]7 q2 n7 _9 _% [( [$ v
+ N8 Q: H1 L+ \  X7 q, D$ h9 Q, |% H+ d- l" Z8 g
option httpchk9 p# f+ q" U2 |" [2 R
option httpchk <uri>
( R8 X0 N1 W" e! @- }$ Ioption httpchk <method> <uri>
- D3 U0 n1 [8 R6 aoption httpchk <method> <uri> <version>
; r- Z9 l. W: K1 `' F1 a  Enable HTTP protocol to check on the servers health
0 ^9 N( I" I- u0 o+ y  May be used in sections :   defaults | frontend | listen | backend
% H* Q' u/ m6 l( Z& Q: p# T                                 yes   |    no    |   yes  |   yes$ Z' p- f3 \- d. A# ~
  Arguments :- V. i1 r( r' H6 j! c; X
    <method>  is the optional HTTP method used with the requests. When not set,
) }! w/ A0 C: E7 b, a& \              the "OPTIONS" method is used, as it generally requires low server
2 n) s6 Z7 T  Z) A% n              processing and is easy to filter out from the logs. Any method
2 m2 x: }: p# O- d              may be used, though it is not recommended to invent non-standard
# ]9 h; O# ~+ @0 s              ones.
# j7 N" w6 [  `1 D9 m: @8 J. I/ S) j# Q
    <uri>     is the URI referenced in the HTTP requests. It defaults to " / "
- V+ D. u$ t* }+ c7 C3 Z1 v              which is accessible by default on almost any server, but may be
8 |5 e9 [  ^7 p0 Y" @) c              changed to any other URI. Query strings are permitted.
- W, Y  W( S3 `6 V, i5 g0 X2 Z
: X2 L" C3 M) r# `% W) Q    <version> is the optional HTTP version string. It defaults to "HTTP/1.0"
5 h$ l: u  ~2 D  Y! A0 K$ ]: F/ \              but some servers might behave incorrectly in HTTP 1.0, so turning) b" s% ^. ]$ @2 d- ^  f5 c- V  q
              it to HTTP/1.1 may sometimes help. Note that the Host field is
0 N" o2 p+ q. v9 }6 r              mandatory in HTTP/1.1, and as a trick, it is possible to pass it- q: `4 e$ o" w9 H6 z
              after "\r\n" following the version string.
5 B. x) W9 N$ o3 h
# o5 @0 e$ b. d  By default, server health checks only consist in trying to establish a TCP
/ j# G! Z+ P( z) r4 x; Q' M  connection. When "option httpchk" is specified, a complete HTTP request is
( M5 l( U7 g9 k  sent once the TCP connection is established, and responses 2xx and 3xx are
, n; n# p' ?, z( H  considered valid, while all other ones indicate a server failure, including' a* K" q7 b1 N) I0 C  _/ R/ i
  the lack of any response.
4 ~( \$ |1 G* ~8 t& W* d9 H' I" y7 Q  ]
  The port and interval are specified in the server configuration.8 S, P7 ]' Z0 x

& t- u# b8 ]& P. V1 f- x6 {$ @  This option does not necessarily require an HTTP backend, it also works with. p; @/ L8 d$ i9 I$ U, R
  plain TCP backends. This is particularly useful to check simple scripts bound$ {/ u0 S7 m/ y8 f! a" w& @
  to some dedicated ports using the inetd daemon.
$ Q# o" r4 s8 x
/ r. k5 Z6 m3 K4 ?! y+ H  Examples :
- |) U; \" l5 B8 [4 [      # Relay HTTPS traffic to Apache instance and check service availability; |) ?8 S7 Y6 b" B3 m/ }
      # using HTTP request "OPTIONS * HTTP/1.1" on port 80.( }' @3 r  s: S8 ]8 V
      backend https_relay7 n& `3 j7 G8 a) o1 K8 n% ^
          mode tcp- B& ~5 f/ r9 [  U, W; B6 @
          option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www* Y- T6 X+ E+ V. |1 Q' {" W
          server apache1 192.168.1.1:443 check port 80: K: u" g5 K& i+ r/ |
4 V/ J; s; q9 U* C; V4 w4 i* J! I
  See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",; I2 v* @$ T# P7 K: ~* N7 m
             "http-check" and the "check", "port" and "inter" server options.
2 S& u& t: l3 e, f
, H% m+ D& T5 M- L0 U2 \  l" N
# C4 s& `+ K7 b/ O8 i! m) o% ^option httpclose
  J% w7 p# x: N0 k* O9 h  K3 qno option httpclose
& M+ {8 K& w# r; v! J* R4 M  Enable or disable passive HTTP connection closing$ B0 X; W+ ?% c) V
  May be used in sections :   defaults | frontend | listen | backend
, _# Y( [( `% d. {                                 yes   |    yes   |   yes  |   yes0 k$ A; p) G6 b/ d( M
  Arguments : none, q& q; c, N3 P9 Q$ T; h! u

2 @$ y6 W$ g- M  By default, when a client communicates with a server, HAProxy will only8 m& `- A( x! N" |& Z7 `
  analyze, log, and process the first request of each connection. If "option7 [5 {( e# E* t4 W) a
  httpclose" is set, it will check if a "Connection: close" header is already! t& l) Z/ g. T# K6 g+ F* L: V( f5 ~
  set in each direction, and will add one if missing. Each end should react to
# g4 W4 E" t* X% g6 R% y  this by actively closing the TCP connection after each transfer, thus3 n) N6 q/ H5 n8 w1 c/ O
  resulting in a switch to the HTTP close mode. Any "Connection" header
# a4 G/ c# N0 f+ N4 [* o# S* u9 c* [  different from "close" will also be removed.
5 n, e+ m- Y3 `2 |9 N. g. B
: \/ k( L3 A% I4 \  It seldom happens that some servers incorrectly ignore this header and do not* j/ n2 e& N2 U/ ?. s+ @8 r* Z
  close the connection eventhough they reply "Connection: close". For this
/ w* Z# ^: ^5 J9 V6 T( O# V+ s  reason, they are not compatible with older HTTP 1.0 browsers. If this happens
: F( T  b2 g. z. S, i  it is possible to use the "option forceclose" which actively closes the
, z) p% x, t6 X( R" Y  request connection once the server responds. Option "forceclose" also
+ V5 {- R8 Y. x3 g2 M3 \3 h  releases the server connection earlier because it does not have to wait for
- N' @9 I8 u4 e5 _  the client to acknowledge it.
  _; V/ R5 A) o4 O( E, S. ^% \- [/ i4 b+ ^3 ?! e: S5 l6 n
  This option may be set both in a frontend and in a backend. It is enabled if' x8 ]0 c( ^& G
  at least one of the frontend or backend holding a connection has it enabled.
+ h3 Y& U6 h2 p, Z4 d' @7 W  If "option forceclose" is specified too, it has precedence over "httpclose".
4 T$ y0 |0 ?6 Z2 Z  If "option http-server-close" is enabled at the same time as "httpclose", it' T  O. M. W5 h' ]. a" U
  basically achieves the same result as "option forceclose".2 Y9 M0 }( {3 a6 E* p

2 j( x' {; M! D  v1 t  If this option has been enabled in a "defaults" section, it can be disabled
! t  g( d4 W5 f$ A3 V" @0 G  in a specific instance by prepending the "no" keyword before it.
) m% b9 q$ ?6 \& B, ]7 n
( e: _, ?/ ~; ]0 g  See also : "option forceclose", "option http-server-close" and
; V, L) a& Z5 E" N; g             "1.1. The HTTP transaction model".( G. H9 S& {+ n* j$ \
( y" H& L8 L9 t8 v0 A
1 I+ z: F" K( @' q
option httplog [ clf ], d  S0 D6 c" ?  L3 q, F
  Enable logging of HTTP request, session state and timers6 [' o  G/ ?1 Z
  May be used in sections :   defaults | frontend | listen | backend' W. D  I$ x4 ]/ U; w4 d! }
                                 yes   |    yes   |   yes  |   yes
9 u7 I( P+ X% \+ O/ m0 F  Arguments :
7 ?* Y: E' k( G( x, r% s2 e/ I) i    clf       if the "clf" argument is added, then the output format will be
9 i1 \$ Q# @* K3 v! k( i  A9 d$ P# D              the CLF format instead of HAProxy's default HTTP format. You can
3 T7 A6 P% G$ H, o              use this when you need to feed HAProxy's logs through a specific
1 Y+ K) D$ D) U7 Q              log analyser which only support the CLF format and which is not+ u( K& \7 d$ v7 ^, D3 [- u
              extensible.
& q( ~6 n+ L" l: o/ Q7 Z$ c" h; j
  By default, the log output format is very poor, as it only contains the) |7 n* h" _% [" \+ u
  source and destination addresses, and the instance name. By specifying
2 f$ ~5 V* V% e, P7 Q6 O  "option httplog", each log line turns into a much richer format including,. m( b( P. e, z) n# {* \
  but not limited to, the HTTP request, the connection timers, the session
. x4 ^+ b# J- u  status, the connections numbers, the captured headers and cookies, the
4 i6 o! h. v. k8 y( a  frontend, backend and server name, and of course the source address and+ t, }6 d- K' l0 w2 }
  ports.
5 U% a# c; k: X( g8 H  l- Y; L7 X3 d
5 O* A6 I0 i8 G  This option may be set either in the frontend or the backend.
/ W7 [; r0 V7 G& `0 s6 u( C! N8 \6 }) c6 k6 p7 ]
  Specifying only "option httplog" will automatically clear the 'clf' mode4 t* [$ Z* l4 Q% {" H# o- w
  if it was set by default., S5 M6 G/ |. n+ F
5 o2 h( r& N' P# m" y9 Q
  See also :  section 8 about logging.
. X/ ~' }/ h# {0 ]
- g( t  n' m( T5 Z5 z
; G& i; L( j/ W# X8 doption http_proxy/ T2 M4 U9 S" n6 p, b# i% g
no option http_proxy
* z) R' _4 G+ `& U& D8 U  Enable or disable plain HTTP proxy mode
$ Y  T( g2 k  Z  f. E; q" N' `  May be used in sections :   defaults | frontend | listen | backend+ [% N# O+ L* N
                                 yes   |    yes   |   yes  |   yes
9 |3 R5 N9 o1 f* G( ^  Arguments : none
( }' M5 S" P0 y" Z$ j. X* }; X1 C
  It sometimes happens that people need a pure HTTP proxy which understands
9 `( h9 y, _+ u* T; s6 A+ T  basic proxy requests without caching nor any fancy feature. In this case,: y" V; A  _; B" h7 j: o' t
  it may be worth setting up an HAProxy instance with the "option http_proxy"% Q8 q2 X$ D- `5 b
  set. In this mode, no server is declared, and the connection is forwarded to: g) t( w5 M. U2 @; N% v* ?
  the IP address and port found in the URL after the "http://" scheme.2 ~: Q( i- ~) o+ W: [9 I7 x7 V
" X% E- W, x$ i0 Q5 D1 l
  No host address resolution is performed, so this only works when pure IP& R# Z/ A/ D2 G1 C' ?; n& }
  addresses are passed. Since this option's usage perimeter is rather limited,1 s( _, l7 }7 ~7 k. z: L2 U
  it will probably be used only by experts who know they need exactly it. Last,
; |* {) ]6 h5 X' C( P  if the clients are susceptible of sending keep-alive requests, it will be. a. f8 q" ^5 u9 D# |8 c* Z
  needed to add "option httpclose" to ensure that all requests will correctly
/ |7 x: j: p5 H% l, {  be analyzed.4 O- M/ J7 N2 X/ E1 n. s

0 c2 c! i. u. m- K" f6 R4 P  If this option has been enabled in a "defaults" section, it can be disabled2 y. e$ Y5 M. m8 ~0 ~' i7 a& a/ q
  in a specific instance by prepending the "no" keyword before it.
9 c  d3 u  a5 i& L5 ]! \3 ]% l( X2 M, [: ]
  Example :
# U9 b9 O- T( B9 K" s  G: b% E- h3 {    # this backend understands HTTP proxy requests and forwards them directly.
3 G/ H5 u, G7 ~    backend direct_forward8 r3 P0 M3 R6 {( M0 V* A1 l0 r
        option httpclose  C% p8 ?: H1 ]0 e
        option http_proxy
6 O: u) I0 e9 f. c, y3 u4 L1 d5 r" r# |$ Y+ @6 m& H, z
  See also : "option httpclose"
9 S* x2 O) R0 Z) G% u) [
' X$ T, X% l' L* J7 B3 q. l. G4 I6 ~$ H4 E- O
option independant-streams
) T0 S) }! j3 Y/ `5 rno option independant-streams
" |1 A) y/ D* u) ?* r4 P  Enable or disable independant timeout processing for both directions
" v7 v- b4 Y, o3 u) y  May be used in sections :   defaults | frontend | listen | backend
. j) b7 ?# t% R. H- ~, N" i                                 yes   |    yes   |   yes  |  yes
. C# f2 F# S8 C! t, H3 T  Arguments : none# C( W/ H' C  M2 x) q
- P1 R, C+ I* ]5 i; w& S) d, l5 R! a
  By default, when data is sent over a socket, both the write timeout and the
% |9 O; t- p: |5 `  G0 T  read timeout for that socket are refreshed, because we consider that there is
' v" S9 c% f0 X+ b! r( B  activity on that socket, and we have no other means of guessing if we should, E. ~; O7 v; E
  receive data or not.
: |: W- i" _" Q+ u) F9 n0 ?  y6 ]3 n7 a/ l7 a
  While this default behaviour is desirable for almost all applications, there
2 Q! y8 P9 r3 V7 ]3 n# T  exists a situation where it is desirable to disable it, and only refresh the  ^5 ^$ E' B) m1 g
  read timeout if there are incoming data. This happens on sessions with large
3 b6 N* J! e# y! [  timeouts and low amounts of exchanged data such as telnet session. If the
( n3 X0 Q. b3 R. M" o! R  server suddenly disappears, the output data accumulates in the system's
9 S5 }8 d* M; }" Z* D0 f  socket buffers, both timeouts are correctly refreshed, and there is no way
! x# a, Y% @" P' z3 J! o  to know the server does not receive them, so we don't timeout. However, when
1 |. q; B5 T: M# H  the underlying protocol always echoes sent data, it would be enough by itself
7 ?! R5 a0 F' i) }  to detect the issue using the read timeout. Note that this problem does not4 V( E4 L' d2 d7 C+ i2 k. Y2 V
  happen with more verbose protocols because data won't accumulate long in the
  i8 _4 c7 U! }7 j$ c  socket buffers.* H6 P- f: \% m
: U! S8 g) t& O! A) V; G
  When this option is set on the frontend, it will disable read timeout updates
0 ~! g* B: t$ w1 x+ A5 f- w  on data sent to the client. There probably is little use of this case. When
* D5 r. x$ {6 K5 }  the option is set on the backend, it will disable read timeout updates on
* l$ A# d" U0 e# s8 W; j& e7 P  data sent to the server. Doing so will typically break large HTTP posts from$ [. J8 b7 b* [3 ?3 y2 r  p
  slow lines, so use it with caution.
& n0 T, G2 b  U  @4 h! V1 b0 H
. g+ S1 J) I+ A' k  q" d  See also : "timeout client" and "timeout server"
- k; W: M0 ^7 O" Z; o: i! N  o' L/ U, }1 I; \+ y! P
6 W+ }' D- U1 S8 R! R
option ldap-check- h$ Q) |! S, Z0 r. M; A
  Use LDAPv3 health checks for server testing
4 g4 L$ E3 |+ Q  g8 g3 ~; U: Q, ~  May be used in sections :   defaults | frontend | listen | backend, h; o0 d/ `+ H
                                 yes   |    no    |   yes  |   yes
" X1 Q8 `, v" h7 D* @3 S  Arguments : none
. w! L& d: K" L# B5 F8 \
/ s; N6 `2 K- u5 o& j: f, [  It is possible to test that the server correctly talks LDAPv3 instead of just0 e  i- z9 }: ]/ n7 F1 ?! B
  testing that it accepts the TCP connection. When this option is set, an
* v- V0 z" h$ f6 U- b  LDAPv3 anonymous simple bind message is sent to the server, and the response
+ N% Z& [+ @$ T: Z3 i6 b  is analyzed to find an LDAPv3 bind response message.
+ h9 t4 I+ }# N, u2 ]) e6 b& z9 k
  The server is considered valid only when the LDAP response contains success0 D$ @7 j3 E+ h% _
  resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).# `4 j. ^2 d' B( M# u7 H! r0 H5 y
9 B  k- @/ y& E! x
  Logging of bind requests is server dependent see your documentation how to5 _" Z. _0 M) d! E- `
  configure it.4 O& @" V8 P* M9 @

- S- r$ f4 [& u2 d. d. }  Example :' W1 z: r& ?, J8 i: {7 d0 u3 v( i
        option ldap-check
* H: i4 p% b& V/ t- {4 T8 [( @7 j* [1 B7 z& y
  See also : "option httpchk"
3 \& i5 ^( O& N& y
, B4 p) e  ^5 ]: ^3 p
0 ~7 B0 z  R" D+ |! D! B. H  j$ |option log-health-checks9 h, r4 f. x9 @# E
no option log-health-checks, x  Y/ h# I' I$ l- ?0 f  g4 w# i
  Enable or disable logging of health checks, y! f1 R" I+ d5 Z
  May be used in sections :   defaults | frontend | listen | backend
3 P" A* z, \; W7 k( u$ I                                 yes   |    no    |   yes  |  yes
9 x9 H+ i- J: W, ?  Arguments : none" L* L9 k; W/ z& G) W

5 L' J* u( P  _  Enable health checks logging so it possible to check for example what
0 `3 f  l% a7 t. R3 d. U  was happening before a server crash. Failed health check are logged if
: q9 g8 `3 H) D8 b  server is UP and succeeded health checks if server is DOWN, so the amount
  r: T$ X3 N5 E  of additional information is limited.& \( c6 `; w9 B( j- L( v( C
6 O2 Z  U. Z3 Z" E: d+ h7 g
  If health check logging is enabled no health check status is printed
/ A2 t# Q0 G) l$ H0 A5 D  when servers is set up UP/DOWN/ENABLED/DISABLED." K3 b1 Y5 |& I8 _& l: a& S$ s' l5 f5 H9 A
, B0 H, I' ]5 D( J' v6 |5 n
  See also: "log" and section 8 about logging.
; Q' k- ]. e/ `. x5 f
- _- A$ O* X& r! T: R, `# s0 W) R0 M6 n4 o# _+ }! z: I* j: |
option log-separate-errors  B6 k! _  t5 G1 Y) E  G! s
no option log-separate-errors
7 T9 N2 }  u4 X0 w! N  Change log level for non-completely successful connections7 f! [' p+ {1 o: v. r% r
  May be used in sections :   defaults | frontend | listen | backend
2 r: S: v6 D) U+ V                                 yes   |    yes   |   yes  |   no
7 ]" d- O' E9 ?: e  Arguments : none( A" P/ |/ ~, v) Z' F5 W
8 @4 h) E) R, w+ o+ `) L
  Sometimes looking for errors in logs is not easy. This option makes haproxy8 q7 N& N' f- T. R% S# j  H- j4 v, g
  raise the level of logs containing potentially interesting information such
' _: f' {" O9 j# @/ k! y8 ]# ?# \  as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The* x- G: l* z3 R& K3 X+ \7 z
  level changes from "info" to "err". This makes it possible to log them
. X6 C& `# T( a$ r4 v  separately to a different file with most syslog daemons. Be careful not to' s7 F! j9 B, e1 ?; l! U
  remove them from the original file, otherwise you would lose ordering which& v+ A. m$ `4 k' l0 N' b/ L; D
  provides very important information.
' W) }) e% i  Q/ j  S' ^8 _5 f; B! U* P+ _% f% x5 X
  Using this option, large sites dealing with several thousand connections per+ l4 m$ p5 v+ T% i( C
  second may log normal traffic to a rotating buffer and only archive smaller
4 p4 T% f: r1 w& ~8 Q6 C  error logs.
9 X  I/ P0 d, q/ z8 `5 S; U
7 o3 K/ ]9 L. y- _  See also : "log", "dontlognull", "dontlog-normal" and section 8 about6 ~& }. y  L6 Q$ ^/ o1 f
             logging., E. ^1 i  \' K, \- _, {

( A  [2 |" ]5 `
! Z- V+ K: h, X. {option logasap- R6 J+ W# k8 C0 f- g$ \# \
no option logasap
1 h9 |( y+ V2 s. b/ r  Enable or disable early logging of HTTP requests. T9 a2 _8 ?+ o
  May be used in sections :   defaults | frontend | listen | backend, X8 F( P' I/ |2 e! L4 x, d
                                 yes   |    yes   |   yes  |   no
* @$ [- s% Y8 o. u; u! U2 s# K  Arguments : none# o% n2 }5 C  p# n4 w' U
- d8 X* i4 K+ k  r3 l& y
  By default, HTTP requests are logged upon termination so that the total
9 \2 w! g" X7 p  transfer time and the number of bytes appear in the logs. When large objects
$ w/ X2 d/ n# `8 [, f  are being transferred, it may take a while before the request appears in the
$ }1 U1 w: O4 Z- W& g" A  t  logs. Using "option logasap", the request gets logged as soon as the server
+ r, ^( f" A3 Z# f/ I  sends the complete headers. The only missing information in the logs will be
, m% H/ I9 ?# u9 O, ^  the total number of bytes which will indicate everything except the amount1 J' l! v& L/ Z1 `
  of data transferred, and the total time which will not take the transfer
5 ?, {7 ?* I- p+ X' Y  time into account. In such a situation, it's a good practice to capture the: n4 S$ p9 `  Q
  "Content-Length" response header so that the logs at least indicate how many  a: h" _0 m$ z; v  o9 ]
  bytes are expected to be transferred./ f  S: K2 l( d) B9 O7 v, F

$ E4 e" y8 @! V8 p% `  Examples :$ y- W# K. G* i% q' G9 `
      listen http_proxy 0.0.0.0:809 U: J( t0 S1 P
          mode http
2 j  A- f( i7 W$ I# M5 p          option httplog
' U9 U) w! S1 `. I& F          option logasap
* R& m5 }, o* k9 _$ ^9 ~1 R          log 192.168.2.200 local3
* Q5 ?' x+ G$ O; H* M, M$ R
1 r, t1 a" ~+ e" d# r1 ^/ W2 F    >>> Feb  6 12:14:14 localhost \
1 W& @& Y9 S* F3 N( y- @5 `$ f          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \' k/ [  t: k7 s, J( {
          static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \
8 R7 x) l  K. J          "GET /image.iso HTTP/1.0"
" @# V. D; W( \) R7 D) X% h, f! `* u3 O7 u# C, K1 \
  See also : "option httplog", "capture response header", and section 8 about8 ~1 {, q$ s1 G7 `8 F4 y
             logging.
3 l4 L. t# D( ^  k4 w  H: ]: _7 L; s& ~# k8 }5 f7 ^
1 L  R8 q% a. i, F1 t
option mysql-check [ user <username> ]( |% R0 R$ K; L2 Y0 ~- o& U: G
  Use MySQL health checks for server testing
/ J  _8 j' l- \0 V* T" Z  May be used in sections :   defaults | frontend | listen | backend' r5 A# r; u% U1 i1 Q
                                 yes   |    no    |   yes  |   yes
; X9 O/ @. P9 e( r* r  Arguments :: Y/ Q, _* u) Q2 R0 t8 z
    <username> This is the username which will be used when connecting to MySQL
5 J. A0 {4 O/ V" c9 o1 h& o( w               server.* \, e' X" x7 I6 P

1 b7 a. |; S, H  d5 J( k- c# ]: Q  If you specify a username, the check consists of sending two MySQL packet,7 Q9 |& r3 i' }6 y
  one Client Authentication packet, and one QUIT packet, to correctly close
/ t. b: P1 @# r8 X. \: m0 I7 p  MySQL session. We then parse the MySQL Handshake Initialisation packet and/or
# q$ \  i" R2 r: G$ B; X# k  Error packet. It is a basic but useful test which does not produce error nor1 z% Q' W2 j4 W5 ?
  aborted connect on the server. However, it requires adding an authorization* P; v8 f9 O1 Q. l# N1 K
  in the MySQL table, like this :
8 J& l, ~# Y1 v  e/ i0 w! b6 L6 z; p( O: H: z( R0 w( N6 c
      USE mysql;
& \- V2 v# q. }# `' ^9 H/ N      INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');  |" i' }/ u+ ?
      FLUSH PRIVILEGES;: q: ]% F) U1 Y

8 Z; j- {8 R8 c$ a5 ?) \4 F0 d  If you don't specify a username (it is deprecated and not recommended), the4 h3 Z8 L" T7 b, [( a, Y0 V7 \. u
  check only consists in parsing the Mysql Handshake Initialisation packet or
$ T3 Z$ b& D1 U  Error packet, we don't send anything in this mode. It was reported that it
; H/ _. J3 A" _$ c  can generate lockout if check is too frequent and/or if there is not enough, c0 Q& o6 J# [
  traffic. In fact, you need in this case to check MySQL "max_connect_errors"
+ F+ q+ |4 {; f. y+ k0 y  value as if a connection is established successfully within fewer than MySQL+ O% A1 F1 {0 M1 U& h/ Y5 J9 ~
  "max_connect_errors" attempts after a previous connection was interrupted," x1 g% j4 z  t
  the error count for the host is cleared to zero. If HAProxy's server get
2 `. s. g2 q& a0 C* w& v  blocked, the "FLUSH HOSTS" statement is the only way to unblock it.4 f2 o5 k2 P  \( T5 C4 B
9 u  q0 y4 k/ }, ]7 F" b( ^: ]
  Remember that this does not check database presence nor database consistency.
  K; y4 ~) m9 E$ `* n7 y* `" J! D9 W  To do this, you can use an external check with xinetd for example.( D5 U1 H5 ]) G- m$ Q7 U

8 Y# S& r- x6 T! R) D/ v3 s4 g9 M  u  The check requires MySQL >=3.22, for older version, please use TCP check.
) w* |' h6 _& \- N% z
* e2 l2 f% Z( h( y0 @, ], t  L  Most often, an incoming MySQL server needs to see the client's IP address for3 T; J4 L! w5 d- f/ L4 I, C
  various purposes, including IP privilege matching and connection logging.2 ^1 Z% l* ~! [. ]# C
  When possible, it is often wise to masquerade the client's IP address when+ D: f9 Q/ g0 \% m* O
  connecting to the server using the "usesrc" argument of the "source" keyword,/ y) f: G  ?  `1 v# N' l, s) [
  which requires the cttproxy feature to be compiled in, and the MySQL server3 ~" z: ^/ ]/ i# u% O
  to route the client via the machine hosting haproxy.
% L0 v1 H( U! I7 T, ?+ Z* s& W9 Q7 a) P
  See also: "option httpchk"$ g, m* B2 \: o" @8 l" f) m" T

; B& ^7 k3 \4 i" I. K2 F3 r% W; w  m4 W& u1 ?: P
option nolinger
- c( r7 E0 a" v# M9 \. f( @9 G* o! M  ono option nolinger
! c$ A1 l8 t' a4 s% H9 f$ @  Enable or disable immediate session resource cleaning after close
6 m3 s0 p: i5 ?$ A( X% i  May be used in sections:    defaults | frontend | listen | backend
$ H6 K3 l8 ^' ^/ [                                 yes   |    yes   |   yes  |   yes
7 ]! w9 y4 n" z3 [  ?1 b& E0 {  Arguments : none
3 ]: p8 V. U2 ?3 l0 u
/ l, @% B2 L8 y7 d$ X) v  When clients or servers abort connections in a dirty way (eg: they are
) _* z# b( W  o% z% l  physically disconnected), the session timeouts triggers and the session is
7 m% ]( ?: e4 k/ {6 S# a  closed. But it will remain in FIN_WAIT1 state for some time in the system,$ K7 O+ ~5 n% c+ t* ]
  using some resources and possibly limiting the ability to establish newer* b! `5 S2 g: `+ ~# e
  connections.$ C; q6 z2 Q9 U5 s* }4 g8 v
& ~8 T& u# s; e
  When this happens, it is possible to activate "option nolinger" which forces
- J: \8 Z: l% C6 l4 q6 U# R  the system to immediately remove any socket's pending data on close. Thus,
/ F0 X: B/ d' Z- P. `3 k' }" N  the session is instantly purged from the system's tables. This usually has
: v& S* S. t5 x  ?+ F  side effects such as increased number of TCP resets due to old retransmits) v" k: R2 p1 K* b& k5 H7 [# ~
  getting immediately rejected. Some firewalls may sometimes complain about
5 ~3 \# }% N8 o4 h1 {' Y  this too.
3 y) U0 ~, H) b3 g+ W' r# q8 P4 D$ Z2 H- V9 z8 g
  For this reason, it is not recommended to use this option when not absolutely. Q8 l+ N" W0 l# R4 i5 s& N; Z8 z8 E' L
  needed. You know that you need it when you have thousands of FIN_WAIT1) t6 t# x& f9 h: `, m9 G
  sessions on your system (TIME_WAIT ones do not count).
3 @+ n% p4 W" d- _. M/ R; P8 Z2 k% M1 E; {
  This option may be used both on frontends and backends, depending on the side
9 w0 V7 ?6 \: l8 T1 U  where it is required. Use it on the frontend for clients, and on the backend
. g: n% Z6 o+ R, \+ s3 X8 W9 g+ s  for servers.# Z' I) l6 z5 ]* y9 ^( F$ H) _( q
. t3 U7 `- D' H* g) D0 E# `" ~9 c
  If this option has been enabled in a "defaults" section, it can be disabled
0 }# j2 |, C( X* q  in a specific instance by prepending the "no" keyword before it.
& C; c, N! N1 V2 n1 p! u9 @- J, d. g, u! o

1 U, {/ @6 L' P0 o; T$ zoption originalto [ except <network> ] [ header <name> ]
5 J. F8 K4 r7 v* ^4 S3 o6 q  Enable insertion of the X-Original-To header to requests sent to servers( A& g& s, e! O, z
  May be used in sections :   defaults | frontend | listen | backend
2 Z9 h8 q; q# N9 B) W                                 yes   |    yes   |   yes  |   yes
6 X- b7 f' M, Y4 U, ~/ h' m( |$ Z  Arguments :" n( h( \4 U& w4 J! f
    <network> is an optional argument used to disable this option for sources
. A0 O% j% }/ Q, n              matching <network>+ `) }1 E+ Y! k8 h8 s
    <name>    an optional argument to specify a different "X-Original-To". C% \$ t: t( H
              header name.
. W) A/ x( u- B* J6 D7 F  w* Q. q, d4 f8 A) V! }' X4 V
  Since HAProxy can work in transparent mode, every request from a client can3 c& B" p0 Y. j2 R
  be redirected to the proxy and HAProxy itself can proxy every request to a
0 M+ |1 Q+ |/ T  complex SQUID environment and the destination host from SO_ORIGINAL_DST will
" y; k8 B( h2 P- U$ ?4 O  `: w  be lost. This is annoying when you want access rules based on destination ip1 ^  |. q+ V* z
  addresses. To solve this problem, a new HTTP header "X-Original-To" may be4 W# A. l$ G4 K2 P6 `
  added by HAProxy to all requests sent to the server. This header contains a! j" }. T4 y" k# j+ F' G
  value representing the original destination IP address. Since this must be1 e" S! L9 V7 r6 E$ Q  E8 P
  configured to always use the last occurrence of this header only. Note that$ Q4 ]- [, Z& s; A
  only the last occurrence of the header must be used, since it is really
: B0 @( z/ F! z3 t; o; @. ~+ h  possible that the client has already brought one.6 j% `- a1 M) h% n" r& Y
0 S5 @# ]2 N, f, Z: H
  The keyword "header" may be used to supply a different header name to replace
5 k$ J/ \' w5 L( @' ~$ }2 h  the default "X-Original-To". This can be useful where you might already: s" |. |" q+ L6 }2 u* r0 ^: \
  have a "X-Original-To" header from a different application, and you need6 i) B1 a; C: J  W/ ~
  preserve it. Also if your backend server doesn't use the "X-Original-To"# N* r1 {" B. B! L, s
  header and requires different one.
) ~# G, r6 t( P
/ T8 o3 V9 z) v  m2 B( \! R  S  Sometimes, a same HAProxy instance may be shared between a direct client- n% b/ L  D' q% J8 ~3 Y, ^
  access and a reverse-proxy access (for instance when an SSL reverse-proxy is
2 v# |) c- W+ }) a' I7 e  used to decrypt HTTPS traffic). It is possible to disable the addition of the
* r3 j' w7 t0 M  B% H2 M$ V  header for a known source address or network by adding the "except" keyword
$ P" H# T8 V+ ]  ]  followed by the network address. In this case, any source IP matching the
; A+ k5 ]: a2 ~) e7 [" r2 ?  network will not cause an addition of this header. Most common uses are with
! {* a( ]+ ^8 Z6 W& v  n# J  private networks or 127.0.0.1.
$ z1 |9 L: E: _9 D
  u6 _  P$ m8 a0 Z% y: i1 o/ h  This option may be specified either in the frontend or in the backend. If at
+ E9 Q  o% T+ ~: ]8 {; {  least one of them uses it, the header will be added. Note that the backend's
9 S! ~7 n! O3 q  U' v  setting of the header subargument takes precedence over the frontend's if8 e5 I1 u4 J& M) r  W
  both are defined.  P' f0 {$ c! |+ }5 A4 a# H* |
/ s7 y8 W% H- ]; i
  It is important to note that by default, HAProxy works in tunnel mode and' |6 n& X6 f8 ]" n
  only inspects the first request of a connection, meaning that only the first: {7 @- G, V8 T! f. {# B$ k0 p
  request will have the header appended, which is certainly not what you want.4 y7 h% w( F; G+ ^8 u- l/ C* |: ]2 T9 I
  In order to fix this, ensure that any of the "httpclose", "forceclose" or) u' N; f9 r) D' B: {: z- v4 Y
  "http-server-close" options is set when using this option.) S5 f2 I" M/ o; M; a
: S) y/ n7 T$ L( W$ W
  Examples :
& \( h2 F) \/ e1 b    # Original Destination address$ i! i) \6 A- Y: c/ H
    frontend www
/ a7 y( X6 Z+ }* q& G1 g        mode http( x( n: A5 e9 Q0 ~# n; F  O- ~$ `% P
        option originalto except 127.0.0.1" h! f6 s- r$ Y. g' T' h' D
3 O  F0 h& H( o0 K) {+ G
    # Those servers want the IP Address in X-Client-Dst4 j! Z* a5 ?- f" I* V8 ?2 q
    backend www5 ^( b' Y* l' }$ S3 R) F/ T
        mode http
( u: T- r; o/ t8 r3 B        option originalto header X-Client-Dst
, O( e. [/ m, |4 p7 P6 ^( G2 j4 H1 q" U. B/ \, E  _& |5 ?
  See also : "option httpclose", "option http-server-close",! M2 N% Y5 S. ?" X/ x2 i
             "option forceclose". Y; L0 w/ F+ ?* t, \
* m( k2 U6 S* Y3 Y1 ?, Y
+ Z; t  M1 V, T1 I  \" P3 }  U0 Y
option persist( Q+ a, n7 ~1 u; i+ ~; A
no option persist
; Y. e3 L/ a& G1 N: o  Enable or disable forced persistence on down servers6 L& L& m1 o1 m% H) o8 b
  May be used in sections:    defaults | frontend | listen | backend
2 G7 B; E- ]; v; x                                 yes   |    no    |   yes  |   yes, ^. c' J# T* }7 K$ B* T( @
  Arguments : none* I, i6 A8 ^! d1 z, Q* x" @
' R) i- {9 c4 g0 u! t
  When an HTTP request reaches a backend with a cookie which references a dead" c1 K* n7 M: z7 C# v7 O; I. S
  server, by default it is redispatched to another server. It is possible to; X2 o$ i( K$ Y: }/ B
  force the request to be sent to the dead server first using "option persist"
# ^& y0 K7 B1 l. t: H2 ~+ D- O  if absolutely needed. A common use case is when servers are under extreme
5 M# i# Q8 l2 j/ [# x5 T  load and spend their time flapping. In this case, the users would still be
# e2 y' m: t3 i, A7 a+ K% @  directed to the server they opened the session on, in the hope they would be
( O7 V8 W# _$ s0 M4 u, p  correctly served. It is recommended to use "option redispatch" in conjunction
1 b! z* [9 E3 }3 }$ {. `  with this option so that in the event it would not be possible to connect to% k" E- l. N0 C. B
  the server at all (server definitely dead), the client would finally be3 A* M# m( ~. I) O
  redirected to another valid server.& D- e% W/ ^  q8 u# ^- A8 w
2 `* _) p4 x" Q7 H% O
  If this option has been enabled in a "defaults" section, it can be disabled  [3 I- J' W- n. R3 i8 D: |. M. p
  in a specific instance by prepending the "no" keyword before it.
! @2 M) B/ M, B4 \0 X4 O  u# s, Y4 @8 i
  See also : "option redispatch", "retries", "force-persist"
/ u7 M; z8 ]9 M2 C% \
5 l9 N' ^: _1 g! ?9 \+ }8 c1 o" k  d$ e; {9 q7 M  [7 R
option redispatch
# b; Q  D8 J& v! x% Yno option redispatch
! ~, g& U0 @; @; g  Enable or disable session redistribution in case of connection failure" n' {, M% V- U% r7 ~% t* V
  May be used in sections:    defaults | frontend | listen | backend
4 R1 ^2 t% @9 g! @2 H5 w! {$ j                                 yes   |    no    |   yes  |   yes  Z) U/ S9 ~/ W; `5 d. f
  Arguments : none9 O% D- b% S$ E# H- d- ^
: d$ _7 }+ t; D2 s) m! z: s
  In HTTP mode, if a server designated by a cookie is down, clients may+ [: Q  J2 w. b& i3 J# E  R
  definitely stick to it because they cannot flush the cookie, so they will not( ]  P+ F" P+ Z. x! {
  be able to access the service anymore.5 n& ^7 o0 O1 v/ I4 x

  d# s# g$ I* h! j* O  Specifying "option redispatch" will allow the proxy to break their) H* ]& j" b9 C# u+ m; P4 G" _
  persistence and redistribute them to a working server.4 ~; z4 s5 V) f# @  P( g; i
2 ^. t& U! g! K! S$ _
  It also allows to retry last connection to another server in case of multiple7 T4 @! r% B8 l  W# c' ~6 N- \
  connection failures. Of course, it requires having "retries" set to a nonzero
9 C' K# L9 \/ u& _6 `) s2 r4 Q  value.: |7 W3 I' z* }, Y! D
: ^  m" s$ L: G3 Z: A! V
  This form is the preferred form, which replaces both the "redispatch" and
3 ~! _! J2 f* `  ]3 M( g6 Q  "redisp" keywords.
2 a1 Q/ @- Q4 G/ N6 S; S/ b0 P
5 E& D+ F$ U' O6 A" Q9 _% q  If this option has been enabled in a "defaults" section, it can be disabled; a9 e6 L" @: S3 x
  in a specific instance by prepending the "no" keyword before it.- P' b7 j- k8 K6 J
: c0 R/ A8 r8 S8 u% H
  See also : "redispatch", "retries", "force-persist"
* h, s% S$ p0 F( F3 X0 V4 F1 H& z
9 c8 |# C: J2 ^5 m7 M* \6 _4 f
) e7 l5 R. O' w1 H0 soption smtpchk
! j+ S, Q8 e& Joption smtpchk <hello> <domain>
- [" S2 l* a& E. m" S. |/ b( r7 j  Use SMTP health checks for server testing# e$ S) y" z  G3 A9 a; z9 l' e
  May be used in sections :   defaults | frontend | listen | backend5 B& L" I3 q: G0 e
                                 yes   |    no    |   yes  |   yes: s$ o* g3 \( x# C' I# {
  Arguments :8 e# d5 I+ P5 ]; \# y3 J
    <hello>   is an optional argument. It is the "hello" command to use. It can
9 V/ W) ?; y8 y. J8 G              be either "HELO" (for SMTP) or "EHLO" (for ESTMP). All other+ G' i- s) `9 `
              values will be turned into the default command ("HELO").; n/ [1 X  M" l$ ~- l# K- V
2 Q, X: X, H- g1 w/ ]1 w  o
    <domain>  is the domain name to present to the server. It may only be
8 R8 `% D4 l( T0 g  a2 n$ T8 r              specified (and is mandatory) if the hello command has been
* q( y" U& m2 }8 z; D1 `7 z              specified. By default, "localhost" is used.
. h! z; d: m5 |: e8 ?+ N
4 M3 A5 o9 w, h9 i3 a  When "option smtpchk" is set, the health checks will consist in TCP
9 v1 Y9 e1 P* l/ P  connections followed by an SMTP command. By default, this command is' \7 t$ J6 W9 M" E2 Z' R/ u/ r
  "HELO localhost". The server's return code is analyzed and only return codes6 u3 z. U; u9 r) e7 s, n/ p# ?- X' K
  starting with a "2" will be considered as valid. All other responses,
; x9 @. {& ~0 a* D. c& q  including a lack of response will constitute an error and will indicate a
& ?( O  g# c. n3 @% G  dead server.- M% L7 O8 w  Z+ `, m% }

: Q5 z4 ]5 S# A. r# a- G2 Z  This test is meant to be used with SMTP servers or relays. Depending on the+ R6 ?4 ]$ n2 {! D/ w
  request, it is possible that some servers do not log each connection attempt,
! A" z  ?" q6 A2 G9 V( p  so you may want to experiment to improve the behaviour. Using telnet on port
4 Z  U5 ^- u7 @& r3 L  25 is often easier than adjusting the configuration.
) L$ w. e4 T! \6 `) H2 Q
. r& T/ w, r$ N6 m# }* h  Most often, an incoming SMTP server needs to see the client's IP address for- |& ^5 E1 K6 K
  various purposes, including spam filtering, anti-spoofing and logging. When: Z' h+ q% [3 |2 F0 R+ w
  possible, it is often wise to masquerade the client's IP address when
" |5 B1 N/ y0 D1 g! p2 j/ ^  connecting to the server using the "usesrc" argument of the "source" keyword,
4 A: R# J9 H0 K5 n& ~( s: x  which requires the cttproxy feature to be compiled in.( a) P  I% G' w$ t8 F# I" x+ Z
/ p+ D0 Z2 J6 f6 a5 B
  Example :- p9 j. e" l6 }) v, Z
        option smtpchk HELO mydomain.org
) W7 Z0 Y. P: Q4 ]" A2 e5 J6 a3 ^, [1 ]7 Q& |. b
  See also : "option httpchk", "source"* ?9 `* X0 c% z% b: X# ?

* t3 R+ P& m6 Z+ @
" m$ [0 }3 d( [; ioption socket-stats- _4 [7 R3 s( i- _) T$ O/ x9 s
no option socket-stats+ j9 @0 u1 K) X/ {3 H! D2 ]
; \" H& b- D! B! t3 k
  Enable or disable collecting & providing separate statistics for each socket.6 z# ?& Y  I, j- T7 p8 I4 `0 o
  May be used in sections :   defaults | frontend | listen | backend3 h( t" D: g1 Q! i
                                 yes   |    yes   |   yes  |   no: o1 t5 i$ i# c- q2 K1 z- F8 O7 z
3 J# z, e/ P  Z: ~3 d2 `0 E
  Arguments : none
5 e$ q3 t/ ?9 P3 r; @: j5 W% a' I
1 C9 ^' K- d& Z6 `5 o0 N- p; J* J( e% f- Y: U
option splice-auto
2 a( O9 V" e$ yno option splice-auto; s9 \; j  {+ c& S
  Enable or disable automatic kernel acceleration on sockets in both directions5 N( k0 l, g" ]6 k  ?, |
  May be used in sections :   defaults | frontend | listen | backend# `0 B9 M2 B# m# }( C' z
                                 yes   |    yes   |   yes  |   yes( y! T* M1 o/ X$ B/ g% E" b
  Arguments : none
# Q, N3 Y1 j" J7 x* N9 [' w, j6 x: `. J8 _% M
  When this option is enabled either on a frontend or on a backend, haproxy
; [+ a$ ^0 a! t7 o7 M2 N8 ~; @  will automatically evaluate the opportunity to use kernel tcp splicing to% @; P# `9 _! \9 O& K
  forward data between the client and the server, in either direction. Haproxy
4 ]& z* P& L! g$ N  uses heuristics to estimate if kernel splicing might improve performance or& w$ J+ T1 C; y6 s) m. Z: L
  not. Both directions are handled independently. Note that the heuristics used) e: j5 I7 d# ^! y) g
  are not much aggressive in order to limit excessive use of splicing. This
* q: b5 j& |% Q+ n3 B  option requires splicing to be enabled at compile time, and may be globally
0 f2 a: J$ S$ o* y  disabled with the global option "nosplice". Since splice uses pipes, using it% w8 o/ t/ v3 B0 `
  requires that there are enough spare pipes.( D/ f$ t6 h( _' H

0 ?  K  ], [, q  Important note: kernel-based TCP splicing is a Linux-specific feature which
0 R, X- \1 G+ d: q" @3 s  first appeared in kernel 2.6.25. It offers kernel-based acceleration to
6 i& t6 J4 t( {0 H6 P9 ?  transfer data between sockets without copying these data to user-space, thus" T  G" \; \' R/ a) a/ E; X
  providing noticeable performance gains and CPU cycles savings. Since many
- H# L1 L) e; y  early implementations are buggy, corrupt data and/or are inefficient, this# S  b+ J( S2 r! ?9 I
  feature is not enabled by default, and it should be used with extreme care.- n* e# [* i9 f" z
  While it is not possible to detect the correctness of an implementation,
% T- N6 ?) g. H' S& ~7 K' _  2.6.29 is the first version offering a properly working implementation. In9 O4 E( S4 N- B: K3 t1 ?1 g8 _
  case of doubt, splicing may be globally disabled using the global "nosplice"# _4 L# w# M' w9 X  m/ {- ~  `
  keyword.  e, J3 d. D4 I- v- H6 V

1 N) n# h4 E: R+ u/ `/ k  Example :  a& z4 Q8 w7 }/ K
        option splice-auto. K. E; e8 n0 C. j3 c+ B4 V6 n

5 [' E) U. O9 u# ?' s4 X# N  If this option has been enabled in a "defaults" section, it can be disabled
5 ]8 H, c/ l. y" N6 p5 s2 G; g1 Y- p  in a specific instance by prepending the "no" keyword before it.$ H: n8 a5 [, J# _8 Q' ]
, E. x7 g$ X. [7 h
  See also : "option splice-request", "option splice-response", and global
" |1 b% G  u1 u             options "nosplice" and "maxpipes"4 W% ]# s7 w! i+ O) z
( ^/ B9 W( k7 o9 R' y* X

8 N) G, ~5 e% ]) W- [% A% ~option splice-request
. L, m2 u1 g# z, |& `# {no option splice-request
3 R" O& x/ I; P3 q; ^: P  Enable or disable automatic kernel acceleration on sockets for requests( b, A" X8 o9 \* ^5 h7 C4 a3 I
  May be used in sections :   defaults | frontend | listen | backend
% B: @3 N; G/ }. P4 I                                 yes   |    yes   |   yes  |   yes
- y3 t5 ]: q6 u  ~5 h  Arguments : none# n6 k2 v8 W6 N/ Z4 o8 W& y
( G% ~! g  O$ a6 f
  When this option is enabled either on a frontend or on a backend, haproxy
# y- {2 i6 z- Q  ^: p- }  will user kernel tcp splicing whenever possible to forward data going from- g% U% z9 a+ q8 z4 O" I
  the client to the server. It might still use the recv/send scheme if there
- M  W, E1 N9 w3 \: ]  are no spare pipes left. This option requires splicing to be enabled at& K; }* H8 N2 F. [( a' J- O
  compile time, and may be globally disabled with the global option "nosplice".
) z$ M! e* ^6 E9 B' F7 u  Since splice uses pipes, using it requires that there are enough spare pipes.4 a3 q6 x4 F0 w* p/ `5 f

+ C2 c/ {" j" O" E4 a  Important note: see "option splice-auto" for usage limitations.
4 N- P3 V6 t# P/ _" Q
$ E+ D! o- P- v; F  Example :* L3 P; Z0 z' R+ D' a
        option splice-request3 v9 P3 k, A. ~; O' |

# L- A" P9 O  p0 j; V; Y& `% X/ Y" B$ u  If this option has been enabled in a "defaults" section, it can be disabled
7 J& W' y9 r2 {( G) h  in a specific instance by prepending the "no" keyword before it.
- Z) h" t8 r- A' l. p2 B6 j8 r. H/ u
  See also : "option splice-auto", "option splice-response", and global options& \2 L' m6 D* S7 h
             "nosplice" and "maxpipes"
6 p" W* f9 ~+ ]0 Q4 G% u* D
& x( e( V/ g; J3 i9 `* c" r- {$ p
1 |: l; d& `+ O- P7 q! @option splice-response) a$ R8 C( }4 r# z1 N" H
no option splice-response
9 k, L/ r& O1 a- {; b/ H' _  Enable or disable automatic kernel acceleration on sockets for responses
9 e5 z4 B) g9 V  May be used in sections :   defaults | frontend | listen | backend
; q. n! z) ~9 q% ?* F2 ~- C" E                                 yes   |    yes   |   yes  |   yes
8 f% l* v# [+ [6 q2 q2 w7 u  Arguments : none
  U1 P" r0 m" @0 P$ r/ ]' Z6 X3 k. b: |/ V! n- P
  When this option is enabled either on a frontend or on a backend, haproxy3 M+ V) t. S. f5 E! p% [% a! s5 I
  will user kernel tcp splicing whenever possible to forward data going from0 \3 ?7 v' U. X
  the server to the client. It might still use the recv/send scheme if there
& \( X( b% m0 i  are no spare pipes left. This option requires splicing to be enabled at$ B4 M4 _5 s2 x' q& b
  compile time, and may be globally disabled with the global option "nosplice".
* D0 u& P" T1 v1 d  O4 \7 X9 x, ^  Since splice uses pipes, using it requires that there are enough spare pipes.0 k" p9 _1 X+ @( g' X; C* X8 F
8 H7 N( ~) E. {
  Important note: see "option splice-auto" for usage limitations.
6 ]* U; J0 D3 i- u' A  t# @
* O: }  M; w' U$ k  Example :
0 w0 o( I- N, M  _) D* f        option splice-response
/ ?: i4 n7 H! W) u7 E: r5 {. V
! x# T# w" c6 m  If this option has been enabled in a "defaults" section, it can be disabled+ k5 p% I! Q/ b1 J7 b
  in a specific instance by prepending the "no" keyword before it.* o: i& ]# j/ \
, c' w: `! O  j6 v4 w6 T: }
  See also : "option splice-auto", "option splice-request", and global options
* q3 Y! e4 P8 Q, y( S4 A1 H             "nosplice" and "maxpipes"8 }0 r( `3 _- q9 p

, U4 O6 d1 S: M$ Q1 Z6 V
8 Y, E9 i- {" ?( Y9 s/ g) hoption srvtcpka
) C& v% a3 k* Z5 w/ z1 Y% _no option srvtcpka
0 U3 P8 a& d' l  y3 \) s  Enable or disable the sending of TCP keepalive packets on the server side
1 N% Q# ]7 J& U4 Y1 ]6 M) J( Y) {  May be used in sections :   defaults | frontend | listen | backend
( L6 F8 l! I( V2 l7 f$ |5 e9 b8 C                                 yes   |    no    |   yes  |   yes3 {: c7 f$ X/ j; `% ^* _( s/ _
  Arguments : none
" D7 X5 b' R3 [% i/ \, c" r+ n8 ^+ i: `; m" W+ N
  When there is a firewall or any session-aware component between a client and
6 B  \: R+ V8 a* G  a server, and when the protocol involves very long sessions with long idle
0 u, O9 Q9 I; u/ G8 J( f  periods (eg: remote desktops), there is a risk that one of the intermediate
- y' A% l+ s. r) n" F( C* j; \9 Z  components decides to expire a session which has remained idle for too long.
8 o1 k. w# G% o1 ~( F; ^( X8 L/ e& l$ u# g# |
  Enabling socket-level TCP keep-alives makes the system regularly send packets
" F, ]! W( P' v- Y3 [6 ?3 m  to the other end of the connection, leaving it active. The delay between) D1 `! u0 O9 {0 E  ~
  keep-alive probes is controlled by the system only and depends both on the
5 W5 D9 C& }8 u. z  operating system and its tuning parameters.
; I: g4 J/ t' M1 r' d4 S* {" ]8 T. n: }. t
  It is important to understand that keep-alive packets are neither emitted nor
4 E: ^9 @  \5 Q  received at the application level. It is only the network stacks which sees
9 s9 j7 Y4 C- b; n- L  them. For this reason, even if one side of the proxy already uses keep-alives6 H$ ^4 l/ N* u7 G! C  D
  to maintain its connection alive, those keep-alive packets will not be
  l  Y: \+ `" u& s& {. l: o# a  forwarded to the other side of the proxy.1 g% K0 c$ w" C/ D" @# K& n

" G6 O& f( V- C3 h' H' f. e  Please note that this has nothing to do with HTTP keep-alive.
' _* Y5 |1 A; n5 I9 E
- ~6 p; M" W5 u6 I1 D% Q1 h  Using option "srvtcpka" enables the emission of TCP keep-alive probes on the
3 _  v! f0 `* q" S9 U( A  server side of a connection, which should help when session expirations are6 V/ {3 x7 ^8 r3 o% w
  noticed between HAProxy and a server.
3 R# {1 Q1 @/ S+ C; n$ O: o
: }# j0 T2 T) O% I" D! v  If this option has been enabled in a "defaults" section, it can be disabled6 r0 I1 [$ E, C* h  K1 }6 O
  in a specific instance by prepending the "no" keyword before it.
* Y2 G+ Z( S0 a; E4 b8 E
2 ~1 e  U7 l& _- D+ k3 B8 R  See also : "option clitcpka", "option tcpka"5 T: C, ?, N# m! G  P

  D  y* K: C) v/ m9 H/ r1 R) w* ?9 v6 T. X& C
option ssl-hello-chk
! U/ N8 V5 U" z" y1 A/ o  Use SSLv3 client hello health checks for server testing
% j' T. [" R' \, B  May be used in sections :   defaults | frontend | listen | backend) }# |; M+ _8 N, G
                                 yes   |    no    |   yes  |   yes: J8 i; d& ]) d! H; P: }
  Arguments : none- W! ?# i# D3 q  Z
. Z) L2 H8 [+ r2 a5 z
  When some SSL-based protocols are relayed in TCP mode through HAProxy, it is" \& s" M2 g0 V/ F" j
  possible to test that the server correctly talks SSL instead of just testing& y5 {# Y; @; ~9 C' K( i9 M: k/ @: u
  that it accepts the TCP connection. When "option ssl-hello-chk" is set, pure0 C/ N# \  a! u2 R4 b% K! E: _
  SSLv3 client hello messages are sent once the connection is established to& D9 k# Y7 u8 S" N) R3 U
  the server, and the response is analyzed to find an SSL server hello message.7 x6 h& s1 l" T9 l! ], p- f
  The server is considered valid only when the response contains this server
( T. S! |; ~8 l( _9 m0 D2 g# w  hello message.( q9 R0 X- d/ p" @: g
3 ]) X: v6 g3 w: x  ?6 n  x# x
  All servers tested till there correctly reply to SSLv3 client hello messages,
$ v- `  Z* `+ D' X' V2 n  and most servers tested do not even log the requests containing only hello
0 t5 l% o% m5 x) C- @; |" X  messages, which is appreciable.
, j, {/ F7 b1 h0 J8 a
1 `" P4 k& k! r8 k  See also: "option httpchk"7 r" J# G1 O; j3 c9 J

! ^6 p2 E7 h+ S  i" D) u# |5 {5 b% ?4 O5 B& x' ~6 _
option tcp-smart-accept
$ _6 X  h, r: c- @no option tcp-smart-accept) H: C3 k8 ?7 S, P# f
  Enable or disable the saving of one ACK packet during the accept sequence
, l8 Q1 `9 M- G2 l% g0 ]" N  May be used in sections :   defaults | frontend | listen | backend
" m8 B! J" T2 t; g                                 yes   |    yes   |   yes  |    no
" ]- h. @9 L' i* c  Arguments : none
8 ~' J0 f1 m3 c. c0 g( j/ t6 ^  A, g, k
; r+ q. m. i. }& P  When an HTTP connection request comes in, the system acknowledges it on
# O, k& l9 W! |3 U2 U  behalf of HAProxy, then the client immediately sends its request, and the, n  _- B9 |4 ?7 x7 r
  system acknowledges it too while it is notifying HAProxy about the new
8 }/ V0 N7 e5 b. K* T8 P5 e' D; k' M  connection. HAProxy then reads the request and responds. This means that we; l2 W( m0 b7 O0 }3 f. z4 w/ Y
  have one TCP ACK sent by the system for nothing, because the request could  H$ M+ ~/ E: `2 o& c
  very well be acknowledged by HAProxy when it sends its response.3 V+ D% l. J' c6 w* ~& r7 u7 W* ~) V

! ^! w7 A# k# E' }8 T6 |0 @: Q  For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
; X; e3 [* V5 M9 W1 Y  sending this useless ACK on platforms which support it (currently at least
/ C  o5 J' {  F% G' V3 @  Linux). It must not cause any problem, because the system will send it anyway& `! u' A2 X% ]% Q3 b4 t4 U. A
  after 40 ms if the response takes more time than expected to come.; y' H! s- f4 X3 n6 _' \+ s
) v8 I" `# ]3 g+ o
  During complex network debugging sessions, it may be desirable to disable
4 `4 b  F" j0 O" [# u  this optimization because delayed ACKs can make troubleshooting more complex3 @. ?. r) ~2 k
  when trying to identify where packets are delayed. It is then possible to9 U4 z4 J4 ?- S) ^& |
  fall back to normal behaviour by specifying "no option tcp-smart-accept".# j5 W" w9 l# l* Z% d- _( @
  O7 i" I' ^7 V! E4 P* z
  It is also possible to force it for non-HTTP proxies by simply specifying
, ~- i. I* e  t2 X) x) T  "option tcp-smart-accept". For instance, it can make sense with some services
2 C$ _- t2 P9 `  such as SMTP where the server speaks first.( ^4 `3 l; [5 D7 }; B

) u4 Y' b! @$ [8 {9 W5 v  It is recommended to avoid forcing this option in a defaults section. In case
% ^4 s& j- O! c/ Y$ H  of doubt, consider setting it back to automatic values by prepending the% }6 r2 v0 {3 J  _* b
  "default" keyword before it, or disabling it using the "no" keyword.1 z7 {8 ~9 J* M
+ i& j. T' @; j/ L. L! P7 P+ n
  See also : "option tcp-smart-connect"
) z$ x  R, E0 d) A$ D# }! I8 d5 Y8 H# T
$ _: H+ l9 }$ p6 M6 p. E3 ^
option tcp-smart-connect
$ {: C" ^0 Q8 A/ Sno option tcp-smart-connect
  c( w/ ~* Q0 ?) Q  Enable or disable the saving of one ACK packet during the connect sequence
  D1 y& s" e8 ~+ w1 }  May be used in sections :   defaults | frontend | listen | backend& A) H% s  [4 m% ]2 I
                                 yes   |    no    |   yes  |   yes
0 {% [  W7 y' K3 o8 k) p/ @6 r. q  Arguments : none
1 W7 _; K! H' y$ Z' O* Q' L
5 j) n8 C0 f8 o3 l2 V! ^# t  On certain systems (at least Linux), HAProxy can ask the kernel not to
5 k# }9 e+ C- v; u  immediately send an empty ACK upon a connection request, but to directly
* b' d' P# @9 l  send the buffer request instead. This saves one packet on the network and
: P( t4 k) ]% R- L* Q" D  thus boosts performance. It can also be useful for some servers, because they4 Z. y' l! X5 x  }$ T% `# H7 S
  immediately get the request along with the incoming connection.& p$ R, ^7 z0 c0 f8 Y2 g+ R8 [

* [# H9 F" ?' z+ i5 D9 W$ c0 i  This feature is enabled when "option tcp-smart-connect" is set in a backend.
4 ]6 F7 W1 C. s" s  It is not enabled by default because it makes network troubleshooting more  ^/ [% R% z* f# D* n5 k
  complex.
/ _9 U0 F/ n/ V9 k: ^8 r9 J" O% F6 K& d5 u- M4 W1 X" z" f6 ^% g
  It only makes sense to enable it with protocols where the client speaks first
6 C2 P. [1 O( P* d) l/ ~7 p: r  such as HTTP. In other situations, if there is no data to send in place of
5 c& j, e+ K, o  the ACK, a normal ACK is sent.: I/ {% q8 h6 _+ `% A2 i! Y# E' B
# w5 ^8 E* ]- C6 W+ C6 m
  If this option has been enabled in a "defaults" section, it can be disabled* i# j* B2 S- ?6 P3 j( X
  in a specific instance by prepending the "no" keyword before it.
: x! t2 V. L! P
' C+ c8 H, ^+ ^7 K9 g' [  See also : "option tcp-smart-accept"
; {% ?- i$ ~# n0 k" o/ f% }
1 Z& Q6 y* p8 b3 v( c
" \) g4 t, H. L- r+ g1 s  z! soption tcpka' y' E2 f' \4 P" h. ^0 O' a
  Enable or disable the sending of TCP keepalive packets on both sides
" H2 w) @0 _9 {. j  May be used in sections :   defaults | frontend | listen | backend: s1 N/ h5 M* O$ j% m9 U5 U% n& Z
                                 yes   |    yes   |   yes  |   yes9 @# r3 I- V& @. Q* w7 R6 T
  Arguments : none, a6 f' v" {5 W7 C
# ]; D  [9 r" M& P
  When there is a firewall or any session-aware component between a client and( k2 ]/ R3 L0 p' ?, ~5 H
  a server, and when the protocol involves very long sessions with long idle
- i; f! L. L5 E% D  periods (eg: remote desktops), there is a risk that one of the intermediate2 F) _1 a4 E' b# `: e: D
  components decides to expire a session which has remained idle for too long.: w, W8 S: u1 \' t! S
* X! [4 K# i( X
  Enabling socket-level TCP keep-alives makes the system regularly send packets1 ]  t+ @* E- {! a9 Y; U4 C
  to the other end of the connection, leaving it active. The delay between$ [. Z/ ?+ h% e4 n
  keep-alive probes is controlled by the system only and depends both on the3 s9 \( i! |" \, |& I
  operating system and its tuning parameters.; Y0 F4 E" K9 J; [( J3 \

3 n- P. a7 c4 }8 `0 u) r; x% S2 {- @% q  It is important to understand that keep-alive packets are neither emitted nor
2 h) y% x' N, Q  received at the application level. It is only the network stacks which sees. H; c5 X4 f! J
  them. For this reason, even if one side of the proxy already uses keep-alives& Z: X  F' M# L" E* C8 Z
  to maintain its connection alive, those keep-alive packets will not be
* g/ I, n" a' `* F0 w) W  forwarded to the other side of the proxy.
0 \' |& q5 P  q
0 r2 J6 s  `5 b9 _" A  Please note that this has nothing to do with HTTP keep-alive.1 i! e7 ^; r8 E2 E2 G8 z

' l# q, @8 u6 X  Using option "tcpka" enables the emission of TCP keep-alive probes on both. M. C4 e4 R0 ], }
  the client and server sides of a connection. Note that this is meaningful7 D4 M* D" u5 c( p
  only in "defaults" or "listen" sections. If this option is used in a: n( e+ S1 `& E: ?# b! x
  frontend, only the client side will get keep-alives, and if this option is% O1 d7 l2 C1 |; k$ R; ^3 [
  used in a backend, only the server side will get keep-alives. For this
# v: Y1 f7 S+ h) P0 V, K  reason, it is strongly recommended to explicitly use "option clitcpka" and
5 y# d+ o3 t" V, e  "option srvtcpka" when the configuration is split between frontends and$ U+ i2 X8 {* O; s
  backends.* M; {2 i. w) n' }6 y$ T  h
( J# u: x" E  l( b7 Q+ t
  See also : "option clitcpka", "option srvtcpka") j6 K8 r+ {) ?. W1 H

) O; v5 Q& L* I  n5 h4 Y
9 c1 t5 f" @' l" `' ]9 L5 zoption tcplog
: v; b) d2 s9 D9 |& v9 x  Enable advanced logging of TCP connections with session state and timers
% m6 r$ P2 h' t" A, o. @  May be used in sections :   defaults | frontend | listen | backend- D7 W4 {- X4 J
                                 yes   |    yes   |   yes  |   yes
5 w! b! v% G7 N2 Y6 p  Arguments : none; K/ B. g& D- H- F* O$ b
. K- h. f- ], v) _( X. Z
  By default, the log output format is very poor, as it only contains the
1 I) v, j: n* R* D  source and destination addresses, and the instance name. By specifying; u: q8 P( S8 e5 Y& `
  "option tcplog", each log line turns into a much richer format including, but
# q, C# Q( C- U% T# X. f0 }  not limited to, the connection timers, the session status, the connections) m; l' w0 _. s0 L( ^0 S" Z  s) S
  numbers, the frontend, backend and server name, and of course the source1 L2 P8 g$ P0 S* e1 z5 R
  address and ports. This option is useful for pure TCP proxies in order to- V0 Q  s2 `5 N7 [4 A! J
  find which of the client or server disconnects or times out. For normal HTTP
# Z  [, i, G# y; f# H  b  proxies, it's better to use "option httplog" which is even more complete.
* a$ T% `4 z" o' t/ V
6 a7 p6 R3 M/ q! w, L& s" C6 Z+ ?  This option may be set either in the frontend or the backend., D) h% _: V2 c/ T, O5 B$ y

3 e/ E0 u  |# c& ?, y9 U7 O/ n  See also :  "option httplog", and section 8 about logging.  I+ N/ W; t" g; A' Z

5 l, }4 S* b+ H3 L* g
. T6 g- w3 n: l$ eoption transparent% j0 r+ h8 J3 c2 Y
no option transparent6 g3 Q4 E: x: U
  Enable client-side transparent proxying
: s( p. m# E& b6 `! C  May be used in sections :   defaults | frontend | listen | backend
+ A  P& N' A# p3 g; x& y                                 yes   |    no    |   yes  |   yes( V# _3 ^% [" f
  Arguments : none
% b" M' q+ O" D' t: s/ B- b: q+ f" _* `( c/ z( m8 j' ^
  This option was introduced in order to provide layer 7 persistence to layer 3
+ I. U3 n. m; a  x3 C5 ?  load balancers. The idea is to use the OS's ability to redirect an incoming) g. p6 R/ f: m- Y
  connection for a remote address to a local process (here HAProxy), and let
5 d2 r' t. h' @% W. B$ g# G  this process know what address was initially requested. When this option is! I& q" H+ h1 _% \, D& Z9 M& k3 s6 L
  used, sessions without cookies will be forwarded to the original destination9 O% ^) r  W7 p  f$ ?/ X% ?  x9 q1 J
  IP address of the incoming request (which should match that of another
9 W0 t* U; n* `  equipment), while requests with cookies will still be forwarded to the! E7 t3 k8 f2 [6 d2 f  c
  appropriate server.$ c7 z) _6 I1 H+ N2 X9 \1 W

9 e5 ]* D5 w; j- b2 G/ L7 g2 D  ^  Note that contrary to a common belief, this option does NOT make HAProxy% s) F0 J' o0 h* `2 g/ J
  present the client's IP to the server when establishing the connection.
: h( F, O9 H! a# e. w+ t/ V; e, n
, v' e- c0 j' }7 u1 N0 S  See also: the "usesrc" argument of the "source" keyword, and the
6 x2 x3 `: L  F. S; ]+ B) y& a            "transparent" option of the "bind" keyword.5 N/ X' P5 L1 G/ Y! |% _$ @
; s$ i8 A3 l3 y3 \! _

1 @7 s& A' b) Zpersist rdp-cookie
. E$ M! A; d# N: Zpersist rdp-cookie(name)* t1 T9 D8 h) \  Y/ S( M1 P- t2 Z2 C
  Enable RDP cookie-based persistence+ F" |6 _9 |7 u7 m
  May be used in sections :   defaults | frontend | listen | backend; V5 Y! t- A7 D/ r+ m) }( e+ d
                                 yes   |    no    |   yes  |   yes7 T( u  Y% ~4 l
  Arguments :
, ~; m2 ~0 w/ u5 I0 R    <name>    is the optional name of the RDP cookie to check. If omitted, the& f0 z" G- v4 o: ~8 H; ^
              default cookie name "msts" will be used. There currently is no3 _) u# M  Z: c, ^( a* g
              valid reason to change this name./ r" y2 h5 h! W8 o1 d. c
, I& T6 c. R* H, i( h: C
  This statement enables persistence based on an RDP cookie. The RDP cookie
: \3 f$ b0 {. g2 Z  contains all information required to find the server in the list of known
/ h9 x1 g5 ?8 |& P# A  servers. So when this option is set in the backend, the request is analysed8 E" ?' L9 H: Z  s! ?: s
  and if an RDP cookie is found, it is decoded. If it matches a known server& C: {: w# X/ U, a0 J. F+ M
  which is still UP (or if "option persist" is set), then the connection is
; m/ e# G( X; V* _$ C8 K8 |3 Y% E  forwarded to this server.* W( {( Z( Y: q

# Y" f4 j' T1 \. [( M6 y  Note that this only makes sense in a TCP backend, but for this to work, the
% d* u$ J& l4 \/ ^+ H  frontend must have waited long enough to ensure that an RDP cookie is present
2 |- P# e3 L8 `+ s$ a+ N7 j8 p  in the request buffer. This is the same requirement as with the "rdp-cookie"
; z! T! K1 J! P9 Q% `  load-balancing method. Thus it is highly recommended to put all statements in5 u: x& Y7 J# l# i3 x9 o
  a single "listen" section.
% H6 K+ F3 y' [) O( n" s  v% d. W% B4 D" ^. _6 p
  Also, it is important to understand that the terminal server will emit this
# ~+ Y# F: ~, N& |  RDP cookie only if it is configured for "token redirection mode", which means
& i7 L9 t! `8 d4 f# |0 R  that the "IP address redirection" option is disabled.
  b) ]8 b- j+ g8 l( T4 J. {! ^' G; c$ Z* F1 ^3 U" M8 D
  Example :" @8 [# ?0 r) a7 O  B, G6 F* N; j
        listen tse-farm# i& {( ], }: d
            bind :3389' p2 v. h5 H0 K, H! _# L8 @! {
            # wait up to 5s for an RDP cookie in the request3 {/ b# r) ?' Q, i7 W
            tcp-request inspect-delay 5s! @' j6 q; ?5 j  [1 `  \' P
            tcp-request content accept if RDP_COOKIE
7 n2 t: g! t1 H8 ^7 ^4 u0 d( u# x            # apply RDP cookie persistence! i( \% h" y8 [/ g0 V
            persist rdp-cookie+ q2 E8 w$ o+ X- k0 @0 v
            # if server is unknown, let's balance on the same cookie.& D# y, N/ |9 F
            # alternatively, "balance leastconn" may be useful too.4 {4 a' k6 }/ D: e0 d
            balance rdp-cookie
; b+ F6 t. y" Y3 D# `& ]5 J            server srv1 1.1.1.1:3389
+ b" N2 D. t  y) f            server srv2 1.1.1.2:3389
3 I1 B( y5 m, F
  M/ \/ X" ~% ^# n  See also : "balance rdp-cookie", "tcp-request" and the "req_rdp_cookie" ACL.1 f5 U& Y: E( K) b

1 \5 w4 }' j' l8 d) r6 C
! j- [. o6 [3 H) z7 }( Q' v8 Xrate-limit sessions <rate>
, ^$ ~6 i4 y' o& M  i3 S! L  Set a limit on the number of new sessions accepted per second on a frontend  X' l  K' D& `/ Z# \$ g7 o
  May be used in sections :   defaults | frontend | listen | backend7 b/ y2 a; {/ m% n$ w
                                 yes   |    yes   |   yes  |   no  [# Q) P4 k/ ^  w) }
  Arguments :
( h% \" X* x4 f* z, L; ~    <rate>    The <rate> parameter is an integer designating the maximum number
1 |, Y* b+ A, @! ^% p              of new sessions per second to accept on the frontend.( z$ u+ @; Q% h! X8 F

- [7 S, y. O8 L; W3 g8 M1 H) u  When the frontend reaches the specified number of new sessions per second, it
' H1 d# |3 ~2 d+ t  stops accepting new connections until the rate drops below the limit again.; g1 T% q! z( w* C( z
  During this time, the pending sessions will be kept in the socket's backlog2 r# P3 x. z7 R  @8 ^( j* O
  (in system buffers) and haproxy will not even be aware that sessions are
' L3 Z7 \: p2 `5 Q  pending. When applying very low limit on a highly loaded service, it may make" S* {& F, `* C% I8 M; u7 T7 q
  sense to increase the socket's backlog using the "backlog" keyword.
& m# ]2 L# {* t; d9 z) I: b3 @- I, _: w9 l1 U4 ^  K
  This feature is particularly efficient at blocking connection-based attacks
0 X5 E: G/ i% @# e- b8 x7 c# S/ h  or service abuse on fragile servers. Since the session rate is measured every
# U3 Q: F+ V) h$ m+ Q" O  millisecond, it is extremely accurate. Also, the limit applies immediately,* Y* [( A8 C! m; e
  no delay is needed at all to detect the threshold.# B; |+ x4 _- S) Z- a6 c

7 g8 P6 R! r! _7 `+ @  Example : limit the connection rate on SMTP to 10 per second max
) D) V7 |" t: x$ ?9 z# O5 T7 L        listen smtp. D$ _; i; D$ j% C  E$ Y
            mode tcp
' }' B4 Y) |* F' y, R& V- d            bind :25% p. d( w( p3 P0 G; N- T
            rate-limit sessions 10" f( `1 {, R+ P: I3 ~. ?
            server smtp1 127.0.0.1:1025% {- \$ J: [$ e; J# x2 |' }
6 K, ?0 G4 O7 }2 j  y! m( j
  Note : when the maximum rate is reached, the frontend's status appears as, Y, e9 h' e" T. L! H; e& u; e
         "FULL" in the statistics, exactly as when it is saturated.
) C3 U* a/ U* E" C
7 x8 n& h. R9 F  See also : the "backlog" keyword and the "fe_sess_rate" ACL criterion." J2 j$ j! `# j+ l4 {( N

  q1 g1 V8 i. w: P- u( I! \0 z* I7 [# Q
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]% p9 ]2 c: K) s: X
redirect prefix   <pfx> [code <code>] <option> [{if | unless} <condition>]
* `) D3 x& [8 `  b6 E6 u8 f4 {redirect scheme   <sch> [code <code>] <option> [{if | unless} <condition>]
3 g1 R! X$ ^* J  x' D+ S  Return an HTTP redirection if/unless a condition is matched
. X) d5 G0 N6 K6 U: H- M& a  }  May be used in sections :   defaults | frontend | listen | backend6 m! W) p$ d2 |* F$ X! x
                                 no    |    yes   |   yes  |   yes
" C" G& L+ J- e2 k. c" |, ]
/ L/ O; M% V1 G. l  If/unless the condition is matched, the HTTP request will lead to a redirect
6 `0 T% i+ j4 a8 K; r) ^& l/ p  response. If no condition is specified, the redirect applies unconditionally.
& Z' I) ^% s! E2 W
  G4 L' n* O. D) \: d7 O9 C  Arguments :
' p6 m# b8 y: w3 f2 I. E    <loc>     With "redirect location", the exact value in <loc> is placed into, B9 h. U4 W9 `
              the HTTP "Location" header.7 [8 ]9 ~% Y9 {! N$ L2 s( P/ S9 N
  M8 l% m: c1 k8 t
    <pfx>     With "redirect prefix", the "Location" header is built from the4 a* ~8 I1 E( n% {% X
              concatenation of <pfx> and the complete URI path, including the
% W2 p4 @  C: K              query string, unless the "drop-query" option is specified (see
# D" o8 ^3 c% A7 T( ?5 H              below). As a special case, if <pfx> equals exactly "/", then3 W3 ]* w6 Z+ i) i2 h+ D
              nothing is inserted before the original URI. It allows one to
& p* ]' }/ F% k' {              redirect to the same URL (for instance, to insert a cookie).
; {+ M. }, z1 k5 s, W
! U2 s" x! x, _7 e9 b* s5 Q, u, _    <sch>     With "redirect scheme", then the "Location" header is built by4 K  M  A1 s1 N( g% ~
              concatenating <sch> with "://" then the first occurrence of the
7 P0 |; a. @: Z- K! }              "Host" header, and then the URI path, including the query string
1 E5 D# T: M2 C( b5 q+ y6 s9 M              unless the "drop-query" option is specified (see below). If no
, E  `5 r" ]& `8 _6 |: z5 Q              path is found or if the path is "*", then "/" is used instead. If6 a( [6 i! k$ k. t0 S4 p
              no "Host" header is found, then an empty host component will be
3 w1 D; m9 p: @1 j/ s              returned, which most recent browsers interprete as redirecting to
# v4 k" }! g( |7 ~$ T              the same host. This directive is mostly used to redirect HTTP to' K. j/ N' p$ M& W* W5 }' K3 I
              HTTPS.8 A0 h# y) k# b; ^( I- E  u
3 M  P  _- }# J2 y
    <code>    The code is optional. It indicates which type of HTTP redirection0 s$ A, X& o- k# o
              is desired. Only codes 301, 302, 303, 307 and 308 are supported,
) }8 n! t' ?5 i$ @              with 302 used by default if no code is specified. 301 means
( `' [% N/ f7 ^4 L4 b6 L& w              "Moved permanently", and a browser may cache the Location. 3020 w$ g7 j7 E4 o1 g* f& E8 ]( C4 |
              means "Moved temporarily" and means that the browser should not# `. i5 q3 k2 q! F! C# i, D
              cache the redirection. 303 is equivalent to 302 except that the
7 Q' w, {6 N+ o5 Z; p( L) o              browser will fetch the location with a GET method. 307 is just
5 |5 F# K& _3 H" x( u              like 302 but makes it clear that the same method must be reused.. o2 C8 g0 N+ H7 w/ R) Q
              Likewise, 308 replaces 301 if the same method must be used.
) y6 P$ ]. D! r% Z* K# @! g# a5 r0 i
    <option>  There are several options which can be specified to adjust the7 w' ^" @+ t" d, I% a9 |
              expected behaviour of a redirection :  _* y+ L1 g. d6 @

3 Y1 F2 M1 C' I( i" `      - "drop-query". R  S% |8 R. T+ a) j
        When this keyword is used in a prefix-based redirection, then the
0 t0 X; g' e. b6 O        location will be set without any possible query-string, which is useful+ d8 \# p# o9 _4 I  @
        for directing users to a non-secure page for instance. It has no effect
0 f2 u# ~5 m0 c% ]" p) _        with a location-type redirect.$ K6 b4 A3 ^, M1 Z# w5 {+ w) |( A
  }* Z7 ?; y5 {
      - "append-slash"0 }/ N. I" J9 }6 Z$ Z8 t+ |
        This keyword may be used in conjunction with "drop-query" to redirect$ v3 b3 b$ T+ b* C9 D6 Y2 u
        users who use a URL not ending with a '/' to the same one with the '/'.
( U* s! ~# r3 z; {        It can be useful to ensure that search engines will only see one URL.9 J) |5 b9 m: d0 s+ g
        For this, a return code 301 is preferred.
" }* Z# \3 i  b3 [7 T% }; U$ `7 _) j7 Z
) o' i" F4 ~9 m2 p! E, _6 _      - "set-cookie NAME[=value]"
4 a5 n5 I# H! g& R' g, t5 X2 B7 c        A "Set-Cookie" header will be added with NAME (and optionally "=value")
6 k9 q% h- A! F9 C$ l        to the response. This is sometimes used to indicate that a user has9 T" H' x6 A$ v! Y, x
        been seen, for instance to protect against some types of DoS. No other8 B4 I+ u! H, @7 S' u9 g! ~
        cookie option is added, so the cookie will be a session cookie. Note
2 S9 c( u% l4 a8 `0 d* H" t8 d        that for a browser, a sole cookie name without an equal sign is
: v/ h* f4 _; l0 L2 ~        different from a cookie with an equal sign.
, ^, G5 S1 p) e0 ^$ l8 X
  P* V5 ^/ X% A& _      - "clear-cookie NAME[=]"6 H  s* M- {- n8 [
        A "Set-Cookie" header will be added with NAME (and optionally "="), but
  [! ~& p1 v+ d3 ^: U0 Q- Y2 `        with the "Max-Age" attribute set to zero. This will tell the browser to- K5 L: i3 a! J0 U9 A$ S) r: `
        delete this cookie. It is useful for instance on logout pages. It is, z: C/ s7 O. q- p
        important to note that clearing the cookie "NAME" will not remove a& }: N9 s7 V2 r8 f: K7 s+ p2 b* Z: x
        cookie set with "NAME=value". You have to clear the cookie "NAME=" for
1 [* o  c8 f/ C  }  ^0 V        that, because the browser makes the difference.
7 T  Y, j; N8 v7 F! u3 G) F0 i; W
1 @& m. f& |! [$ h' d  Example: move the login URL only to HTTPS.7 q& N3 n/ p/ a1 q" j
        acl clear      dst_port  80" x7 T( L7 f( }+ r" Q) M3 B
        acl secure     dst_port  80802 p( S( B; ]! N) |6 c: C, V: t
        acl login_page url_beg   /login
# M9 _3 A2 b; P3 \        acl logout     url_beg   /logout
8 i/ @  h. F; A# [4 \+ j        acl uid_given  url_reg   /login?userid=[^&]+0 \9 R* K: o. P7 b# d9 a0 ^5 w
        acl cookie_set hdr_sub(cookie) SEEN=1
: C' z- @5 u" U( V0 d/ a, e, F( L+ @
$ Z+ N6 q+ a4 U  T! c+ k3 R( p% v        redirect prefix   https://mysite.com set-cookie SEEN=1 if !cookie_set
" j; F4 k( U3 H0 D! V  \7 L7 ~% ^        redirect prefix   https://mysite.com           if login_page !secure
2 q7 C, q% \" b! h& a) |9 d7 q        redirect prefix   http://mysite.com drop-query if login_page !uid_given; T/ m9 M+ d; ?$ X
        redirect location http://mysite.com/           if !login_page secure; e8 E. Z' _1 L! Z( K
        redirect location / clear-cookie USERID=       if logout
9 {5 n. ]3 C8 s( ^4 Z7 u, A: H  s% b5 `
  Example: send redirects for request for articles without a '/'.
& H8 U+ {" {' @# {. |4 d6 O% ]        acl missing_slash path_reg ^/article/[^/]*$7 P( b& g5 Z; r$ Q$ W
        redirect code 301 prefix / drop-query append-slash if missing_slash9 u4 K0 P1 [7 Q6 R. z/ R9 F
. T: u9 I. U) S; S- B4 H
  Example: redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.
, c+ ?* K  t2 u6 v1 z        redirect scheme https if !{ is_ssl }
) E- c& D; [/ U! J4 I8 ~
. V6 M2 e9 D0 A4 s  w& \  F4 j: T  See section 7 about ACL usage.1 ^' b, N: j% n$ M: |9 x- Q
, W( u+ N! \3 Y' s. ]2 T$ q
% S9 z% D' D' e7 ^, }& r: e
redisp (deprecated)
. G0 S' i4 b% M! r) v/ z* E; _& tredispatch (deprecated)7 R- ?6 u  j& r6 z$ y$ o2 U
  Enable or disable session redistribution in case of connection failure
& i/ @  Z9 }8 p* X7 ?7 {  May be used in sections:    defaults | frontend | listen | backend6 P# x2 P3 B6 ^. w2 p, ?* k1 F! \/ Y
                                 yes   |    no    |   yes  |   yes
6 p4 |) j7 i! q& ~# C  Arguments : none
% N" n' b  C# n4 B* }" @, f. H+ |: l' Q& I/ T* E
  In HTTP mode, if a server designated by a cookie is down, clients may! N2 v1 o, i0 V) K
  definitely stick to it because they cannot flush the cookie, so they will not
$ L1 ^3 v9 K8 W" P, j, B7 w  be able to access the service anymore.2 N5 ]+ y% Z' x& R' b( H

; {; ]3 c; X: }9 g  Specifying "redispatch" will allow the proxy to break their persistence and
. ?3 E' {# o% B! G8 ^8 @  redistribute them to a working server.% ]' L% v# |' E8 y- |" ]
  v( u: j" k# F) [5 K1 e/ ?( i9 Q
  It also allows to retry last connection to another server in case of multiple
! z' V; k  E. r8 i7 B% k  connection failures. Of course, it requires having "retries" set to a nonzero
3 w  k4 g  {$ Y, P& T  value.2 p2 a4 M+ O3 P' M" I% x* @9 K
3 N& S# v% @3 I3 e7 j
  This form is deprecated, do not use it in any new configuration, use the new
/ G% k" c/ U) s/ w1 [4 }- n: `0 x  "option redispatch" instead.
% s. F7 j: M" Y: f8 A
" D7 d' o6 h0 D1 T4 e* g  See also : "option redispatch"
" S4 D. Z/ e. P0 u
2 ^- h! }$ O- |  {, S0 C+ }1 o; b+ i% v6 ?8 T" z
reqadd  <string> [{if | unless} <cond>]
; Y. @- v- [: N4 I* X  Add a header at the end of the HTTP request& n0 |8 X( Y& b) h2 H7 U0 j# V0 a
  May be used in sections :   defaults | frontend | listen | backend- H8 o, \" q4 R9 v) k
                                 no    |    yes   |   yes  |   yes; i9 a- C0 f7 q8 o: y, K
  Arguments :6 r& y  C/ ]( s2 Z5 s8 V
    <string>  is the complete line to be added. Any space or known delimiter
' j2 `6 L  n; P4 L; g              must be escaped using a backslash ('\'). Please refer to section* p# N. j9 O2 R0 \; I
              6 about HTTP header manipulation for more information.
( M4 W. h  y* o2 X) A. Z" Y
+ m0 F8 s% `4 C7 E+ D    <cond>    is an optional matching condition built from ACLs. It makes it$ y" j% Q; ]3 k8 b% \" B: L
              possible to ignore this rule when other conditions are not met.- Y1 e' ^2 R) h! C6 F& @- X7 {
  q6 @3 e3 A( j5 @2 h
  A new line consisting in <string> followed by a line feed will be added after
3 s3 n* g+ X! V( @1 L: Z2 S! N  the last header of an HTTP request.3 @! R9 ]% q. O, |' X

' i- G) [9 H: U; }) a  Header transformations only apply to traffic which passes through HAProxy,' n# M* X2 }% L2 p' B
  and not to traffic generated by HAProxy, such as health-checks or error9 ]6 y# B; ~9 g$ @+ h+ L# o
  responses.
/ {1 O0 }0 g+ |' }( r6 ]7 `6 K6 C9 P! N: ?
  Example : add "X-Proto: SSL" to requests coming via port 81
! y! c3 ?, R- l5 ?8 N! ?     acl is-ssl  dst_port       81$ t, S. T' p, O
     reqadd      X-Proto:\ SSL  if is-ssl
4 r5 a5 j& p* y3 s5 z  f+ r3 D. ~& Y- X. k
  See also: "rspadd", section 6 about HTTP header manipulation, and section 76 Z0 @9 d1 P% L9 Q  M# T
            about ACLs.1 Y: p% j# b3 H
9 l" |2 P0 e9 p9 G3 s
8 F; T9 w1 T$ [( m( T
reqallow  <search> [{if | unless} <cond>]
1 k- K0 p( p+ z9 |0 zreqiallow <search> [{if | unless} <cond>] (ignore case)5 z" ?3 i1 F  g7 h4 Z' m
  Definitely allow an HTTP request if a line matches a regular expression3 P9 G9 l( r% _4 W9 S- z6 p: ~
  May be used in sections :   defaults | frontend | listen | backend
1 l, {6 b6 X( q( J% o& F3 a- Q6 c; z, l* W                                 no    |    yes   |   yes  |   yes. {/ Y& I* V( i
  Arguments :
4 |7 H& V5 V8 J. ]7 G    <search>  is the regular expression applied to HTTP headers and to the
( S+ @! p; Z) D$ U( G              request line. This is an extended regular expression. Parenthesis
/ M: r6 t& z0 P, f+ k% q              grouping is supported and no preliminary backslash is required.4 a3 {" e6 @3 w( S) `1 x
              Any space or known delimiter must be escaped using a backslash6 A& Z5 C  D  J6 h. i
              ('\'). The pattern applies to a full line at a time. The2 E: b$ f. q) U' w$ w
              "reqallow" keyword strictly matches case while "reqiallow"
6 Q: p5 G6 _6 Y$ R              ignores case.
/ i/ {1 C6 I& U. y3 n$ t$ V5 U- T/ Q4 o4 `
    <cond>    is an optional matching condition built from ACLs. It makes it
- }. P/ M6 `5 U0 k% \" ^              possible to ignore this rule when other conditions are not met.# _, W+ z% R2 x  h; L3 w8 r, C7 ^

# ], A  @& A2 s+ E  A request containing any line which matches extended regular expression
6 V# [) ?. D5 ~, C# D7 j! S  <search> will mark the request as allowed, even if any later test would9 O% S4 s: S& B
  result in a deny. The test applies both to the request line and to request+ E  Y9 B5 W; {0 l0 `5 @
  headers. Keep in mind that URLs in request line are case-sensitive while* C4 K2 {9 w& g8 B
  header names are not.5 M  g9 q$ f8 x  r- Q' r
6 T2 v5 e9 S! p- i- M4 g. ]& T4 \
  It is easier, faster and more powerful to use ACLs to write access policies.
4 o: w' h% Y5 Y5 q  U  Reqdeny, reqallow and reqpass should be avoided in new designs.
5 O  O# Z, |4 T3 Y4 _! X% h4 L7 t
) P: B7 D! q5 v  Example :1 {, V1 ~$ ^: M4 \3 h; A/ ~% a
     # allow www.* but refuse *.local
8 H' ~7 F5 Q: z" K' W& M     reqiallow ^Host:\ www\.  {0 w) W2 C. V/ C( L% H
     reqideny  ^Host:\ .*\.local; J5 x) G4 H. ~0 {

1 R' H/ J) {" _% K3 T! t# K  See also: "reqdeny", "block", section 6 about HTTP header manipulation, and+ n: E! p/ r  p
            section 7 about ACLs.
/ Y# R% S# |) Z% t8 L3 E; ]( f# i

8 E( U* T4 y) @9 E+ qreqdel  <search> [{if | unless} <cond>]
# P- n9 J3 `0 W) B9 N5 Oreqidel <search> [{if | unless} <cond>]  (ignore case)
, D: T2 k. B. G3 g9 \  Delete all headers matching a regular expression in an HTTP request
! o2 j- u2 J1 Q  May be used in sections :   defaults | frontend | listen | backend
* c/ N% c- P, A; c* X9 o                                 no    |    yes   |   yes  |   yes
( S$ I7 B3 n& u* A/ P  Arguments :
- f2 o6 |* d  w: m$ n, O( f& _    <search>  is the regular expression applied to HTTP headers and to the
0 t$ \% h7 _1 X; n              request line. This is an extended regular expression. Parenthesis, o+ F3 R6 J  N* T5 z7 G$ L
              grouping is supported and no preliminary backslash is required.3 C% v* H9 c4 e' g- o2 I
              Any space or known delimiter must be escaped using a backslash3 `/ p1 j/ c( D8 L, X
              ('\'). The pattern applies to a full line at a time. The "reqdel"
1 h" \2 a5 j' z  r, g              keyword strictly matches case while "reqidel" ignores case.
/ N0 ?2 Y' I: T7 d! Z. T
' J- s  N1 L7 n* A: E; n    <cond>    is an optional matching condition built from ACLs. It makes it
. ]1 E  u1 v# `/ h* ?4 z              possible to ignore this rule when other conditions are not met.# F$ r2 s& J& |, p0 }/ |

1 s9 U7 S$ K: C. C1 E2 a9 x+ {9 q  Any header line matching extended regular expression <search> in the request
5 X2 `: T+ ~: ?: m, P* s  will be completely deleted. Most common use of this is to remove unwanted4 g' `* A+ b( u8 l5 m* `" `
  and/or dangerous headers or cookies from a request before passing it to the
; ?/ h+ O  v8 L" A) o! \  next servers./ g  H' p% L2 d6 I9 u
$ }4 \# d$ A" T! U% e# k8 G, v* z
  Header transformations only apply to traffic which passes through HAProxy,& Z2 |1 \  B/ Z
  and not to traffic generated by HAProxy, such as health-checks or error$ }4 ]  ]) o0 U$ C: h1 c
  responses. Keep in mind that header names are not case-sensitive.
1 U  Y" W7 n) S4 L0 o0 o$ p! C+ W0 |, m9 _6 G" F" A6 j
  Example :6 x: A; q& G: v0 h
     # remove X-Forwarded-For header and SERVER cookie& z2 O$ I! c! h; ^2 w: m4 D
     reqidel ^X-Forwarded-For:.*
7 O1 K  l6 \. ^: u     reqidel ^Cookie:.*SERVER=) s6 o# X! m: d

% l) t/ f% `3 i1 J# O1 x- k  See also: "reqadd", "reqrep", "rspdel", section 6 about HTTP header
; w, H! G* H5 F) m            manipulation, and section 7 about ACLs.! P9 L4 l: k9 _; A: z  T

' [: b2 j( R3 G$ E7 }
2 |' p  p7 O8 N5 Y6 ^1 @reqdeny  <search> [{if | unless} <cond>]4 `1 x; M% i& g$ ?
reqideny <search> [{if | unless} <cond>]  (ignore case)
4 `7 J1 n- R+ K, n& E5 Z: M& y  Deny an HTTP request if a line matches a regular expression. h4 }8 |! V6 l+ ~
  May be used in sections :   defaults | frontend | listen | backend7 B( u* p0 d) c
                                 no    |    yes   |   yes  |   yes
' D/ u  k9 Z3 n5 ]7 A  Arguments :4 D9 ?9 P* Z) e! y3 |
    <search>  is the regular expression applied to HTTP headers and to the
9 _1 Y1 _6 q" L( y4 ~4 f              request line. This is an extended regular expression. Parenthesis4 q2 _+ u6 D& q1 ~5 a1 \
              grouping is supported and no preliminary backslash is required.
2 K# f0 ^* j4 E7 j2 k. D  c* |* q              Any space or known delimiter must be escaped using a backslash
* E  S4 Q* k- S" m              ('\'). The pattern applies to a full line at a time. The. v  l0 S% z7 n) w, b- ^& @
              "reqdeny" keyword strictly matches case while "reqideny" ignores
2 t5 R4 [) ]1 A& E' q7 h2 i5 ?              case.
; ?8 t; s, H0 z- y. ^1 ^, y) b9 |( n* m, P1 V& Q4 W
    <cond>    is an optional matching condition built from ACLs. It makes it
5 b1 a. i% _* L% x# I# E8 U              possible to ignore this rule when other conditions are not met." h7 ?) H3 k7 P% i

9 @  ^8 Z8 t$ L* _8 a0 c1 J  A request containing any line which matches extended regular expression
6 U! U4 E& K# t  <search> will mark the request as denied, even if any later test would" W4 r* v' t; h; ~  ?$ v1 V
  result in an allow. The test applies both to the request line and to request# U- ~1 i, d5 w: o
  headers. Keep in mind that URLs in request line are case-sensitive while
) Q' t# M7 Q0 j2 M: j; m- J  header names are not.
9 _1 [. H; H3 K( ]9 B" Q" n0 {* Q! F2 q0 Z) B
  A denied request will generate an "HTTP 403 forbidden" response once the
- P6 G  W4 j& [/ d* ^  complete request has been parsed. This is consistent with what is practiced
# K2 z* [3 z9 ~+ j1 T  using ACLs.  `7 R. l+ S5 u: L$ B

- P/ e& b. D8 v. W# Y  It is easier, faster and more powerful to use ACLs to write access policies.
, x' M: G8 \. P* B. Q0 [4 a/ b  Reqdeny, reqallow and reqpass should be avoided in new designs.
7 D$ G4 v- F: K' c/ z+ f3 Z! K  \* W0 A, a6 ~& Y) t
  Example :2 s/ U8 F/ U2 e4 H
     # refuse *.local, then allow www.*3 v: g; z% Z3 O  D) @% h5 O( H
     reqideny  ^Host:\ .*\.local
% @( h! S. O9 c# L/ B  n& |1 i     reqiallow ^Host:\ www\.
' Z$ F' n9 X- y( f9 X5 Y
$ E& v3 B, t5 z! Z# d! m  See also: "reqallow", "rspdeny", "block", section 6 about HTTP header
1 m) F) }; H  j8 Y' u            manipulation, and section 7 about ACLs.
  _' R: E  d# B/ q- D# ~2 r' B6 ~/ a8 H) }1 B% o$ d( P

' n" r- s. N: R/ v* }3 @" b/ H9 ~reqpass  <search> [{if | unless} <cond>]( Z# u5 h# ^) a$ a+ c4 L/ Y
reqipass <search> [{if | unless} <cond>]  (ignore case)
0 K- Q0 |4 C4 S& I5 J& F  Ignore any HTTP request line matching a regular expression in next rules
0 H) @# S: L3 B( f  May be used in sections :   defaults | frontend | listen | backend" m8 y6 ^+ Z* a4 I* j/ U
                                 no    |    yes   |   yes  |   yes
5 i2 ?# X' Q  J5 v+ y; \* X  Arguments :
  k$ H: [3 S7 ~& o    <search>  is the regular expression applied to HTTP headers and to the8 A4 `3 D8 f7 ~* W7 y! D
              request line. This is an extended regular expression. Parenthesis
, d9 ~4 r' w1 q1 }              grouping is supported and no preliminary backslash is required.
! v% k1 C0 ~) p6 H$ f              Any space or known delimiter must be escaped using a backslash. X' |" T" V) }, \( ~
              ('\'). The pattern applies to a full line at a time. The
7 q# d5 d0 p# v              "reqpass" keyword strictly matches case while "reqipass" ignores
: x1 F! y! M0 {/ U9 X              case.- f/ n' l% ^/ c  f

7 M, S" u- \' B" k2 |2 O9 v    <cond>    is an optional matching condition built from ACLs. It makes it* S* }5 b, }1 ?* `1 h5 i- B, n
              possible to ignore this rule when other conditions are not met.
8 j7 N/ }3 p# w  c' ^! g/ Y8 L+ O1 A* I. I
  A request containing any line which matches extended regular expression0 x$ [3 Q2 C) A9 J! T
  <search> will skip next rules, without assigning any deny or allow verdict., j/ ^3 M) X# `
  The test applies both to the request line and to request headers. Keep in
$ r0 Z- N( L1 o4 a5 [  mind that URLs in request line are case-sensitive while header names are not.8 M5 O' c+ X) W. S8 v! }! ]

/ K8 D! @+ C5 w* v- B8 N2 L; F5 S  It is easier, faster and more powerful to use ACLs to write access policies.# Z8 j+ w3 s+ s0 j  V3 U; v
  Reqdeny, reqallow and reqpass should be avoided in new designs.- W9 d  a  q: F+ T$ O5 v  {
5 F$ Q  Q+ p1 v* J; u3 e
  Example :, Y( M- g: w3 z: g, M2 \
     # refuse *.local, then allow www.*, but ignore "www.private.local"7 Z5 X+ Z8 e" r* u. v3 c
     reqipass  ^Host:\ www.private\.local
! Q( p/ `3 [/ V  t1 t% q" R     reqideny  ^Host:\ .*\.local$ _1 f. u4 S4 v9 A
     reqiallow ^Host:\ www\.7 T/ }& t. c% z  ~! h

; d" W1 Y5 g3 O3 }" V, G9 p  See also: "reqallow", "reqdeny", "block", section 6 about HTTP header) R* _# x9 F6 q. D
            manipulation, and section 7 about ACLs./ X. z# p$ e! T' E

+ g; u0 T/ Y0 C) O, P( }8 _) M# k5 C" ?: a
reqrep  <search> <string> [{if | unless} <cond>]
3 w9 o% P8 b4 h: |( y- ]reqirep <search> <string> [{if | unless} <cond>]   (ignore case); Q6 y( a. o. |( s* H& {- W
  Replace a regular expression with a string in an HTTP request line8 b0 Q& ~' W; j# S# H4 B' t
  May be used in sections :   defaults | frontend | listen | backend
3 Y6 b( X4 D! E0 n1 N2 l                                 no    |    yes   |   yes  |   yes
! {" f0 g3 D7 ]/ @  Arguments :
0 I6 L8 Z! w. C2 b2 ^, `    <search>  is the regular expression applied to HTTP headers and to the9 W; [6 m* R: p1 b
              request line. This is an extended regular expression. Parenthesis7 }. K+ [8 z; z: x# q$ W8 v# j
              grouping is supported and no preliminary backslash is required.6 ]8 M- s. o$ B( m- G- G) J- y
              Any space or known delimiter must be escaped using a backslash
: }$ \- c1 G! W5 \* y! D              ('\'). The pattern applies to a full line at a time. The "reqrep"" I' y  k: D2 p: s- V- v- Z0 f
              keyword strictly matches case while "reqirep" ignores case.
4 s6 h1 Z  @5 O7 E& B% v8 s9 F5 ~6 A* [
    <string>  is the complete line to be added. Any space or known delimiter! R: T( x$ s6 v1 J1 a3 v4 t3 e
              must be escaped using a backslash ('\'). References to matched1 V+ y3 W# G; M, m/ ]
              pattern groups are possible using the common \N form, with N
) z- x- |7 w8 z/ [) N: I3 Q9 }5 @              being a single digit between 0 and 9. Please refer to section
1 n: J' u) P/ H1 |2 t0 ^4 i              6 about HTTP header manipulation for more information.4 K( B! r& I# Z/ m9 w: b8 S0 V
' X& B9 q2 x8 D+ t* z
    <cond>    is an optional matching condition built from ACLs. It makes it
8 F% _7 N0 J+ @8 V              possible to ignore this rule when other conditions are not met.! j$ \) d" Y$ p2 c
$ b$ G  R8 w+ X, ]3 l0 H0 c
  Any line matching extended regular expression <search> in the request (both
3 I5 m  K! |( ^7 A  the request line and header lines) will be completely replaced with <string>.
$ R: p' Z0 z& V8 U1 [. g4 S, m  Most common use of this is to rewrite URLs or domain names in "Host" headers.$ K8 o7 c  [, A" |9 p9 F% G

' f. |4 b# C5 \6 a  Header transformations only apply to traffic which passes through HAProxy,
' y  \$ K( P2 h- Y, ^  and not to traffic generated by HAProxy, such as health-checks or error
; p8 N' L) c4 u8 e  Y8 g/ T' a  responses. Note that for increased readability, it is suggested to add enough
6 t: L" t) L7 H3 @0 d  spaces between the request and the response. Keep in mind that URLs in8 F4 u9 w8 b/ o  _8 s, y! P, X, v& u
  request line are case-sensitive while header names are not.
/ f( d) `2 T6 p8 U7 D& ]
) {" p" s% D- j6 _- O* u* x; A/ k  Example :
; A  I5 J8 S+ Z/ h+ [     # replace "/static/" with "/" at the beginning of any request path.7 i" g6 W3 e; a
     reqrep ^([^\ :]*)\ /static/(.*)     \1\ /\2
9 R0 ?& |1 }9 T     # replace "www.mydomain.com" with "www" in the host name.
5 }" m2 g- R* H     reqirep ^Host:\ www.mydomain.com   Host:\ www
$ n( d& M5 W) T! u( p$ s5 n- v9 H% W9 D
  See also: "reqadd", "reqdel", "rsprep", section 6 about HTTP header
% e# @, J4 b4 t5 {! G# b$ z            manipulation, and section 7 about ACLs.
7 \* l2 X1 @9 b6 Q3 R1 u' F; [2 d# k9 w! k  t  Q. Q& z1 y6 h1 e

2 K+ L  N. j  g$ L6 lreqtarpit  <search> [{if | unless} <cond>]8 \( N' t- }; W" O& H* U% Z
reqitarpit <search> [{if | unless} <cond>]  (ignore case)
9 O# Q) g0 q3 g( H  Tarpit an HTTP request containing a line matching a regular expression0 H) X3 e6 Y6 l$ l, j
  May be used in sections :   defaults | frontend | listen | backend5 o, j; i& [, O. i  q
                                 no    |    yes   |   yes  |   yes/ |3 X+ K/ S  e+ m
  Arguments :. d6 r+ x6 J# J, Y5 B; i" n
    <search>  is the regular expression applied to HTTP headers and to the
0 Y$ a0 S$ v* f3 @' ]              request line. This is an extended regular expression. Parenthesis; }9 W, W9 b: ^) E
              grouping is supported and no preliminary backslash is required.: L- I5 B8 e' n6 k% _% j' g3 A
              Any space or known delimiter must be escaped using a backslash
! r. B" @1 N' u              ('\'). The pattern applies to a full line at a time. The
1 \+ _+ ^9 |; {4 s+ a              "reqtarpit" keyword strictly matches case while "reqitarpit"
4 h" w  i- |$ Y# W$ e              ignores case.
) D+ X& w" N# p, M0 A8 b: P
& b+ c5 D9 w0 y    <cond>    is an optional matching condition built from ACLs. It makes it# P% @  W) t* w" }
              possible to ignore this rule when other conditions are not met.3 }/ R6 }' ?2 \$ k0 }

) [, a3 H! N, e; r6 J  A request containing any line which matches extended regular expression
3 v+ U) X$ E, ?, t: X  <search> will be tarpitted, which means that it will connect to nowhere, will
; H; Z+ N3 l9 g5 N, B: X  be kept open for a pre-defined time, then will return an HTTP error 500 so% D" ~: M+ u$ N$ A
  that the attacker does not suspect it has been tarpitted. The status 500 will
- |6 u# l" Q9 v7 K) E/ W5 I/ g  be reported in the logs, but the completion flags will indicate "PT". The
) A/ K0 R- O9 z4 T% d  delay is defined by "timeout tarpit", or "timeout connect" if the former is
5 Z. V* Y2 g- [, ~6 U& c/ Q# a  r# a  not set.! ~. {. p$ [5 W- O" j& t
" Y; c" s& f* I" k% j/ Y, {- i- r
  The goal of the tarpit is to slow down robots attacking servers with
5 f. ^" X6 T' O6 V% \- j  identifiable requests. Many robots limit their outgoing number of connections  e8 j5 Q1 }3 v' A  m/ {
  and stay connected waiting for a reply which can take several minutes to# z7 c: j8 g  q- u9 V
  come. Depending on the environment and attack, it may be particularly
* `( B! i; \6 g$ C9 K/ c  efficient at reducing the load on the network and firewalls.
) w, y1 I, X5 {
& p. M* o7 b' p  Examples :
2 y7 t3 f- a: S" E" v* v4 F     # ignore user-agents reporting any flavour of "Mozilla" or "MSIE", but
3 |( z" ?* @% F     # block all others.
/ \6 f" o1 M5 J2 W4 c- |2 a     reqipass   ^User-Agent:\.*(Mozilla|MSIE)' I  G7 T1 `- r! }# t8 L
     reqitarpit ^User-Agent:
! ?, T! H8 U: Q
! K( s, u7 [) O/ I     # block bad guys
, C2 k2 a. x* Y! R     acl badguys src 10.1.0.3 172.16.13.20/28, v3 d5 S: _8 a1 T& x/ f9 v9 E
     reqitarpit . if badguys
) ?) ?3 i: U& j# j% H+ {* u
- J6 f+ F0 d: c' u8 g  See also: "reqallow", "reqdeny", "reqpass", section 6 about HTTP header
: g( R" X, A) b$ ^5 |( g" G            manipulation, and section 7 about ACLs.& X& F& |( w2 I- O

  D8 [) l3 [' c6 s0 y1 u
- s0 ]3 K; p  q/ s* ?retries <value>
6 G* w3 o3 i( V  Set the number of retries to perform on a server after a connection failure
0 \! W8 B5 R( Y+ p/ k$ M( n  May be used in sections:    defaults | frontend | listen | backend
/ W. K5 z" P2 Q& U# B* g3 y7 I, e                                 yes   |    no    |   yes  |   yes" @% r# ~- P+ g7 Q
  Arguments :8 b# p" V( S7 t5 `6 I3 ?
    <value>   is the number of times a connection attempt should be retried on
' I2 |! H* r  V' ~8 Q              a server when a connection either is refused or times out. The
1 [7 D) ?# I4 e3 L              default value is 3.
! t7 _" B( {, J9 Y3 B4 I9 [' [, I: t0 E. W( J: I
  It is important to understand that this value applies to the number of
5 C* K. T$ h8 ~) g' y& y6 P" \  connection attempts, not full requests. When a connection has effectively
0 a' x" L* K& r/ e: O  i8 c  been established to a server, there will be no more retry.
( Z- c, X+ p, J  M7 q/ a6 J: w4 s; _
& v0 M" I5 t$ ]5 Q" v  In order to avoid immediate reconnections to a server which is restarting,0 P, d' `. p  u9 w6 F
  a turn-around timer of 1 second is applied before a retry occurs.) m. x. W$ W7 G- V' t, {
! y4 w9 Z3 j( z) `# n) n( E
  When "option redispatch" is set, the last retry may be performed on another
3 k# S# `; J  x  server even if a cookie references a different server.
  M/ Z. N* f5 s1 H
' _+ ]& u' `5 [. \  `  See also : "option redispatch"
2 a$ J0 F3 z' o' s7 C  J
2 i* Y  c1 {4 N1 T3 w' k7 R
' f6 Y' I7 S6 H& Mrspadd <string> [{if | unless} <cond>]
! N' K2 W" C* M0 _; v9 ?  Add a header at the end of the HTTP response6 s# B& Y( ~" s0 A* a, V6 o
  May be used in sections :   defaults | frontend | listen | backend
  {/ F; H/ S; K7 P% F+ K' Y% ?                                 no    |    yes   |   yes  |   yes( T# Y, d5 ], u7 k$ Q9 c+ p
  Arguments :
* |2 h* ~9 O/ D    <string>  is the complete line to be added. Any space or known delimiter+ n& b  ~. j4 d
              must be escaped using a backslash ('\'). Please refer to section
% t" s- l$ m2 V; }" k0 ^7 m              6 about HTTP header manipulation for more information.! Y  i- e2 ]& u/ d

# e0 Y2 F7 L9 k( S    <cond>    is an optional matching condition built from ACLs. It makes it& `0 r5 W" |7 i
              possible to ignore this rule when other conditions are not met.
& N) j: `7 [+ J+ c& R
3 v/ k. O! K4 M: A' A  A new line consisting in <string> followed by a line feed will be added after
6 V6 F1 z  Y+ e( w5 g7 O2 U, I  the last header of an HTTP response.. t: }% f" F: z, ]
2 u% ?1 {/ p7 m3 l$ I
  Header transformations only apply to traffic which passes through HAProxy,$ u7 Z2 m( p- R8 N( \4 i
  and not to traffic generated by HAProxy, such as health-checks or error1 K/ V5 T6 W$ v# g
  responses.; R3 j) }2 P9 U- o

  V; K% W+ y+ a0 N4 D! h  See also: "reqadd", section 6 about HTTP header manipulation, and section 7. ]! G8 Z/ A+ g9 \
            about ACLs.8 s! I, ~  e) U( Y

7 Z0 G. q) L$ c6 ]: w! F% V# Q  E- y5 C5 ?9 T3 y6 w$ F6 l- m
rspdel  <search> [{if | unless} <cond>]* R8 @- t, H! }
rspidel <search> [{if | unless} <cond>]  (ignore case)* n( H+ B6 D" w' y7 @. k9 d
  Delete all headers matching a regular expression in an HTTP response
% u/ t2 Z8 H. {1 ]* v/ M6 l( E3 F  May be used in sections :   defaults | frontend | listen | backend
# J: n, c6 Z$ s1 h                                 no    |    yes   |   yes  |   yes" ~" f: ^! ?8 Q5 M/ g
  Arguments :# y% X+ u8 E: F3 a& y/ |6 r. C
    <search>  is the regular expression applied to HTTP headers and to the- Z5 v# R4 b4 E7 L1 _/ R) D
              response line. This is an extended regular expression, so
8 \3 f$ W, S1 X; j              parenthesis grouping is supported and no preliminary backslash1 g6 N% W* w$ b2 r0 b. n
              is required. Any space or known delimiter must be escaped using
  \4 e: t* V! z% ]0 W' b  J              a backslash ('\'). The pattern applies to a full line at a time.% b5 f6 s& ]  A; P# @8 q1 k
              The "rspdel" keyword strictly matches case while "rspidel"
8 S; ]# y' L# H9 ]' M' d$ a* d) v              ignores case.
' G/ s; q) j4 S) r
9 {, o+ x. u( [) X' \8 L% D) I    <cond>    is an optional matching condition built from ACLs. It makes it
8 X3 y' Q& F4 C  N- R9 _% F              possible to ignore this rule when other conditions are not met.& E+ A: ~, Q9 a

" g0 `: @2 F1 @! g8 L7 T( q' P  Any header line matching extended regular expression <search> in the response0 I* {( `* h! Z2 `% _( Q
  will be completely deleted. Most common use of this is to remove unwanted
/ A& }9 _2 e" L. ]8 \) W  and/or sensitive headers or cookies from a response before passing it to the, ~! a3 F; ^4 ]# V5 r! N" A
  client.
4 k* d" Z1 s1 [0 l+ [
3 c& p# _2 y3 A" b/ {7 l4 S7 w0 h: C! f) g  Header transformations only apply to traffic which passes through HAProxy,
4 o& n" k2 @0 {! U: w+ v: o  and not to traffic generated by HAProxy, such as health-checks or error! V% J$ S1 ?7 a1 H
  responses. Keep in mind that header names are not case-sensitive.( ~( j" k. v) T/ E9 U: b' v
5 L" u. M% V) ]) G1 d  q
  Example :
! K& \, H4 t  j, I# S4 e8 T* p( Y     # remove the Server header from responses9 U+ |) Z/ l8 b  y$ V
     reqidel ^Server:.*) ~  P$ z( S  n. {/ r$ C% W

# Q: S" J, k6 @  See also: "rspadd", "rsprep", "reqdel", section 6 about HTTP header8 q% @  T$ v2 \" ~  H
            manipulation, and section 7 about ACLs.
+ X& E& f" j$ H( x) W# J3 h5 B  w0 V. X9 P2 g; E/ T2 C2 c

# v, }% B! g, v0 d, g0 q9 Q. @rspdeny  <search> [{if | unless} <cond>]4 m- @# d1 q6 `
rspideny <search> [{if | unless} <cond>]  (ignore case)
# ]: s* G+ T. M4 H  Block an HTTP response if a line matches a regular expression
4 C) X3 V! N8 f) Q+ `. t6 V4 g) {  May be used in sections :   defaults | frontend | listen | backend, ]; i4 L; s9 x8 H" O& m3 ?
                                 no    |    yes   |   yes  |   yes- i. I7 n# r! n* K% J
  Arguments :
8 L8 d* D4 C8 l0 r    <search>  is the regular expression applied to HTTP headers and to the! I" ]- t; D' X
              response line. This is an extended regular expression, so2 B; d: q: n# E1 a  B& {+ f9 v# _2 p* g8 i
              parenthesis grouping is supported and no preliminary backslash
* x0 O, r9 v. O# X              is required. Any space or known delimiter must be escaped using
8 D6 _- W9 o  A$ v* u3 `              a backslash ('\'). The pattern applies to a full line at a time.
$ `# d0 J8 g+ E3 ]! g              The "rspdeny" keyword strictly matches case while "rspideny"' t) ?0 z. ^# R5 ]$ T4 ]' e6 ^
              ignores case.- }9 a! h/ _0 J% |1 W, [, o% x% K

) k% D+ k3 U. l; c5 W! Y5 ^    <cond>    is an optional matching condition built from ACLs. It makes it
2 E4 ~9 I; h7 T( P8 p              possible to ignore this rule when other conditions are not met.
. `' Q# R4 D& |! R+ k5 K7 y8 g) p
3 K& i, P2 L' C0 e. s7 d  A response containing any line which matches extended regular expression
; G& s* q$ i5 C  <search> will mark the request as denied. The test applies both to the6 e  J* y6 ?9 L* [' x4 A; W9 }& c
  response line and to response headers. Keep in mind that header names are not
0 L* H; U/ s9 i) E4 y) \4 I  case-sensitive.' `  s6 F* A: ?" B9 X( y
. R# C4 v# V2 U( |  d+ I; H0 r. \
  Main use of this keyword is to prevent sensitive information leak and to% X) e& G" {  a6 x% |- a1 A7 w
  block the response before it reaches the client. If a response is denied, it
# e0 S4 p* X* n/ D7 G1 c2 _$ k$ X9 y  will be replaced with an HTTP 502 error so that the client never retrieves
( q4 W; r5 L" e8 I6 ^: [$ J, X9 ~6 f  any sensitive data.  X4 H" e7 m) q% D: }

3 H# Q% O" w+ Z  It is easier, faster and more powerful to use ACLs to write access policies.3 S0 d, h$ G' s! r+ p
  Rspdeny should be avoided in new designs.
1 e: J" y7 K+ l1 ~9 W4 v* i, A
! w6 }4 F. |1 P* U# `  Example :
7 q, U- k3 k+ m0 P1 u0 R& r4 T( a# C     # Ensure that no content type matching ms-word will leak
2 G: K& e$ Y; P! y6 X) [, K     rspideny  ^Content-type:\.*/ms-word" l' j$ c  ?+ u

3 s1 w4 t4 \8 z8 l( i% |2 d  See also: "reqdeny", "acl", "block", section 6 about HTTP header manipulation% y' k3 `0 Z! g% Z" H. ^
            and section 7 about ACLs.
3 w- t4 Q& C4 ?/ M7 M, n$ s* D) q  i/ g+ ~
8 N8 V9 J" v7 V
rsprep  <search> <string> [{if | unless} <cond>]) u$ k4 c% \! Z, c
rspirep <search> <string> [{if | unless} <cond>]  (ignore case), F+ E0 n! f, F9 |0 K0 z* E
  Replace a regular expression with a string in an HTTP response line1 k: t* n% x& ?" H
  May be used in sections :   defaults | frontend | listen | backend( M' H7 _$ \8 J
                                 no    |    yes   |   yes  |   yes
0 \6 u6 W! m- ^* C* b$ H  Arguments :
* E7 M& o' A8 J    <search>  is the regular expression applied to HTTP headers and to the
2 j) B. i4 c1 A! B4 a              response line. This is an extended regular expression, so2 Y# D" M6 {* k$ {/ l
              parenthesis grouping is supported and no preliminary backslash
5 J; P) v& Q' b/ V! ^6 P6 Y              is required. Any space or known delimiter must be escaped using
: U: ~: t# H. V, x7 _- u% `              a backslash ('\'). The pattern applies to a full line at a time.
+ c# T4 q, _; G) L  A& \! p# Z              The "rsprep" keyword strictly matches case while "rspirep"
( c6 {/ S5 d1 K% E  l5 {, f7 K              ignores case.
% I4 E- S1 S  k6 F( Q! Q: o% a9 A/ s# t1 g* D1 q
    <string>  is the complete line to be added. Any space or known delimiter
- `" l- g$ c, P( M  ^. i1 [* V              must be escaped using a backslash ('\'). References to matched
8 ~! A* K9 }! n. ?3 y: @              pattern groups are possible using the common \N form, with N
; c& O0 a/ r8 T2 [              being a single digit between 0 and 9. Please refer to section
' {- q' i2 \. [              6 about HTTP header manipulation for more information.  h( r3 {1 ?2 Y7 l& n; k

2 {; }& e9 y" w" l    <cond>    is an optional matching condition built from ACLs. It makes it; S4 J! E/ _; \# D$ _+ ?) i
              possible to ignore this rule when other conditions are not met.) ~$ I1 w, M9 J
; G; D* X2 H& N; Z& [
  Any line matching extended regular expression <search> in the response (both
+ q" d$ z5 X/ `/ s# {6 r  the response line and header lines) will be completely replaced with
* N2 f) F8 u+ S; u. f  <string>. Most common use of this is to rewrite Location headers.
4 W# N1 z/ [  L1 I+ j
: E) G; B3 N6 N% ~! @& r: H; w  Header transformations only apply to traffic which passes through HAProxy,
) i' h0 x! H& ?8 x3 z  and not to traffic generated by HAProxy, such as health-checks or error
/ D( e! _' f+ g6 i5 I2 m: x: M! I9 p; N  responses. Note that for increased readability, it is suggested to add enough
) I: b9 h5 K4 j2 D. d# @% b  spaces between the request and the response. Keep in mind that header names
, z1 I" V) M' z  E) y  are not case-sensitive.
1 n0 `1 M+ Q0 Z7 C/ V2 @( i- D  ^5 n, V2 N; O
  Example :/ }& A, a* f5 D5 G
     # replace "Location: 127.0.0.1:8080" with "Location: www.mydomain.com"
! V% p! _  L. r, h' ?     rspirep ^Location:\ 127.0.0.1:8080    Location:\ www.mydomain.com- A: f" c. q/ z7 C3 m) a

8 _+ P5 p% u) J4 X  See also: "rspadd", "rspdel", "reqrep", section 6 about HTTP header
! ~* p- w2 N1 t( z0 S            manipulation, and section 7 about ACLs." p% i& w0 W5 K1 z. w  t  }
  ^) R' H9 V# q' m2 ?

- F/ D5 ]' g: C' C! H8 O4 j& g: mserver <name> <address>[:port] [param*]
! M1 Y2 C; o4 m. c  Declare a server in a backend
9 [1 e7 M$ @- L, m  May be used in sections :   defaults | frontend | listen | backend7 f4 V0 _; l4 a- W  p' D
                                 no    |    no    |   yes  |   yes
% r' n3 N  Q8 b1 ~- {  Arguments :( E# F+ e/ R- \* o  H& d5 K
    <name>    is the internal name assigned to this server. This name will
1 ]1 P2 k, M" b2 V              appear in logs and alerts.  If "http-send-server-name" is
  x# g! N0 i  k              set, it will be added to the request header sent to the server.! C( `+ ?# w' Z& B  [* J

8 x+ B4 [  f$ t1 H- j" o5 O) n3 Q    <address> is the IPv4 address of the server. Alternatively, a resolvable* q8 z. K4 ]- W6 h' `1 i
              hostname is supported, but this name will be resolved during; e3 o) U' X; R* H& A
              start-up. If no address is specified in front of the port, or if: ?0 i# z8 W7 Z9 Y! S+ Y8 M. ^
              address "0.0.0.0" is specified, then the address used will be the
/ H) g5 E% e; |( w3 y  I8 l3 B, B              same as the one used by the incoming connection. This makes it. r4 q- @2 D! O
              possible to relay connections for many IPs on a different port or
8 ^; R# L! {) k& }              to perform transparent forwarding with connection limitation.+ q  E5 g' q- Y# l% M6 ]$ C

1 r, D" Z6 O% W    <ports>   is an optional port specification. If set, all connections will2 t# z" t+ O" E
              be sent to this port. If unset, the same port the client& U  x2 W; V7 M$ l' Y
              connected to will be used. The port may also be prefixed by a "+"/ |# W$ B  e2 i6 i  @9 ^
              or a "-". In this case, the server's port will be determined by
9 l3 K0 a* u- l  w              adding this value to the client's port.
8 p; F! \7 |0 d% ?9 V' V5 L5 i+ F  e" C# w
    <param*>  is a list of parameters for this server. The "server" keywords
7 G) R0 B6 b8 i' d& c( q              accepts an important number of options and has a complete section
; Q& h& O* x5 y' G  d2 s              dedicated to it. Please refer to section 5 for more details.
& W3 H% A1 @$ {) }/ h+ l
$ u. y& q% L) N5 ~& f8 [  Examples :' K2 m' u" p  O+ `! P+ w/ L8 X
        server first  10.1.1.1:1080 cookie first  check inter 10003 R  x) o; J! L8 |+ B7 s6 f
        server second 10.1.1.2:1080 cookie second check inter 1000
/ G' m9 n, H* j$ d! v+ F  v
$ x5 G7 f4 S# s. y! ^2 }( {  See also: "default-server", "http-send-name-header" and section 5 about' }9 j# I4 y3 [! |" N  y( l
             server options8 N0 l) p: A2 i$ O; p
5 Y; o7 i7 m4 U& C; n6 A' W

7 _/ w1 R* M6 l5 b2 ]- Asource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ], X+ V# b  Y0 H. M
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]( s- Q) y. T* P: D$ \( x3 ^( }. ]+ I4 [
source <addr>[:<port>] [interface <name>]
: E* v" Y$ O% u- Y1 M  Set the source address for outgoing connections
1 ]* T. U( X: ?6 c1 s9 M  May be used in sections :   defaults | frontend | listen | backend
/ A2 i: J7 k4 h                                 yes   |    no    |   yes  |   yes
$ n) \% i1 Q# G5 d- s  Arguments :
, i! D) d8 _# ~* i& x1 H0 h( K    <addr>    is the IPv4 address HAProxy will bind to before connecting to a0 U1 j+ c8 g8 ^# R6 u  C
              server. This address is also used as a source for health checks.
, h2 F8 m. v/ p              The default value of 0.0.0.0 means that the system will select
; f7 Z6 [, D' _7 t$ T              the most appropriate address to reach its destination.
8 ]9 o8 i% j- A- g/ P% W/ F) @2 w7 ^9 Z( G+ M# p1 e
    <port>    is an optional port. It is normally not needed but may be useful$ G9 S: K, v$ a8 n
              in some very specific contexts. The default value of zero means
/ E" |! @& Z' q, Q6 v/ m0 p              the system will select a free port. Note that port ranges are not
7 S% a, C2 h& L# k' k              supported in the backend. If you want to force port ranges, you/ ~: E% N  c# y+ N' o# R5 b" `
              have to specify them on each "server" line.  h0 G$ }# w6 g' z. e. o5 Q9 |- d
- J' i% S6 u' E0 c
    <addr2>   is the IP address to present to the server when connections are
/ k9 s$ {2 e( f6 d              forwarded in full transparent proxy mode. This is currently only
5 R8 m) [7 A' N8 _: c/ U              supported on some patched Linux kernels. When this address is0 O' u4 o  c. Z5 Y: j/ d: I
              specified, clients connecting to the server will be presented) r* `# V8 z/ r
              with this address, while health checks will still use the address
' f, s+ F! f( x0 U              <addr>.1 g/ k: b* F1 r# \3 q
. O# l. p& s, B; c
    <port2>   is the optional port to present to the server when connections1 W1 t& M3 P& a
              are forwarded in full transparent proxy mode (see <addr2> above).% x( }3 ?/ ?- s7 |  r3 a+ a9 }
              The default value of zero means the system will select a free' O8 Q1 k, h0 d3 l
              port.% C' A$ t/ N. W5 E& S) y- i6 |

( Y$ R, F4 E$ \2 d5 e& c    <hdr>     is the name of a HTTP header in which to fetch the IP to bind to.
, S( C9 p/ Y$ Y) N( |) A3 P              This is the name of a comma-separated header list which can
0 U. j" c- R& u2 Z              contain multiple IP addresses. By default, the last occurrence is
  u6 T) d" o  W  q              used. This is designed to work with the X-Forwarded-For header5 s3 }# _3 I+ S% r% Q! P& x7 I% A: S0 t6 U
              and to automatically bind to the the client's IP address as seen
/ b# p+ Z& Q+ u4 F: t              by previous proxy, typically Stunnel. In order to use another5 n$ [7 g: h7 J3 b/ w& |
              occurrence from the last one, please see the <occ> parameter
$ c: H* x; w" |( O              below. When the header (or occurrence) is not found, no binding
8 E2 [7 Q; ~3 o7 C) U$ W; h8 m              is performed so that the proxy's default IP address is used. Also
5 f2 S7 Q. `  u4 H2 W) H$ M' P6 W              keep in mind that the header name is case insensitive, as for any
( ~( Q# D! G+ I4 d              HTTP header.! p( \3 _0 d* i5 q( N3 V# q5 A
: b- ]3 x- I$ w% a
    <occ>     is the occurrence number of a value to be used in a multi-value) h/ ~% \7 \( \, R/ G3 P8 U
              header. This is to be used in conjunction with "hdr_ip(<hdr>)",
7 L1 k! W1 X, h1 o2 d# B$ p# c              in order to specificy which occurrence to use for the source IP
7 \4 C% o  O7 R" ~9 L% U              address. Positive values indicate a position from the first
9 j# T2 o0 @5 w) K7 ^              occurrence, 1 being the first one. Negative values indicate
& U6 U8 x. T5 C8 ?              positions relative to the last one, -1 being the last one. This. W0 z1 {/ W( H6 o1 l8 E
              is helpful for situations where an X-Forwarded-For header is set
" d$ Q$ m. y7 x              at the entry point of an infrastructure and must be used several
4 }5 o" X" u9 k# t              proxy layers away. When this value is not specified, -1 is
: W; ^$ _* D- U* l              assumed. Passing a zero here disables the feature.* k# R/ |' @% H: b8 I, m
  R- x3 P8 I, h% w" L
    <name>    is an optional interface name to which to bind to for outgoing
* u- s6 o2 G; {+ n' V3 N& P8 o              traffic. On systems supporting this features (currently, only" n; E- i3 D4 g  A
              Linux), this allows one to bind all traffic to the server to
: ]  W7 r/ o4 W. q- |              this interface even if it is not the one the system would select
0 @; `+ T7 \* l4 ^              based on routing tables. This should be used with extreme care.  V. V! N- B: D5 N7 @8 v. K, U
              Note that using this option requires root privileges.: G1 Q, M# q2 A  t
1 a  ?' f+ w1 i& K
  The "source" keyword is useful in complex environments where a specific
# l! ^- `  u( S4 C  address only is allowed to connect to the servers. It may be needed when a* l7 l5 _+ o2 @; Y1 K% K( z
  private address must be used through a public gateway for instance, and it is
/ R8 ^2 N0 N. u( i  known that the system cannot determine the adequate source address by itself.# o: V% Z# x" k

5 p1 O  n! d% |" a& o  An extension which is available on certain patched Linux kernels may be used# s9 l7 l5 M6 `0 h. O* W
  through the "usesrc" optional keyword. It makes it possible to connect to the) y9 l# G( P" ]5 B! A
  servers with an IP address which does not belong to the system itself. This4 z, H4 o; p6 Y9 z# d# G( f
  is called "full transparent proxy mode". For this to work, the destination
9 u8 `4 n! O; Z  servers have to route their traffic back to this address through the machine
) |  v) ^+ O5 F% z% k6 Y) H  running HAProxy, and IP forwarding must generally be enabled on this machine.7 a1 j; q8 U4 O1 b

# }- L- V8 q8 G, ]  In this "full transparent proxy" mode, it is possible to force a specific IP
! q" U, A" n, ^4 x, j% m) m  address to be presented to the servers. This is not much used in fact. A more+ ?# a9 _/ {; K2 ]  n* y
  common use is to tell HAProxy to present the client's IP address. For this,
/ d( i% S7 _: b: {& V) l  there are two methods :
" Y2 s2 c' X; }4 F/ H& y' b2 E
( ~% j, t; _* M9 t3 V7 ^& k, j; Q    - present the client's IP and port addresses. This is the most transparent2 |: o4 N2 f! R: J; s" ~: _8 ?/ _- [
      mode, but it can cause problems when IP connection tracking is enabled on+ `& f9 Z* C3 B/ m
      the machine, because a same connection may be seen twice with different2 t$ L3 z% X; _
      states. However, this solution presents the huge advantage of not
  U$ W, A" w% r2 h3 e' M) V! i      limiting the system to the 64k outgoing address+port couples, because all
' t$ t/ G+ ?' q! S      of the client ranges may be used.( J0 U( B, k* `0 p
7 ?" _1 N3 n7 l; l! }( E
    - present only the client's IP address and select a spare port. This
4 ^' |$ M) @5 ^1 I* m      solution is still quite elegant but slightly less transparent (downstream' o9 Y/ |# a" z. K1 x
      firewalls logs will not match upstream's). It also presents the downside
! X' i+ R7 l# d: @0 ?8 H! U+ Q      of limiting the number of concurrent connections to the usual 64k ports.
$ x) S0 H5 j- O) ~: a/ v      However, since the upstream and downstream ports are different, local IP
9 {' z) V* u# s. y0 e# H      connection tracking on the machine will not be upset by the reuse of the: U- S) J. f2 D9 `
      same session.
8 R4 W% [, g! E# t; n% O: X
/ `5 F5 \  x  L* o9 g/ x7 Z  Note that depending on the transparent proxy technology used, it may be
1 F7 X1 v2 z; ~6 {$ a: {; s) ]  required to force the source address. In fact, cttproxy version 2 requires an0 P1 m! W3 t0 Y2 y9 t
  IP address in <addr> above, and does not support setting of "0.0.0.0" as the0 ^% H8 m9 M; {) s9 D7 u+ [; {6 r
  IP address because it creates NAT entries which much match the exact outgoing
' N& `/ k7 A6 m& c% x3 ^  address. Tproxy version 4 and some other kernel patches which work in pure8 Q6 e  E4 A; \$ D/ K* z. i
  forwarding mode generally will not have this limitation.! Z2 j# d4 {6 }& p
9 h$ Z3 c1 J: n: R
  This option sets the default source for all servers in the backend. It may/ ^. U5 C. h" S7 a' h8 q2 e
  also be specified in a "defaults" section. Finer source address specification5 k8 g, o5 ~/ b* y( {5 Q
  is possible at the server level using the "source" server option. Refer to
4 f: u* e6 X) K: u4 v  section 5 for more information.
$ D* ~8 f) b! i; @7 A
+ E, h' }* \' A  q9 k  In order to work, "usesrc" requires root privileges.8 E, T; H) X) n* h( C

# B+ b1 W8 H: U8 c! D; v- {  Examples :* \/ Q9 k+ g& s' @# m, e6 ^
        backend private
( h7 F8 L! j# l' e. S& w+ ~8 `            # Connect to the servers using our 192.168.1.200 source address
% q' @- Z' Q) F9 o9 e            source 192.168.1.200
3 g6 M: O# K0 J8 g) G6 l6 `5 B, e% H. K& L8 s, L$ u& C
        backend transparent_ssl1; Q2 b( Z  B- u0 P- c
            # Connect to the SSL farm from the client's source address
+ T/ s: M6 k, }+ f8 S            source 192.168.1.200 usesrc clientip
3 B' d. J" O5 Q1 R' }
1 ?0 b( g) Z3 `% E        backend transparent_ssl2* E9 {! N) s0 W4 o) l
            # Connect to the SSL farm from the client's source address and port3 Y6 G* {& N7 {" q, v- v- t4 ^
            # not recommended if IP conntrack is present on the local machine.
+ f. D" o$ e" v8 W            source 192.168.1.200 usesrc client! V( C* o4 j3 I

" Y, ]7 k6 {9 U  ?- L( Q        backend transparent_ssl3
# Z$ \7 l- S4 A8 d            # Connect to the SSL farm from the client's source address. It4 p4 P7 {$ D* q, P# R
            # is more conntrack-friendly.2 g, ]$ l4 {; v" N. L
            source 192.168.1.200 usesrc clientip! Q' F4 X# \# D( G" E/ C+ y, u

0 D8 `4 l! D" Z8 k! J  s/ t, B1 Z        backend transparent_smtp# s6 G/ W: D& Q7 E4 \% A8 @  h
            # Connect to the SMTP farm from the client's source address/port
3 i3 w/ I6 z6 I/ P+ q1 x$ {            # with Tproxy version 4.
# C: K) Q! T( [$ M* q" F7 F            source 0.0.0.0 usesrc clientip5 S+ m& z3 o. {$ s+ e+ F# @
5 @! I* c1 p5 `, x% l
        backend transparent_http
( H( j8 B. [/ I* F, d' w            # Connect to the servers using the client's IP as seen by previous2 g% g5 j" k* I, [+ ~; j, A
            # proxy.: a1 V$ T' r. S: s8 ?
            source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
% E) X/ F' ]) V; A7 S7 J% t, T
  X9 F3 X1 ^5 g  See also : the "source" server option in section 5, the Tproxy patches for
9 }. w; ?8 g- O* t1 s  ]4 h# V             the Linux kernel on www.balabit.com, the "bind" keyword.
( s5 p2 a$ I1 y6 B* U% D/ y; o$ t, @2 h% n3 ^: s% c+ g7 [! e

/ l3 E$ Y/ I0 U& }6 l! Psrvtimeout <timeout> (deprecated)
, ?% z, [3 H, E; d  Set the maximum inactivity time on the server side.' B4 L2 P0 G4 P, _3 e- ?
  May be used in sections :   defaults | frontend | listen | backend
' R9 X' }* J& Z$ f                                 yes   |    no    |   yes  |   yes
8 e, q8 F% G5 a& `$ L: A2 X* w4 t4 \  Arguments :+ G  \* _' k. \/ \! {. c
    <timeout> is the timeout value specified in milliseconds by default, but
& T; I9 r* N/ Q              can be in any other unit if the number is suffixed by the unit,
" t- S- k& j4 G& C! J% K2 Y1 H1 Y              as explained at the top of this document.& @2 e' y  k) {1 c' m7 V. d$ L' R
! f( T* P, k* w4 W# q* Q
  The inactivity timeout applies when the server is expected to acknowledge or
! |6 Z6 t* ~9 W7 e  send data. In HTTP mode, this timeout is particularly important to consider+ p6 Z; p' v$ A7 s, v$ u- b$ y. _2 v% B+ L
  during the first phase of the server's response, when it has to send the1 O0 q, z  t5 G$ _3 M
  headers, as it directly represents the server's processing time for the9 b2 ~0 O8 I9 g. D. F7 B
  request. To find out what value to put there, it's often good to start with
0 |: H% d$ O) X5 g1 p  what would be considered as unacceptable response times, then check the logs
( ]  r' m; H8 i. _  ?0 b  to observe the response time distribution, and adjust the value accordingly.
  I- f" h' l; \/ O$ s! i) K9 J  Y
  The value is specified in milliseconds by default, but can be in any other- k) G7 |4 n/ y0 P1 o
  unit if the number is suffixed by the unit, as specified at the top of this
2 c% c! P, }: o/ d) m  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly, n* l8 G' Y+ ?- d* [( n
  recommended that the client timeout remains equal to the server timeout in1 N  T1 n% H2 _4 {
  order to avoid complex situations to debug. Whatever the expected server
! ^0 f) [( p) I5 I  response times, it is a good practice to cover at least one or several TCP
/ p, P# q7 Y( C. F6 Y; G& t  packet losses by specifying timeouts that are slightly above multiples of 3$ r/ o) [' b4 z5 t
  seconds (eg: 4 or 5 seconds minimum)., o9 L2 y7 A% Q' X7 ]) B5 W

8 j* [4 m' L! C! [2 G8 f  This parameter is specific to backends, but can be specified once for all in! ~. @! Q+ v' q
  "defaults" sections. This is in fact one of the easiest solutions not to
& w; p9 I; z+ ~" |  forget about it. An unspecified timeout results in an infinite timeout, which1 ]$ Y4 q0 V  s- V& q& u
  is not recommended. Such a usage is accepted and works but reports a warning
' j; U+ K7 P" p0 s& q5 @  during startup because it may results in accumulation of expired sessions in6 o* x; w( i+ o# n- b# C% h5 l' `
  the system if the system's timeouts are not configured either.
9 ?& |# L! d  s0 @+ {4 y  ~1 I4 `. X9 N% t8 ^
  This parameter is provided for compatibility but is currently deprecated.3 A" t7 H% \! U! Z
  Please use "timeout server" instead.: ]# S+ ?. T/ W8 w; I/ k# C; j

6 }) b9 X9 j  ?5 g$ ]7 O1 e/ Z  See also : "timeout server", "timeout client" and "clitimeout".
% {8 F* \" Q( N' X/ D8 F: ?+ O: e, Y! \0 Z

7 V$ V1 Q$ \, ?9 w6 m5 _2 e% \stats admin { if | unless } <cond>
, C- a8 q  E4 D, X, S# E& f1 d  Enable statistics admin level if/unless a condition is matched
: x. J0 L7 w( `4 S( n4 x  May be used in sections :   defaults | frontend | listen | backend
. |9 r( r7 S' u9 h- D9 R% T, P                                 no    |    no    |   yes  |   yes) Z) i8 V! Q- I: f2 l

1 Q5 e/ Q" J9 u5 f* S  This statement enables the statistics admin level if/unless a condition is
+ P: K# c) q- j  matched.7 X$ W( q" s, E
& F4 @7 [4 s( a- S7 x: e% x
  The admin level allows to enable/disable servers from the web interface. By. k! y0 U. a% V4 F' D
  default, statistics page is read-only for security reasons.+ W7 v# X4 n) D& ^
3 l6 k: I' X' ^) b9 U2 a: R
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
3 @0 x" X3 m" Y& V4 t         unless you know what you do : memory is not shared between the
; {  x: r3 z5 E8 ^         processes, which can result in random behaviours.
/ @. b$ {/ c8 d" `
  _+ `$ i- ?8 L3 S$ u  Currently, the POST request is limited to the buffer size minus the reserved
$ J3 L* ?# H) Y6 X1 D1 h0 ]8 q  buffer space, which means that if the list of servers is too long, the
  f$ o1 Q" j9 b3 H  request won't be processed. It is recommended to alter few servers at a0 |0 N( A) a5 Y$ J' J
  time.
: v9 p+ a+ u- p4 m/ s
5 E1 i$ C2 R( E/ L4 f' u& V  Example :2 V. y* B) f, a; T. V2 Z, i
    # statistics admin level only for localhost
) `) W& a) A0 A+ W    backend stats_localhost
! b& M9 d; S* n        stats enable
8 V0 }& v- z& X7 i: x1 ]        stats admin if LOCALHOST! D' A/ b7 A& N& U& K9 A( Y
( Q8 z! j+ u( q8 Z* {4 u$ r. N
  Example :) s# q; ?6 j* O! K
    # statistics admin level always enabled because of the authentication
( H3 _% e9 _& T- V% s! W    backend stats_auth
- B& o6 ?1 N  f  N6 E7 J' o        stats enable$ X& O: y- R0 y+ C, P
        stats auth  admin:AdMiN123
! d# S" i8 H) D. |( h        stats admin if TRUE* h2 ^" O' Y4 H4 p: i1 \% T% ~
; F6 Y0 G, Z/ t2 i; x4 k- v3 c" f
  Example :
4 ]4 S) R( j" D    # statistics admin level depends on the authenticated user+ p/ p) w) ~" [7 e7 z
    userlist stats-auth
' O' m# W$ O" D& n9 B  \3 x9 l        group admin    users admin5 k; W% ^# _) }" W6 v& D2 d; G8 r
        user  admin    insecure-password AdMiN1236 v) w+ `* y" s
        group readonly users haproxy" I$ ^4 R! v. s# R, J
        user  haproxy  insecure-password haproxy
8 W, J0 S* F( F) G$ w3 ~* R  t9 }0 A. S. E0 Z7 x: W# n4 U$ i
    backend stats_auth+ ~4 Q+ Z$ ^& J: w
        stats enable
: a0 {2 S5 y* j" P        acl AUTH       http_auth(stats-auth)
! p4 s/ \0 i+ s5 q% L        acl AUTH_ADMIN http_auth_group(stats-auth) admin' I2 H0 ~1 T8 w5 O* l% w
        stats http-request auth unless AUTH* Z- n) h- D6 U% }! b0 K
        stats admin if AUTH_ADMIN
! a" J) p) }! k& j7 }. x5 r0 i% h4 o$ u( i. t
  See also : "stats enable", "stats auth", "stats http-request", "nbproc",6 i2 c7 [& i- D* F. Q; u
             "bind-process", section 3.4 about userlists and section 7 about& G- s2 i# [, b3 ?" p; ~
             ACL usage.
4 W" i& D; K2 ~, k& ^: B5 M7 h" A% P

+ [* W% H- y% e5 k2 h7 M7 ]4 estats auth <user>:<passwd>
/ Z2 o" }6 F5 R1 A9 _+ T9 Y  Enable statistics with authentication and grant access to an account
6 I" p( Q* s0 b; D  May be used in sections :   defaults | frontend | listen | backend8 ^/ a( o3 o# M/ Z* {9 w. }
                                 yes   |    no    |   yes  |   yes
* Z, m5 N# Q! H' B  Arguments :
5 v8 x& }* p' D& g  L* k6 }    <user>    is a user name to grant access to4 N2 h( M, P" y! q; _  ^  n

+ t: Z% I+ |% M8 X4 B    <passwd>  is the cleartext password associated to this user
/ n& Z8 J* r5 l5 M8 n8 X% G$ b* G# Q$ d
  This statement enables statistics with default settings, and restricts access
1 R6 A( }! P" y  to declared users only. It may be repeated as many times as necessary to( e8 c0 v& A8 Z3 R6 \
  allow as many users as desired. When a user tries to access the statistics
" k8 r6 e0 v0 a. V% T) \- q# D  without a valid account, a "401 Forbidden" response will be returned so that
! c! E, e1 U2 a2 H5 Y3 ~; ^7 f0 Z& }  the browser asks the user to provide a valid user and password. The real  Z( r4 ~6 o1 J; @8 G' o$ l
  which will be returned to the browser is configurable using "stats realm".* a; F3 `; Z" B" w+ T' G% j) L' s

* u8 K/ T" e" [7 C# h  q* I9 y4 t  Since the authentication method is HTTP Basic Authentication, the passwords( B" |; q  [: s: l/ t+ P
  circulate in cleartext on the network. Thus, it was decided that the
; d) N: R2 t$ ]9 x6 S  configuration file would also use cleartext passwords to remind the users) Q' v& R) G: F) l: e
  that those ones should not be sensitive and not shared with any other account.
& W& X5 S3 X) ~6 @; f, C) @' `6 Y6 c. N3 m
  It is also possible to reduce the scope of the proxies which appear in the
! A: u5 x! Y0 q( s  report using "stats scope".2 t) L8 U3 z0 F" i7 I. ]

9 Y% l2 K& ]: |# ]6 E  Though this statement alone is enough to enable statistics reporting, it is
* ?- Y; l  B7 ^  recommended to set all other settings in order to avoid relying on default
9 F' L# k& s; d. @: `! Y+ p  unobvious parameters.8 t! X3 G8 J! b( a* p8 @

- i0 S' m. J, V9 g; l. Q# r1 E. H  Example :
% E. ^4 }- }- F: K$ Z    # public access (limited to this backend only)
' w: i  b& D+ b1 Y+ d    backend public_www
9 ]& e4 k" i4 |" I        server srv1 192.168.0.1:80
  p( H' w# i" p$ ~. _7 ]        stats enable/ E, a/ v% ]# o$ X1 b3 B" S
        stats hide-version
0 y/ W, Z4 B, Y2 n: a        stats scope   .& x$ }+ l8 Q  X" c( Z8 q8 E1 i
        stats uri     /admin?stats
) v7 ?3 Y3 c: j- ?' O  u+ w1 z        stats realm   Haproxy\ Statistics
9 w. D5 M" ~" [2 n* Z4 O        stats auth    admin1:AdMiN123' p. G# S" @& C2 J' W$ X
        stats auth    admin2:AdMiN3217 ?6 z5 k( \7 j  z% e: s9 k

7 O  q* }; ?; \9 B    # internal monitoring access (unlimited)' b* o/ Q7 R$ q* `4 `6 o3 f% \
    backend private_monitoring
5 r* a$ h) @& m5 Z        stats enable
9 W4 R) F! U, x2 x3 X        stats uri     /admin?stats# i: j9 m" `2 y% |, ?
        stats refresh 5s" n; {3 K1 Q6 G" J8 C7 w$ f- J

" \3 [! {: ]4 B) f' G  See also : "stats enable", "stats realm", "stats scope", "stats uri"
, i+ S6 y! [  `3 G) y2 o- k; _% D6 T% P

6 Z4 o+ J  M" a" s( k2 lstats enable
2 ~) ^4 Y' W9 j( L0 v6 b0 m2 W  Enable statistics reporting with default settings$ F9 j  z6 e8 e/ q* f' U8 `$ @' l
  May be used in sections :   defaults | frontend | listen | backend' ~/ h) V! S9 W2 x' L5 O# C
                                 yes   |    no    |   yes  |   yes
$ [2 p# ?, [; K3 Y/ z$ ^3 }  Arguments : none4 B! p' u& i9 d0 F+ k$ {: G* }$ ~

2 h# P  D% f6 s7 _2 h3 E  This statement enables statistics reporting with default settings defined
" ~+ G8 K' @! q: x$ F  at build time. Unless stated otherwise, these settings are used :
0 [9 T  x; Z: x+ d2 B    - stats uri   : /haproxy?stats
& P8 u* h( b7 Z1 t: x* U    - stats realm : "HAProxy Statistics", I1 D+ C3 U3 w$ L$ R0 `# {
    - stats auth  : no authentication2 c( ^2 \4 U: J8 u
    - stats scope : no restriction
& X$ U9 P* X& z2 \# i' a0 J
2 r9 ]8 o" g" N6 Q  Though this statement alone is enough to enable statistics reporting, it is
% E  w9 {! X. t) W5 C5 ~7 ?; C* C  recommended to set all other settings in order to avoid relying on default
6 V6 v# y$ L$ F1 {8 P6 p  unobvious parameters.
) T' ^- W9 L& Z$ K: K. X. V6 D9 X7 j$ T  S* O0 o& K+ r
  Example :' ^0 v& Q4 b$ F. x$ N2 A  D; h) L4 \
    # public access (limited to this backend only)5 U: P- q0 `# X3 v0 y* G+ k* {
    backend public_www' `( j. N/ ^7 f9 b, G( k
        server srv1 192.168.0.1:802 B  T; [$ c5 T
        stats enable
, z0 w/ T) t: L/ X+ k. a0 ^        stats hide-version
5 @4 C! M6 ]6 ~; q        stats scope   .
$ L8 v$ Z. Y. m" {, A        stats uri     /admin?stats
$ |$ ]2 X9 y' [+ F+ [) _2 b        stats realm   Haproxy\ Statistics
. \2 d2 Y# r; b& X& {        stats auth    admin1:AdMiN123
9 \% f- I* p/ W* R% l        stats auth    admin2:AdMiN321- i" h1 w: k" A: Z' `; Y0 O2 w
7 p8 b" x# c5 k; {( B$ R
    # internal monitoring access (unlimited)
* V0 Y8 a5 d, U7 `7 ]2 q( F, m    backend private_monitoring% J# Y' `4 C, d9 a5 ^
        stats enable% U% W, o6 ?, D. O4 L9 B
        stats uri     /admin?stats' K  i0 r9 n/ J6 U3 O7 ]7 r* W
        stats refresh 5s
* R0 Z/ L0 F0 ^
6 a2 @2 z& h. E3 C  See also : "stats auth", "stats realm", "stats uri"
4 r( W, ]6 ^* c2 W" E/ |& o$ a4 L
9 O1 g! Q& Z6 c1 ~; H
stats hide-version
4 b7 G- T  Q. r2 t1 Q* I+ t  Enable statistics and hide HAProxy version reporting6 I" P% r7 E9 _
  May be used in sections :   defaults | frontend | listen | backend; v" o0 g$ w8 q* S0 l8 ~
                                 yes   |    no    |   yes  |   yes  B# G7 `4 Q/ Q/ ~9 o& y9 y
  Arguments : none5 |  d% T! \) r& ^
% v% F# g3 O9 w4 g3 J- o: D$ k
  By default, the stats page reports some useful status information along with
$ f5 H$ \" `* }. A6 m  ~  the statistics. Among them is HAProxy's version. However, it is generally- m( ]8 E* G& L& `# ~- T
  considered dangerous to report precise version to anyone, as it can help them9 W* T; E- l- i* z
  target known weaknesses with specific attacks. The "stats hide-version"
- M. g7 q$ f2 n$ g6 T; c; R8 U  statement removes the version from the statistics report. This is recommended4 K$ L9 @# ^) W2 L
  for public sites or any site with a weak login/password.% J( ^$ P) L" H8 `- S: v
7 X! V8 T# D$ W: G$ ^- F
  Though this statement alone is enough to enable statistics reporting, it is1 I; H. Z% a$ h
  recommended to set all other settings in order to avoid relying on default. x/ t' l& T! Y
  unobvious parameters.$ E7 X+ [2 R/ D0 B! [( A* ~

8 w. I; t  P( b3 R  A  Example :
0 G9 y/ X: d  x6 |    # public access (limited to this backend only)
) P3 O0 c) E- f, t% z) A    backend public_www
# R& r' ~2 \3 [* Z) D# v. B        server srv1 192.168.0.1:80
/ d1 f. \( A! U, J- A( U0 z7 O6 W- r        stats enable
' s* G4 h" T6 d- G% \! M- R: g" S        stats hide-version  G' [4 C* F+ }; A. D' j
        stats scope   .- q* N) K6 s2 W+ U+ F( M
        stats uri     /admin?stats1 R: R2 d  V( q5 o; T$ l
        stats realm   Haproxy\ Statistics& O( M$ O7 z5 t( `0 E
        stats auth    admin1:AdMiN123- ^  A6 g4 }$ R/ E
        stats auth    admin2:AdMiN321/ q8 O+ A* p' |% W) ?3 }7 b

) H- P9 S7 D0 p' P4 V6 d    # internal monitoring access (unlimited)- p6 ^0 s! v' d2 [
    backend private_monitoring0 n4 A& G6 a7 i7 Y/ N& G, _. e* y
        stats enable
7 ?$ ~2 {% g9 b        stats uri     /admin?stats6 i( L6 `8 b: ~5 |: [. K( i1 k: `. t" R& Y
        stats refresh 5s# K9 w1 H9 Y' g$ E
! t- A& ]* U( }6 i& ~
  See also : "stats auth", "stats enable", "stats realm", "stats uri"
" W9 s! e: U7 {0 r- j5 V/ S
7 d& c% i' w/ B, R, K# Y4 k: f. P) d) E% M8 O) r( o# q. L
stats http-request { allow | deny | auth [realm <realm>] }
  w; o6 Y/ f; [             [ { if | unless } <condition> ]6 S/ A0 J( r( w' ^- V& K
  Access control for statistics
+ |! L" n3 W, c/ s, _& K' w6 b& P7 S! S7 W1 ]. ?- {
  May be used in sections:   defaults | frontend | listen | backend, f( d3 K; C6 o% w* G6 ?% E
                                no    |    no    |   yes  |   yes
  g; k; G6 G( k* g. @5 x$ a4 @/ M6 e  L7 b, Q
  As "http-request", these set of options allow to fine control access to
$ [9 o* |8 t: _" F3 a! q  statistics. Each option may be followed by if/unless and acl.& d4 I7 H4 X5 d- q7 P" S  X% j/ Z" o+ b
  First option with matched condition (or option without condition) is final.; g$ H  u; [3 D' e* O
  For "deny" a 403 error will be returned, for "allow" normal processing is
& e8 W3 A% V* P6 N# x+ @6 f  performed, for "auth" a 401/407 error code is returned so the client" I2 c* e5 O2 W2 C- m
  should be asked to enter a username and password.
, g5 }) R: E6 M4 ~% m
1 k" q2 e6 I2 |) C1 M  There is no fixed limit to the number of http-request statements per
- R: @+ f$ O; x3 p1 @  instance.
1 @: j! c4 `& p. ~  W6 K& [% c- S% f6 r4 ~
  See also : "http-request", section 3.4 about userlists and section 72 C, B8 c  _9 n: z/ R3 W
             about ACL usage.
! R4 I: N4 S; A) a
- y7 o( i% i  E7 s8 S+ C: D% V/ K. _
* d& n2 Z& R. T( m. `! Lstats realm <realm>
$ F. g, e0 f5 {+ H& m" A  Enable statistics and set authentication realm
! @3 q, k. M! i# R  May be used in sections :   defaults | frontend | listen | backend/ J' a4 R0 w3 Y' X
                                 yes   |    no    |   yes  |   yes
$ V$ M1 Z% ]3 }# B  Arguments :
% u; ~; B8 n( r8 Z" S  Y0 L) B    <realm>   is the name of the HTTP Basic Authentication realm reported to: U, B  n, ?2 N5 F' p1 b3 k
              the browser. The browser uses it to display it in the pop-up9 X" |; l3 c' ]9 M. ~
              inviting the user to enter a valid username and password.
/ `( p- u( \; s* t0 F$ N$ |
, l( x& v; U& w1 W7 ~  The realm is read as a single word, so any spaces in it should be escaped$ u  \6 [) U1 e0 C+ [0 @
  using a backslash ('\')., f( Q! h: n* l" m3 {! a
2 B' ~( a7 U& G0 I4 W5 g6 A0 g
  This statement is useful only in conjunction with "stats auth" since it is  M6 f& [. L) E+ N/ A
  only related to authentication.
5 i' t, O2 w8 [9 p+ b" {' x6 ]! s: k, e! O) H
  Though this statement alone is enough to enable statistics reporting, it is
7 l2 ~" v- T2 c- }+ x( q- p  recommended to set all other settings in order to avoid relying on default( k  ~$ z9 q6 ^: d( F
  unobvious parameters.
" |7 Q& _4 I9 ?9 @1 ^$ L4 k: j4 R/ l8 z! p( a5 N
  Example :
* k4 p5 _8 K4 e. ~    # public access (limited to this backend only)- ~6 [* @  F7 o0 r
    backend public_www
+ _/ I6 f* ]8 F, B' P8 \) }3 R        server srv1 192.168.0.1:806 `% m9 [0 q- \# S
        stats enable
/ d; \5 h+ a; h' N" e        stats hide-version% b6 Z* @7 z( S
        stats scope   .  g) Q  n$ v7 q
        stats uri     /admin?stats
0 l$ j, B9 G" J, M        stats realm   Haproxy\ Statistics
: a$ i3 |# d1 P$ Y; S8 M        stats auth    admin1:AdMiN123
6 K. v& W& q  G" U        stats auth    admin2:AdMiN321- n, Z2 {# n+ \$ h. @7 S

7 S1 J5 y4 S* g1 _4 L    # internal monitoring access (unlimited)* N8 K2 p0 [, d! G' Z8 }
    backend private_monitoring, n5 E' p, I4 C4 `& P
        stats enable
& a) o$ C+ I/ }0 D" e        stats uri     /admin?stats
5 W: f, ?; V( E  y2 P5 m        stats refresh 5s
8 A* r9 {6 ~: c3 j) R  N3 q' s! e# ^% D7 `6 r
  See also : "stats auth", "stats enable", "stats uri"
" Q6 {1 F7 p! v% I4 g
7 h) @* ~0 ^+ }2 f& V( v& u
8 o' ~# w/ n, b- y$ ?( Sstats refresh <delay>
7 K4 T) J# E6 R/ }/ F  Enable statistics with automatic refresh  G' B5 G$ W" K7 O3 Y+ f
  May be used in sections :   defaults | frontend | listen | backend  M2 c+ U- D$ ~& _5 w3 Y
                                 yes   |    no    |   yes  |   yes
3 G) e1 E" K# i+ F0 E/ x+ Z  Arguments :
/ r& a, p/ Q5 C9 A5 S3 Q    <delay>   is the suggested refresh delay, specified in seconds, which will
7 m9 K9 K! e  i" B) Q5 P              be returned to the browser consulting the report page. While the# [' G" v, z# ~
              browser is free to apply any delay, it will generally respect it# `/ }  D( o. `* G& D9 B0 L+ p% j$ K# K
              and refresh the page this every seconds. The refresh interval may
( k; S' N! v; i              be specified in any other non-default time unit, by suffixing the
/ W4 P! x5 _  Q, F              unit after the value, as explained at the top of this document.
$ w, G$ `& b4 \, D% A
: _8 p( r- J$ i9 g" l  This statement is useful on monitoring displays with a permanent page. X7 h# t: g0 N; ~6 N: ]; |
  reporting the load balancer's activity. When set, the HTML report page will
  Y" n; K& ~+ S7 \' z& [. I0 H8 j  include a link "refresh"/"stop refresh" so that the user can select whether
. Y% n5 y& x' y  h6 G6 i! d  j  he wants automatic refresh of the page or not.. j0 E7 b) a- n% ^3 `

6 d. ?2 Q0 f; Q& {( E. R  Though this statement alone is enough to enable statistics reporting, it is
7 m. t, B2 n5 H  q. d  H6 d* i  recommended to set all other settings in order to avoid relying on default
" _4 J! l/ x: o  unobvious parameters.7 u! L1 A, H8 T3 ^% ~+ w4 W

+ W1 y, k1 \# J! x' k; t8 D% @1 d. f  Example :
7 G0 o7 t& [9 m2 T: n3 u  }( x3 m' }8 v# v    # public access (limited to this backend only)
8 J, ?. u# k+ N$ v    backend public_www
# H$ Z3 `9 W0 s1 C* L8 f* @        server srv1 192.168.0.1:801 C) V+ j4 T8 g) `" z; J) x, O
        stats enable
9 L+ S0 j4 U+ w. {% r' }$ A        stats hide-version
7 R8 g2 o7 }7 l0 F2 \$ L3 I        stats scope   .( J9 f4 z* Q, j3 p: x( z
        stats uri     /admin?stats
0 i6 k/ u" h" D/ K9 A        stats realm   Haproxy\ Statistics( `8 A/ e0 L$ B4 R" k4 t( z
        stats auth    admin1:AdMiN123
4 s/ b0 ?/ A* Q* N9 v+ `& e        stats auth    admin2:AdMiN321
( v& r- r& z5 |# i5 K6 Y: C" K6 r1 P* v& x+ T4 ?
    # internal monitoring access (unlimited)4 F3 v* |$ z) b3 ], W
    backend private_monitoring
) N" l" R0 S8 @" z2 B9 x        stats enable6 D8 S3 ?2 b1 o: Y; A  [
        stats uri     /admin?stats
$ j- K6 Y* y! a" G9 \        stats refresh 5s) ]. F/ L! S: j

' |2 M$ \4 {" G" p; Q: j  See also : "stats auth", "stats enable", "stats realm", "stats uri"
% ^( M$ U5 m6 q/ l, `3 L
6 g: t$ [8 \2 y8 c% q
1 R2 l( q0 w' l% v9 I$ Ystats scope { <name> | "." }# \4 ~' R# G  p) M2 B0 ^
  Enable statistics and limit access scope1 i( k" v8 c3 i7 M4 X) n( z" w
  May be used in sections :   defaults | frontend | listen | backend- Z! n1 ]5 x' V7 \+ ^2 x' e* [. K
                                 yes   |    no    |   yes  |   yes
4 q; [0 _# m! [# N  Arguments :  X, D4 H' `1 T
    <name>    is the name of a listen, frontend or backend section to be% ]- t2 c( J, O+ }) G9 c7 @
              reported. The special name "." (a single dot) designates the
2 q& A. p6 ]1 J0 e- e: Q              section in which the statement appears.
7 `! M: m; M4 U7 [  _4 X
8 A* q6 b- t0 ]* i* K0 R3 Q- q- D  When this statement is specified, only the sections enumerated with this
5 A0 B8 l8 @9 F/ u; J# P/ h" N  statement will appear in the report. All other ones will be hidden. This/ n8 l( o% w4 N4 [
  statement may appear as many times as needed if multiple sections need to be
# m3 g( R2 b& b! w* c  reported. Please note that the name checking is performed as simple string: A* b! F* R  B6 ?
  comparisons, and that it is never checked that a give section name really) ~' d; p/ L& F- r- N
  exists.
$ z+ X. x! c  U8 [
% e- o$ O6 H" y3 ]. K" K  Though this statement alone is enough to enable statistics reporting, it is( g8 B4 [; P, Z
  recommended to set all other settings in order to avoid relying on default( E3 M1 A6 r& P3 Q1 E& D8 a9 `
  unobvious parameters.8 y5 Y2 K6 \" D! S4 Q: u$ _
' G; a- A* c) ]# \8 T
  Example :4 E; y7 @1 v" K, {, J
    # public access (limited to this backend only)) N5 ]7 R7 r' f; k6 u; H# {" @
    backend public_www4 P2 l/ Z* h1 A; K) r9 }3 X
        server srv1 192.168.0.1:800 ~3 V* _5 \6 _( K1 \& Z
        stats enable6 q* o; ~& Y- q; n, H! ]6 ?
        stats hide-version9 Y2 h: t# Z) \- x
        stats scope   .
8 y2 l; X: [5 M, M, t+ \( J        stats uri     /admin?stats0 D- s0 R3 z" j# o$ h
        stats realm   Haproxy\ Statistics. T/ D" ?. g, P, `" H
        stats auth    admin1:AdMiN123; M' N; o8 \5 X3 X
        stats auth    admin2:AdMiN321
' G& Y3 w( @% l- _
0 N# _) V3 S$ v    # internal monitoring access (unlimited)
7 M# C6 p6 ]4 v- \: ]    backend private_monitoring
! j& G; j% ]/ L8 o& K& n0 p        stats enable8 [: e( ?3 A0 }7 [/ I$ U) T
        stats uri     /admin?stats
  w; f. w4 c' a3 |; m: c        stats refresh 5s
; {" W* v, u" }6 a0 |; }; j
3 |! O3 N4 l8 i  See also : "stats auth", "stats enable", "stats realm", "stats uri"/ r- Z+ U8 J& [6 a7 W" }* H; N. H7 Y0 e

  ^% w6 J/ r  w) T& g# ?8 F& x
; ?% Y# G9 @- V  r  i' b, J2 ?, Lstats show-desc [ <description> ]. L1 X4 n( a0 T+ }  `) g$ Y( @3 o
  Enable reporting of a description on the statistics page.2 B7 m; N* R! W; v* V" }2 T
  May be used in sections :   defaults | frontend | listen | backend2 K6 I: j5 \% g+ @! n6 M. a
                                 yes   |    no    |   yes  |   yes
: G: f. ]4 s! R' R4 j+ w3 t" _2 y2 G  i" A: c
    <name>    is an optional description to be reported. If unspecified, the
8 `- z% u2 P1 q, A/ c6 E              description from global section is automatically used instead.+ _" `5 |! i. F

( Z3 m+ T5 k' j; B( Z8 h  This statement is useful for users that offer shared services to their. ]+ z) U; J) v( b( |, z
  customers, where node or description should be different for each customer.
/ p6 _) I+ r- ]' Q/ b% o" V4 i
/ m! ?; L) V' T7 d  l: a  Though this statement alone is enough to enable statistics reporting, it is% {9 W9 v+ @( R. q) z5 f$ v& d
  recommended to set all other settings in order to avoid relying on default; `. Y; m; i! p% R: M' [# [
  unobvious parameters.  By default description is not shown.1 u. |/ c' H+ F2 Q: @+ `! j

" S2 d* {, `* `: n0 ]  Example :
" j3 q" \6 J9 }+ ]; G    # internal monitoring access (unlimited)* i. w) _5 i& J0 U; m! a) ^
    backend private_monitoring1 \! x) ?. e. Z2 T/ h, G1 i) R: T6 q
        stats enable7 [/ y  f) V# @, V
        stats show-desc Master node for Europe, Asia, Africa( }$ l; i/ T2 V
        stats uri       /admin?stats4 P" `& x( s7 C
        stats refresh   5s
, j5 F6 s* M  j" C
, |: `' y4 ~; P  See also: "show-node", "stats enable", "stats uri" and "description" in
8 @( k6 [* @5 c& A# Q# A7 z            global section.2 q3 @. {! o& `
& h! ]0 q  K& U; Z  K
* c- ~% J2 h% @( }, H: k
stats show-legends5 N  R/ z! s& i: o& W) @* P
  Enable reporting additional informations on the statistics page :
3 W: F7 X$ u% N; w- @    - cap: capabilities (proxy)- m: U, Y: F& m: g
    - mode: one of tcp, http or health (proxy)
1 _7 i9 I7 I2 u8 B    - id: SNMP ID (proxy, socket, server)
1 {2 e/ C$ x' S  c8 v0 ~- X: `    - IP (socket, server)6 t* e! [. N) h9 K# J6 q1 y
    - cookie (backend, server)
5 Y7 y6 ^, }* p4 B( ?( _: `1 u
, ~5 o3 Y& m! H  Though this statement alone is enough to enable statistics reporting, it is
0 `- h7 n  `, f  recommended to set all other settings in order to avoid relying on default
7 h. z0 q* u& f: c5 ~- e  unobvious parameters.  Default behaviour is not to show this information.' g5 L2 _% {3 [' S
0 M4 M3 r7 N9 m! h: N2 ~
  See also: "stats enable", "stats uri".( |, l( P! m3 p5 s
$ E2 ~$ I. W- k" `

" D2 m8 Z) A! Y3 C- G, {8 \stats show-node [ <name> ]8 D1 t+ ~* m9 f! R
  Enable reporting of a host name on the statistics page.! F! F$ c' Y( Z4 v0 \- y+ N) i
  May be used in sections :   defaults | frontend | listen | backend7 ?( k7 a# ?: C
                                 yes   |    no    |   yes  |   yes  a1 b8 B' G/ b" M
  Arguments:
& ~- G0 e6 `* q+ d    <name>    is an optional name to be reported. If unspecified, the6 _( H8 W0 B% K6 P: q
              node name from global section is automatically used instead.- T7 C: ^- j* F5 g2 j& _+ `

  }. [7 x7 a  n4 ]4 T  This statement is useful for users that offer shared services to their$ u  g# r! ^, E
  customers, where node or description might be different on a stats page
) z! T: W( D( e; i  y+ y! z% e, U  provided for each customer.  Default behaviour is not to show host name.
8 k+ J; e! v. u+ D* d2 f
1 M1 f$ w3 p) p+ r/ u1 k/ n6 N  Though this statement alone is enough to enable statistics reporting, it is
/ c+ M1 S# z8 h* b0 q  recommended to set all other settings in order to avoid relying on default: E2 l3 R/ i6 M2 B  N- {
  unobvious parameters.+ p2 _9 x. t* f1 A: z( k6 Z8 Q
% w9 @, N. d0 ~+ d
  Example:: d0 f1 N% f$ J. ^) L% j0 r& a. Q
    # internal monitoring access (unlimited)& d: k9 q6 B# W  P
    backend private_monitoring+ |+ T% t) g) o+ E( N; u
        stats enable* h) D! R- v5 z8 f
        stats show-node Europe-1
3 x- X) M$ c- M( }        stats uri       /admin?stats
: A; V0 M% m% A% c& a9 M8 w  t        stats refresh   5s% E+ x$ }9 I9 Q$ `
7 l/ Y5 k6 K* {3 F9 G, I" u
  See also: "show-desc", "stats enable", "stats uri", and "node" in global8 R* |+ B. a9 ]/ m  a* C
            section.6 A' @9 y* z$ r  v& l. d

. c& S" L  h- T' [7 O
6 I9 s- t$ g& @5 [/ ustats uri <prefix>7 z  K& S; x0 t3 i6 l
  Enable statistics and define the URI prefix to access them
  N  P4 t* C* [: R& I: F: D  May be used in sections :   defaults | frontend | listen | backend$ A* ]7 b( ?& C8 F( I
                                 yes   |    no    |   yes  |   yes( v( Y' X. y; i( Z* X! ?0 K3 Y6 v" V
  Arguments :
& l6 ^. k) Q7 ]" |) D- d9 Z    <prefix>  is the prefix of any URI which will be redirected to stats. This+ j- {, [+ n( T3 k1 y  a) n* W
              prefix may contain a question mark ('?') to indicate part of a" y5 G. S1 T+ Y6 U7 ^# l4 v# ]5 b
              query string./ Y7 w/ v. \) w. a9 p

, a. \0 t6 F* \/ D# C  The statistics URI is intercepted on the relayed traffic, so it appears as a
$ k  a7 u* E* K& u  page within the normal application. It is strongly advised to ensure that the4 \8 M, l( e: V6 n) W" r
  selected URI will never appear in the application, otherwise it will never be
* o8 }6 f  j" O: S  possible to reach it in the application.
, G2 y8 x3 k" _" c$ r7 L0 T$ x- @, x' {6 U9 p
  The default URI compiled in haproxy is "/haproxy?stats", but this may be
. D, c# l( \* B; f  changed at build time, so it's better to always explicitly specify it here.
- ^* L$ b! I! N% S$ E  It is generally a good idea to include a question mark in the URI so that7 G- \! M# {& U- u( e
  intermediate proxies refrain from caching the results. Also, since any string
6 ~$ K2 V' d/ |' p. C" R' ]  beginning with the prefix will be accepted as a stats request, the question5 g4 Q1 p7 q1 G2 v4 {
  mark helps ensuring that no valid URI will begin with the same words.7 H+ d1 U) _6 r. O: i: M' Y

4 T( c7 b" y; ?1 r% t# E  It is sometimes very convenient to use "/" as the URI prefix, and put that3 l* h  k+ p9 P/ m; K# L6 {
  statement in a "listen" instance of its own. That makes it easy to dedicate9 U4 O& C* ]# a, ~' u7 c4 @
  an address or a port to statistics only.
9 S% _# v/ `5 _- s. y1 A' [: G6 ~( l/ u) N( q/ F
  Though this statement alone is enough to enable statistics reporting, it is' w) s8 y& P( E; S
  recommended to set all other settings in order to avoid relying on default, S  B0 n/ G3 ^4 C8 c! t
  unobvious parameters.7 `$ o" D$ Y" A4 A4 a# d+ J
" b- p% L- Q- Q- d4 h
  Example :
- n/ d. o/ }) h+ @4 k! U    # public access (limited to this backend only)4 Q3 E$ h" P8 k) o7 u9 w/ |
    backend public_www( G7 B& c$ |, b" y" |5 X$ U
        server srv1 192.168.0.1:80/ m$ w* v4 k( P0 _) ^
        stats enable8 U/ ^  g& E& P  ^+ ?& U. C- K/ U
        stats hide-version6 N. G5 f* j1 P  \5 c
        stats scope   .
3 v" u' x" d- k0 ?& R6 N5 |" ~( @1 p        stats uri     /admin?stats
% s; F6 }0 u9 W1 a( b" u" S        stats realm   Haproxy\ Statistics+ T# d5 r% p+ v  U0 B$ W
        stats auth    admin1:AdMiN1233 X5 F- u( x; F5 ^0 T
        stats auth    admin2:AdMiN321' V0 Z- L0 g+ c5 e" W, b
1 p- A0 A& Y, L0 e$ J
    # internal monitoring access (unlimited)
7 m! Q/ h- p" O4 A! ?    backend private_monitoring
- s4 m" g# a1 y: ]        stats enable& ~$ A" U3 Y; y8 @
        stats uri     /admin?stats" ]8 v5 X3 L4 T) [% Q0 y
        stats refresh 5s- ^6 T$ E# L* H

/ A; O( i! T, H3 u  See also : "stats auth", "stats enable", "stats realm"- O6 W8 `1 e1 m

! H$ f4 D2 u( C; T1 }  `. J4 B5 r- F
stick match <pattern> [table <table>] [{if | unless} <cond>]$ o. U8 f) e) y7 s* ~$ J
  Define a request pattern matching condition to stick a user to a server& f& K. Z3 B; R+ c+ c2 m& t$ `
  May be used in sections :   defaults | frontend | listen | backend* }4 q, m0 Z3 t/ v
                                 no    |    no    |   yes  |   yes6 f+ }& d  V3 P! {
  f, E% w# s+ c" W7 S% S0 `
  Arguments :9 |% B+ [2 f/ V& e, o
    <pattern>  is a pattern extraction rule as described in section 7.8. It, l0 s, O1 g& R$ l; h
               describes what elements of the incoming request or connection
! w  Q# C0 z; J               will be analysed in the hope to find a matching entry in a
+ F! y4 ?6 z2 `0 K" j3 t               stickiness table. This rule is mandatory.- \7 H& B* @4 @! `6 }/ E

" G$ b% D- O* K' `2 }: @# g    <table>    is an optional stickiness table name. If unspecified, the same' U0 m& z2 A& J! e
               backend's table is used. A stickiness table is declared using% g. Q3 T% m& W  G# n( ?' c+ B
               the "stick-table" statement.! H& Y) j7 e# k0 Q3 B; T- B

% c- P, w3 c8 m! v4 r# t    <cond>     is an optional matching condition. It makes it possible to match9 X; K7 Y! h1 }8 ~8 f
               on a certain criterion only when other conditions are met (or  ?0 n% _* v2 O4 u5 X
               not met). For instance, it could be used to match on a source IP
$ u  e: X4 A: L4 V               address except when a request passes through a known proxy, in, F( U) j. `3 E6 `
               which case we'd match on a header containing that IP address.
7 d; i5 j' v' H4 j  r$ p
% ?) q; j8 @1 ?$ D9 _2 O, A) h  Some protocols or applications require complex stickiness rules and cannot) q* n% u# ?: |
  always simply rely on cookies nor hashing. The "stick match" statement0 |, ~7 z, ]7 n  ]' u9 o0 F
  describes a rule to extract the stickiness criterion from an incoming request
- W: [4 Q  p0 q  or connection. See section 7 for a complete list of possible patterns and
% F+ d. u. G. l6 @6 F0 L  transformation rules.0 |! f2 g# t2 J) I' c! {

: x' _+ k2 i! `4 X  The table has to be declared using the "stick-table" statement. It must be of  ~8 S/ U3 U& q: Z2 H: J
  a type compatible with the pattern. By default it is the one which is present. ^6 j+ x& H' l3 Z1 y8 O
  in the same backend. It is possible to share a table with other backends by
- J1 {  [$ H, Y2 d  referencing it using the "table" keyword. If another table is referenced,
. x: u; w/ _0 s" ?; \6 k% O% K  the server's ID inside the backends are used. By default, all server IDs
( {( w0 |  F9 Z6 k5 r  start at 1 in each backend, so the server ordering is enough. But in case of
" v5 Q' b( e0 y, ?. E6 ~9 G  doubt, it is highly recommended to force server IDs using their "id" setting.. h4 O) A/ d" P( Q8 {4 w# l
) t$ M- A  P4 u
  It is possible to restrict the conditions where a "stick match" statement1 t" ~* W2 {1 A+ n
  will apply, using "if" or "unless" followed by a condition. See section 7 for" ]( H- U  v. ]% Z7 r4 k9 U9 D* l
  ACL based conditions.
2 d( g& S, w- @  Q9 |
. |- T( [/ f- Y. r4 ]: H. }  There is no limit on the number of "stick match" statements. The first that* q8 ]3 c! b6 b+ x  E! u
  applies and matches will cause the request to be directed to the same server  T: M' D/ J, R+ Q$ d
  as was used for the request which created the entry. That way, multiple
0 v9 [  }+ Y# }6 Q( N+ i" `7 E  matches can be used as fallbacks.- D) `3 F2 J, ~" L& P
9 U6 n, v. z# o5 I$ M
  The stick rules are checked after the persistence cookies, so they will not5 m) `; I5 g2 a8 d; g+ M
  affect stickiness if a cookie has already been used to select a server. That
% ?4 z; C# n' Y' e8 ^" t  way, it becomes very easy to insert cookies and match on IP addresses in* o2 L3 ]; a' U8 Q# a
  order to maintain stickiness between HTTP and HTTPS.0 d9 a4 A  T4 T9 J1 ]$ E: k
9 R8 T0 v6 F7 j" p
  Note : Consider not using this feature in multi-process mode (nbproc > 1)' y2 n2 S7 l: e6 i% a
         unless you know what you do : memory is not shared between the$ ]$ @0 P+ W6 W9 O0 \
         processes, which can result in random behaviours.9 Y' u. r' J; ^! z6 J
  e& _. w2 \0 A4 z; O
  Example :
3 I7 I0 z7 |9 i6 J/ ?' t) a    # forward SMTP users to the same server they just used for POP in the
7 K2 Q+ A9 c! W9 R, _8 E1 G    # last 30 minutes" ~% z! X( ~8 m: U6 e2 N& }1 J
    backend pop# e  n3 t( z9 w
        mode tcp
/ }  A1 f% r+ p& W9 I9 s$ B        balance roundrobin: I% D/ B7 B) E+ S/ j. V
        stick store-request src! p/ Q- g& U+ {5 F& t
        stick-table type ip size 200k expire 30m
2 e( Y. h" k* J( t) n1 T6 U        server s1 192.168.1.1:1106 b4 H" v! |( K6 r5 _  t
        server s2 192.168.1.1:110+ m& U+ c6 p' o' e

+ A; Y; D- h" z& C* u- O; L    backend smtp
. B4 b7 A6 t% b1 t+ A. r        mode tcp
$ j( L. N8 W2 v% u, Z        balance roundrobin
+ Y+ g& V8 l% s! j) W        stick match src table pop1 Y4 Y4 R: }# n" b; b7 }
        server s1 192.168.1.1:25( F/ `: L3 L' ~; G5 H* g" d
        server s2 192.168.1.1:25
- I( Z' R; T/ e6 i1 W$ y: B' x6 _
$ ^, r1 J* L+ v. y9 s7 `6 _  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7$ u% F: c, p* f2 o. |& P
             about ACLs and pattern extraction.9 o- p2 b( O/ K
) k! t7 _+ ~+ p  I% w+ ~) ^; i5 v% a
* l; s& `2 c. V, G" J! M1 c. A+ V
stick on <pattern> [table <table>] [{if | unless} <condition>]/ ?8 W4 c! m# f, I
  Define a request pattern to associate a user to a server
. A% z# R* I* r$ x1 w  May be used in sections :   defaults | frontend | listen | backend
% ?# f' \$ L2 G% B9 G; i% C# {                                 no    |    no    |   yes  |   yes
/ F  a& x- V7 v) _
9 U$ v- M, o; G5 U$ s# v1 S  Note : This form is exactly equivalent to "stick match" followed by( s* r" u. N/ y4 r, W* w
         "stick store-request", all with the same arguments. Please refer
( K  W" J+ a  m; G) w5 B# s/ v         to both keywords for details. It is only provided as a convenience9 W' X# k2 x, x4 s7 h1 N! G
         for writing more maintainable configurations.
" t8 C/ g: B, W. b2 K9 ]7 z% p' b# \  T# _
  Note : Consider not using this feature in multi-process mode (nbproc > 1)0 }; i0 m- C3 @
         unless you know what you do : memory is not shared between the* B0 I9 c- X# w! C8 f! q9 V
         processes, which can result in random behaviours.
: E, j+ Q. ]4 e. Y
  K: X8 E$ E, d! l. q  Examples :
, g  f5 a- A: e    # The following form ...- m) n) q. G- y" O1 l" U6 L
    stick on src table pop if !localhost
+ H/ v4 U( L$ R; ^% ^; A' H% E% Z/ N* h( u( h
    # ...is strictly equivalent to this one :( s' |! L' x. R  Y& _& }$ m6 s
    stick match src table pop if !localhost) W% m3 C7 ~) D& s! D! b
    stick store-request src table pop if !localhost0 {7 j& F( a8 F* b% C  q
2 X' p1 f: N& T5 b+ r- h

" `- m4 l# _+ c! B# M    # Use cookie persistence for HTTP, and stick on source address for HTTPS as
# b, q" @3 M( t1 U# n$ T; i    # well as HTTP without cookie. Share the same table between both accesses.
& V- t8 E" S% O$ W* F+ ?3 R    backend http
$ |( U( o) N# N* z9 P9 N. D        mode http
& E7 Q* D8 o$ s  L        balance roundrobin* `9 q; B; G  T+ Z* M$ b2 B$ |9 F
        stick on src table https
* l0 ~" K0 Y# S" C/ K2 [/ b7 `        cookie SRV insert indirect nocache
) w) W: [: \! P        server s1 192.168.1.1:80 cookie s1
2 c- ~1 ?7 ]9 T& T8 m        server s2 192.168.1.1:80 cookie s2
. b' ?5 ?2 K. T4 |2 l! x
1 v6 E, C  r, G' Z7 K  o: z% B    backend https
+ k' D8 H5 o+ k, `; {; o        mode tcp
+ z# Z3 n& o( ~7 {        balance roundrobin+ q& s8 v- ^0 ^6 z3 k$ m9 }7 T0 K8 j5 y
        stick-table type ip size 200k expire 30m
/ w6 z8 w+ b( g/ r3 f5 u        stick on src( C( `# j. L+ x& n
        server s1 192.168.1.1:443  Q8 s  n0 G; a! Y4 k2 o
        server s2 192.168.1.1:4430 p8 y4 N  S9 ~5 I

* h$ Z- M( A8 |  See also : "stick match", "stick store-request", "nbproc" and "bind-process".
/ N) B0 z- M) ?' h+ s- l
' g; q5 J, ^# ^0 A5 O4 F" X7 L( E  Y7 U, }& A
stick store-request <pattern> [table <table>] [{if | unless} <condition>]' f+ z! L8 H) Z/ W$ H# G# |+ b; c, ~) W
  Define a request pattern used to create an entry in a stickiness table
/ J  \& D) ^+ y6 W2 o. o  k4 v. {  May be used in sections :   defaults | frontend | listen | backend+ S; G* C& `' ~7 h  j5 u/ c
                                 no    |    no    |   yes  |   yes
" @% }" h0 x: I9 z# o
4 ?6 x+ L! A& @; c  Arguments :% x# p. A' |( d9 P* h' t& H
    <pattern>  is a pattern extraction rule as described in section 7.8. It
3 G  ^1 ~& C* F5 [! q               describes what elements of the incoming request or connection7 G2 _3 z! O9 c. t' v. u$ i
               will be analysed, extracted and stored in the table once a
% A$ t* x. c) b$ C               server is selected.$ F) v9 g) {$ }8 S
+ b/ a/ k/ R( _( ^
    <table>    is an optional stickiness table name. If unspecified, the same
. k0 Z" m3 r3 b: g( N" t               backend's table is used. A stickiness table is declared using4 {( K. w( ~: J, P1 O
               the "stick-table" statement.
, N" L8 q9 [" l, W+ ?; g% o1 ]: q; W  X% Z3 o4 f! |
    <cond>     is an optional storage condition. It makes it possible to store
& [- \7 a7 S- E" k               certain criteria only when some conditions are met (or not met).1 }9 I3 o# o1 G' {6 F
               For instance, it could be used to store the source IP address
, Y: I/ z$ ~" a( D) ?& s               except when the request passes through a known proxy, in which4 h/ A8 V) `" Y7 J
               case we'd store a converted form of a header containing that IP
" M% f6 l/ b) i+ ^               address., Z9 [, e; \& J& j
$ T; n: w2 e# i) b
  Some protocols or applications require complex stickiness rules and cannot; x1 N6 q) ~, o# E, r$ z
  always simply rely on cookies nor hashing. The "stick store-request" statement
8 O" s. d/ I% `2 `  describes a rule to decide what to extract from the request and when to do# z1 v: y  ?% t9 R  B4 K: ~5 J2 S
  it, in order to store it into a stickiness table for further requests to
1 e/ L* C" ], i% q2 f7 w$ \  match it using the "stick match" statement. Obviously the extracted part must
- D* ~! {3 V7 T% P5 m  make sense and have a chance to be matched in a further request. Storing a
# V8 Q. I0 z( q/ w. X  client's IP address for instance often makes sense. Storing an ID found in a4 D$ l$ h" m9 }9 T' e9 O! @
  URL parameter also makes sense. Storing a source port will almost never make
' _- w* H0 b& K7 K; y  any sense because it will be randomly matched. See section 7 for a complete  m7 u; S: E! G$ _4 N
  list of possible patterns and transformation rules.3 s; K: S: [6 b) X+ n# R
" ?& ?  u  b) F0 A
  The table has to be declared using the "stick-table" statement. It must be of4 c, j- {9 a7 v% C( m; m
  a type compatible with the pattern. By default it is the one which is present
' K+ h$ [+ N+ \$ p  in the same backend. It is possible to share a table with other backends by
. V. e( L6 `/ ^9 P  referencing it using the "table" keyword. If another table is referenced,9 I% [* \# Z! q- m6 t3 R( \
  the server's ID inside the backends are used. By default, all server IDs
% t: W; L- G( a4 k4 h  start at 1 in each backend, so the server ordering is enough. But in case of
; G% p; p1 }" o4 a" q( \( r: K& Y9 G  doubt, it is highly recommended to force server IDs using their "id" setting.
3 L# |1 Z# D& e8 T' F1 {8 X
$ i+ u+ m, O% M; V) b) x  It is possible to restrict the conditions where a "stick store-request"
* w( N, j2 F8 y0 f/ p$ B- t  statement will apply, using "if" or "unless" followed by a condition. This/ [, [- Y4 n) _( \
  condition will be evaluated while parsing the request, so any criteria can be5 d2 c% l7 K2 \
  used. See section 7 for ACL based conditions.$ I9 P9 C" A! X% m1 ?

7 _1 j: I) I( B8 ]: j+ W. X% D/ d  There is no limit on the number of "stick store-request" statements, but
# M* o& P5 L3 ^* X/ P3 U5 K( p* c7 r  there is a limit of 8 simultaneous stores per request or response. This$ c) e3 W: q2 u+ m$ t9 N7 B
  makes it possible to store up to 8 criteria, all extracted from either the
- O0 o7 J+ ?) [! ?  request or the response, regardless of the number of rules. Only the 8 first2 V" C. T, `; m" B( x4 X! W& r$ `
  ones which match will be kept. Using this, it is possible to feed multiple
( }/ s, b. P! O; {  tables at once in the hope to increase the chance to recognize a user on2 @5 h# l7 U: p# R  ^+ S2 d
  another protocol or access method. Using multiple store-request rules with9 A0 E2 h& R( o9 y7 J
  the same table is possible and may be used to find the best criterion to rely
+ K9 O. q3 t7 w: F2 e3 Y2 B; e# o  on, by arranging the rules by decreasing preference order. Only the first
; m) w: D3 f6 j( b, @) [5 d  extracted criterion for a given table will be stored. All subsequent store-9 O$ c% p$ q- W7 R2 J$ R; u% K
  request rules referencing the same table will be skipped and their ACLs will
, N( w7 f  `  s# S/ }  not be evaluated.; M) R4 |  |" D' d( x
/ G' i7 t8 k: }
  The "store-request" rules are evaluated once the server connection has been: K; ?1 r9 S6 Z# X7 l
  established, so that the table will contain the real server that processed
" r) @; i- U8 _+ t* ]9 s  the request.' X  n! s2 F) k7 `  a+ p" a7 ?

, a* Y$ U6 B0 n) ~  Note : Consider not using this feature in multi-process mode (nbproc > 1)
8 @' O+ C: h2 ?4 a, Q! Z0 Z6 i         unless you know what you do : memory is not shared between the
. u9 {( c* O8 @         processes, which can result in random behaviours.
# f+ g/ K  V2 y$ Y& W5 o' p8 m% x* L2 Q* a% _' D9 q: Y  W4 q+ K% r
  Example :  o& e: ^/ {5 G  Q4 L5 x
    # forward SMTP users to the same server they just used for POP in the
( f( ^& Q" b. y1 ~    # last 30 minutes
8 `- }6 ]" \- q' e    backend pop1 ]2 \; J) E' O  o8 [
        mode tcp
8 I1 o! I& b: o9 @6 L# X& r        balance roundrobin
* Z! k' ]% P: x        stick store-request src2 Q$ h# i% g7 {& C, U; ^
        stick-table type ip size 200k expire 30m
5 w* z' u( D+ X0 P        server s1 192.168.1.1:110% m5 `6 M+ s$ z0 ^% o( z0 Z
        server s2 192.168.1.1:110
, Z' x2 B! u( k! C/ [- A+ G8 Y5 L8 v. f- y( e* P
    backend smtp
9 W) h* n4 ?, S9 q  o9 W        mode tcp
5 V0 ]0 J6 n2 x9 F9 @# q: t        balance roundrobin
9 O' T& q0 r( M' Z% g, @1 I) B6 n        stick match src table pop
. e) H/ O5 D, x8 g3 X  N: ^0 C        server s1 192.168.1.1:25
/ x8 Y, P8 D8 ~        server s2 192.168.1.1:25
: u; x( B4 ^: r  N9 _  _" o- C  t% D
  See also : "stick-table", "stick on", "nbproc", "bind-process" and section 7
# B2 K" g% Y6 S- ^+ S             about ACLs and pattern extraction.
% W1 v' K! ]& n- k5 `
" v) @7 B" K6 z6 w) y$ j) ]) ]
' W2 F  \! ?% E, w( Y4 fstick-table type {ip | integer | string [len <length>] } size <size>
% g: R$ S: A2 i; a6 [/ b            [expire <expire>] [nopurge]- n5 E0 |2 f5 S+ i
  Configure the stickiness table for the current backend
9 a4 D% M4 [9 a9 V8 a9 k( p  May be used in sections :   defaults | frontend | listen | backend
" O! z) X# G4 o3 G" N" t                                 no    |    no    |   yes  |   yes2 P' {; N4 `. ]! F, l4 R' J5 H

6 g( R7 Q( F$ W6 D9 u6 n; Q% b# n9 @  Arguments :
$ C1 I) i  s7 R1 E    ip         a table declared with "type ip" will only store IPv4 addresses.( }4 a  \( I7 x: p* S
               This form is very compact (about 50 bytes per entry) and allows0 T5 l0 c1 G# v2 O
               very fast entry lookup and stores with almost no overhead. This) k( [* d# S# ~3 E2 ~
               is mainly used to store client source IP addresses.; i$ }2 |1 k  p$ ^' H

2 O$ n& I7 Q% H  w5 ~* i2 z$ j: x. X    integer    a table declared with "type integer" will store 32bit integers
( \: Y# s/ \" g% a, g               which can represent a client identifier found in a request for) w( j" k" x* j9 k2 R5 d
               instance.3 v3 P& @; K+ W8 d% p: ?5 k
) a7 U4 \& |6 H6 s% y! P7 ?0 v: \
    string     a table declared with "type string" will store substrings of up
" ?4 w: u" t# @  j               to <len> characters. If the string provided by the pattern# K$ `- ^( {- e2 p* ~$ j+ {/ T
               extractor is larger than <len>, it will be truncated before
+ s# i) h$ b6 `4 [" b+ F9 r+ t3 x/ u; o               being stored. During matching, at most <len> characters will be5 f# d3 V$ u5 D; H2 i" d
               compared between the string in the table and the extracted
- D7 O- a- r1 A0 W( [  b( ]               pattern. When not specified, the string is automatically limited
% M1 l6 ~4 v0 `) {0 g1 l               to 31 characters.
# C+ T) h$ j! z0 L: |( V/ x. \. D& }: b: I
    <length>   is the maximum number of characters that will be stored in a. v7 v7 ]# @0 t% [7 G
               "string" type table. See type "string" above. Be careful when0 N& P: ?& f; n
               changing this parameter as memory usage will proportionally
; d2 K0 A" }) t               increase.
- G) `: G# X5 P' }3 I* l1 _, i% r; t! m9 k
    <size>     is the maximum number of entries that can fit in the table. This; t6 ^4 T- T' a- G% O" C# ~
               value directly impacts memory usage. Count approximately0 B( M$ y0 \6 A# `2 N
               50 bytes per entry, plus the size of a string if any. The size
* ]7 K% K9 ?9 `5 o3 `% b* Z' l               supports suffixes "k", "m", "g" for 2^10, 2^20 and 2^30 factors.
) h; K: f) t+ y! _& I3 ~- H6 X" p  |% a0 ^
    [nopurge]  indicates that we refuse to purge older entries when the table
7 r9 S$ G! [, |' Y               is full. When not specified and the table is full when haproxy  ^9 |2 q$ k7 M! m  k6 P" T
               wants to store an entry in it, it will flush a few of the oldest8 ^( X' T7 V- k1 D. Z  }
               entries in order to release some space for the new ones. This is4 F8 C2 `# ]6 n" u0 J
               most often the desired behaviour. In some specific cases, it% t* \' I8 T4 R
               be desirable to refuse new entries instead of purging the older
, s+ P5 ~8 d, v& Z1 d# R& Y$ H               ones. That may be the case when the amount of data to store is% v1 N$ K1 m" m& k1 K
               far above the hardware limits and we prefer not to offer access
- o0 R( Y# ]$ L( f7 E7 i, M: n               to new clients than to reject the ones already connected. When
6 W( k% {) j) q; i/ G               using this parameter, be sure to properly set the "expire"
# n, v. z1 M& H               parameter (see below).
7 `# Q& j- I+ m
9 C" c( a7 [, J7 S7 {1 H% P$ v    <expire>   defines the maximum duration of an entry in the table since it, {: A# Q% q. }" V) `5 r/ G
               was last created, refreshed or matched. The expiration delay is/ i2 g) C& {/ N9 [; P
               defined using the standard time format, similarly as the various
/ n  P7 i, R! p0 Z- b6 m               timeouts. The maximum duration is slightly above 24 days. See
. Z, G7 J7 H+ Y0 a               section 2.2 for more information. If this delay is not specified,
+ a3 {2 [( d2 `2 M2 m+ X( l6 ^( n& N               the session won't automatically expire, but older entries will
* z4 c7 `8 J3 \5 {               be removed once full. Be sure not to use the "nopurge" parameter: i$ `7 j0 L7 x8 t1 \
               if not expiration delay is specified.3 E2 F# y4 o, K+ l: p7 X

7 g9 L+ |% n, G* f! W1 @6 j  The is only one stick-table per backend. At the moment of writing this doc,
- O. D, E7 K& [+ G  it does not seem useful to have multiple tables per backend. If this happens
( r6 |4 K2 R+ r* U" }0 P) H7 M  to be required, simply create a dummy backend with a stick-table in it and( d4 {1 \) v  l! V
  reference it.
) j1 y$ ?# r. F
9 {  k( v" B5 T3 l& m! E* \  It is important to understand that stickiness based on learning information
! |" W( S; f' I! z) L  has some limitations, including the fact that all learned associations are
/ `  y5 m6 M( W' [& e$ ~' q& B& u  lost upon restart. In general it can be good as a complement but not always
( W* O4 _& l& ^' m  as an exclusive stickiness.1 V7 R+ |- j* `! @. Q3 }

" S2 A+ f4 E$ U4 `, b: `* E. o7 j3 h  See also : "stick match", "stick on", "stick store-request", and section 2.2
1 r3 b; M3 U6 l' a             about time format.
5 {; l1 u5 b5 P3 o( n/ j
* G* L$ w+ _/ L$ W$ s# f9 d$ r6 @7 `) @; ], D
tcp-request content accept [{if | unless} <condition>]: K4 o+ D% o# j% h/ x6 _0 ?
  Accept a connection if/unless a content inspection condition is matched+ S. \2 j$ P+ _9 z
  May be used in sections :   defaults | frontend | listen | backend
& i9 U; `) X; c7 x9 M  ~                                 no    |    yes   |   yes  |   no
0 C& K0 T6 r( [" ?! P- S8 x0 E; ]+ i; A+ n! G5 C  c9 h
  During TCP content inspection, the connection is immediately validated if the" }- }# J& B5 Z. x: e& |, M) H
  condition is true (when used with "if") or false (when used with "unless").- [6 o2 Z# [" S/ Q" I2 n
  Most of the time during content inspection, a condition will be in an
8 m2 s1 s6 |6 ^& r, y, R5 ]+ l  uncertain state which is neither true nor false. The evaluation immediately9 K4 h9 f3 W: a3 ?& ?+ k* P. [
  stops when such a condition is encountered. It is important to understand$ ^6 y+ ?0 R3 Z7 h! @) F- s
  that "accept" and "reject" rules are evaluated in their exact declaration
, q  E$ q. r! H2 t  order, so that it is possible to build complex rules from them. There is no
1 s/ z) {! G8 L( M; r0 p  specific limit to the number of rules which may be inserted.- o' t* ?3 A2 O6 l' h

/ Q* X* V6 t4 l3 i  Note that the "if/unless" condition is optional. If no condition is set on
  O' h# \/ S  [( h, B  the action, it is simply performed unconditionally.
; Z% B9 G1 E/ \& B9 ^9 r! {/ T8 T- \# U9 P9 S  \
  If no "tcp-request content" rules are matched, the default action already is
7 ]6 l( ^1 v+ U  p# V" v4 J4 I  "accept". Thus, this statement alone does not bring anything without another; N( w) `  ]% c, u* |+ c. p7 h
  "reject" statement.
( ~. ?9 ?, r9 a! V% \, k! g% H0 e' K( F6 i5 S
  See section 7 about ACL usage.
, r: M; Y3 I7 \! L) D
3 T/ q" Q5 k& I& u( a0 }2 t' ~7 x, `  n- v  See also : "tcp-request content reject", "tcp-request inspect-delay"0 g* ^/ u6 S. @$ g

, c% J0 \7 r7 q5 D
" b1 f' P9 H8 j2 [6 p4 gtcp-request content reject [{if | unless} <condition>]8 U( d; r# F4 b" T9 j/ ~$ S) Z
  Reject a connection if/unless a content inspection condition is matched6 S4 u+ @4 i! }- Y
  May be used in sections :   defaults | frontend | listen | backend! A; {% z! a  d' K+ @: ]
                                 no    |    yes   |   yes  |   no/ Q! x: F& {  W# J& M
1 q$ L2 C. K0 T$ v
  During TCP content inspection, the connection is immediately rejected if the
# y% n5 g5 C: E. ]2 @  condition is true (when used with "if") or false (when used with "unless").) m  J9 t* ?8 G" }# N2 P
  Most of the time during content inspection, a condition will be in an2 B* A2 s/ q5 l' C& h- o
  uncertain state which is neither true nor false. The evaluation immediately
. _0 G" G7 s/ Z1 y  stops when such a condition is encountered. It is important to understand$ O. K4 ^9 e) {) Y; r! Y" j
  that "accept" and "reject" rules are evaluated in their exact declaration, {* V8 f; s. S
  order, so that it is possible to build complex rules from them. There is no& c3 p( z9 [2 ?. Z' T# H
  specific limit to the number of rules which may be inserted.
3 j/ f/ U, v0 d/ B
2 P% l4 I: \, K  l6 P  Note that the "if/unless" condition is optional. If no condition is set on! d0 G8 r7 q, p9 v  P2 v  t" U' ~
  the action, it is simply performed unconditionally.9 q6 ^/ W5 E. j

* z$ `9 H7 W5 S) T) C  If no "tcp-request content" rules are matched, the default action is set to+ |  v1 Y/ W8 G: @+ R
  "accept".! {+ H' i0 m( u4 @2 g/ ?1 @' z
, S3 o: ~! h- }/ g: f: G/ X  f
  Example:. a! g3 Z3 B6 m* g' T, H
        # reject SMTP connection if client speaks first
& t! f" O! O  g" P; W% S3 F, p# w        tcp-request inspect-delay 30s- @# i! X: |5 g9 H6 n/ ~
        acl content_present req_len gt 0
  Q4 a4 ]; m; o+ Y2 x: v        tcp-request reject if content_present* H3 p4 W$ M& q# `; A( n# A
, y; d: n" N+ z
        # Forward HTTPS connection only if client speaks2 _# E# G9 Z7 b9 p, q! |# X, U% H
        tcp-request inspect-delay 30s/ v8 @  d5 U3 B* M+ x0 h+ T; X; _& K
        acl content_present req_len gt 0  F( ?: J, D6 f7 g
        tcp-request accept if content_present! P) b# h: S4 I+ e" g# t
        tcp-request reject
) M1 r/ l9 Z0 [- P
* t' U/ ]; D0 d- s5 V3 ]7 o5 ?  See section 7 about ACL usage.1 P" U% c# B# {3 n. o. r! u6 k

: Z2 O% }$ F: `$ ^, t5 Y/ {  See also : "tcp-request content accept", "tcp-request inspect-delay". m! X' b7 T  V9 n1 y

& y, F; Q0 o) K
1 J- Z" K2 m9 h, i* htcp-request inspect-delay <timeout>
6 k0 V' a1 M) I  Set the maximum allowed time to wait for data during content inspection
  @& @  m* k. X$ c  May be used in sections :   defaults | frontend | listen | backend9 g9 Q8 a2 f6 x
                                 no    |    yes   |   yes  |   no
; G) p7 ]% w. f2 t  Arguments :
/ A' ~2 C2 Q, r5 r% {5 O8 B    <timeout> is the timeout value specified in milliseconds by default, but
; K; ~* R3 [, Z0 k              can be in any other unit if the number is suffixed by the unit,2 U  I' p* z6 D" q6 m
              as explained at the top of this document.9 u3 I% l, v* Z1 h0 Q1 L3 h4 _

0 s0 S) `5 g8 i" B+ x+ b* T  People using haproxy primarily as a TCP relay are often worried about the( Q' h8 s( D- U7 @4 k
  risk of passing any type of protocol to a server without any analysis. In
' ]: F& R7 Q' H; a; J1 D: O" d4 a' W  order to be able to analyze the request contents, we must first withhold
7 P; |! ]4 w# F- @( e0 U' `  the data then analyze them. This statement simply enables withholding of/ }' q+ x7 o% [/ W. s/ s
  data for at most the specified amount of time.
+ k6 _1 O& X0 P7 \- F1 I3 M% X5 @( p- D: \
  Note that when performing content inspection, haproxy will evaluate the whole
: T, f- d# B9 U- _2 G+ H) n  rules for every new chunk which gets in, taking into account the fact that' L1 y# I6 k1 }1 n0 Z3 z( E4 ~
  those data are partial. If no rule matches before the aforementioned delay,- d9 ]" I* q3 }* b; b9 _6 q8 n
  a last check is performed upon expiration, this time considering that the, u4 @1 s5 Y0 Q: l1 e, b3 g
  contents are definitive. If no delay is set, haproxy will not wait at all
% g2 ]1 ]# F7 B  and will immediately apply a verdict based on the available information.& |; s2 P7 k3 j
  Obviously this is unlikely to be very useful and might even be racy, so such% q0 Z7 v4 a2 X1 z
  setups are not recommended.
5 X# ~! `: A6 G6 r/ N  d
& I0 k; H5 D" e* l, `9 ?$ W3 j: q  As soon as a rule matches, the request is released and continues as usual. If
0 q$ E5 \) f+ v4 f7 }) i4 l) j2 Q  the timeout is reached and no rule matches, the default policy will be to let  [, x8 S% A, f' \1 k0 k
  it pass through unaffected.: D0 n- D1 U3 @
- Z) l0 ^, [: w3 G" `; L
  For most protocols, it is enough to set it to a few seconds, as most clients
' a' [1 D3 a& R' F  send the full request immediately upon connection. Add 3 or more seconds to
# y+ f5 h0 W; \- Q( Y4 Y0 w  cover TCP retransmits but that's all. For some protocols, it may make sense
( h4 Z' S+ T; N! D$ O  to use large values, for instance to ensure that the client never talks
* q: ]) l- j, ~! P" I& [  A  before the server (eg: SMTP), or to wait for a client to talk before passing
0 j$ l' u1 F% e5 u; v  h  data to the server (eg: SSL). Note that the client timeout must cover at
$ Y1 S8 Q( e+ N& c2 P8 K0 j  least the inspection delay, otherwise it will expire first. If the client* _: {2 X0 j7 C/ U6 M) I* |
  closes the connection or if the buffer is full, the delay immediately expires
9 ^+ ?+ _1 d& f! |  since the contents will not be able to change anymore.
' n' t  r) H. Z5 v4 [* L0 f0 r/ o; L! h. S: J1 y
  See also : "tcp-request content accept", "tcp-request content reject",
( {" Q  X2 ?+ j' ?$ S1 `: \" u" Q) d             "timeout client".
- V  e% r3 `/ N6 F* I# o+ J
% a& \0 T" t' B! w
0 A: s2 O  o7 ]' \* Q6 e1 Otimeout check <timeout>, Y9 u# @4 s$ x- Z5 o
  Set additional check timeout, but only after a connection has been already4 ^# V! ?6 Q+ m5 k* `" j
  established.2 M2 a3 e9 a; `& ]5 b, _6 J
' b' y: G: r" o! N; K( D3 |
  May be used in sections:    defaults | frontend | listen | backend/ B; z9 O' x3 T
                                 yes   |    no    |   yes  |   yes
& O  ]$ G( |* Y: g( L3 B+ w; {  Arguments:  F# S! o3 H; w& N
    <timeout> is the timeout value specified in milliseconds by default, but
" B9 W6 \9 t2 j' {" _              can be in any other unit if the number is suffixed by the unit,& v+ s8 z7 ]" p9 ~1 H
              as explained at the top of this document.3 X/ c! |" p4 h$ k% m; A: F" B
* @  F3 s; e2 c: i  C& C& j  F
  If set, haproxy uses min("timeout connect", "inter") as a connect timeout
. E3 B  D5 A2 z  for check and "timeout check" as an additional read timeout. The "min" is
9 f# r! w. k& u9 t2 z  used so that people running with *very* long "timeout connect" (eg. those
8 R! p: [# n9 Z, Q7 P0 I4 p% C  who needed this due to the queue or tarpit) do not slow down their checks.
2 s; _2 w5 q# C, x' a# R' `  (Please also note that there is no valid reason to have such long connect( c; t9 E" k9 w. @5 `
  timeouts, because "timeout queue" and "timeout tarpit" can always be used to
5 u: j9 \, U/ K  avoid that)." v8 e; Y# Q. [
9 |3 s9 p! x8 @9 H
  If "timeout check" is not set haproxy uses "inter" for complete check/ }7 e7 y: X" D4 E
  timeout (connect + read) exactly like all <1.3.15 version.
& I% y# p/ J* p6 g" ^
/ j: T& M4 p- W. C% I  In most cases check request is much simpler and faster to handle than normal
4 F4 M% {+ _5 X  requests and people may want to kick out laggy servers so this timeout should
+ W* b/ [' \  P3 p! s' t" H  r  be smaller than "timeout server".0 Z$ X; x0 R7 A( ^" t( N; {

; x5 Z6 x4 ]) X& `  This parameter is specific to backends, but can be specified once for all in7 F" M# C7 X. y, T0 w; }% x) ]; ]
  "defaults" sections. This is in fact one of the easiest solutions not to' l4 \& o4 Y- {- R& Q; E# p5 ~0 J7 W
  forget about it." e; j) Y& S1 o: K+ j* c

* q! m/ R$ W8 S2 P+ V  a$ P  See also: "timeout connect", "timeout queue", "timeout server",
3 f$ L; N6 P9 ?3 U% u- A- T  g            "timeout tarpit".) i9 y& w9 _! @+ i" n

$ }5 W- M" `; h" s+ C  A( l2 A9 D" d$ b# @! P
timeout client <timeout>
2 r1 d6 w& P- \$ ^3 i/ F1 etimeout clitimeout <timeout> (deprecated)7 b8 W1 F' `4 k& e4 g6 J
  Set the maximum inactivity time on the client side.
$ h$ D5 R- b8 D, u' _3 A! Q6 D  May be used in sections :   defaults | frontend | listen | backend4 H8 e% `* u" x$ E# j1 \% X0 n
                                 yes   |    yes   |   yes  |   no: I9 e8 n  c" H" T
  Arguments :
6 D7 M$ f' s0 `/ ~    <timeout> is the timeout value specified in milliseconds by default, but
! _! b$ B7 k( @( k9 |/ b1 \" B              can be in any other unit if the number is suffixed by the unit,
, R0 A$ ]7 Y9 x4 c& j              as explained at the top of this document.* @$ t$ Q8 v- C$ e, K6 c/ L

4 ~2 M; I3 \+ _  The inactivity timeout applies when the client is expected to acknowledge or
: N4 @/ H5 w* N, y- p" R  send data. In HTTP mode, this timeout is particularly important to consider
& \: N9 w. R( s+ q9 ]% {+ Z  during the first phase, when the client sends the request, and during the  c8 }4 T2 u( C
  response while it is reading data sent by the server. The value is specified& t6 b5 t; Y1 c8 ?$ M6 c. H# j
  in milliseconds by default, but can be in any other unit if the number is, O3 o' s- b. U" D( d. o
  suffixed by the unit, as specified at the top of this document. In TCP mode. [$ u% _; n0 H" T' h' }
  (and to a lesser extent, in HTTP mode), it is highly recommended that the% C! P* L% @) Q8 p; U2 U
  client timeout remains equal to the server timeout in order to avoid complex
' B9 h' W2 Q" @! u! M  U8 d' C  situations to debug. It is a good practice to cover one or several TCP packet6 x) @. N* q) O8 _0 f
  losses by specifying timeouts that are slightly above multiples of 3 seconds
: h" d& n) X1 ?) f9 O3 M  (eg: 4 or 5 seconds).
4 e$ {8 q4 u5 L5 [5 ]& W- g; C0 \* r% b7 I
  This parameter is specific to frontends, but can be specified once for all in
4 k: C: c# |8 m5 i  "defaults" sections. This is in fact one of the easiest solutions not to
  K1 m  e* t4 b" U- q  forget about it. An unspecified timeout results in an infinite timeout, which
0 i/ x, E  e( u5 t1 W  is not recommended. Such a usage is accepted and works but reports a warning
3 {) J% C7 s2 ]7 Q  during startup because it may results in accumulation of expired sessions in# {$ G& W/ e, w) i* Z: z
  the system if the system's timeouts are not configured either.
* a& i7 U! W7 G4 A0 Y
  W8 c% b- j4 R  [& D  This parameter replaces the old, deprecated "clitimeout". It is recommended
) D* ]7 q+ B) Q8 i  to use it to write new configurations. The form "timeout clitimeout" is5 D/ L) \  B* b9 h1 l
  provided only by backwards compatibility but its use is strongly discouraged./ y9 K7 r5 l( ~
& s$ N* M% x( H1 H' [
  See also : "clitimeout", "timeout server".
; C& J3 d: V6 B1 W- w' ~5 g% I# ?+ U7 }/ v* r

3 q* U  T: l/ S7 Z2 x5 G  m9 Z- itimeout connect <timeout>
: b6 X: w- a0 K" v4 r8 i& `! wtimeout contimeout <timeout> (deprecated)
/ c1 I3 f; U4 i1 F  Set the maximum time to wait for a connection attempt to a server to succeed.
6 {' q0 w% _3 [+ X' N' r7 v  May be used in sections :   defaults | frontend | listen | backend
/ u; D5 m0 ~1 V4 {$ D                                 yes   |    no    |   yes  |   yes, v  g; }0 f; x5 ?
  Arguments :
( ]. A+ p$ _# w" [7 q1 G3 Y    <timeout> is the timeout value specified in milliseconds by default, but" w, \/ d8 s' Q% l
              can be in any other unit if the number is suffixed by the unit,
% e0 K1 e- Z6 _1 u1 Y/ ]8 X: z. A+ l              as explained at the top of this document.2 I7 N( _' x# l& G' v

) p! T7 P( @/ k) i* _  If the server is located on the same LAN as haproxy, the connection should be
1 {" T' k/ q+ e' |  immediate (less than a few milliseconds). Anyway, it is a good practice to) ~- }* Q; v) ^  s. U2 c
  cover one or several TCP packet losses by specifying timeouts that are
2 }$ r, k! P) {  slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the
7 |" c0 b  i) |( ^; A2 D  connect timeout also presets both queue and tarpit timeouts to the same value
3 ~  M5 w( }2 n% [' X4 ~" V6 M8 @  if these have not been specified.1 S$ \' X4 N' D3 ~4 A" Q

# l0 a. {% n' R! T/ C5 R  This parameter is specific to backends, but can be specified once for all in0 S# n% M  ^4 z
  "defaults" sections. This is in fact one of the easiest solutions not to/ u& r8 |& V' ~: J
  forget about it. An unspecified timeout results in an infinite timeout, which
) {/ |$ D) w2 ]- u8 c& M+ l  is not recommended. Such a usage is accepted and works but reports a warning# h. O  l' P! N& x7 x4 R- R3 j
  during startup because it may results in accumulation of failed sessions in
9 _: ?5 u3 T( Z1 C) U  the system if the system's timeouts are not configured either.# c+ l' N. X0 m- g; I3 f. A: B
3 Y/ y# @7 L% B" R
  This parameter replaces the old, deprecated "contimeout". It is recommended) @5 k1 a- ~* x2 R1 q* D  r; m8 V2 |9 T
  to use it to write new configurations. The form "timeout contimeout" is
2 O- Z7 e9 h7 R7 j& M* j6 x  provided only by backwards compatibility but its use is strongly discouraged.' N( w  s2 ?1 z% l

9 e, }2 x4 j7 ?. {" b  See also: "timeout check", "timeout queue", "timeout server", "contimeout",
1 y2 t" s4 T  b3 T3 r% `9 A2 R            "timeout tarpit".% B+ G% o6 q5 D  \; l
) N% B" Q0 ]. e- x. j8 C

; u' R; y1 M! q/ [timeout http-keep-alive <timeout>2 c+ |% P. y0 A* k3 U/ R
  Set the maximum allowed time to wait for a new HTTP request to appear
! E* ?) N; u0 y' o  May be used in sections :   defaults | frontend | listen | backend" `' C3 j; N" @/ ]) _- }# d
                                 yes   |    yes   |   yes  |   yes3 Z  T- @) Z7 P+ R  O
  Arguments :
- r$ }2 G: N* }3 \    <timeout> is the timeout value specified in milliseconds by default, but" G  S' `: g2 G' h: c+ n
              can be in any other unit if the number is suffixed by the unit,9 s( \7 I! V5 K! a9 [* [1 U
              as explained at the top of this document./ s9 h1 o) Q' Z1 H3 }" W2 w& |
2 _. J: Y' x) T4 n* K! e
  By default, the time to wait for a new request in case of keep-alive is set
* K$ R: @* o1 u, q& z0 i/ C6 l8 Z  by "timeout http-request". However this is not always convenient because some- k' `- \% @0 \2 T4 H7 E
  people want very short keep-alive timeouts in order to release connections
8 J) L+ d9 @5 F  faster, and others prefer to have larger ones but still have short timeouts
9 k- s1 [! N6 S1 Y, r  c  once the request has started to present itself.
3 x2 I1 U0 _9 `8 x
7 a9 @% R& Z% F: q0 u7 ~  The "http-keep-alive" timeout covers these needs. It will define how long to( b9 z6 N1 L% T9 E3 T
  wait for a new HTTP request to start coming after a response was sent. Once
/ j; R$ }9 q% {  the first byte of request has been seen, the "http-request" timeout is used
3 v; @; [! p+ t5 v  to wait for the complete request to come. Note that empty lines prior to a
8 X' M2 [' d& O8 E, q  new request do not refresh the timeout and are not counted as a new request.
- v. R6 p8 }( ?% V# {4 N1 C7 D* [9 c7 g
  There is also another difference between the two timeouts : when a connection% D* u% ]( @) ?* f3 {# I  q9 o
  expires during timeout http-keep-alive, no error is returned, the connection
. V0 T+ x6 [! D% \) h  just closes. If the connection expires in "http-request" while waiting for a# t4 J" c: D3 A5 X5 |( ?2 H
  connection to complete, a HTTP 408 error is returned.
; P. K4 d4 w' H) S+ c4 g: z1 \8 w( Y4 a- }% [6 d! R$ c- X
  In general it is optimal to set this value to a few tens to hundreds of8 U7 l  B  E1 C7 }0 [( p
  milliseconds, to allow users to fetch all objects of a page at once but" H% y) P3 Q9 O. I  x0 W4 o
  without waiting for further clicks. Also, if set to a very small value (eg:
3 k8 C, X7 v. w. I4 |2 l  1 millisecond) it will probably only accept pipelined requests but not the
" I* l0 H* ^3 [: a" y  non-pipelined ones. It may be a nice trade-off for very large sites running
, P8 o) C6 ?9 O5 H  with tens to hundreds of thousands of clients.
2 s5 L0 K$ v; U. F5 V% u8 ?+ l6 t$ L+ _3 }6 V) Z; m$ e
  If this parameter is not set, the "http-request" timeout applies, and if both
+ V+ T3 q* ?9 j( u4 g  are not set, "timeout client" still applies at the lower level. It should be! m' B0 X) t7 y$ F9 n# `
  set in the frontend to take effect, unless the frontend is in TCP mode, in
& Z' M# F4 d! g2 F1 W8 V( n  which case the HTTP backend's timeout will be used.
$ g& p1 _9 n5 _1 l2 j4 U( j1 I. m8 ]; C3 I3 l% w5 c  p# B
  See also : "timeout http-request", "timeout client".
; H3 ?+ j8 g  q* n) u# i  P9 A+ F1 v; b. M9 Q0 W* ]8 t$ n

% Z$ t8 k% v% V3 ~4 Z2 ^9 Ltimeout http-request <timeout>* [  `& T( ^! n
  Set the maximum allowed time to wait for a complete HTTP request
* ^0 b1 B# W% h  May be used in sections :   defaults | frontend | listen | backend- a  M9 S) k( W) S# |
                                 yes   |    yes   |   yes  |   yes
2 S1 o# S- I2 L) w' u/ V  Arguments :
+ K2 G8 y, z9 I3 c. a! {5 m    <timeout> is the timeout value specified in milliseconds by default, but. ]+ _; k& D' C
              can be in any other unit if the number is suffixed by the unit,$ Z' \! B/ \" T4 U
              as explained at the top of this document.9 a4 k% S1 e% b
' {& d6 h0 w7 H4 E1 m, e# y( A
  In order to offer DoS protection, it may be required to lower the maximum; C1 k& x* A: {. E% ^
  accepted time to receive a complete HTTP request without affecting the client
6 l6 M% J: o% V- f' H" Q  timeout. This helps protecting against established connections on which
" r, u9 s' z, v. l8 X0 R& Y7 \$ p  nothing is sent. The client timeout cannot offer a good protection against: N7 H% T8 g0 r
  this abuse because it is an inactivity timeout, which means that if the
& V) x: U) }) J( [9 r  attacker sends one character every now and then, the timeout will not# J8 W* T; h- z# }! r
  trigger. With the HTTP request timeout, no matter what speed the client: g& c( K3 E: e
  types, the request will be aborted if it does not complete in time.- Y$ Q) @9 |- v+ d  h. q" i

1 E% X. V) U: C1 b  Note that this timeout only applies to the header part of the request, and
7 g7 L3 z& |+ M; j  not to any data. As soon as the empty line is received, this timeout is not; |  V+ P6 X) q, w& D  M! y
  used anymore. It is used again on keep-alive connections to wait for a second
  A( k2 \0 W2 @# b! ?- Y9 s$ ?0 q  request if "timeout http-keep-alive" is not set.  [8 M; w2 f- }/ W- u2 B3 R

& j; j- k4 A! R3 Y: S) G  Generally it is enough to set it to a few seconds, as most clients send the) E2 }& p! E3 v" A6 Z
  full request immediately upon connection. Add 3 or more seconds to cover TCP9 x6 H4 u, v, d1 P' L: ]
  retransmits but that's all. Setting it to very low values (eg: 50 ms) will
) x6 G' A$ |; z  generally work on local networks as long as there are no packet losses. This
: e2 B! u7 p; x* B2 v& y+ t9 t2 m! H3 R  will prevent people from sending bare HTTP requests using telnet.! `, b3 Q" p9 B8 u) c

' X" H5 s8 E4 \' d8 M7 p) f  If this parameter is not set, the client timeout still applies between each
1 {5 Z; ]& O+ V  chunk of the incoming request. It should be set in the frontend to take2 c) w( L3 A# V: ?* C, I7 q
  effect, unless the frontend is in TCP mode, in which case the HTTP backend's
: e" x6 F& q  P, N7 n3 U4 `/ {; z- g  timeout will be used.
* b) c& i6 k; P2 [3 R; @3 u* O! n
/ l$ {# w4 D5 g& L7 F( n  See also : "timeout http-keep-alive", "timeout client".( n4 ~! U2 `, _2 R4 z; H
! m& ~2 g$ N$ L( n' |
7 W# m0 c+ V# ^8 P
timeout queue <timeout>
% H/ s: c  p, W- C5 d& F6 r. v  Set the maximum time to wait in the queue for a connection slot to be free8 t* ^# z- ?) A& j9 u% y" |
  May be used in sections :   defaults | frontend | listen | backend  Y% v2 e. p. F! s2 b
                                 yes   |    no    |   yes  |   yes
& a& m4 m7 Z/ I  Arguments :0 |7 W) Y& p: s" O
    <timeout> is the timeout value specified in milliseconds by default, but7 E  W# U2 Q6 G$ X2 B8 F) H
              can be in any other unit if the number is suffixed by the unit,
- L* Z" A3 Q! r' Y4 V1 X( g. E              as explained at the top of this document.3 E" D9 X5 v& E8 O' l

) K2 t) n) _5 w  When a server's maxconn is reached, connections are left pending in a queue
# x1 u7 u" B8 C( X- G- e% o0 ~  which may be server-specific or global to the backend. In order not to wait# O* u; E7 e* n: B/ o8 J+ V
  indefinitely, a timeout is applied to requests pending in the queue. If the
2 D8 k: t& M9 D  r9 P  timeout is reached, it is considered that the request will almost never be
+ K; G/ }" A4 G- }9 N9 F  served, so it is dropped and a 503 error is returned to the client.
  i8 E& ]9 d% d( l# b4 x( k2 D; h* @* P5 y1 ~9 s/ i
  The "timeout queue" statement allows to fix the maximum time for a request to
& y  s, J# R5 D6 T  V  be left pending in a queue. If unspecified, the same value as the backend's; f9 X5 `- ^: X" s$ l7 S
  connection timeout ("timeout connect") is used, for backwards compatibility
  n4 J% A% Z& w6 Q- w  with older versions with no "timeout queue" parameter.3 ~! l; g1 {" e  X, u

3 h# d" h" [% t, S; j  See also : "timeout connect", "contimeout".
3 t( L1 F3 c+ _3 w8 z$ y# v' I4 z$ S1 t& H% e! e, G6 N
9 l  x/ y3 R+ J! d
timeout server <timeout>
9 q1 _) y$ y0 Q0 }  z$ ftimeout srvtimeout <timeout> (deprecated)4 g3 G% Y8 J# u5 |
  Set the maximum inactivity time on the server side.; ]! b* _+ }$ J& q6 m) H
  May be used in sections :   defaults | frontend | listen | backend
3 k: D$ y( R6 U/ E1 T' a5 M$ A- q                                 yes   |    no    |   yes  |   yes- Q* y0 V+ s$ \+ z$ \* ^7 B8 j4 L
  Arguments :9 o: d9 l5 P% L+ e# I
    <timeout> is the timeout value specified in milliseconds by default, but2 e3 K2 ?1 C0 `9 Z6 D
              can be in any other unit if the number is suffixed by the unit,
7 G& M" V; c4 \# o! g/ E; |4 a              as explained at the top of this document.
! l8 @3 ~" B% v% F( W
0 q  X, e$ P4 q5 Y; k4 ^# b" t  The inactivity timeout applies when the server is expected to acknowledge or
/ {; Y( Z3 R1 S8 U0 F2 {  send data. In HTTP mode, this timeout is particularly important to consider+ Z+ ~# F  W, ^! `' }
  during the first phase of the server's response, when it has to send the
; M+ u  E8 g7 G, L# z7 C  headers, as it directly represents the server's processing time for the9 G( g8 ^2 w' o, D# v; I* O& r3 @) B
  request. To find out what value to put there, it's often good to start with) A- J9 w: w6 k! C9 x# c
  what would be considered as unacceptable response times, then check the logs
! Q( N% x) U; N& C. L3 j  to observe the response time distribution, and adjust the value accordingly." P1 `" X% U  x
6 @$ }3 Z& O  T* ?" _9 a
  The value is specified in milliseconds by default, but can be in any other
& y4 \) y  s7 S+ t9 _# i  unit if the number is suffixed by the unit, as specified at the top of this' ]- N( x! g3 h) R+ [
  document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly
$ p; A# `0 K0 h- E! y" e+ e3 Z  w/ k/ U  recommended that the client timeout remains equal to the server timeout in7 ^- F# q" N5 E; m; a' I5 W
  order to avoid complex situations to debug. Whatever the expected server0 ^3 b) O2 r0 P9 Q; l% k
  response times, it is a good practice to cover at least one or several TCP
3 f1 P: q- L6 ?5 _6 E  packet losses by specifying timeouts that are slightly above multiples of 3
/ i# O/ B& t& H) G  seconds (eg: 4 or 5 seconds minimum).
4 o& j6 [$ R' l: a& L  p$ g) x; ~+ }. s+ g8 n: o! G
  This parameter is specific to backends, but can be specified once for all in; q9 o) _8 o3 u% \! P+ V
  "defaults" sections. This is in fact one of the easiest solutions not to
, i' ]/ p) ^! y1 c  forget about it. An unspecified timeout results in an infinite timeout, which
1 ]5 A7 M% g# L  is not recommended. Such a usage is accepted and works but reports a warning
& P# r+ g  I1 U$ Q, p( l6 Q  during startup because it may results in accumulation of expired sessions in
7 {/ [) y4 \/ Y( Z7 e  the system if the system's timeouts are not configured either.* f0 ~1 W! L8 L4 a# W3 Y* |

+ R( P+ E, y: \8 K: w  This parameter replaces the old, deprecated "srvtimeout". It is recommended8 ~4 s% a8 d5 g
  to use it to write new configurations. The form "timeout srvtimeout" is) s6 D" A+ z7 i5 f; M
  provided only by backwards compatibility but its use is strongly discouraged.9 f! x9 G4 d0 |. A: {* C5 T
0 V: z: C/ G) \* f; y% K5 U
  See also : "srvtimeout", "timeout client".
8 ?$ ^, R2 x( q! f, ]) O5 u. i" h% \0 u/ U2 E9 l. l- C8 v
' f  |2 Q" w) G! @% }+ p: z
timeout tarpit <timeout>
' B% R. |: f& v5 L& b  p; {5 W  Set the duration for which tarpitted connections will be maintained
2 ~) |2 ?* |0 F. r$ a4 r  May be used in sections :   defaults | frontend | listen | backend
7 a; J- W' v* x4 r& _* t. h9 e                                 yes   |    yes   |   yes  |   yes* ?2 Y6 E, ]& z1 g" y
  Arguments :
& N8 {0 k4 ?1 g) l' c# J9 ^    <timeout> is the tarpit duration specified in milliseconds by default, but& U; a5 ?- x" x$ b! F- _# R+ [/ b
              can be in any other unit if the number is suffixed by the unit,
' ]. i/ B  L+ }, H, U$ s              as explained at the top of this document.1 i5 C) W5 N. v
7 {, y  L  v% M8 s2 t7 r. b# o
  When a connection is tarpitted using "reqtarpit", it is maintained open with" f$ Y8 U, z9 t+ R: c4 n
  no activity for a certain amount of time, then closed. "timeout tarpit"
; K1 b) B. g( E, o: y7 F1 `  defines how long it will be maintained open.+ z; H0 X8 d$ I$ O, g$ ?# W) H

% B9 P7 ~" y# H$ q9 y3 |  The value is specified in milliseconds by default, but can be in any other
) w* W8 M3 d0 y5 l  unit if the number is suffixed by the unit, as specified at the top of this' Q! Z" x( L( p1 @
  document. If unspecified, the same value as the backend's connection timeout0 Y0 K5 _1 }0 Y1 h+ K. ]3 F
  ("timeout connect") is used, for backwards compatibility with older versions8 F( q% Q  w/ Q4 z5 X# u$ {
  with no "timeout tarpit" parameter.
8 N. z0 i  H  [! h
" T; C0 ~* x% T+ D- D0 f0 N& ?' r  See also : "timeout connect", "contimeout".0 C, x& }# \; t7 O! J: P1 f
2 f' |& k, }, e+ \7 S. J
2 N4 ?( z/ i0 b9 |% u" }
transparent (deprecated)
1 n# X- c& q, w# h  Enable client-side transparent proxying! _0 r% k; l/ C4 [- F- V; _
  May be used in sections :   defaults | frontend | listen | backend# }( l9 S5 d2 n: G/ `
                                 yes   |    no    |   yes  |   yes3 T+ s6 {( y. a4 w2 [2 J
  Arguments : none
/ ^6 }7 W: {6 k8 p6 H3 ]: W2 s7 {3 v5 H& l# Z' a' c  J$ y4 R
  This keyword was introduced in order to provide layer 7 persistence to layer$ S! Q; |- N7 d( \5 z. w6 e
  3 load balancers. The idea is to use the OS's ability to redirect an incoming3 y" M7 W% F+ X' |. B) h
  connection for a remote address to a local process (here HAProxy), and let
6 M3 r7 d- P  T5 Z: T  W! t8 ^  this process know what address was initially requested. When this option is
  r: e8 x0 I" t6 o7 B3 I, Q- E  ^  used, sessions without cookies will be forwarded to the original destination" x1 ^# w5 G+ U# r
  IP address of the incoming request (which should match that of another
$ W8 U/ J( O  J2 s' b) v4 D  equipment), while requests with cookies will still be forwarded to the2 T) d$ _7 [9 g4 \' z) O
  appropriate server.
% S* U" o2 l$ j. K' P& I- f
; S! y. E" P/ y  @% ~/ f  The "transparent" keyword is deprecated, use "option transparent" instead.
: \- ?% Y/ A2 x) O* A8 ~" V
0 b) f0 K) E* l0 O" q' ?  Note that contrary to a common belief, this option does NOT make HAProxy
9 r* p2 E. _) u" z% u; p! A  present the client's IP to the server when establishing the connection.
7 C: _6 B( b6 A4 ~
& T7 n0 ?+ y' W/ z3 x  See also: "option transparent"
( Z7 M$ J* a: e% ^/ D' y" N& |0 ?! G9 V: {' w, j

% P0 A3 l; u" l5 N( d- l4 puse_backend <backend> if <condition>
* F* v& w' ]. S1 C7 E7 I% Duse_backend <backend> unless <condition>
" ^. P' E3 Z+ c3 [5 o0 F3 a9 g  Switch to a specific backend if/unless an ACL-based condition is matched.
# G4 n' b. ^+ p1 P* A( k6 ~  May be used in sections :   defaults | frontend | listen | backend
% U/ y! f' S9 u+ S9 y: h. V& m                                  no   |    yes   |   yes  |   no
7 X, @$ X  t. P% I  Arguments :
  r& z9 n6 D- s/ W& I# a# Y    <backend>   is the name of a valid backend or "listen" section.
$ q# b* y5 s8 @9 ], R" Y, l8 S" A% ?9 ]& ^& J# g
    <condition> is a condition composed of ACLs, as described in section 7.; c$ r( ^' v1 Y$ q- @9 W

# E3 f% ~# N; w  When doing content-switching, connections arrive on a frontend and are then
0 a8 C2 H! Q! Q  N  dispatched to various backends depending on a number of conditions. The5 W# Y# a; S" f# P2 v
  relation between the conditions and the backends is described with the+ c- F) _8 m1 V
  "use_backend" keyword. While it is normally used with HTTP processing, it can0 {) f8 m! M& `0 Z2 B/ o
  also be used in pure TCP, either without content using stateless ACLs (eg:9 P5 M- G; k8 O+ l( \
  source address validation) or combined with a "tcp-request" rule to wait for& d& B$ E/ r- T/ x" O7 L
  some payload.% d$ D/ N) t4 C; {
; T" q3 [( T) S8 q
  There may be as many "use_backend" rules as desired. All of these rules are7 v( d; \4 }, h( A
  evaluated in their declaration order, and the first one which matches will  i* s, d3 j. M+ x
  assign the backend.
$ ]9 d0 H) w# W( x9 c  N# {
; A$ G- }( I" `# {) o" f  F  In the first form, the backend will be used if the condition is met. In the
! e( L: I; E2 Q/ {  second form, the backend will be used if the condition is not met. If no
6 s2 o4 E. x# e0 h/ N  condition is valid, the backend defined with "default_backend" will be used.9 ^, f: {5 N' ?/ v) v% r
  If no default backend is defined, either the servers in the same section are
1 E  I* A# g/ A4 }5 I( Y  used (in case of a "listen" section) or, in case of a frontend, no server is
* V# g, j+ u, n! T. n$ [  used and a 503 service unavailable response is returned.8 b8 @" S; }3 A0 [
. U! X+ d6 k5 n! T) g2 P
  Note that it is possible to switch from a TCP frontend to an HTTP backend. In
' M) n. |2 l; f  this case, either the frontend has already checked that the protocol is HTTP,
8 F# a- Z0 {( |1 }* j8 v/ C3 P  and backend processing will immediately follow, or the backend will wait for( S! b( \/ P" t4 ?$ B# I/ i% w
  a complete HTTP request to get in. This feature is useful when a frontend
4 ^0 U! }0 X* m& J; d2 Q  must decode several protocols on a unique port, one of them being HTTP.9 `5 n' p* J/ l! i! n
7 [  C8 O7 ^7 A3 u8 {% p
  See also: "default_backend", "tcp-request", and section 7 about ACLs.
, Q  i/ o/ L) @$ P% _5 T) _# s; {) u, S  O' i
7 H+ B1 ~5 J8 o, x0 y& V/ I. r
5. Server and default-server options
  ]; z8 E8 `2 {------------------------------------2 i. B2 ?# t0 N) [4 N
+ s7 Y# p5 e) j' u: ?
The "server" and "default-server" keywords support a certain number of settings
" u1 g6 U2 w2 w; U" \/ Xwhich are all passed as arguments on the server line. The order in which those
$ Y* E$ E4 s6 \9 a- O4 B5 uarguments appear does not count, and they are all optional. Some of those
6 q* \* l' w7 z. ?settings are single words (booleans) while others expect one or several values
6 @; g1 r+ r" p* p7 aafter them. In this case, the values must immediately follow the setting name.& Y4 R9 L( L- R% P
Except default-server, all those settings must be specified after the server's
+ t6 ?0 n3 F9 W& Z! `address if they are used:
  o2 L! [# b& q; D8 V$ d4 n8 `% I7 ]6 Y5 h) @! y. C
  server <name> <address>[:port] [settings ...]6 g) M; G1 g3 N2 _" t
  default-server [settings ...]$ P( n# q# N/ b. |/ D

; Z7 k9 R, d1 h" I, o6 GThe currently supported settings are the following ones.
+ ~, v- `+ o; y# f0 _% v
) U- n' }/ G4 g2 J2 F& Vaddr <ipv4>
8 o+ [, d* F6 A$ Q* `6 }+ S$ ?  Using the "addr" parameter, it becomes possible to use a different IP address3 `6 c1 C0 K" |1 G3 G1 [
  to send health-checks. On some servers, it may be desirable to dedicate an IP
0 x9 t: n7 P& Q" ^7 J0 w  address to specific component able to perform complex tests which are more# `/ d3 o/ e# o# w( [- G& `) C
  suitable to health-checks than the application. This parameter is ignored if
, V; d* Y8 |4 l9 k: `' W+ N# R! z  the "check" parameter is not set. See also the "port" parameter.  c/ i3 [: E6 r& Z. M

2 c1 m0 ?0 Y& ~) x  Supported in default-server: No
! J: d( l4 B0 U, y5 e  z
% C# f/ T) g2 R% cbackup
$ p1 }5 w9 u; x5 B  T  When "backup" is present on a server line, the server is only used in load4 e% D% |  p  t9 Q7 p9 q6 p( d7 j" ~2 j
  balancing when all other non-backup servers are unavailable. Requests coming
1 _; u2 e- f) B- Q$ D* \, e  with a persistence cookie referencing the server will always be served2 b5 }( ?7 _; g& g# x- K% W
  though. By default, only the first operational backup server is used, unless- Y* \8 [$ h: M4 \+ f. Y
  the "allbackups" option is set in the backend. See also the "allbackups"
9 j$ `4 A  P9 ]- p+ H7 L! d  option.2 }0 C4 }2 Y1 P* v9 J1 l4 O* }
) ]  V7 P& w1 j: ?0 B
  Supported in default-server: No
; N  f: k# J7 ?/ ^1 `
7 Z( T/ y; t4 a. Z( y) ?. R8 E6 jcheck
. ?0 F, U" o$ \9 S6 s2 U* i# C" e  This option enables health checks on the server. By default, a server is0 X. f" M# ]0 g' L( H) ^$ H
  always considered available. If "check" is set, the server will receive! f! d+ E; G2 A8 K/ i
  periodic health checks to ensure that it is really able to serve requests.
* C- a9 P( M# N3 {" h; I  The default address and port to send the tests to are those of the server,
7 S5 y; v6 m8 B7 z  and the default source is the same as the one defined in the backend. It is' b/ ^- @' w( h1 ?
  possible to change the address using the "addr" parameter, the port using the
  K5 y" w( p  }+ b+ @  "port" parameter, the source address using the "source" address, and the9 |" U, G' _' B* a
  interval and timers using the "inter", "rise" and "fall" parameters. The
2 Q* e7 c: y! K  J( V0 {  request method is define in the backend using the "httpchk", "smtpchk",
' @' f) q$ h2 x6 O# h  "mysql-check" and "ssl-hello-chk" options. Please refer to those options and
1 s# K5 O6 [( _1 u: i. _* s  parameters for more information.+ y& |7 A7 i7 W4 C# c6 W& j6 N

* K, o! S: S3 P9 ?' w& b  Supported in default-server: No' b0 y% ]( O+ U# }( T
7 b6 ?% f' O( y( k2 L4 T" Q# k7 x
cookie <value>
7 L  n0 e3 k* {% O+ L* n/ k  The "cookie" parameter sets the cookie value assigned to the server to
# W: r2 N: A% K( r. k/ r3 d  <value>. This value will be checked in incoming requests, and the first
# l9 L$ P8 j6 y4 Q  operational server possessing the same value will be selected. In return, in6 `- z. n' t* A; V
  cookie insertion or rewrite modes, this value will be assigned to the cookie
9 _; r- S( a6 |5 b6 l: _  sent to the client. There is nothing wrong in having several servers sharing
4 @. }% y6 \4 L8 m% t( S  the same cookie value, and it is in fact somewhat common between normal and
+ @, ^) m  X' x. u6 M+ h  backup servers. See also the "cookie" keyword in backend section.
# Q* w- t; `* t/ g4 R! M; A7 m0 |' r% w3 J9 L2 ^0 c; G6 A+ Y: H
  Supported in default-server: No/ f, `8 I4 `/ p
/ \+ O7 H) G2 i1 O
disabled
3 f( \# X, @7 w/ Z  The "disabled" keyword starts the server in the "disabled" state. That means- j8 y, i4 @0 M: V+ k
  that it is marked down in maintenance mode, and no connection other than the
. y2 t8 p0 m; ]3 ?0 g0 K  ones allowed by persist mode will reach it. It is very well suited to setup7 R  A: @$ G6 G+ z
  new servers, because normal traffic will never reach them, while it is still+ |. ~% Q9 k2 y0 m+ P
  possible to test the service by making use of the force-persist mechanism.
1 H. i6 f/ ~) w" Z1 s6 P4 t  u6 n; [( N) V8 b
  Supported in default-server: No) s# U: y  f: ^2 q6 ?
9 I  [, v4 {! U( g
error-limit <count>
6 U, p" Z2 }" X% r  If health observing is enabled, the "error-limit" parameter specifies the9 p6 z8 m' h6 a( k/ P2 \
  number of consecutive errors that triggers event selected by the "on-error": Y$ l/ r2 x, |, X$ Q4 V
  option. By default it is set to 10 consecutive errors.8 L) o  e% ?! Z* @  u0 _
  _& X* ^5 `( V; @: x( I, H, I
  Supported in default-server: Yes
+ V( ^$ Z. c% ~+ u! x! k1 {$ S/ U3 l5 j' i" p
  See also the "check", "error-limit" and "on-error".
4 t0 N- j. L4 B1 J: ]8 ^8 y, }
# U6 r2 F6 t% G0 o; P2 E' `7 ~fall <count>% G& q$ X1 j0 B6 d; x/ ?) p/ R/ t% m" o% V: m
  The "fall" parameter states that a server will be considered as dead after3 W, t% ~0 W9 g4 q% d4 `
  <count> consecutive unsuccessful health checks. This value defaults to 3 if
3 d- ^5 z3 l9 _' k: D  unspecified. See also the "check", "inter" and "rise" parameters., e1 D( I3 @+ {* z( Q; S1 ~
/ `3 V% l4 ~3 f2 o5 {/ L6 z
  Supported in default-server: Yes( d# X9 ^- \. v# A: b, @, Q8 s
  F  n+ o5 Q4 Y+ q9 Q. \' `
id <value>4 x! B) a. E2 n1 t- v# }
  Set a persistent ID for the server. This ID must be positive and unique for
' L. ^, o. d; C3 h) J' X  r9 {  the proxy. An unused ID will automatically be assigned if unset. The first0 S' c9 p7 b, z1 j
  assigned value will be 1. This ID is currently only returned in statistics.8 |4 [( _6 j! o# j1 A1 ?
" W+ J+ i! ~! g; w) u& {3 L7 z
  Supported in default-server: No
, _! y+ N  G, }+ u3 ^1 @3 C8 o7 G% D% Q4 y) u  A
inter <delay>
& h: \6 Y9 ]% U- W2 ?fastinter <delay>
: h' H9 ^' S  o$ E' C9 @2 Hdowninter <delay>! y- b( [! ?  m
  The "inter" parameter sets the interval between two consecutive health checks
2 \( h* j( ~$ ?: s  to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
6 b! j& H* X5 T' x0 f4 y  It is also possible to use "fastinter" and "downinter" to optimize delays# L3 E' `- E5 {; S! A2 Q  |% D2 S
  between checks depending on the server state :7 r% }' E/ s$ ^, X) U+ `: n8 [
# |- \* Z9 T* G* X: G; a/ ^) L2 i
             Server state            |             Interval used7 S2 A/ W4 h/ {- C; K8 \8 ]6 d9 c# @
    ---------------------------------+-----------------------------------------
  N. @2 X' Y. e) F; H  E     UP 100% (non-transitional)      | "inter"
1 X1 @3 @8 n3 {* E% ~    ---------------------------------+------------------------------------------ G: O" i9 r- v! z& b
     Transitionally UP (going down), |
3 X# @9 T# N4 A# B: k     Transitionally DOWN (going up), | "fastinter" if set, "inter" otherwise.7 l1 O6 |& W# K0 j7 a0 g
     or yet unchecked.               |
& g# x8 H3 i" f. r3 J% A0 I9 W    ---------------------------------+-----------------------------------------
- _3 w# e. q, h5 w7 o) E" T     DOWN 100% (non-transitional)    | "downinter" if set, "inter" otherwise., E1 i2 n2 ~0 v7 P! y
    ---------------------------------+-----------------------------------------
7 H' @* [  o' Q7 C6 Y' M3 g. `6 O4 W+ X6 Z8 u+ y/ T
  Just as with every other time-based parameter, they can be entered in any: u7 k4 P, i- M& X- Z) |' p; V
  other explicit unit among { us, ms, s, m, h, d }. The "inter" parameter also
" B2 [  d$ i9 x) x4 F; K: N  serves as a timeout for health checks sent to servers if "timeout check" is) }4 X3 p2 }* z# F
  not set. In order to reduce "resonance" effects when multiple servers are4 i5 ?( I7 ^* z6 i9 l
  hosted on the same hardware, the health-checks of all servers are started& @4 o; i& l- e4 J( n6 G7 S
  with a small time offset between them. It is also possible to add some random
2 p# p5 B& i  O4 x+ A: X8 E  noise in the health checks interval using the global "spread-checks"
8 I: |5 k% h) x; I  keyword. This makes sense for instance when a lot of backends use the same
% v; |0 K1 _8 \( a  servers.0 ?! d  Q. X' e* z. ~

  W3 B0 M% S8 B" }: e  Supported in default-server: Yes8 ~. {) x$ k$ N1 e* @8 v( t

% u4 @2 g2 y0 B( h: Ymaxconn <maxconn>- H0 K, U; o+ z/ ~. Z' ^
  The "maxconn" parameter specifies the maximal number of concurrent3 D; _3 [, B- f6 |9 e+ Q4 `
  connections that will be sent to this server. If the number of incoming1 h' t$ N3 a8 ]! s: q2 v7 D, B
  concurrent requests goes higher than this value, they will be queued, waiting
8 A1 d& A5 Q# S$ t! G  for a connection to be released. This parameter is very important as it can+ F) ?/ r; v6 }- d& w
  save fragile servers from going down under extreme loads. If a "minconn"4 i9 p2 c) O) n; k0 _
  parameter is specified, the limit becomes dynamic. The default value is "0"# l; J4 \* U  b+ P
  which means unlimited. See also the "minconn" and "maxqueue" parameters, and+ R7 G0 a, [1 h% Q  a
  the backend's "fullconn" keyword.+ V) Z; j2 D0 t' r( Z( s

3 o( z3 W9 u' F  Supported in default-server: Yes
& o" [* L( J( y  `9 Z+ _: ]' z( d& h/ N7 [1 \1 y: T- S) x4 Q
maxqueue <maxqueue>' U) q! q7 B1 e2 c1 c* [2 {1 n
  The "maxqueue" parameter specifies the maximal number of connections which, q- T" R* V* i" W! B& ^+ S
  will wait in the queue for this server. If this limit is reached, next
' p8 T8 y+ ]  N5 J  requests will be redispatched to other servers instead of indefinitely
$ D4 q, P$ n5 j3 i+ @  B5 d0 b3 f6 D  waiting to be served. This will break persistence but may allow people to
: z8 b2 J# G0 Y% g  quickly re-log in when the server they try to connect to is dying. The
3 [3 [) I% Q% a  `* [3 L+ P  default value is "0" which means the queue is unlimited. See also the; f- u. e$ z- B( x
  "maxconn" and "minconn" parameters./ z7 e  G8 v# @8 ^- r- L- N3 i1 K

: F/ @! t. g$ f/ q  Supported in default-server: Yes2 X* ]: d( q4 @8 J+ V

1 n& E* [  ^! T8 X1 W4 w, q! \3 |minconn <minconn>
/ A6 v0 @: `5 Y8 C( U  When the "minconn" parameter is set, the maxconn limit becomes a dynamic7 K/ T( G5 c: z# c
  limit following the backend's load. The server will always accept at least
) Y+ Y. z- @; J7 W# W  <minconn> connections, never more than <maxconn>, and the limit will be on$ v6 V  ^( ^* E4 m1 i/ c8 Z" k
  the ramp between both values when the backend has less than <fullconn>
& E2 v1 d$ q3 R' d# p7 r8 _# T; W  concurrent connections. This makes it possible to limit the load on the
  I, a1 D, ~5 o  ^$ R  [  server during normal loads, but push it further for important loads without
+ P1 ~' h( r( y  overloading the server during exceptional loads. See also the "maxconn"" R4 ~, Y+ J3 U( F% u# p
  and "maxqueue" parameters, as well as the "fullconn" backend keyword.7 w* Z% K; v' Z1 w' u$ w; i

0 B9 p- l7 q: Y- e8 n" h, X6 i  Supported in default-server: Yes9 I4 A! D; @0 a, m8 n, z; E5 F& n- W4 z

6 J' X, n1 G- ~observe <mode>
, r" h, P: `! c5 r2 l; {5 d  This option enables health adjusting based on observing communication with" S8 o$ f  M; u$ {# a0 c
  the server. By default this functionality is disabled and enabling it also6 j8 l* x0 F0 Q
  requires to enable health checks. There are two supported modes: "layer4" and6 w# `/ S% D( I
  "layer7". In layer4 mode, only successful/unsuccessful tcp connections are
# t- x9 @5 h; N) m/ }  significant. In layer7, which is only allowed for http proxies, responses; ^/ J; ^5 G3 ^  Q& d' N5 U: D
  received from server are verified, like valid/wrong http code, unparsable5 s/ z+ X& T' W$ o, H
  headers, a timeout, etc. Valid status codes include 100 to 499, 501 and 505.5 g9 k9 v" J/ o3 r
8 B5 K" {; g# Q# C3 N5 }
  Supported in default-server: No
3 N0 e9 A9 |6 ^6 x
% o$ w* X3 e8 x" k  See also the "check", "on-error" and "error-limit"." M& d7 `, q( o
+ ?6 F& N! q: `& C; n; s
on-error <mode>
; u- e' d, j! m( l- R  Select what should happen when enough consecutive errors are detected.4 ?3 }6 R" I* B/ ~$ Z' R+ b5 }7 p
  Currently, four modes are available:
# V1 w0 U3 Z) _% U8 [" l5 S& H7 L  - fastinter: force fastinter# k4 L: g# r! `1 ]3 u% V# D
  - fail-check: simulate a failed check, also forces fastinter (default)
2 e) \$ C& K. x2 L9 q6 @4 J% c  - sudden-death: simulate a pre-fatal failed health check, one more failed
# N0 K3 f; n  Z+ F  |8 h    check will mark a server down, forces fastinter& w. n8 \2 h3 @% N2 i5 |3 D* c
  - mark-down: mark the server immediately down and force fastinter
: n: _! e) f$ Z! a7 R( I9 ]- B
2 G/ h: d5 c) K1 `. c  b8 z- `  Supported in default-server: Yes
$ V9 w* w0 Z/ B! s% R0 I6 M% v9 i. ~" o7 T; o4 j- R# a5 [
  See also the "check", "observe" and "error-limit".
( g) h* I* s+ s; M. x4 Z3 F" d. R* {' j) [
port <port>
  d- ?) R, _" V3 j. X8 w4 {% x  Using the "port" parameter, it becomes possible to use a different port to3 M2 @4 z+ t9 S8 g; l
  send health-checks. On some servers, it may be desirable to dedicate a port
8 U# _; n1 l$ `4 G+ r* n  to a specific component able to perform complex tests which are more suitable# g) l! }  E! h. _% U/ h% u9 ^
  to health-checks than the application. It is common to run a simple script in
9 W) r6 E0 y2 J: E' l& @0 K1 E# T  inetd for instance. This parameter is ignored if the "check" parameter is not7 n' a/ Z  U9 T# t8 m/ ~
  set. See also the "addr" parameter.
, }8 ]: O, g- G7 X- ~! d; |. y) ?) m' T( g
  Supported in default-server: Yes/ K5 o. s8 R) _( `- y

/ n* G4 S  q, L% Eredir <prefix>
5 @5 G" k6 ?5 H3 [5 K( w  Q  The "redir" parameter enables the redirection mode for all GET and HEAD2 ~( m5 Z# \9 O) C
  requests addressing this server. This means that instead of having HAProxy6 G$ m6 F1 I2 b
  forward the request to the server, it will send an "HTTP 302" response with5 }/ m! A$ n: Z. q6 _/ S9 z
  the "Location" header composed of this prefix immediately followed by the7 x) y+ ^& z, A/ `2 Y( K
  requested URI beginning at the leading '/' of the path component. That means1 h1 P+ `9 f6 f  {  B
  that no trailing slash should be used after <prefix>. All invalid requests2 v! Q. s# H. O/ `& s7 k1 G
  will be rejected, and all non-GET or HEAD requests will be normally served by
! Q; x* X9 f+ _. ]1 A. y1 @9 U  the server. Note that since the response is completely forged, no header
, N8 P$ Q; B5 T3 V/ S; s5 \% V  mangling nor cookie insertion is possible in the response. However, cookies in1 M" G' v6 Y1 V4 S% p( u
  requests are still analysed, making this solution completely usable to direct9 ^4 J+ Q' k% s9 K/ f  c# ^
  users to a remote location in case of local disaster. Main use consists in: ~3 D* n& Z5 e5 h- x+ f8 O; z% d2 Y+ e
  increasing bandwidth for static servers by having the clients directly
) P5 t! m3 F7 h1 M& {% |  connect to them. Note: never use a relative location here, it would cause a
8 p1 t' i5 R5 w  loop between the client and HAProxy!
; b$ s" r8 [! J5 J: J. E# ]" p! v% D. c
  Example :  server srv1 192.168.1.1:80 redir http://image1.mydomain.com check9 b, \- V* D) G/ I2 ]" C& `2 h0 S
9 W+ e7 `% K. D, W+ r
  Supported in default-server: No& b1 ?2 _: E1 X$ O+ H) J  w  H
4 n0 y3 |# v7 ~: R9 D
rise <count>
+ {" _1 \. J) n$ m  The "rise" parameter states that a server will be considered as operational: g- Z4 @9 B0 @+ V# L2 p: G
  after <count> consecutive successful health checks. This value defaults to 2
" E; O  a& a$ H. _" y7 b2 }) y* b  if unspecified. See also the "check", "inter" and "fall" parameters.
3 p4 \6 a; R4 H. a) W  h! ]1 Z6 o" B7 R. a
  Supported in default-server: Yes
2 M- _2 k9 P0 y9 P" v( j
- }8 y& z9 P! J; r! Nslowstart <start_time_in_ms>
& X' w  v$ [0 I  The "slowstart" parameter for a server accepts a value in milliseconds which
# H! |7 v3 t$ I% N. r  indicates after how long a server which has just come back up will run at* t! w) E# C' v  u; l7 S
  full speed. Just as with every other time-based parameter, it can be entered8 M' m. {8 T0 t+ P( n
  in any other explicit unit among { us, ms, s, m, h, d }. The speed grows
8 E% [* Y2 Y4 i- K  linearly from 0 to 100% during this time. The limitation applies to two( A% G0 E) ^+ Q
  parameters :' B: s  q/ h; A3 f) o7 t2 M! t4 e# R

* ^8 U' b6 m$ ^: ?: D1 Z2 m1 L1 U& X' U  - maxconn: the number of connections accepted by the server will grow from 1, z0 ^) y* C& o$ r
    to 100% of the usual dynamic limit defined by (minconn,maxconn,fullconn).; C3 c. x0 D5 `" Y4 u1 `

- \2 y/ H4 E8 A& O  - weight: when the backend uses a dynamic weighted algorithm, the weight8 u( k7 Q  u% J1 P
    grows linearly from 1 to 100%. In this case, the weight is updated at every
9 z1 b8 w3 c6 A/ E0 \    health-check. For this reason, it is important that the "inter" parameter
9 _. K- T( `3 t/ H/ R    is smaller than the "slowstart", in order to maximize the number of steps.
/ {( u$ V  Y) ?2 a1 c; E* _5 q% ^# k
. n! d, {6 q; |6 d1 p  The slowstart never applies when haproxy starts, otherwise it would cause3 z- n. K3 \9 {1 z
  trouble to running servers. It only applies when a server has been previously
  N, v1 ^- n# b4 \- o6 N6 j  seen as failed.( E6 Y* }  W# b8 m, K) ^( l1 _

4 Q# T! f9 Y( b0 F  Supported in default-server: Yes, h6 J7 B3 ]) l

! G; |; B* I: E& |* tsource <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
8 v' A/ C0 k% a: G5 ^( y4 Jsource <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
* [; f0 K; n# I" I, dsource <addr>[:<pl>[-<ph>]] [interface <name>] ...
% m8 Y2 b3 L$ v3 h! N  The "source" parameter sets the source address which will be used when2 a7 a) |: j! V' L
  connecting to the server. It follows the exact same parameters and principle+ k! M& z0 ~8 V; I! ~
  as the backend "source" keyword, except that it only applies to the server
/ d8 n* e$ Q# B1 y2 H: X) E1 n  referencing it. Please consult the "source" keyword for details.
' U+ E( J) x2 u& |# J$ u% ?+ G. w1 `7 h
  Additionally, the "source" statement on a server line allows one to specify a  C3 ^4 u! `" g8 `! N% _
  source port range by indicating the lower and higher bounds delimited by a
1 o# q' f2 {$ W& n  f( B+ n6 f  dash ('-'). Some operating systems might require a valid IP address when a
3 d. O5 B3 |* F7 x% ?! E  source port range is specified. It is permitted to have the same IP/range for. ^% S% N- Q! I* z- v: @- ]! k
  several servers. Doing so makes it possible to bypass the maximum of 64k  s% }* t$ t' ~' b; q' W% h
  total concurrent connections. The limit will then reach 64k connections per
+ s9 x& E; @6 ]  W. f  server.* E/ G# X/ ^* e
# I+ A2 {( h+ A! W* r$ X' @
  Supported in default-server: No. {; A0 e' ~" Z. ^$ |- L
! U( C+ e  S+ n8 D: [' R5 h
track [<proxy>/]<server>: F0 o3 Q1 M# ^
  This option enables ability to set the current state of the server by" ~9 ^1 R6 e/ f/ f+ e
  tracking another one. Only a server with checks enabled can be tracked
: C7 @# p* \" P1 z$ C+ P! B  so it is not possible for example to track a server that tracks another
7 t4 b1 ~6 D% E% W4 r* l% S  one. If <proxy> is omitted the current one is used. If disable-on-404 is3 E& T& z4 b& J9 q4 r: z  u
  used, it has to be enabled on both proxies.$ B: M9 ~( g* ?: t. W
. n8 j+ b! P+ S* _/ N
  Supported in default-server: No
1 w3 ?$ Z: n2 [& s, Z# z0 t' Z$ f" X8 s
weight <weight>
$ @. K* C& b: {, R+ G" [. y9 r  The "weight" parameter is used to adjust the server's weight relative to- x6 g0 r6 e' \. d# j6 y4 p
  other servers. All servers will receive a load proportional to their weight" ~: C) S  O4 [9 Q8 \/ ^5 a8 W3 |
  relative to the sum of all weights, so the higher the weight, the higher the
" t6 A. N0 e5 V  N5 A  load. The default weight is 1, and the maximal value is 256. A value of 0, O+ h0 C* h% i) _4 n4 w% ]  T
  means the server will not participate in load-balancing but will still accept8 J) ]  c/ A8 c8 Z* Z
  persistent connections. If this parameter is used to distribute the load# b: }  P4 X0 _+ J5 C" V% ?
  according to server's capacity, it is recommended to start with values which% c: ?- N# ?! p1 _4 D4 r/ B
  can both grow and shrink, for instance between 10 and 100 to leave enough
; e9 @% q9 t/ \  room above and below for later adjustments.
# d# Z( \+ v; Q! j
/ T# g6 ^! H- ?- w6 L& d1 o7 L  Supported in default-server: Yes$ q: [- \4 m9 o8 O( ?' C  p! ]

$ t1 ~8 Q& e4 H- p* h8 q5 w
! P' |, [) a4 I6. HTTP header manipulation
, T8 l/ D7 t  m& x9 i7 u---------------------------' y9 W" A  q: I" h1 Q" f+ J
. m  Z# Q8 \) m& `; i
In HTTP mode, it is possible to rewrite, add or delete some of the request and
$ Y- X+ D. V+ u9 \5 {" Qresponse headers based on regular expressions. It is also possible to block a
$ @4 P9 v7 |4 nrequest or a response if a particular header matches a regular expression,
' s4 n  S: d2 ?& T0 k: `3 t( Mwhich is enough to stop most elementary protocol attacks, and to protect
  m: g3 y. f5 l0 U; y! p$ _against information leak from the internal network. But there is a limitation
5 X/ j5 _; ]- g+ V& M% Dto this : since HAProxy's HTTP engine does not support keep-alive, only headers
) {7 ]5 s7 _4 W; o& Spassed during the first request of a TCP session will be seen. All subsequent
1 G# L% j6 z/ G! h/ Theaders will be considered data only and not analyzed. Furthermore, HAProxy& C/ S- w5 r) B* d+ {
never touches data contents, it stops analysis at the end of headers.
# a2 k* ]- Q1 H$ p3 h8 N) z2 k  ]. s  M
There is an exception though. If HAProxy encounters an "Informational Response"
1 S% ^. G: [) V(status code 1xx), it is able to process all rsp* rules which can allow, deny,% f5 K6 f9 f* W& b+ f* V( H6 q
rewrite or delete a header, but it will refuse to add a header to any such0 Y# R  ~% a8 T# V$ J, J4 g
messages as this is not HTTP-compliant. The reason for still processing headers
  v" W- ^& W% y( Tin such responses is to stop and/or fix any possible information leak which may/ [* T% l0 `1 L/ q
happen, for instance because another downstream equipment would unconditionally/ I9 J/ y* _) G8 U% f. c4 y
add a header, or if a server name appears there. When such messages are seen,
& J( Y8 @$ i$ U% ?& Q% l7 h+ pnormal processing still occurs on the next non-informational messages.& r& ]9 }7 r* n3 {

8 h& L5 r/ @8 y, `* i: U' W* U0 |4 HThis section covers common usage of the following keywords, described in detail
" Y" \5 z9 p4 n6 I; L. H$ p2 Gin section 4.2 :/ m7 g+ ^( [/ Z- [) B
5 p+ P8 y$ ?( l! ~, V" F/ h0 L+ b
  - reqadd     <string>- X+ a1 i" d& s7 ~* a
  - reqallow   <search>" s, ]+ l7 t7 C7 e/ R, n) A
  - reqiallow  <search>! A: n) l- C1 m; y/ ~3 N1 z
  - reqdel     <search>
+ V- g4 s8 Y, |  - reqidel    <search>
' K3 i1 Z5 Y$ ]+ Y  i" S) v- D  - reqdeny    <search>3 H, ^) `( R. l3 N' J& s
  - reqideny   <search>. W4 o* @! y5 i& F" @
  - reqpass    <search>4 D9 A8 _$ s! t, U& ^  M- h, T
  - reqipass   <search>
  f& f6 ^. P6 E  - reqrep     <search> <replace>, o4 y- c# @; X3 \8 @+ @
  - reqirep    <search> <replace>. ]- S+ B! w% g# h3 o
  - reqtarpit  <search>
/ {8 F! p! N  y2 J  - reqitarpit <search>
/ I9 P$ e# Y& U3 ^4 e  - rspadd     <string>5 l9 V. [4 t# u8 P3 J
  - rspdel     <search>
+ Z: f3 Y& B8 q% k; Q  - rspidel    <search>
1 c4 d: |; g& U" n0 ?  - rspdeny    <search>3 P1 h/ Z  U  ^1 l
  - rspideny   <search>3 @. l) G* X- X& O
  - rsprep     <search> <replace>6 x% f+ O' r+ L% {; f
  - rspirep    <search> <replace>7 Z( i" H: z+ M, g& D$ T" I

& a  r) N  q$ ~4 g5 OWith all these keywords, the same conventions are used. The <search> parameter
( r: y* u$ q0 x' {% @is a POSIX extended regular expression (regex) which supports grouping through6 r/ f# G% s; v  I8 ]
parenthesis (without the backslash). Spaces and other delimiters must be( I% f& N' I# T! P3 f3 S- B" P: j
prefixed with a backslash ('\') to avoid confusion with a field delimiter.9 G( V; x& O! L$ Z9 T
Other characters may be prefixed with a backslash to change their meaning :
6 w" A( t. {2 i( v  t# H
, J3 _5 h- Y' O. i  \t   for a tab
  |3 u* e, W  U+ p  \r   for a carriage return (CR)( i4 `- b, Q6 u! W/ q
  \n   for a new line (LF)5 n3 h& Y" ?# X, O! b
  \    to mark a space and differentiate it from a delimiter. Y# b: w6 s+ u3 Y# g
  \#   to mark a sharp and differentiate it from a comment3 N$ O) T, L' ^
  \\   to use a backslash in a regex
/ Z( h6 @: S5 E5 W! G  \\\\ to use a backslash in the text (*2 for regex, *2 for haproxy): p) T0 {1 d  @/ F6 b- |
  \xXX to write the ASCII hex code XX as in the C language
* T/ j; i) h) U6 s5 A5 s7 i1 Y$ a: {" K. }
The <replace> parameter contains the string to be used to replace the largest0 H6 d$ J" R' j
portion of text matching the regex. It can make use of the special characters
! t; Z( P5 F$ a9 m5 u6 Eabove, and can reference a substring which is delimited by parenthesis in the
: K4 U, U* E" w/ n% U; D5 t+ Iregex, by writing a backslash ('\') immediately followed by one digit from 0 to, ]& f) g% s8 o( R4 A
9 indicating the group position (0 designating the entire line). This practice5 k" Q; L1 r6 j2 ^: t7 O9 _
is very common to users of the "sed" program.
. N8 P9 j; O: @9 W1 V% H
8 K8 D+ D& A' eThe <string> parameter represents the string which will systematically be added
6 B/ S! Y0 U) H* u; G4 u0 Dafter the last header line. It can also use special character sequences above.* X- l; X# @& \+ z& A

" f: G% y, c) v+ z7 D; j: }+ qNotes related to these keywords :
; w" m3 q  }4 b" @% T+ o---------------------------------
, g$ o6 H- Q! b- c: ?  - these keywords are not always convenient to allow/deny based on header7 O. F2 [# s8 O( E6 \) @/ h
    contents. It is strongly recommended to use ACLs with the "block" keyword$ u4 \9 ^" T+ F5 `* a! B
    instead, resulting in far more flexible and manageable rules.
6 c& E* {8 r4 _
4 [9 _0 D1 z. k- _) ]: E  - lines are always considered as a whole. It is not possible to reference
% R" V+ ]" l" M9 B6 ^    a header name only or a value only. This is important because of the way
' u9 ^- T, N0 W+ Q+ P$ r% T; S    headers are written (notably the number of spaces after the colon).$ u0 G$ W9 ]2 [0 ]. N
, k1 _* T, i+ Q5 e  h2 p
  - the first line is always considered as a header, which makes it possible to
1 F9 ]0 Q) [8 i    rewrite or filter HTTP requests URIs or response codes, but in turn makes
( @8 M4 t5 @1 j/ u. n9 {    it harder to distinguish between headers and request line. The regex prefix
; X: d% U1 V% i! J5 V' |    ^[^\ \t]*[\ \t] matches any HTTP method followed by a space, and the prefix2 l/ t- b+ t: s& X& k: C7 Q
    ^[^ \t:]*: matches any header name followed by a colon.
$ K  w6 A8 i  n$ D  F0 ^
1 d2 h7 Y0 C1 o5 L1 j' w; ^" A  - for performances reasons, the number of characters added to a request or to2 b8 M7 m; e/ Q) X* A0 @# h
    a response is limited at build time to values between 1 and 4 kB. This$ N7 e+ t4 r: i% E& z$ ?
    should normally be far more than enough for most usages. If it is too short
: h+ w  G( ?4 x+ o2 z6 T! ~' Z    on occasional usages, it is possible to gain some space by removing some2 F( v6 w, |! b1 y3 Z
    useless headers before adding new ones.
1 c& O0 @8 s( |: e3 F3 v1 x; |: n1 k- d( ~* D
  - keywords beginning with "reqi" and "rspi" are the same as their counterpart7 \' @8 E. q  C5 b  F) i' R
    without the 'i' letter except that they ignore case when matching patterns.
. }! j; ?( p& _: j: e. p
/ \3 u% E" K# ^( j2 {  - when a request passes through a frontend then a backend, all req* rules- U* i- W: c; k% k, b
    from the frontend will be evaluated, then all req* rules from the backend8 Z3 Z, {% ~! O% R* q9 F- s2 R5 B
    will be evaluated. The reverse path is applied to responses.
  B& z# A5 M5 O
1 ?# L( m  G& G) R8 g6 j3 V  - req* statements are applied after "block" statements, so that "block" is
( y: j9 b8 V! X) V% c  j    always the first one, but before "use_backend" in order to permit rewriting, w$ s# ~# p- t# A  U! h: t1 v
    before switching.
/ {7 ^* k' n5 r% V9 e
5 S; B9 u5 U( o% X4 k' b; O* {4 N, a; O9 [) q! M
7. Using ACLs and pattern extraction, ?; ]/ |- q# O  a% Q
------------------------------------' H6 G8 h4 t/ L* Y

2 W* S7 ?: [/ d: E3 r3 dThe use of Access Control Lists (ACL) provides a flexible solution to perform& X4 s: Y( @& w6 O
content switching and generally to take decisions based on content extracted
- H/ b! F+ a. s, I/ E6 ]: Ufrom the request, the response or any environmental status. The principle is) d8 U. s3 `/ Z1 u! I
simple :  W, G! t8 p+ p. k- m
1 j( r; y' L$ m' W% S' R3 y" _* B
  - define test criteria with sets of values
" c! M& G& a% k+ z  - perform actions only if a set of tests is valid
5 \4 N9 c) X. x  f# `+ p6 @( B8 ]* \) I: D$ z" o) x
The actions generally consist in blocking the request, or selecting a backend.
$ W$ E+ O7 f1 t9 M# r% F: {5 T% _( H: c; W! t
In order to define a test, the "acl" keyword is used. The syntax is :- n* l* q7 n7 T6 f- b  I% l

* ?6 \2 K& p  [# d( d. B0 N& m   acl <aclname> <criterion> [flags] [operator] <value> ...3 S7 r" N" y4 l* v8 @

6 b4 q  g7 D, _This creates a new ACL <aclname> or completes an existing one with new tests.: P1 |+ S- L. T9 ]3 X
Those tests apply to the portion of request/response specified in <criterion>
7 o3 x1 I8 q& r4 \- F, Pand may be adjusted with optional flags [flags]. Some criteria also support$ q; A3 G: Z6 n. T2 c' L& V2 n
an operator which may be specified before the set of values. The values are
" u! H6 d: z% J5 o& ]of the type supported by the criterion, and are separated by spaces.
$ W: H- l# S( J1 S; r9 Y: ^. b7 t$ D" Y7 G/ S
ACL names must be formed from upper and lower case letters, digits, '-' (dash),
, h# h" a1 B: F6 N; i' x1 a'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
7 k3 `# ~8 H( i& V! swhich means that "my_acl" and "My_Acl" are two different ACLs.
  r+ }6 {! m$ ~  C( f% u4 q! M5 @) M$ Y' j
There is no enforced limit to the number of ACLs. The unused ones do not affect, {* d0 N& _8 O  T2 b( `# ^% f. V
performance, they just consume a small amount of memory.# Q; I2 Q! C% S. X6 S4 t1 R
: Z3 ~3 G6 F4 J" @% p; H
The following ACL flags are currently supported :
  [1 ]' s8 Z& y! \4 O
+ U, U1 o: _6 x   -i : ignore case during matching of all subsequent patterns.% Y, `- v- c: G2 C4 O/ B5 p' }
   -f : load patterns from a file.( w/ p/ i. ]5 d
   -- : force end of flags. Useful when a string looks like one of the flags.
0 B" |- _1 n. z/ Y5 u1 ]0 q4 G0 q9 z& s  [, d
The "-f" flag is special as it loads all of the lines it finds in the file$ x! l% V" {8 U
specified in argument and loads all of them before continuing. It is even
7 F# B" T4 K5 o% P% Ipossible to pass multiple "-f" arguments if the patterns are to be loaded from
, j0 v* q; [; h! b/ `" hmultiple files. Empty lines as well as lines beginning with a sharp ('#') will+ M, A3 @" t+ v7 n3 W
be ignored. All leading spaces and tabs will be stripped. If it is absolutely
9 W# G. F/ ~' ]+ k5 y" mneeded to insert a valid pattern beginning with a sharp, just prefix it with a# U) B) q) U( E9 r$ K# N9 {
space so that it is not taken for a comment. Depending on the data type and0 [4 I  [0 _+ M. V( g, ]6 u! P% C- V$ v
match method, haproxy may load the lines into a binary tree, allowing very fast/ I7 C4 v7 _( X5 X) J- {
lookups. This is true for IPv4 and exact string matching. In this case,0 l+ h5 o/ Z. X* T4 u( q+ d
duplicates will automatically be removed. Also, note that the "-i" flag applies7 w$ r) c5 E! T+ |
to subsequent entries and not to entries loaded from files preceeding it. For
! d' B' _7 q; w: H# pinstance :
. C" ~; Z: Z# D; V" l/ x  X9 M# W; c$ P6 }: t
    acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst  test
1 |- H% ^2 a$ x. }/ d
  q- N  H  t9 lIn this example, each line of "exact-ua.lst" will be exactly matched against( j" {: q1 W* z1 r% H
the "user-agent" header of the request. Then each line of "generic-ua" will be; F1 q! y* e9 b3 |
case-insensitively matched. Then the word "test" will be insensitively matched
4 s& V6 ]  {6 i- O" D$ Mtoo.
$ a) x: j6 C/ q/ Z5 p* M7 Y
1 E, |0 p9 h  z. i5 h! cNote that right now it is difficult for the ACL parsers to report errors, so if
' p7 X& [2 q/ p2 La file is unreadable or unparsable, the most you'll get is a parse error in the, `* j, N* ~6 f+ f7 F$ v/ \4 y
ACL. Thus, file-based ACLs should only be produced by reliable processes.! k- C2 S- `9 s) P# [+ l* ?

) }! w+ u" @" G9 v; v5 L0 `& ZSupported types of values are :# X! R( u) t9 }. A# B& X" B9 D$ R
5 G* o  U) ^, I
  - integers or integer ranges
0 G. @/ ^* H6 k! a) P  - strings) I: G1 d, I7 L* ]
  - regular expressions
9 s( j0 @+ A9 P1 o  - IP addresses and networks
. i4 R+ L3 Z* \  F3 Y  `1 Q
0 _6 t) ?( n! A5 R- i
/ a* ^' X9 _4 R+ ?$ {! T% ^7.1. Matching integers" O0 @3 I: D0 ?7 Z( P9 l0 b
----------------------4 `, J  K4 z- {  g; W* O+ m9 H6 i  q$ n
1 p- J6 U9 O7 ]( }7 F' T  Z1 [
Matching integers is special in that ranges and operators are permitted. Note
# T  W$ H, ~) ]7 }: B4 Fthat integer matching only applies to positive values. A range is a value+ p( h8 V: }% b. L  t; S
expressed with a lower and an upper bound separated with a colon, both of which$ d) {$ U1 ?- n& C0 `
may be omitted.
9 \9 @$ d+ x) R" n% ?6 R3 b5 F! u
& B8 m$ e& e' T, V7 x  V3 EFor instance, "1024:65535" is a valid range to represent a range of8 s+ K7 t; Y! \! b  S
unprivileged ports, and "1024:" would also work. "0:1023" is a valid
- l6 Q/ u& Q; m  v% Y# D8 t+ lrepresentation of privileged ports, and ":1023" would also work.
% z" G! p! v  k8 R
$ x! m. Y, |- D0 ]$ }  ]As a special case, some ACL functions support decimal numbers which are in fact
. j. A# e1 ^* I: A* V; ]two integers separated by a dot. This is used with some version checks for
* W: b3 U8 k8 q4 |; ^instance. All integer properties apply to those decimal numbers, including  X3 j" _  y& N6 I# T
ranges and operators.
/ f5 E- B. Z7 I$ [$ H1 F# C  d7 M3 Q
For an easier usage, comparison operators are also supported. Note that using- k9 P' ], V$ o4 |, |9 q# C
operators with ranges does not make much sense and is strongly discouraged.1 F1 i5 |$ }6 m% f
Similarly, it does not make much sense to perform order comparisons with a set
' B  c/ q( z9 v0 v( i6 J4 Uof values.
2 a- l3 k5 l& M7 Y
# @. Y1 R( w" o( G- jAvailable operators for integer matching are :! C. \, s# ~% S3 p9 W7 ^9 z
% ^9 Q4 Z0 M- L
  eq : true if the tested value equals at least one value8 I8 L4 v1 V) C8 @
  ge : true if the tested value is greater than or equal to at least one value: X# E3 @1 V' P' H$ v
  gt : true if the tested value is greater than at least one value# h. \/ M0 T* \2 [" j$ Z" h; F
  le : true if the tested value is less than or equal to at least one value
* {8 \6 [" H) ]: s& _( k/ G  lt : true if the tested value is less than at least one value
- y1 `& E' z( w1 R  s4 F! @) V
0 ~+ f# u9 u/ S9 XFor instance, the following ACL matches any negative Content-Length header :$ d/ {$ \  F% ]
7 L" L0 Y8 w: }
  acl negative-length hdr_val(content-length) lt 0% L) J+ j, e% n3 Q; S; A9 _: ~! a
# K8 a( z* y5 m& a
This one matches SSL versions between 3.0 and 3.1 (inclusive) :& x% {* @& ~0 U8 \% r: m$ i% ^
2 i8 h% i4 ]. O$ B" B
  acl sslv3 req_ssl_ver 3:3.1
8 I0 x) C, B9 l% |- H! v
4 N/ S! \5 ], V4 n5 Z7 R2 `! [5 A7 u" K/ D9 m
7.2. Matching strings. c5 Q5 I& \/ k; ^
---------------------
8 v' a( L# _; |! {$ M; d6 c# z! C$ f
String matching applies to verbatim strings as they are passed, with the- r. E. Z* M, c  @$ ]1 a) {/ n
exception of the backslash ("\") which makes it possible to escape some
. \8 K8 b, ~: Icharacters such as the space. If the "-i" flag is passed before the first- F3 U/ l5 G" |
string, then the matching will be performed ignoring the case. In order/ g9 V! D( ]! `4 Y
to match the string "-i", either set it second, or pass the "--" flag7 M( M' q' o2 d& {- K
before the first string. Same applies of course to match the string "--".7 f) D) t4 Y% Y5 o8 L& W+ n# V  v" `

) _0 r" o' J* K1 C3 b4 C
& I$ C7 R) ~: E% g2 b. u* j7.3. Matching regular expressions (regexes)
- h3 s  K. c7 G  o  X4 Q-------------------------------------------
# H% n& A2 R1 q& Z: {& g* ?
  _4 j8 \8 l4 H3 v3 yJust like with string matching, regex matching applies to verbatim strings as
$ `5 h1 X. X- T: K1 C2 Nthey are passed, with the exception of the backslash ("\") which makes it
, V$ m; F# \! V2 u) upossible to escape some characters such as the space. If the "-i" flag is
- ~: X. Z' H9 P6 @7 _( Z' H' Jpassed before the first regex, then the matching will be performed ignoring  h/ |. U& {6 j( }& ~- [" ?& v
the case. In order to match the string "-i", either set it second, or pass7 k. v) w' u' R5 Y
the "--" flag before the first string. Same principle applies of course to6 v+ a5 o% H6 H/ Z3 I9 f
match the string "--".
& d3 Z. W# [+ f& |9 K) z2 P5 B: }3 `. m5 B: w

  N8 `6 S- U9 i' \1 s/ g  m7.4. Matching IPv4 addresses2 N7 I& i( Q  [- a
----------------------------; L' q4 r4 j4 f
0 U3 ^, U. z+ P$ J; Y% R) g5 Q* O# x
IPv4 addresses values can be specified either as plain addresses or with a! Y1 r# E0 S, q, L+ c3 I
netmask appended, in which case the IPv4 address matches whenever it is
! `5 ~5 m3 G2 rwithin the network. Plain addresses may also be replaced with a resolvable
: Y& l8 a5 W. z$ R% R$ I8 l  rhost name, but this practice is generally discouraged as it makes it more( [/ W* c! _8 m
difficult to read and debug configurations. If hostnames are used, you should
. o* W; M$ d: H7 x, Zat least ensure that they are present in /etc/hosts so that the configuration2 M- ]# K: x8 d: v) ?* r
does not depend on any random DNS match at the moment the configuration is7 [7 `8 Z' w8 W
parsed.
6 W4 Y( R, T. ?8 R6 |+ [/ q% h' W0 U# Y2 y/ z6 ~7 N: S
& b- t. {' x9 E- l5 _7 q
7.5. Available matching criteria0 V$ @7 \. I, V; h1 \+ p# I
--------------------------------4 j3 e( Y/ B1 C0 ^* P7 z* x* t
) u- V5 `* v" o. H6 C8 H2 Z
7.5.1. Matching at Layer 4 and below+ |; W# d, h- g! T+ |9 G
------------------------------------9 X8 \+ Q; J# _% A

) X5 c2 I! C, m3 y" EA first set of criteria applies to information which does not require any
3 `! y$ ~0 h+ V8 Lanalysis of the request or response contents. Those generally include TCP/IP
- K' P% h2 j1 ~. {4 faddresses and ports, as well as internal values independant on the stream.6 O/ |/ A2 f$ ]. Q+ S- k% Z0 L' K
+ l" y4 |* @+ R1 b  _2 l
always_false
# y2 [( [6 K2 U, ]8 S, ^  This one never matches. All values and flags are ignored. It may be used as- Q9 G% S4 A1 X7 ?$ D% \) p
  a temporary replacement for another one when adjusting configurations.
2 k' O6 q* f: f9 Q4 ]4 z8 q/ ?8 m5 y* p8 U! y" K
always_true* f; o0 A! Q/ K2 C2 X+ I" Y- d% i
  This one always matches. All values and flags are ignored. It may be used as$ r# v  Q/ r/ I
  a temporary replacement for another one when adjusting configurations.
+ D  b( x* t* i7 k1 }" E2 M
2 U8 E2 I; W; Z1 W2 y9 h4 s+ Y& y/ n  Favg_queue <integer>, M; T' i8 K7 L! J3 Q& F2 O0 _
avg_queue(backend) <integer>/ z% [3 `: W2 _
  Returns the total number of queued connections of the designated backend
6 Z6 b7 g% @* u7 _  R! v  divided by the number of active servers. This is very similar to "queue": P+ i4 k! r8 a) w
  except that the size of the farm is considered, in order to give a more0 Z( o4 T% H, x5 S( `% o
  accurate measurement of the time it may take for a new connection to be5 B7 C6 F& A. S: Z" U/ ]
  processed. The main usage is to return a sorry page to new users when it$ f7 Q; K9 h* K/ K% E
  becomes certain they will get a degraded service. Note that in the event
9 B  V7 a1 |4 u" S1 S  r  there would not be any active server anymore, we would consider twice the
1 Y, y& F" `8 k; ~  number of queued connections as the measured value. This is a fair estimate,
) L7 u' U* C: x: F$ O9 A  as we expect one server to get back soon anyway, but we still prefer to send
1 [1 J5 R* v& R) ]* J3 L; E/ }  new traffic to another backend if in better shape. See also the "queue",) b: \1 U# J% F4 t+ A" o' T1 k% E
  "be_conn", and "be_sess_rate" criteria.
7 j7 E5 R4 ?9 ^: e
! `, W7 W( _1 I! L+ x, k; Cbe_conn <integer>3 H4 @# S+ ]8 a, u1 x5 y3 Y# `
be_conn(backend) <integer>
: J& [' E, Y* X+ z  Applies to the number of currently established connections on the backend,9 W, C# t% p/ _) ~" @
  possibly including the connection being evaluated. If no backend name is
7 h* W+ n2 l5 P1 o% s  F  specified, the current one is used. But it is also possible to check another
- X# _* X. z7 l; P6 L  backend. It can be used to use a specific farm when the nominal one is full.
# s. N7 n, q8 L% n  See also the "fe_conn", "queue" and "be_sess_rate" criteria.
% ]( Q( |/ z* y/ ^4 x$ u$ \: R3 i& n* o7 N6 q
be_id <integer>
, `) x' E2 c9 o: p, x4 k6 ~" T  Applies to the backend's id. Can be used in frontends to check from which" P; N, M& I- o: p6 h
  backend it was called.% E9 `9 \& N; E
  s+ K5 ~/ d) M! V6 Q$ V, f
be_sess_rate <integer>0 @' b5 o0 @' K8 _, f5 g1 I
be_sess_rate(backend) <integer>: h& \8 D7 g  Z; }. E: o
  Returns true when the sessions creation rate on the backend matches the3 m8 |; [8 v# b3 D) P
  specified values or ranges, in number of new sessions per second. This is
4 `, R+ x5 u3 c" }; [! ~  used to switch to an alternate backend when an expensive or fragile one
/ P. V; X* J6 R5 Q" r4 ^+ m/ L" Y  reaches too high a session rate, or to limit abuse of service (eg. prevent
, Q  f3 x3 ~4 h) R4 m! H& x  sucking of an online dictionary).& g! w, @# z. L3 Q  ], O' n
4 u* A1 F: }* l, d
  Example :- ~) p9 Y5 ]9 T6 U7 x
        # Redirect to an error page if the dictionary is requested too often! M/ |. N4 u2 O5 e3 b8 X
        backend dynamic, Y3 p: q5 ]" t+ \9 t
            mode http) [7 I% a5 z2 |  F* T
            acl being_scanned be_sess_rate gt 1009 J7 }3 D  G4 M
            redirect location /denied.html if being_scanned* n' S2 D; w. J! X6 g

+ h- [" q& v0 Q3 T- h& ?0 mconnslots <integer>
7 O( h9 X$ k9 A/ A  G, Iconnslots(backend) <integer>  [- A1 B+ M9 G1 l" q
  The basic idea here is to be able to measure the number of connection "slots"
- A. s2 ?( n' d+ o: H  still available (connection + queue), so that anything beyond that (intended
) N& ~8 |( z2 `1 [  usage; see "use_backend" keyword) can be redirected to a different backend.
, ^& F! }' h& H5 f& H8 C& s4 O, }$ j' N8 }; W
  'connslots' = number of available server connection slots, + number of1 V; Q& U: m: t7 ~8 Z% g/ @9 x
  available server queue slots.( b0 u2 c  f6 P/ x% A8 f

  ]' B8 W6 m# u# ^7 _$ P, w  Note that while "fe_conn" may be used, "connslots" comes in especially
9 G  a# a: q  D' O$ B4 N8 k/ \+ j  useful when you have a case of traffic going to one single ip, splitting into& Y6 f% n, ?- `
  multiple backends (perhaps using acls to do name-based load balancing) and
8 L" Q; ]( b# H* B  you want to be able to differentiate between different backends, and their6 B- ~) E2 R; A& D/ C! O
  available "connslots".  Also, whereas "nbsrv" only measures servers that are, T' Y7 E) I, s/ i* d  P
  actually *down*, this acl is more fine-grained and looks into the number of
# Y: b  z, m" K$ U  available connection slots as well. See also "queue" and "avg_queue".4 v& D% U" o9 [0 ]8 T. K6 m
. V: U5 v! L2 Z* T" U$ C# d; a& d
  OTHER CAVEATS AND NOTES: at this point in time, the code does not take care0 `# z! }# |3 R1 j+ y
  of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,  q4 f* h* b/ O4 Z5 @2 l: U
  then this acl clearly does not make sense, in which case the value returned
# f6 r& K) h; T7 U  will be -1.2 ?( h+ ], [  m* I1 U$ `! L+ b

  l$ H: s$ [) y2 L# S/ a( ~dst <ip_address># {  F, o: t, ?3 k
  Applies to the local IPv4 address the client connected to. It can be used to
! p: t" w1 O( N  switch to a different backend for some alternative addresses.
# R8 P( U9 E  f1 a" s4 R( U* U; N9 l8 d: y7 g! n
dst_conn <integer>8 C4 _, V8 L- C( q2 V5 e/ M
  Applies to the number of currently established connections on the same socket; P8 f& v+ u$ j- \6 G' i/ X& I
  including the one being evaluated. It can be used to either return a sorry
/ n% |2 w' W, D4 U3 d  page before hard-blocking, or to use a specific backend to drain new requests
6 \& T+ g5 n8 z. c9 e8 ~7 z7 s  when the socket is considered saturated. This offers the ability to assign
+ i$ J! L2 D( u  different limits to different listening ports or addresses. See also the
3 k& J. T  }3 D" X$ }  "fe_conn" and "be_conn" criteria.+ R/ ~& i9 s3 E' |  W8 l+ U" D
2 G/ I9 ~7 L) y% K/ t
dst_port <integer>
: J; Y' M! X$ K7 l/ [  Applies to the local port the client connected to. It can be used to switch8 ^6 _: v5 m2 _- d3 Y) o
  to a different backend for some alternative ports.% c1 F# D5 U0 N6 ~7 Z1 L4 o* o
0 r  z$ R& d; f8 V& M  F
fe_conn <integer>
! ~" s4 m4 d* pfe_conn(frontend) <integer>
- f* V3 Y& d# C: D6 Z/ r  Applies to the number of currently established connections on the frontend,$ m2 [8 j/ p" q
  possibly including the connection being evaluated. If no frontend name is
6 l( u( f+ I( E4 N  specified, the current one is used. But it is also possible to check another5 A4 O4 p! r7 ~/ D
  frontend. It can be used to either return a sorry page before hard-blocking,
7 h' f$ ]( k7 v1 p( c  or to use a specific backend to drain new requests when the farm is. B5 _9 p. s% X  I4 w1 w+ x8 E
  considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"
" w) w. G# g/ i& _( F, K  criteria.$ Q& |! F; X0 C3 w# _: S4 w" V" Q

8 O0 w7 ^7 l/ X2 \8 z# cfe_id <integer>
; m5 M3 v* j; ?  Applies to the frontend's id. Can be used in backends to check from which
/ n4 n: c7 M5 f5 R1 G5 g+ H6 W  frontend it was called.5 K, l0 t1 y% R+ {( [" R
! C& c% y- h# l
fe_sess_rate <integer>
( D! s; v  V6 w- bfe_sess_rate(frontend) <integer># x# Y  H. g  v" I! {- p
  Returns true when the session creation rate on the current or the named
4 }! p" l1 I* h4 K  frontend matches the specified values or ranges, expressed in new sessions( b( \% H9 n+ W; G) y
  per second. This is used to limit the connection rate to acceptable ranges in
7 e& r+ M( g& p# @" V4 E  order to prevent abuse of service at the earliest moment. This can be6 ?3 b; M, T+ ?  U
  combined with layer 4 ACLs in order to force the clients to wait a bit for
4 f* m! d. ^% X7 O% m  the rate to go down below the limit.
5 m3 [# H# Y5 w$ O
* [1 i; Y- ^5 h5 u# y2 w" L: e& ?  Example :: E; Z2 v. }/ n- K
        # This frontend limits incoming mails to 10/s with a max of 100
( D. |# [8 N- O3 M0 W0 g        # concurrent connections. We accept any connection below 10/s, and
8 E7 |& |8 X, A% O1 P( j        # force excess clients to wait for 100 ms. Since clients are limited to
7 m4 `) d3 `  K        # 100 max, there cannot be more than 10 incoming mails per second.& q/ ]: r% _7 H% p2 X6 b2 T& E* l. U
        frontend mail
/ U1 |6 d8 h0 D4 g8 F2 H- g! F            bind :25
2 h# G; I: n+ L# U            mode tcp% h7 y( \6 B4 f* j( v+ \, d9 S
            maxconn 100! f& m" z) V$ F# Q
            acl too_fast fe_sess_rate ge 108 V+ i' T: @5 v4 i* Y
            tcp-request inspect-delay 100ms
$ L: v" P" J  P3 \            tcp-request content accept if ! too_fast
2 Q( j' Z. S2 E8 H. t8 B            tcp-request content accept if WAIT_END
) v- R% p0 `% O& c
+ T$ R$ c6 a8 C. ^% ^" qnbsrv <integer>3 i$ N- {' J+ T6 V/ u3 Z' {
nbsrv(backend) <integer>+ f* n1 p- b. J/ i  {& C1 |
  Returns true when the number of usable servers of either the current backend) e/ W, j6 m. P% a
  or the named backend matches the values or ranges specified. This is used to+ }# w6 r4 u+ h' \" r: `
  switch to an alternate backend when the number of servers is too low to8 [- B+ O% z4 j7 c% j
  to handle some load. It is useful to report a failure when combined with  W: _4 I1 |% D2 L! o& O5 _* D
  "monitor fail".
. B$ u4 W3 J4 B" p3 s! @0 e; W1 D0 X2 p  Z
queue <integer>) p- H* k/ J1 c  j4 m
queue(backend) <integer>2 p8 x+ a3 o& F( D
  Returns the total number of queued connections of the designated backend,
- k( m  x% ~3 A7 W8 _  including all the connections in server queues. If no backend name is+ [  C" U0 N! @8 ^8 t" F
  specified, the current one is used, but it is also possible to check another' D! K* T2 |% I7 e. [
  one. This can be used to take actions when queuing goes above a known level,! }* k/ |. M9 W% O
  generally indicating a surge of traffic or a massive slowdown on the servers.
: x0 Z' h9 Q1 W# `! z  One possible action could be to reject new users but still accept old ones.
4 y9 g1 h9 T3 g! P/ x  See also the "avg_queue", "be_conn", and "be_sess_rate" criteria./ Y8 Y: _. F" U
; L: c/ r7 R% f
so_id <integer>4 Q, ~! u/ e- B- P7 F& f
  Applies to the socket's id. Useful in frontends with many bind keywords.5 L2 {/ ~& F5 U; Y; n5 a; J
- \" `$ B+ l/ i4 m0 K- N3 ^/ [! ~
src <ip_address>
: b5 ^0 ?/ f+ R! b% t; p  Applies to the client's IPv4 address. It is usually used to limit access to; C! N4 D, i# g" R  ~0 w
  certain resources such as statistics. Note that it is the TCP-level source4 D7 M$ @9 @. q) i5 \
  address which is used, and not the address of a client behind a proxy.) D" H' f7 Z% N& k! o
& W9 _/ |7 X4 J$ G
src_port <integer>4 u% F! y6 |- k( |8 J1 R  X+ l3 `
  Applies to the client's TCP source port. This has a very limited usage.# |9 a( ]4 ^5 t

" Z' ]: g, b; I2 Csrv_id <integer>& X. W* v0 ?4 c. @
  Applies to the server's id. Can be used in frontends or backends.4 N2 y  }! q/ _: W1 i8 ~" H) o0 i2 Z2 T- M
, k. a0 o0 Q' V  P" @
srv_is_up(<server>)
6 O$ g9 w0 W$ t( N0 X. j8 Osrv_is_up(<backend>/<server>)
: H8 V: @6 ?3 m, n& o$ E  Returns true when the designated server is UP, and false when it is either7 u/ Y/ [0 a$ m! a! I) R' C9 d( _
  DOWN or in maintenance mode. If <backend> is omitted, then the server is
) A# I$ w* n3 }0 ]/ J  looked up in the current backend. The function takes no arguments since it' H2 A( |* x& q9 y
  is used as a boolean. It is mainly used to take action based on an external
- T# k- U  b3 i: x% Q+ c8 Q" V. N  status reported via a health check (eg: a geographical site's availability).7 @2 n3 o! }; h
  Another possible use which is more of a hack consists in using dummy servers
) `/ k3 j, e) y$ t* R$ v  as boolean variables that can be enabled or disabled from the CLI, so that
& t1 r* }  Q  D4 j% K7 w  rules depending on those ACLs can be tweaked in realtime.
/ A$ ~9 n6 ^! `! B0 Y2 I  W8 q& _0 L. ^2 O1 d$ j# e  C$ k, H
6 I' ~: c9 b, m! y
7.5.2. Matching contents at Layer 4
( c; b, U: |7 {. D9 s9 f-----------------------------------7 p; X4 |* _  P: Y) W# r

& H' U$ X. X+ `) N2 A* v* ?6 i8 }A second set of criteria depends on data found in buffers, but which can change! S/ o2 o7 H6 U6 ~% b. V; w: H) J
during analysis. This requires that some data has been buffered, for instance7 N3 ]4 X9 H% t+ P" R  k
through TCP request content inspection. Please see the "tcp-request" keyword
5 p( e9 a) Z2 V! n# C/ p2 ?for more detailed information on the subject.& R( n* n( |* g

' c% P8 W! `7 m0 e% K' [+ h6 M' Breq_len <integer>" L0 f0 H9 D/ `4 r% C
  Returns true when the length of the data in the request buffer matches the
) I' ?4 l. Z) D; a3 U7 C  specified range. It is important to understand that this test does not6 [/ e" V* V: `0 n' j- F1 E! m
  return false as long as the buffer is changing. This means that a check with
8 c! m5 U6 F7 g8 K  equality to zero will almost always immediately match at the beginning of the
$ G1 c2 `/ B; e3 U  session, while a test for more data will wait for that data to come in and) q' ^/ |6 b8 C) k6 P+ ^6 r# Q
  return false only when haproxy is certain that no more data will come in.9 I' Q* f& q, W$ ^
  This test was designed to be used with TCP request content inspection.' ^( Y/ ]  s2 g7 Q( x0 @' l5 }

1 \( k  w) R% r* G: n& U& u& Treq_proto_http
( b* W' o2 Z1 s1 Z2 S  Returns true when data in the request buffer look like HTTP and correctly
' d: `: B- r8 H, k/ n% N" m/ O  parses as such. It is the same parser as the common HTTP request parser which
6 @3 n4 s, a3 N6 w) T: F  is used so there should be no surprises. This test can be used for instance
3 V& B8 c8 F1 `1 q% D; ?( N  to direct HTTP traffic to a given port and HTTPS traffic to another one9 ?0 ~2 T: R( @) \. N0 R
  using TCP request content inspection rules.  Y9 _: h$ v6 [' w! I+ v9 S0 N

+ x: y/ e! J- g1 P3 l, j6 preq_rdp_cookie       <string>8 ]/ q/ @- i( x. d
req_rdp_cookie(name) <string>
  L6 a3 |' w' A- J8 J) N. }# e  Returns true when data in the request buffer look like the RDP protocol, and( I5 l! n$ m! l0 n( ?4 i
  a cookie is present and equal to <string>. By default, any cookie name is
; B' r' X, e+ R  checked, but a specific cookie name can be specified in parenthesis. The
* ?9 R$ w6 y' [+ T! w8 w% K  parser only checks for the first cookie, as illustrated in the RDP protocol
6 D; l$ ^1 @& _! W. T  specification. The cookie name is case insensitive. This ACL can be useful
* r: y2 F) Q1 [7 \7 E  with the "MSTS" cookie, as it can contain the user name of the client
1 R( ^( a- |7 m; \& U& }* v9 ?) E  connecting to the server if properly configured on the client. This can be
6 @- Y2 V' o: F$ f# _6 J  used to restrict access to certain servers to certain users.
% l9 `# U) ~- a6 g$ `8 Z8 Y4 {
5 r9 T3 c! B! sreq_rdp_cookie_cnt       <integer>
8 r# Z+ ]$ t, n0 H/ ?2 v5 \req_rdp_cookie_cnt(name) <integer>% p: |% H" c8 u- {
  Returns true when the data in the request buffer look like the RDP protocol
# y, S% X" l  f$ Q. {3 q2 G  and the number of RDP cookies matches the specified range (typically zero or
' S* m' H, I2 G( z; I  one). Optionally a specific cookie name can be checked. This is a simple way
( T" Z9 q8 |6 X5 O" X  of detecting the RDP protocol, as clients generally send the MSTS or MSTSHASH
% J% J! H9 T% P& w+ A  cookies.
3 `" A7 C/ s+ D( E$ D5 N3 s0 Q5 Y* U$ i
req_ssl_ver <decimal>" }. R: }8 {3 d  `/ V
  Returns true when data in the request buffer look like SSL, with a protocol
6 m" S# u8 k! ^7 T  version matching the specified range. Both SSLv2 hello messages and SSLv3
/ E8 A; Q9 `2 X: H# }: I( k3 [' u  messages are supported. The test tries to be strict enough to avoid being
0 y6 o/ G7 W5 c1 o  L6 ~  easily fooled. In particular, it waits for as many bytes as announced in the& z% [( c+ e8 h  S' F1 m; b0 y' Q
  message header if this header looks valid (bound to the buffer size). Note
7 N; G& F0 k7 a0 _, M$ T) N4 ~; D2 D: s  that TLSv1 is announced as SSL version 3.1. This test was designed to be used
1 P( Q0 S6 d. C( X# }  with TCP request content inspection./ }* C+ Y( C* U- H4 {* A; B) Y
$ U7 U* `$ K* n) w$ u) W
wait_end* M1 ^- ^+ k3 |( |
  Waits for the end of the analysis period to return true. This may be used in# A* q! U8 z) h# ^: |7 y* g
  conjunction with content analysis to avoid returning a wrong verdict early.
: _/ w1 }6 K# u- I# W7 V  It may also be used to delay some actions, such as a delayed reject for some
: c' h# r2 Y$ N9 Y+ h  special addresses. Since it either stops the rules evaluation or immediately, c. R0 ]: _" }9 E
  returns true, it is recommended to use this acl as the last one in a rule.1 {: P9 ?$ q  n
  Please note that the default ACL "WAIT_END" is always usable without prior8 c# I/ s% _% Q- H% Q
  declaration. This test was designed to be used with TCP request content
/ S) t& v$ O  V( y% _: p  inspection.
+ k3 A5 R4 m- L! |
# Y% @5 l' J$ |% Q, H  Examples :
9 [+ o) k0 |6 C! a  U1 |) ]/ x# Y     # delay every incoming request by 2 seconds
: G. A/ \2 ^3 p     tcp-request inspect-delay 2s
$ y0 L4 V* A' |4 n0 c4 k. K     tcp-request content accept if WAIT_END( v  ^8 f! O3 P& c

6 o* ]1 c$ c7 M7 G9 J2 t     # don't immediately tell bad guys they are rejected
4 A8 {9 f8 _9 ^- ?; r% W# G; q     tcp-request inspect-delay 10s
) e; K* B4 u+ A8 J. y+ s% w     acl goodguys src 10.0.0.0/24! m' g# W# C5 y# y$ s6 ^1 v7 H
     acl badguys  src 10.0.1.0/24
' r1 e9 w; u" W3 j     tcp-request content accept if goodguys
# X. Q3 a+ B7 E+ K3 n8 ~, E, r     tcp-request content reject if badguys WAIT_END
+ y7 i' W! P, X7 F     tcp-request content reject* i0 ]3 Y, n( f! S
9 d' I% j0 z4 [% q/ Z

, ?5 k  W/ f' G3 j& r# E7.5.3. Matching at Layer 7! ]' s/ c1 d0 r+ N, c+ A! u0 L
--------------------------) ?7 b3 k6 T* [% Z+ J3 A
- A% ^  ?9 k: G
A third set of criteria applies to information which can be found at the
* g  X9 q" }6 D3 a$ y6 J$ c! Fapplication layer (layer 7). Those require that a full HTTP request has been& z) \: l7 t# @8 N% F5 [+ u; r
read, and are only evaluated then. They may require slightly more CPU resources" H* H, t& t/ n7 B6 k( n8 S
than the layer 4 ones, but not much since the request and response are indexed." B! {4 I# G/ U+ |# ~2 A- ?, `
+ O6 P( }, z3 s4 }% _* [7 t
hdr <string>! B# A0 y3 V( h; z: b; M/ i& K5 V' j
hdr(header) <string>+ v! F( a, h" ^5 w) _
  Note: all the "hdr*" matching criteria either apply to all headers, or to a
7 l" y9 g3 K! w  particular header whose name is passed between parenthesis and without any
. I9 F# `! b, k6 ^8 p) ?8 y  space. The header name is not case-sensitive. The header matching complies
/ o( F, ]% G% F/ ^; _' @  with RFC2616, and treats as separate headers all values delimited by commas.
( v4 Z7 {* U: q1 j) _  A  Use the shdr() variant for response headers sent by the server.9 h4 e; G! A4 A) V" ]. ?( j
. L: ?. S9 Z/ z% _* y
  The "hdr" criteria returns true if any of the headers matching the criteria6 V# ^) O6 @/ N2 s# K: o& Q
  match any of the strings. This can be used to check exact for values. For" |4 l$ r2 C; a7 {1 p, D
  instance, checking that "connection: close" is set :
$ a' M$ d3 `% I6 L) r  R+ T+ J
) H% l, v$ ~( M% J! R( L4 ~     hdr(Connection) -i close
; z5 X' f2 v3 P. @* @; O+ a# k& s9 p, N1 ]+ k# @
hdr_beg <string>
! P2 p6 S: ^' s( G3 whdr_beg(header) <string>4 C4 h/ K3 A" N( z/ ^' N8 z
  Returns true when one of the headers begins with one of the strings. See$ R. |, D" H3 f/ _( F$ v2 o& {
  "hdr" for more information on header matching. Use the shdr_beg() variant for
7 _$ I. y: E' q- i$ a4 r6 s  response headers sent by the server.- Y. k2 Z+ {2 R5 g" p9 F' q
7 P. z5 e# Y8 x0 m9 ]: M
hdr_cnt <integer>9 P# t' ]- L' V1 x) v, ?2 [! z3 r
hdr_cnt(header) <integer>& @  F% J" d. }' Z! V3 ~1 u3 Q% G
  Returns true when the number of occurrence of the specified header matches
. ?5 O& ^8 |$ q( ]$ ~8 D$ [- `7 ?  the values or ranges specified. It is important to remember that one header
! q9 ]! g! e" I% v. Q) v  line may count as several headers if it has several values. This is used to
2 p, Z5 D, J7 Q% s8 f9 j  detect presence, absence or abuse of a specific header, as well as to block' \* X7 L' D& q/ G# Z+ ^$ R
  request smuggling attacks by rejecting requests which contain more than one# A' q: c  K9 g/ e
  of certain headers. See "hdr" for more information on header matching. Use4 F! s8 \) V/ K& Q: P0 |; A3 q% Y
  the shdr_cnt() variant for response headers sent by the server.; X3 l- \" R" a, ^9 T- ]3 @

5 x) u: b# W  P  ?; U2 x2 zhdr_dir <string>
8 e/ a! ?' {1 q  [hdr_dir(header) <string>+ n2 f) r: V4 T2 J& _3 N
  Returns true when one of the headers contains one of the strings either
( c' {$ r2 G/ ~/ n+ m  isolated or delimited by slashes. This is used to perform filename or
+ b: M) E$ D, R7 F  directory name matching, and may be used with Referer. See "hdr" for more
3 U4 J+ i$ j3 u. q4 C1 o  information on header matching. Use the shdr_dir() variant for response
3 E% ^/ \) J+ o* n  headers sent by the server.
& b2 _( ~; c" S; @8 k0 m
9 I7 ^3 [7 c8 d4 Q. x0 Hhdr_dom <string>' c. ?; b3 v. e
hdr_dom(header) <string>. y7 T2 X- k. q0 }$ N# l, m1 f
  Returns true when one of the headers contains one of the strings either
8 X; ^& c0 ^; {! \  c  isolated or delimited by dots. This is used to perform domain name matching,
8 X- m, ], [, d6 a$ G' G0 T9 c/ L  and may be used with the Host header. See "hdr" for more information on
- F  w; q3 O4 v5 b3 M  header matching. Use the shdr_dom() variant for response headers sent by the
  ]% g. b: K' O* `  server.* x( w1 \* p; r. n. R. p
- d4 S) E: |. y9 {8 t/ k' q  ]
hdr_end <string>
3 o2 I& u: [3 W% j0 O. thdr_end(header) <string>& ~7 I6 T1 ~( O8 u6 H
  Returns true when one of the headers ends with one of the strings. See "hdr"8 X1 r( G$ C( O, B5 I
  for more information on header matching. Use the shdr_end() variant for
+ h7 D3 P, |) C. ?  response headers sent by the server.; E. K- V8 {1 \/ t( Z5 K

5 H: f6 c7 b- R. Ghdr_ip <ip_address>
% h! d8 \2 v; G) p7 v$ E  U" phdr_ip(header) <ip_address>" |8 g1 d- U& w. m' j2 F
  Returns true when one of the headers' values contains an IP address matching
; K$ S' T3 u9 Y2 o; U  <ip_address>. This is mainly used with headers such as X-Forwarded-For or% O, i, U2 @' u) r: j9 {0 G
  X-Client-IP. See "hdr" for more information on header matching. Use the
- p/ R: a# p7 P7 x  shdr_ip() variant for response headers sent by the server.& A/ F2 }: O; ~; U  O; x/ F

. F9 F/ Q2 B" xhdr_len <integer>
) J: v( N- }+ b; q4 chdr_len(<header>) <integer>8 v. p! g6 X" T) T" v  g
  Returns true when at least one of the headers has a length which matches the
# U' o$ z5 u1 ~$ E  values or ranges specified. This may be used to detect empty or too large
: @3 h8 |8 f. v5 A  headers. See "hdr" for more information on header matching. Use the
% }: F; X! O' E+ T2 e: ?  shdr_len() variant for response headers sent by the server.: C0 f5 l2 D+ O( G

7 \' t2 c: ~* khdr_reg <regex>$ n, N7 K. a' Z+ D. ?+ _, u: M* T, r
hdr_reg(header) <regex>( i1 E  E5 }" X+ A2 \* M- P
  Returns true when one of the headers matches of the regular expressions. It
3 n+ }0 z" q& f# s2 y9 A  can be used at any time, but it is important to remember that regex matching
  e/ B& i1 w' Q& D. h  is slower than other methods. See also other "hdr_" criteria, as well as" o) ?: i& \7 o# B1 A6 y2 o/ @
  "hdr" for more information on header matching. Use the shdr_reg() variant for5 M0 C" @$ C1 H9 b( n3 ~# h, O
  response headers sent by the server.% f6 C7 P0 F: R
& d& M; \$ B, S5 ~% k
hdr_sub <string>! ?! x6 }1 u' h" a3 x; _& U
hdr_sub(header) <string>( T% d; F0 e$ R7 U
  Returns true when one of the headers contains one of the strings. See "hdr"; H2 F! Z* y( L
  for more information on header matching. Use the shdr_sub() variant for! O+ W  }9 B; u. v/ D* D- W
  response headers sent by the server.
( u: F5 r, t0 E5 L* A/ H
( D- }; _( r+ Hhdr_val <integer>2 Q2 b& N! Q% ]) S; L
hdr_val(header) <integer>
+ ]6 i! h' _' Z2 e  Returns true when one of the headers starts with a number which matches the) p* ]/ f- R0 N9 g
  values or ranges specified. This may be used to limit content-length to
9 l( [9 c) q. |8 X/ ^  acceptable values for example. See "hdr" for more information on header" O$ \, l6 I0 y1 h& R& c
  matching. Use the shdr_val() variant for response headers sent by the server.+ J4 x& n9 C% X9 N" O
( A- I6 e5 G$ }7 L
http_auth(userlist)
5 x& u* j: {( U7 Hhttp_auth_group(userlist) <group> [<group>]*
+ c6 v' T8 v! j8 }5 t' Y  Returns true when authentication data received from the client matches* |9 N8 s9 F0 \: y
  username & password stored on the userlist. It is also possible to/ F0 R7 X7 n# K$ @0 R
  use http_auth_group to check if the user is assigned to at least one* S' L: l# y) I  W) w+ M2 b2 ]" K
  of specified groups.* J" ~7 [! ^2 z& k9 |4 |+ ~+ D% E
+ k5 a! e) D# N
  Currently only http basic auth is supported.1 u2 Q$ f9 n4 i# @
5 E& Q$ p, e( r7 U7 e! B
http_first_req* b+ L9 n2 M8 i, Q  I3 J
  Returns true when the request being processed is the first one of the
9 w% \! S6 d9 `; f7 ~  connection. This can be used to add or remove headers that may be missing
5 q- G6 c/ x1 b/ d' e7 v  from some requests when a request is not the first one, or even to perform
' W2 S& k% d/ F; n& y, t) s$ u  some specific ACL checks only on the first request.8 H+ |9 q# o  J% t9 S4 v- q: M
8 z. H0 \! c4 N2 H$ w
method <string>0 G; y& x# L* d
  Applies to the method in the HTTP request, eg: "GET". Some predefined ACL! O, |! w- \, q4 M. u- B' ]; L
  already check for most common methods.
: c/ ]6 l( V0 Y1 A( R8 u
! d) S/ y5 D/ c) ]  C% ]1 w  W$ Xpath <string>
# y( C/ {9 I, {( o  Returns true when the path part of the request, which starts at the first5 V1 T2 W7 Z0 e
  slash and ends before the question mark, equals one of the strings. It may be
) v9 O. u6 I8 O3 x9 v# \  used to match known files, such as /favicon.ico.
; ]9 n8 l7 Z8 ]/ H: Z) U. r; {" }; \" ?/ x# D
path_beg <string>/ @, @; N$ ]0 [  }, c1 ]
  Returns true when the path begins with one of the strings. This can be used) i8 f8 f6 R' \- q  B, Z8 G0 J. C
  to send certain directory names to alternative backends.
' o# ~( E$ ?) \6 l% e: _0 I8 p
; |4 o6 j$ y* b% q9 P6 [8 Xpath_dir <string>7 p6 c8 }3 l  a0 G! i& ]2 f; d
  Returns true when one of the strings is found isolated or delimited with) r3 W, y# `( k
  slashes in the path. This is used to perform filename or directory name/ }  Z, ]- j* U$ a7 M9 J2 v! I/ n! h
  matching without the risk of wrong match due to colliding prefixes. See also
% q/ V( M1 W* t) G% s# o  "url_dir" and "path_sub".
8 p- A5 Q& G) L# X6 o% o& X, v* A% F
path_dom <string>
: z2 B2 g- @) X# y: P  Returns true when one of the strings is found isolated or delimited with dots
& p9 @( w* v4 d5 v4 k% o( ?  in the path. This may be used to perform domain name matching in proxy
7 N3 w+ y$ e( `0 T7 {7 {' M2 [  i. G  requests. See also "path_sub" and "url_dom".
( B( @5 ~& g/ G4 c5 Q0 h- L, p- \" o! N- f8 [' W5 p& l, Q& S
path_end <string>
% ?- _# Y" m6 c1 B; E! l  Returns true when the path ends with one of the strings. This may be used to# F% s& e" O! {' W+ s, ]# y
  control file name extension.  M' m1 M; ^, L

- L- P/ v7 N7 n+ C5 O# ~; z4 Spath_len <integer>* S$ }: e+ Q, z0 {; T& I2 m. F+ W
  Returns true when the path length matches the values or ranges specified.7 ^" U: }* ?4 M& M
  This may be used to detect abusive requests for instance.
( o* H  f9 u2 l* l
- T% j! Y" ]0 H" ]; tpath_reg <regex>
; w  P8 T' {3 k+ N# t  Returns true when the path matches one of the regular expressions. It can be2 c! V  w: ~: W5 h: R% G+ S3 O' p
  used any time, but it is important to remember that regex matching is slower
4 v7 u: n% B: g0 D3 @  than other methods. See also "url_reg" and all "path_" criteria./ C2 n( c1 A% H: E9 k

8 T6 G1 A8 g" i$ \1 c2 wpath_sub <string>
4 h% j5 o* ?' e: ?7 ?  Returns true when the path contains one of the strings. It can be used to
! A  E7 T6 q# w& [  detect particular patterns in paths, such as "../" for example. See also
: z+ ]/ o. C0 _7 m) _1 k  "path_dir".  _# O" j: |3 M) q% i/ g# D. S

- ^  D9 w( C3 `8 U# ereq_ver <string>( P; q2 v% F4 R7 O- q+ M2 {4 f
  Applies to the version string in the HTTP request, eg: "1.0". Some predefined
3 Z6 R$ w" \5 P6 N. h1 D- v  ACL already check for versions 1.0 and 1.1.- d" e+ d9 C- c) A% ]' q/ e& @! O* Y0 E) n: D

2 o1 }  t1 L% [% i- zstatus <integer>
( U0 y* |* ?( H+ i3 w  M  Applies to the HTTP status code in the HTTP response, eg: "302". It can be
1 t8 [7 e8 D' g: N! |! e  used to act on responses depending on status ranges, for instance, remove0 [- ]5 d# D3 s- }/ d
  any Location header if the response is not a 3xx.
6 h% W/ r- f& X& j
9 Y' W% I; _" v, r4 Y/ `/ qurl <string>
5 _+ E, T& {/ i1 C! y  Applies to the whole URL passed in the request. The only real use is to match
1 K. t& \( ?- w6 c7 _  "*", for which there already is a predefined ACL.$ f& Z7 ~" }, K: V( y

% }+ s! G; o9 {2 U. surl_beg <string>
# e3 p/ q& l( U1 P! {# p. y  Returns true when the URL begins with one of the strings. This can be used to
1 ^" v# d. B1 j- |  check whether a URL begins with a slash or with a protocol scheme.
9 X" M7 f4 `- L* r
# N7 v% r$ K$ t, {url_dir <string>
8 [% S" u( j  D) N  Returns true when one of the strings is found isolated or delimited with. \; z$ c2 X. h! W& L! [, @
  slashes in the URL. This is used to perform filename or directory name$ ]1 e  v0 T& @2 O4 g  U4 M6 [3 n
  matching without the risk of wrong match due to colliding prefixes. See also
: A, E6 f. O- p" Z  "path_dir" and "url_sub".4 ~2 P/ J% c% ~
9 m6 W* k7 {7 N9 a" D  ^
url_dom <string>
) g, [* Q5 b2 e  w  t  Returns true when one of the strings is found isolated or delimited with dots$ v, U+ u  C' ^" `- U# f. R
  in the URL. This is used to perform domain name matching without the risk of1 ]6 A7 k' p0 m& M9 `
  wrong match due to colliding prefixes. See also "url_sub".
* B% v* w+ _2 _1 @  K& s: m6 Q8 P+ p! d8 \$ I$ \. v: i
url_end <string>  i. I3 m, K, ?* M! V9 J- |
  Returns true when the URL ends with one of the strings. It has very limited
6 _* ?  h* ~/ [% I' p$ ?  use. "path_end" should be used instead for filename matching.
0 P) k' D5 o. {7 ]+ b9 O8 ^  `$ \: M2 p3 U2 {8 Y- B. }" X9 R3 P# T% O5 p
url_ip <ip_address>6 q7 d( J+ R; k7 m7 f
  Applies to the IP address specified in the absolute URI in an HTTP request./ h6 D' i/ k1 m! `" e$ f6 A% `' E
  It can be used to prevent access to certain resources such as local network.
: v5 U0 V2 h9 p3 Q  It is useful with option "http_proxy".$ `( m/ V7 v9 V  `' G2 W
3 q$ {, N. ^3 Z# B7 @; r% N
url_len <integer>) s7 O5 c! C& B; X: V# H" l
  Returns true when the url length matches the values or ranges specified. This- K4 E! S$ B  K$ o
  may be used to detect abusive requests for instance.
' r, R2 |- L2 {9 j1 J
+ K6 K% L+ d- b$ R& Q! |url_port <integer>
0 M4 V+ c7 s$ d- ]' K4 e4 J  Applies to the port specified in the absolute URI in an HTTP request. It can
  v3 A: U' J3 P7 a  r- ^  be used to prevent access to certain resources. It is useful with option! q: n% r7 B, S
  "http_proxy". Note that if the port is not specified in the request, port 80
, \* A& W' x# z3 v  is assumed.6 ^3 k. a) V$ I0 e. }" {9 j

; s4 o- B% N% s5 D! Aurl_reg <regex>
0 ]1 V, r# G7 J8 l  Returns true when the URL matches one of the regular expressions. It can be
2 P1 i$ W' j& m$ V8 H8 f' c" R1 G3 N! _  used any time, but it is important to remember that regex matching is slower2 x$ W4 r: b' j
  than other methods. See also "path_reg" and all "url_" criteria.: r# W' z8 k& ?) k8 @9 [& i
$ V/ h! T% [# |  ^+ v
url_sub <string>
' b6 Q& v: M9 [3 `) Y  X! |  Returns true when the URL contains one of the strings. It can be used to
' n+ c5 F. S4 E0 y6 j  detect particular patterns in query strings for example. See also "path_sub".
+ r: a9 |$ |" s
+ r' g7 ]; R5 V7 [9 x1 T, y
0 j0 _" R7 Z, j, J! V8 n+ I7.6. Pre-defined ACLs2 x- `: V5 q3 E& o' O+ T6 t* a
---------------------
" y+ e: ^6 C4 v5 G6 j  X
5 D; _! G0 g) S1 tSome predefined ACLs are hard-coded so that they do not have to be declared in& u2 X9 Q2 i* `2 K* D! K6 |
every frontend which needs them. They all have their names in upper case in: D/ S; ]- d* V5 v5 X, k% _
order to avoid confusion. Their equivalence is provided below.0 g: K- P' q, g9 A3 R3 s+ v% I
$ T& x; f1 ^/ H1 N, j
ACL name          Equivalent to                Usage
& x! e0 S( O" C$ V9 Y4 v---------------+-----------------------------+---------------------------------
- m$ \; P7 `* j& j, M) nFALSE            always_false                  never match
# x3 T  S- l- m$ ^HTTP             req_proto_http                match if protocol is valid HTTP0 i- f: S0 k& o1 l
HTTP_1.0         req_ver 1.0                   match HTTP version 1.0/ d: {7 P7 M8 G0 E" r
HTTP_1.1         req_ver 1.1                   match HTTP version 1.14 Y7 C( ^3 S4 f4 e* W2 B
HTTP_CONTENT     hdr_val(content-length) gt 0  match an existing content-length
+ [/ d6 H1 y) |) d* p; t4 jHTTP_URL_ABS     url_reg ^[^/:]*://            match absolute URL with scheme
( N3 X' b2 C5 w  V  |, R0 V$ iHTTP_URL_SLASH   url_beg /                     match URL beginning with "/"
/ q7 M" W6 F4 _6 N! X) fHTTP_URL_STAR    url     *                     match URL equal to "*"
( N4 e6 h' S9 \LOCALHOST        src 127.0.0.1/8               match connection from local host
) G. ~/ |- ]8 D5 b' p& ]METH_CONNECT     method  CONNECT               match HTTP CONNECT method
. J! y: Q$ j4 d( u; C4 U' x# `' fMETH_GET         method  GET HEAD              match HTTP GET or HEAD method
$ v$ P! \0 q+ r! eMETH_HEAD        method  HEAD                  match HTTP HEAD method
: g  G# ?% m7 X" _2 c. T; jMETH_OPTIONS     method  OPTIONS               match HTTP OPTIONS method
, V- {3 @' s( T7 x  f: N0 R" kMETH_POST        method  POST                  match HTTP POST method# j4 ?# _2 ^9 Q  a- o& U
METH_TRACE       method  TRACE                 match HTTP TRACE method
# T7 S" m# V; x$ D- qRDP_COOKIE       req_rdp_cookie_cnt gt 0       match presence of an RDP cookie
8 ^6 a. D' ], G, \3 AREQ_CONTENT      req_len gt 0                  match data in the request buffer
; k2 ~* l+ [5 e' }) n$ s) \TRUE             always_true                   always match! Z" \2 u1 w" r  f1 [  E" W1 P
WAIT_END         wait_end                      wait for end of content analysis
. k& x' Z0 l* J# Y) m( ?3 ^( v---------------+-----------------------------+---------------------------------
) K" \  Y# W/ ^5 |% w6 Z
/ `2 r0 P* c: N1 g
, a* z; x1 K. @7 I8 x7.7. Using ACLs to form conditions3 ^+ ?5 `2 {' [4 s' K% w, L
----------------------------------" w( ^( }! r9 \6 a8 r! w! i9 g2 W

1 `2 Q2 }& ^& `+ g, n) VSome actions are only performed upon a valid condition. A condition is a
& D8 I9 ^0 C  n# \& {& E. Y& rcombination of ACLs with operators. 3 operators are supported :" j% Z6 P) }8 \/ Y) E1 w! b

3 K  z# n# C0 ~' |3 y2 Z7 V  - AND (implicit)4 Z2 ]0 F, |, o! |: t
  - OR  (explicit with the "or" keyword or the "||" operator)
7 N5 X1 R0 ]& H. O/ K  - Negation with the exclamation mark ("!")
6 J8 U; k, n8 B% C' n  D5 X* T% s+ J" A# a& l
A condition is formed as a disjunctive form:
) v: R3 [$ o( ?5 ]& Q7 D7 }9 `7 s# Y% k# A5 P; Q( F
   [!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...
  m; K1 _) Q0 q2 \
. D% o7 ~. K7 p0 r2 k% `Such conditions are generally used after an "if" or "unless" statement,2 T4 D- K- J2 `6 Z9 n. T7 G$ `
indicating when the condition will trigger the action.
. V  f* W2 a* ^4 U
" o2 P. E- H0 b; d, Q6 }For instance, to block HTTP requests to the "*" URL with methods other than, V% }1 x; j0 `; _4 O* t! J9 ?
"OPTIONS", as well as POST requests without content-length, and GET or HEAD: o6 H6 m7 X0 ^8 d5 G! @
requests with a content-length greater than 0, and finally every request which$ w0 N6 y9 j. z1 I+ \- B
is not either GET/HEAD/POST/OPTIONS !
: {4 S9 x3 _1 `4 X6 O+ X6 E2 H" a4 x9 W" W7 C+ \5 _
   acl missing_cl hdr_cnt(Content-length) eq 0
: ~6 d4 N0 b6 X9 c; i. C   block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
7 I9 J9 K. h# x4 V- @6 T/ W   block if METH_GET HTTP_CONTENT) n4 |8 u. [, G% N5 ~% G# q
   block unless METH_GET or METH_POST or METH_OPTIONS% t% x; U* A. g( t- e6 g( d1 q  z
' x' ]% R5 q2 @* _& {  s' A
To select a different backend for requests to static contents on the "www" site
, n7 G, y! [, _2 b  |; s9 |( Hand to every request on the "img", "video", "download" and "ftp" hosts :1 Z* Q) O" ?* T# u- r( Y+ M
0 e7 W1 L2 Y0 B' J
   acl url_static  path_beg         /static /images /img /css) v6 ~* }) `2 e1 f5 Q
   acl url_static  path_end         .gif .png .jpg .css .js
0 e" g& }! w1 c! D4 l! R   acl host_www    hdr_beg(host) -i www
/ C/ G- P- o+ d. e" Y   acl host_static hdr_beg(host) -i img. video. download. ftp.
$ L& s" i% N1 a& }' T
  X, \' i, d8 K5 x# }   # now use backend "static" for all static-only hosts, and for static urls
3 h2 E% }0 w, g   # of host "www". Use backend "www" for the rest.
( g; l! ~" a% w5 D# z6 O$ m   use_backend static if host_static or host_www url_static( m* L- ]2 m. m% a- E/ c
   use_backend www    if host_www
. ]! ^! K7 E1 j4 m  P0 }5 [8 |5 ^6 a% R% O6 T) o  {4 x
It is also possible to form rules using "anonymous ACLs". Those are unnamed ACL
* m4 Z& b. ~0 K7 Fexpressions that are built on the fly without needing to be declared. They must
3 y  w" t) H/ ^/ |be enclosed between braces, with a space before and after each brace (because
# ]- O. l/ f9 a& p; n) u2 M, c; othe braces must be seen as independant words). Example :
* N! z2 N" w; A
" u/ l! ~$ m9 j+ }4 a$ Y   The following rule :( o# Z9 x: ?4 q( I, o+ Q7 d

! I$ S; N1 l$ B. p9 M( G6 _( }       acl missing_cl hdr_cnt(Content-length) eq 0" g( Y; _( n) w5 i# `
       block if METH_POST missing_cl5 N' k- \, j2 P
; ^) k$ z# s5 Y) ?! V. C
   Can also be written that way :
7 i1 C& t( }  w) H+ A# W$ R8 j8 q! @, D
$ H. R# ^& l4 F' M8 R       block if METH_POST { hdr_cnt(Content-length) eq 0 }8 u9 C0 w. Q! D, c+ @

  p# N& D) \, n# j! a& a, p9 k, |, EIt is generally not recommended to use this construct because it's a lot easier& f4 @! C3 R2 w
to leave errors in the configuration when written that way. However, for very/ g# M) E/ r# \$ p2 {" a7 L! d
simple rules matching only one source IP address for instance, it can make more7 N2 z: Y2 w( l
sense to use them than to declare ACLs with random names. Another example of
0 V/ M; t6 j6 Lgood use is the following :
( k0 c  F( r# y: j; c) G9 ]
) I- h( a6 s; p. E/ S8 a" e. F   With named ACLs :
4 j0 Q! ~( x# l+ c  p; V4 y. [1 N* U  U1 q# m
        acl site_dead nbsrv(dynamic) lt 2
1 J$ x, X1 h1 V! Q        acl site_dead nbsrv(static)  lt 2& z* f! B! j* X& y% X
        monitor fail  if site_dead: m4 y) z: u+ j7 S; h7 J, Z3 r, Y0 a
+ J) L5 {- l2 H* c
   With anonymous ACLs :$ F1 ]  Z7 q$ V8 l
( t) ]4 ~/ I3 c4 Y% X: u
        monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
* b% w3 H0 N: Y: `( f* r. q4 C, T- _$ }" M& a; R2 p* B" L7 i
See section 4.2 for detailed help on the "block" and "use_backend" keywords.
- ?# y5 {3 j5 i, ^' S4 Y, U( |  o9 y$ T2 ?" O" N3 R+ p

2 _; z2 L4 J( X% [. @( ^% ^- Y7.8. Pattern extraction7 k* v4 A* r+ e# d" M
-----------------------
' {% S$ H  t/ j5 P: m) Y  o# c) |- y1 R* Z/ k+ S+ K
The stickiness features relies on pattern extraction in the request and3 e! @3 ?" Z' O
response. Sometimes the data needs to be converted first before being stored,
: F8 J, H1 W- J% yfor instance converted from ASCII to IP or upper case to lower case.
8 x. @) @, T8 ~2 P' P' y3 l- x3 j' u0 o
All these operations of data extraction and conversion are defined as4 \1 W7 ^2 l1 P( T' i8 z3 Q# i
"pattern extraction rules". A pattern rule always has the same format. It8 i0 V) |! n& ^+ o
begins with a single pattern fetch word, potentially followed by a list of
% m# [& y; t7 t6 @" O* M5 X- karguments within parenthesis then an optional list of transformations. As
7 x, C, n+ @: O& F# [much as possible, the pattern fetch functions use the same name as their
7 [' P2 k# w( I! q" Requivalent used in ACLs.4 w$ R- m: X3 w: S5 ~' |: Z3 [
2 J; E& f% T3 m- w4 K9 e
The list of currently supported pattern fetch functions is the following :: I. G& A" P2 q" f  N

. I- \5 t" g# Z  src          This is the source IPv4 address of the client of the session.
5 z2 a# v2 L' P$ ^               It is of type IP and only works with such tables.( p/ i/ @% G2 o. ]* t* c, o
0 j1 m+ s- l0 U" k
  dst          This is the destination IPv4 address of the session on the
) F/ }7 f& C) q- k$ t& B- V8 \               client side, which is the address the client connected to.
# P5 a6 i. q( F% p               It can be useful when running in transparent mode. It is of$ @+ j, y+ M: o0 [* G% M3 \4 V
               type IP and only works with such tables.- B; J' d2 ^+ ~; j4 a

; {) P5 i/ b0 K  dst_port     This is the destination TCP port of the session on the client
) R! _# d  D4 \% |               side, which is the port the client connected to. This might be
& P* B, ?/ L5 y  M( G1 h) s               used when running in transparent mode or when assigning dynamic
8 ^3 b2 f% a* x) @/ j4 e7 P2 g3 N& G, t               ports to some clients for a whole application session. It is of1 z  m" ?' B/ q7 y+ B
               type integer and only works with such tables.$ t5 n/ A; h0 H  O- z: |7 J! C

2 P) C% `% H8 f  hdr(name)    This extracts the last occurrence of header <name> in an HTTP
* w) E7 o0 F# Q: C, B               request and converts it to an IP address. This IP address is1 w! h$ Q7 O: [" p. ?  T5 n
               then used to match the table. A typical use is with the, f9 F! F/ q. g- s& r8 J
               x-forwarded-for header.
# \: [) T# m/ c2 Z- L2 g
$ U7 `7 ~1 p0 W( d9 c+ A2 F
; ]) V8 s8 |# F8 _; pThe currently available list of transformations include :
% s- K2 q* M6 W( G: T
4 z, W4 i, o0 m' h5 }. s  lower        Convert a string pattern to lower case. This can only be placed* s1 {( T8 U& ?& \( O) v
               after a string pattern fetch function or after a conversion" \# s2 J: W* W# d+ B
               function returning a string type. The result is of type string.
. V1 _8 Y' D8 X! B+ E- J( w7 e/ Y  t: i/ w! ]6 @
  upper        Convert a string pattern to upper case. This can only be placed
1 H- z+ P, f7 n, j- H9 }. w               after a string pattern fetch function or after a conversion
, k7 g7 z1 Q2 `               function returning a string type. The result is of type string.3 }, I+ T- p6 q

$ V8 d  N' W8 `% r/ _0 S  ipmask(mask) Apply a mask to an IPv4 address, and use the result for lookups* }' `% [3 ?  n
               and storage. This can be used to make all hosts within a
1 I* t) b) u$ [' w, Q; g               certain mask to share the same table entries and as such use3 R2 w) @+ C, Q7 E) J2 B: V  p
               the same server. The mask can be passed in dotted form (eg:
  ?, w8 Q7 _$ J) `% w5 p               255.255.255.0) or in CIDR form (eg: 24).
7 c! O+ {- H/ I( a
0 l& k+ N7 E: K6 @
; I0 K$ k* L% j( b: V7 `0 q, g8. Logging% C) @! f: X. a3 ~
----------
6 T7 q8 M; p) A0 m
4 U) W$ i6 h+ n, h1 p# IOne of HAProxy's strong points certainly lies is its precise logs. It probably  |; T% d% U! R2 R2 s$ u$ k, X7 R
provides the finest level of information available for such a product, which is1 P8 U3 X* P+ H* z" V
very important for troubleshooting complex environments. Standard information
( B$ Q3 K( L: Iprovided in logs include client ports, TCP/HTTP state timers, precise session
; V/ }* w5 N8 _% |state at termination and precise termination cause, information about decisions
0 P1 v% x  Q2 M+ J! V6 yto direct traffic to a server, and of course the ability to capture arbitrary
- @4 K! C' E& {* I& S" Z# h8 Lheaders.
6 s# T6 g0 N% |- @( [! Q; W7 ^* `
; X( P/ f- g1 i" R8 y7 ?In order to improve administrators reactivity, it offers a great transparency
3 u$ @; ]  P/ a; c  M2 |about encountered problems, both internal and external, and it is possible to
  g- D2 m2 F7 fsend logs to different sources at the same time with different level filters :, s* X9 q( k/ r% w4 s& \" `& s

5 n7 b8 |/ t! V6 M  - global process-level logs (system errors, start/stop, etc..)6 }+ O+ o% k+ d6 K1 Y
  - per-instance system and internal errors (lack of resource, bugs, ...)8 R2 V/ P: g3 D) c$ `/ M4 @
  - per-instance external troubles (servers up/down, max connections)
9 k% g, C" a  W7 t# X, \  - per-instance activity (client connections), either at the establishment or
$ _% v& Z8 a' ?8 S% Y" s% C/ M9 U    at the termination.
; X- P0 G3 i2 v$ K' s% D" Q, G, W0 f& e! O
The ability to distribute different levels of logs to different log servers
/ N% C5 b& S' i) w0 qallow several production teams to interact and to fix their problems as soon$ @2 F% D: M6 a; R+ z
as possible. For example, the system team might monitor system-wide errors,+ \6 @9 t. [4 H) G! U
while the application team might be monitoring the up/down for their servers in
1 Y6 b0 u6 g2 }3 A/ Hreal time, and the security team might analyze the activity logs with one hour3 [0 |3 f5 y9 U# I* J+ B
delay.( s2 K# y! A1 L9 |! x' m) @
; ~% Y7 F: Y$ ]3 ^- J
) K6 u2 x& u8 Q
8.1. Log levels
5 A5 t* r$ s$ e2 I---------------
8 F' [! z$ e% `4 X. G4 i1 i2 A8 r, s1 h( ?. ~: ^! `& G2 r) y
TCP and HTTP connections can be logged with information such as the date, time,+ N, r1 x) E4 F/ L+ o
source IP address, destination address, connection duration, response times,* X: i& D# e5 p, I% _2 z
HTTP request, HTTP return code, number of bytes transmitted, conditions
% m" |6 z+ ?; z* ?2 m# U' Tin which the session ended, and even exchanged cookies values. For example
+ k: ^& N) q7 }6 X8 @5 utrack a particular user's problems. All messages may be sent to up to two3 L# U3 I4 k! w* o
syslog servers. Check the "log" keyword in section 4.2 for more information
" L0 D/ i/ }, `+ Gabout log facilities.4 ^7 M5 r( {( p
0 G6 h$ b; B( f5 i3 h" s% e% |9 G/ t
5 X; E# G) c  Z! ~% [
8.2. Log formats
3 o6 i. M0 T: R: z1 l----------------
, ^' V) G$ m% }: Z9 H  R; G+ m) v1 m- q+ R
HAProxy supports 4 log formats. Several fields are common between these formats, B$ M$ C6 f- g  C5 A
and will be detailed in the following sections. A few of them may vary; {) T. t) l$ E6 }
slightly with the configuration, due to indicators specific to certain* r8 f0 {8 j( x8 a2 S5 W: b" S
options. The supported formats are as follows :
- T* [6 s8 N9 Q5 k
+ b% F; P! W/ w0 T8 |  - the default format, which is very basic and very rarely used. It only- F8 n4 p$ a0 @) p
    provides very basic information about the incoming connection at the moment
' b2 T7 n6 g' d7 a6 T    it is accepted : source IP:port, destination IP:port, and frontend-name.3 D- V9 j9 j' h/ H5 A
    This mode will eventually disappear so it will not be described to great: |$ w- v) m* K4 c3 Z; E" N5 f
    extents.
7 `6 x8 _2 Z9 |2 T8 F# w: _. S
4 ~3 Z3 H7 }1 Y. Z* c  - the TCP format, which is more advanced. This format is enabled when "option% H  w% W! M5 I+ o+ `3 X
    tcplog" is set on the frontend. HAProxy will then usually wait for the
% a# o' a6 z# M: Q    connection to terminate before logging. This format provides much richer
( f6 o) g! m! i0 n7 A! `# ?    information, such as timers, connection counts, queue size, etc... This
- o( S: n  a. O$ f0 X    format is recommended for pure TCP proxies.
( W; N& {1 `# c. i* t* {; z3 {' R2 t# x1 r2 Q
  - the HTTP format, which is the most advanced for HTTP proxying. This format7 H0 f! ]9 s3 @2 `# n2 |1 B/ ]! j
    is enabled when "option httplog" is set on the frontend. It provides the
2 v" ]. [% D! i. K5 g$ N    same information as the TCP format with some HTTP-specific fields such as: t! c0 m- \. [" T* C4 N, _
    the request, the status code, and captures of headers and cookies. This
! W3 s5 p  x- a1 n% L    format is recommended for HTTP proxies.8 a7 g% ~) o) Q/ T- P# m
/ I( ^8 s$ {( g" u! l# B5 d
  - the CLF HTTP format, which is equivalent to the HTTP format, but with the
0 s2 }8 A6 I0 m% T5 `( a  |    fields arranged in the same order as the CLF format. In this mode, all9 e' G7 q! {( O
    timers, captures, flags, etc... appear one per field after the end of the1 I$ f+ k8 }  }2 R) {! y
    common fields, in the same order they appear in the standard HTTP format.
' g/ x* Q7 m  ^) U% `
8 ?. |4 i1 T. a% Z6 ~! oNext sections will go deeper into details for each of these formats. Format7 _3 @) O$ z% F! i6 m
specification will be performed on a "field" basis. Unless stated otherwise, a9 ?3 n: Z( j& p8 e7 P8 m& h
field is a portion of text delimited by any number of spaces. Since syslog! V( t6 M/ {# m! m6 f
servers are susceptible of inserting fields at the beginning of a line, it is
% r4 b' e. x9 v7 X; D; palways assumed that the first field is the one containing the process name and
1 q2 s5 s' |# l  s- S9 m0 ]identifier." ]. ~/ E# x6 k: m- Y( c/ x. ^" n
: G  S! a& f. a8 y
Note : Since log lines may be quite long, the log examples in sections below4 l& p8 H, ~  e2 B% ]
       might be broken into multiple lines. The example log lines will be
; ]; I% I5 h1 e* x: b" k       prefixed with 3 closing angle brackets ('>>>') and each time a log is
; m3 d# ?9 m$ w! ^/ {4 @       broken into multiple lines, each non-final line will end with a
1 j; [  m* u1 W0 w9 d+ Z' {       backslash ('\') and the next line will start indented by two characters.6 y$ {# P  l* e6 `4 K5 v$ A4 q
- r+ }! o9 a% b1 x3 y- Q
6 |/ N" q/ t- K, N, M
8.2.1. Default log format" `2 ~: X5 K. z. L& X$ I
-------------------------+ D8 {6 @5 W) M2 t, r

2 q0 I( [' K; Y+ h' v5 {$ S2 j( CThis format is used when no specific option is set. The log is emitted as soon
( A+ H6 x9 C/ cas the connection is accepted. One should note that this currently is the only* T! E% I# z! \, K
format which logs the request's destination IP and ports.( c% P3 b+ `2 u9 N
  b/ J% Z/ f. l$ J
  Example :
6 q+ x3 T2 U0 D* [        listen www, l5 Q# i! Z$ X8 }+ I: V6 U" W
            mode http
! `% I( y) Z7 O/ m            log global
4 |9 I  Y. @5 h  a" `6 S0 @( Z            server srv1 127.0.0.1:8000  v0 _! y+ Y6 U. L" O& K. `

+ B7 u7 U3 U* P    >>> Feb  6 12:12:09 localhost \
* I% R! J8 }$ l. v7 Z) o          haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \. b  l2 H. G4 p2 W
          (www/HTTP)( o& k. M9 P5 a+ ?. v4 _/ |
8 o9 e5 Q* w4 f  q5 \) w
  Field   Format                                Extract from the example above
- s; J2 T' j7 `2 v. @0 ?      1   process_name '[' pid ']:'                            haproxy[14385]:
& y( c0 W$ u$ \* s1 \- s      2   'Connect from'                                          Connect from+ x& H/ r% Z: e5 s, {
      3   source_ip ':' source_port                             10.0.1.2:33312% z, D1 _% R1 Z' I- a+ u
      4   'to'                                                              to
. [6 T4 E$ q* }8 \( \# T7 n      5   destination_ip ':' destination_port                   10.0.3.31:8012
' e$ k' X2 a' m0 T$ v/ ^! l      6   '(' frontend_name '/' mode ')'                            (www/HTTP)
. h+ o$ k# O6 Q. T% O! f8 l  U" ~/ m, r, B0 e* K
Detailed fields description :1 [7 l  x7 T( s, y9 M4 a
  - "source_ip" is the IP address of the client which initiated the connection.! c- o( e6 d8 C4 t
  - "source_port" is the TCP port of the client which initiated the connection.! j' u; W4 w' ]& Y
  - "destination_ip" is the IP address the client connected to.
" T* a1 t: u% ]5 S& p  - "destination_port" is the TCP port the client connected to.0 {$ ]% R! o3 r% Z( b
  - "frontend_name" is the name of the frontend (or listener) which received1 v" e* {3 l. }% C' R# u
    and processed the connection.; J) D3 q: h* _: ^4 ]: ?
  - "mode is the mode the frontend is operating (TCP or HTTP).' ?) [. j& `0 k& I
* T$ t+ W1 c$ l- M
It is advised not to use this deprecated format for newer installations as it
- A: Z1 g- [& l: \/ B4 Dwill eventually disappear.
3 w8 P0 N- k. O) X/ n0 z' r0 j5 K. J

; j2 {2 f$ _* |# R9 ], h" W8.2.2. TCP log format
8 i- J5 j5 V4 y. [9 i8 {---------------------( h" S# P5 X1 S
% n% G4 O" t: J( q- Z4 f
The TCP format is used when "option tcplog" is specified in the frontend, and) d! ^% Z9 R  T1 P
is the recommended format for pure TCP proxies. It provides a lot of precious6 K6 o: |0 j# R' U; G6 j  R
information for troubleshooting. Since this format includes timers and byte5 o. U, g0 U! q7 {4 O! \  x
counts, the log is normally emitted at the end of the session. It can be
. s( i/ u5 u8 ?( Q# i) h  B' iemitted earlier if "option logasap" is specified, which makes sense in most; s1 h& y1 c+ R" K
environments with long sessions such as remote terminals. Sessions which match% ^  P, L+ d9 E3 i0 U7 ~& x' W$ E
the "monitor" rules are never logged. It is also possible not to emit logs for
1 n8 o2 t+ t& Q: I5 r- ssessions for which no data were exchanged between the client and the server, by6 N- E( Q6 _2 Q3 M& f  `
specifying "option dontlognull" in the frontend. Successful connections will
- N+ m) b7 e7 b6 {/ K# onot be logged if "option dontlog-normal" is specified in the frontend. A few
- e0 I& d) A* z' ~fields may slightly vary depending on some configuration options, those are
5 I* C8 x- s# N( |" l9 umarked with a star ('*') after the field name below./ h* a: k: U9 o5 I. f

/ m$ j$ R% o7 y9 z- s  Example :
8 u# T% I" c) U2 z/ q  q* F0 z, x        frontend fnt
; H, C0 T: S( h& Z. H2 z            mode tcp
( R0 H0 n/ P0 \5 V1 V            option tcplog
# P- Q7 W8 `- t; P            log global
( V* C, I+ U& ]2 L0 d7 o            default_backend bck. t6 Y6 s6 S  S0 t6 z( o
' Y8 ^- P1 B9 i( H& P2 r
        backend bck* S% E6 I& v+ `; P- ^" ]2 s
            server srv1 127.0.0.1:8000
6 L; ^1 S1 b4 {- n. W+ K# F% O* V6 q7 N+ ?0 T. l& F
    >>> Feb  6 12:12:56 localhost \1 Q6 z- [2 S1 F2 R, F0 F
          haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \
' N. g( ^6 b( d) k          bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0& H) T9 g; L* j& i7 Z8 i
7 y1 b2 r/ L9 g
  Field   Format                                Extract from the example above3 O! ~% n: B0 X: z+ z4 N% |
      1   process_name '[' pid ']:'                            haproxy[14387]:3 Q, J9 e: J  _. C$ P
      2   client_ip ':' client_port                             10.0.1.2:33313
' H& x) \" l; I9 g! W) N      3   '[' accept_date ']'                       [06/Feb/2009:12:12:51.443]+ `( \, F; N3 p! F' I5 |1 s
      4   frontend_name                                                    fnt% C% D) f9 F" [8 H
      5   backend_name '/' server_name                                bck/srv1
$ K. j+ b$ o4 z; v      6   Tw '/' Tc '/' Tt*                                           0/0/5007
2 D1 }  D) g( s' e$ h, G      7   bytes_read*                                                      2129 e0 M5 l9 b- R/ ~
      8   termination_state                                                 --  P  A: j8 t' a5 S0 S
      9   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    0/0/0/0/39 `  H0 I. `; f* U/ F0 d
     10   srv_queue '/' backend_queue                                      0/0
" M3 g! f/ r& `1 Y: O1 O) ?1 N- \9 h0 \% h
Detailed fields description :6 j: B% J7 V$ g. F1 \" H
  - "client_ip" is the IP address of the client which initiated the TCP; D" O* ~* ]1 h7 g" b* E, s% X- d
    connection to haproxy.
8 T& e% L8 L! A% T; K9 C2 F; E! h7 f' q" F1 L9 u5 r
  - "client_port" is the TCP port of the client which initiated the connection.4 i" d8 N2 _8 S4 y4 \7 L9 O2 w! k

; C& `; w4 I- ~' u% E+ S  - "accept_date" is the exact date when the connection was received by haproxy
0 h& N$ G+ Z  i8 b/ {% c% C+ t5 g+ z    (which might be very slightly different from the date observed on the$ y0 I; A9 j9 Q
    network if there was some queuing in the system's backlog). This is usually8 B" [. y8 R( `4 F8 G1 Q0 O
    the same date which may appear in any upstream firewall's log.
: a, g1 [; ]9 {# J$ O) J  h( W8 w0 T$ y& I" U
  - "frontend_name" is the name of the frontend (or listener) which received) C* C- p; ]2 ]3 _+ `" b- d1 t
    and processed the connection.
# J- V1 l9 D6 N; m! L  d
% A+ w8 _. l. l5 x$ o0 l3 i$ o8 X2 v  - "backend_name" is the name of the backend (or listener) which was selected
' l! E8 x8 z$ H( K" D% K    to manage the connection to the server. This will be the same as the# c( S, \" \2 g" y  p- D
    frontend if no switching rule has been applied, which is common for TCP
9 |1 m, H( L1 g    applications." L5 R  j2 S9 G$ D; r+ V

  x8 k4 Z% ?* T% E+ y; o' N  - "server_name" is the name of the last server to which the connection was
7 U& p0 O0 Z0 f) ?: H  L    sent, which might differ from the first one if there were connection errors
4 e6 n. |. p* s) V    and a redispatch occurred. Note that this server belongs to the backend
, k% g& h3 M( F    which processed the request. If the connection was aborted before reaching
8 ~9 }8 O% @+ W( x    a server, "<NOSRV>" is indicated instead of a server name.
9 D" z9 J4 ?  i; d5 n
& q* |1 ]0 v! [. \2 I' C# D2 y3 L  g  - "Tw" is the total time in milliseconds spent waiting in the various queues.; P1 U5 y) q. X4 o
    It can be "-1" if the connection was aborted before reaching the queue., P$ }8 h# ]+ s
    See "Timers" below for more details.3 ]0 I% \$ b! B' @
/ v- j8 D9 W: I+ `+ w6 w
  - "Tc" is the total time in milliseconds spent waiting for the connection to( a8 m6 v! t8 T% l
    establish to the final server, including retries. It can be "-1" if the
1 E8 ^8 Q9 [1 v1 g    connection was aborted before a connection could be established. See6 a1 o; w+ e( N' w% i" z
    "Timers" below for more details.- G; T0 S2 a2 z( l" Q1 s" ~
0 u* V! L0 _) V9 i! x9 g& V0 N1 F  _
  - "Tt" is the total time in milliseconds elapsed between the accept and the
, G* ~" Q& ], n    last close. It covers all possible processings. There is one exception, if
4 F. R8 t/ J6 S% L    "option logasap" was specified, then the time counting stops at the moment
* u  g/ O& S2 L6 v' v+ z    the log is emitted. In this case, a '+' sign is prepended before the value,9 Q' h$ i6 ^, g) T% m# M) j1 Y
    indicating that the final one will be larger. See "Timers" below for more
5 r# W$ _/ E3 L' h) n; Q    details.
, h. y, a& V4 k9 \; W
2 D5 e( Y( f# G/ U  a  - "bytes_read" is the total number of bytes transmitted from the server to/ v% l3 ^, E! p( D) z, i2 G
    the client when the log is emitted. If "option logasap" is specified, the* `8 ?3 F1 u% ?% r9 |
    this value will be prefixed with a '+' sign indicating that the final one8 [6 N1 B  W3 h2 j. @1 X9 }+ P
    may be larger. Please note that this value is a 64-bit counter, so log
) |8 F- Q" U& |    analysis tools must be able to handle it without overflowing.1 ~. k) L, {! O& a; G
" T6 M7 c- ^& A8 S
  - "termination_state" is the condition the session was in when the session9 i- r' U6 ^+ z. J# K
    ended. This indicates the session state, which side caused the end of+ }- I/ {* s+ k# g) E
    session to happen, and for what reason (timeout, error, ...). The normal
% v# A( X/ A* h3 S4 D    flags should be "--", indicating the session was closed by either end with
( s1 H! K4 u! d& t* z1 y+ H$ ~$ Z& h    no data remaining in buffers. See below "Session state at disconnection"0 A5 M1 V* J  Y
    for more details.' p: a. p* l' L) T  x

4 i9 h5 |4 s) V: Q- T6 v) g  - "actconn" is the total number of concurrent connections on the process when9 C9 t3 I: X; n# j
    the session was logged. It it useful to detect when some per-process system
: X" O) e+ r- h$ n    limits have been reached. For instance, if actconn is close to 512 when
9 V9 I: p6 t4 I5 w" h% K    multiple connection errors occur, chances are high that the system limits
( G3 Z5 ~: Z. L7 p# e    the process to use a maximum of 1024 file descriptors and that all of them8 Z8 ^; z, c# S# j2 m
    are used. See section 3 "Global parameters" to find how to tune the system.; L: n" o* y6 j5 m% N. b

) W4 U( v6 n& Y1 M. ]0 P  - "feconn" is the total number of concurrent connections on the frontend when
4 k4 O2 J# A0 |; l: Z' d    the session was logged. It is useful to estimate the amount of resource" m# h+ N  L2 C  ?; G2 p( \# G
    required to sustain high loads, and to detect when the frontend's "maxconn"4 `- E4 \1 n  F  M1 t1 o1 r
    has been reached. Most often when this value increases by huge jumps, it is# V  M1 p8 b: o) B7 y7 R7 D! {
    because there is congestion on the backend servers, but sometimes it can be
; [, i3 [! E' d    caused by a denial of service attack.
  w1 o, M# L% ^% e! @  b
4 c; ?) \  s* U9 g: z- \  ]  - "beconn" is the total number of concurrent connections handled by the
0 D1 @4 R+ |& t9 Y# {; o7 C    backend when the session was logged. It includes the total number of
$ b& V6 W) e7 N- o4 D4 j/ f    concurrent connections active on servers as well as the number of: Q3 y6 L: ^, X, q0 S- t+ v
    connections pending in queues. It is useful to estimate the amount of4 `2 [9 _* r$ {( p
    additional servers needed to support high loads for a given application.
6 N4 V* A3 i6 V! _    Most often when this value increases by huge jumps, it is because there is/ a* m% H+ P% y( X6 A" G# r
    congestion on the backend servers, but sometimes it can be caused by a
  @3 h  X% R$ `* _. E    denial of service attack.
  p3 \+ H1 D; g* v
3 C6 i5 h( N& v4 a* M2 v  - "srv_conn" is the total number of concurrent connections still active on5 C  v4 C+ N+ t% H9 y2 k
    the server when the session was logged. It can never exceed the server's, Z$ i7 G! L, {/ G- [
    configured "maxconn" parameter. If this value is very often close or equal
; [; f* \0 H9 R% j    to the server's "maxconn", it means that traffic regulation is involved a  L9 r- R: T) o: V' g& E
    lot, meaning that either the server's maxconn value is too low, or that
9 q  h; u2 B6 K    there aren't enough servers to process the load with an optimal response
$ S9 B. y( u  O2 A0 y1 z6 v    time. When only one of the server's "srv_conn" is high, it usually means" K( N+ `/ ~% e( z8 c1 |+ [
    that this server has some trouble causing the connections to take longer to4 k3 x/ A- T" Y: I% {0 q2 ~; Q: C
    be processed than on other servers.8 v8 m! Q2 f! ^
, b4 l! ]- Y) @# X' m2 D
  - "retries" is the number of connection retries experienced by this session
# w& X) ]( I/ Q( ^, m3 u    when trying to connect to the server. It must normally be zero, unless a
. S8 l6 a( b# m% y    server is being stopped at the same moment the connection was attempted.
# s( y  Y3 p# x3 P, R, ]6 R+ Z; L- f    Frequent retries generally indicate either a network problem between
& Q3 [6 m6 V* E" e6 ], U    haproxy and the server, or a misconfigured system backlog on the server3 T; }: o* @. u! H) N$ o
    preventing new connections from being queued. This field may optionally be
8 ~. A3 p$ U$ G    prefixed with a '+' sign, indicating that the session has experienced a" g8 l  O# h  Y. `; R
    redispatch after the maximal retry count has been reached on the initial
/ z6 ^# _8 E* o- }    server. In this case, the server name appearing in the log is the one the; A; U# A( U+ z& |, [) x( A
    connection was redispatched to, and not the first one, though both may
- ]7 o( \9 H: j& s0 v    sometimes be the same in case of hashing for instance. So as a general rule; g) X0 `) B* z6 I5 I
    of thumb, when a '+' is present in front of the retry count, this count
# N4 r# K7 j1 b& d    should not be attributed to the logged server.
$ v- W* j6 y1 I
7 n7 d* |" k% F: @% u4 A- v  - "srv_queue" is the total number of requests which were processed before
4 G" @0 H; n- y0 G. f5 U    this one in the server queue. It is zero when the request has not gone
) A0 R% [- G& Y7 `1 o' Z    through the server queue. It makes it possible to estimate the approximate
; S9 z  ?! ~$ c    server's response time by dividing the time spent in queue by the number of
4 t- N* j% G& P, g) X0 m3 }    requests in the queue. It is worth noting that if a session experiences a
$ `/ x2 `, g( W    redispatch and passes through two server queues, their positions will be
( o# k% ^! r8 F- |' Q    cumulated. A request should not pass through both the server queue and the: l! `! F+ N& _; e# U1 j
    backend queue unless a redispatch occurs.  }9 m/ A( r% h* a5 x% e
) y, R* F8 p  j/ U5 L
  - "backend_queue" is the total number of requests which were processed before: Y, R2 j9 r" Y1 G' w6 v& u
    this one in the backend's global queue. It is zero when the request has not
, G# z6 Y9 L# h    gone through the global queue. It makes it possible to estimate the average; v' Z  z5 [9 n5 B4 u: @
    queue length, which easily translates into a number of missing servers when
+ ?* v+ m& @3 N: ?    divided by a server's "maxconn" parameter. It is worth noting that if a
) z9 w; _" n  w& \) d2 g$ j    session experiences a redispatch, it may pass twice in the backend's queue,8 @, A! D4 F% o1 k+ H: s" I" E: L
    and then both positions will be cumulated. A request should not pass4 v0 q- l7 \* F: O+ J) K5 i3 f
    through both the server queue and the backend queue unless a redispatch
& ?+ \( }( i4 a/ k4 v0 U6 \    occurs.
+ Q. `7 h% K: `1 D- l: y, h% L  u& ?* J+ P

  C1 a' b+ L5 O5 U. N  ~8 ]. o) \8.2.3. HTTP log format! u: X) q6 y2 J. f9 X$ Y2 }
----------------------
& p4 h: r: t6 k& ~! X& H6 P
5 h9 S9 ]9 ]2 B' ~: r0 P  cThe HTTP format is the most complete and the best suited for HTTP proxies. It
. r' `) D6 t# ^4 P& ^2 ais enabled by when "option httplog" is specified in the frontend. It provides
% K: O/ {2 S/ C& t1 U: Fthe same level of information as the TCP format with additional features which
, m6 u$ s  {2 A' tare specific to the HTTP protocol. Just like the TCP format, the log is usually
( ]0 S" J- _1 |+ X" c8 G* ^emitted at the end of the session, unless "option logasap" is specified, which& F3 n) P1 A0 Z! t% ?* `
generally only makes sense for download sites. A session which matches the- x7 f$ x) C" j; `) v0 l
"monitor" rules will never logged. It is also possible not to log sessions for8 m# X: k- z4 e1 U& x
which no data were sent by the client by specifying "option dontlognull" in the- }8 {; K" Z/ @/ i/ l) P. j
frontend. Successful connections will not be logged if "option dontlog-normal"
. @1 v& H- H3 v5 h8 ais specified in the frontend.
) M6 y! D8 [7 s7 s5 h& _6 l6 Y3 S0 o5 Q# z0 ^3 Z; Y) f5 I; x) V6 e4 N
Most fields are shared with the TCP log, some being different. A few fields may
4 z/ ]) X: @6 S1 ?5 ~8 W: ?: T) `  K+ T0 oslightly vary depending on some configuration options. Those ones are marked1 R) R2 |- D# l" ?0 i
with a star ('*') after the field name below.: a) J6 h$ W& Z% F" u7 b

4 X9 L2 L9 ]% O' [  Example :
% k. f9 [3 J" N; R        frontend http-in5 n; R7 d4 ^& x$ @
            mode http' f  I/ d7 w, q; a6 {
            option httplog
2 I  s8 u% M7 X8 H) M            log global
; U6 ?/ N) E  e4 L0 F, l* }$ u( j3 m            default_backend bck
6 A( ]. J4 c  M1 ?/ _; H; R! Z) j
        backend static5 F" F& p/ D- N' |: b
            server srv1 127.0.0.1:8000) G* P0 a; e) i9 {, a

6 ]+ A5 h; H( Q5 f    >>> Feb  6 12:14:14 localhost \
. T' I1 f9 P6 b7 ?% V          haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
/ L& `4 r4 r& j$ y% Y          static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \1 D; E: Q* p* [1 Y' @
          {} "GET /index.html HTTP/1.1"
9 m1 x+ d+ R& Q. \8 b0 E
  X; S3 y* B7 O4 H  Field   Format                                Extract from the example above
0 Y" s$ d% c1 y0 C+ V7 s( `' s2 `      1   process_name '[' pid ']:'                            haproxy[14389]:
5 `9 j8 f# Y9 N5 t( |7 K$ N      2   client_ip ':' client_port                             10.0.1.2:33317
. z" A2 r9 @# d6 w7 ~9 O& |      3   '[' accept_date ']'                       [06/Feb/2009:12:14:14.655]' S, A) b9 c: R+ \: |7 u- b
      4   frontend_name                                                http-in4 u6 J5 U" m5 o) F" e1 U
      5   backend_name '/' server_name                             static/srv1
1 v' h. i0 ?7 ^      6   Tq '/' Tw '/' Tc '/' Tr '/' Tt*                       10/0/30/69/109( l) ~5 f/ `2 c1 D+ S3 V
      7   status_code                                                      200
& D! w. t& T2 Y  ?( S; ^      8   bytes_read*                                                     2750+ g( h/ ?- A& b& p
      9   captured_request_cookie                                            -& L& X4 n' k& Q7 {; g' Q% D
     10   captured_response_cookie                                           -( m7 y  ~" A! C9 K, v
     11   termination_state                                               ----& b+ j% x8 V6 C5 ?; N( {
     12   actconn '/' feconn '/' beconn '/' srv_conn '/' retries*    1/1/1/1/0
6 Q: c# F$ Z. O9 X& `% \     13   srv_queue '/' backend_queue                                      0/0
  b6 g; j. r  j     14   '{' captured_request_headers* '}'                   {haproxy.1wt.eu}
* S7 Z0 p: l+ T8 c" @, L     15   '{' captured_response_headers* '}'                                {}
. b  T) w9 z5 H7 w8 x: x     16   '"' http_request '"'                      "GET /index.html HTTP/1.1"7 w3 R& p3 ?4 D6 `, y: S- X

0 k0 V. k5 j# l8 q+ v. A% }3 ?
: @) r, b$ f' r  F, T5 G% ADetailed fields description :
: p' o1 L$ I5 n+ {  - "client_ip" is the IP address of the client which initiated the TCP
% R2 Y3 }( u% }) P0 X    connection to haproxy.
( x! ~  L2 ^" n, A! b- V7 n  |* N* U" Q
  - "client_port" is the TCP port of the client which initiated the connection.9 E6 a6 [1 p# J1 |4 ?! n

" ~9 C- i# v% A8 B: g8 M  c9 r  - "accept_date" is the exact date when the TCP connection was received by
; ~* |9 e: v  z/ @# Z+ C5 |+ l/ @' C    haproxy (which might be very slightly different from the date observed on7 w2 S3 ^  ~9 O# y: ^4 g& _. y
    the network if there was some queuing in the system's backlog). This is
- `# g& ~- u; ]3 N' {" ^- y0 L5 l    usually the same date which may appear in any upstream firewall's log. This
7 t$ _$ u9 ~# U. s1 T' r    does not depend on the fact that the client has sent the request or not.
+ |& x. }# K! B" M, v/ w* U$ }: n* f& U# G
  - "frontend_name" is the name of the frontend (or listener) which received
2 A: f9 v' P: G8 v2 c( [    and processed the connection.
, ]% V8 c6 `& E1 U0 I7 z8 `& Q( A+ Z7 @6 d
  - "backend_name" is the name of the backend (or listener) which was selected  |4 A' X9 g/ a, I1 a! B
    to manage the connection to the server. This will be the same as the; E- I2 ]3 T, l, j3 V. C+ j
    frontend if no switching rule has been applied.2 ]4 Z. ~' n  a1 ^3 K+ q) i

8 ^) R/ G9 S* I: j$ c  - "server_name" is the name of the last server to which the connection was9 J- P/ C% P. E0 i
    sent, which might differ from the first one if there were connection errors
( s! b% e5 N+ p5 R  V    and a redispatch occurred. Note that this server belongs to the backend
. D- Q& c  L7 R6 p1 Y1 J, \. g4 d    which processed the request. If the request was aborted before reaching a
5 g: P: r; f& P& z% `  O    server, "<NOSRV>" is indicated instead of a server name. If the request was( |" D# [5 x) [0 k9 z: u* n1 X6 J
    intercepted by the stats subsystem, "<STATS>" is indicated instead.
. y$ x' d1 c! d1 r5 T- U8 c
6 Z; f9 Z$ Z7 I( h  - "Tq" is the total time in milliseconds spent waiting for the client to send: v7 c! q% ^3 K- q+ t' \! ]" m; w
    a full HTTP request, not counting data. It can be "-1" if the connection
' J& e% ^" _6 c' w) r( J3 L- O    was aborted before a complete request could be received. It should always
; m3 g8 R! d0 S( ^    be very small because a request generally fits in one single packet. Large/ M1 |. A  F/ J/ a( f& \$ k; \; t
    times here generally indicate network trouble between the client and
6 V% e% Y. `9 j- e    haproxy. See "Timers" below for more details.9 X2 h) ?% G6 a7 V: A" c: D6 z

9 P  [) K  {0 F1 u8 D  - "Tw" is the total time in milliseconds spent waiting in the various queues.
1 Q+ U/ P! r- T. R$ k8 ]    It can be "-1" if the connection was aborted before reaching the queue.
* v9 h5 B+ H: Y6 c$ P& G; H6 T    See "Timers" below for more details.
- ]* ~8 P; M( Q% O$ e' e
3 K9 i: O1 v- l* O  {4 u/ `. c  - "Tc" is the total time in milliseconds spent waiting for the connection to% [" E" J/ P$ v
    establish to the final server, including retries. It can be "-1" if the
$ }' Q7 S% t6 ?: }- |4 K  _    request was aborted before a connection could be established. See "Timers"
+ h- N$ U% e% i5 b7 w4 j    below for more details.$ @' f7 s$ ]5 F( x
6 U) }: ~8 M) M" C
  - "Tr" is the total time in milliseconds spent waiting for the server to send
% A+ a2 _; v& ?    a full HTTP response, not counting data. It can be "-1" if the request was
' N8 O9 F- {$ F; s2 }    aborted before a complete response could be received. It generally matches1 X7 T: Q% x9 }
    the server's processing time for the request, though it may be altered by7 u0 I* H, S7 e$ d- r
    the amount of data sent by the client to the server. Large times here on* N* S3 c, c; Y1 d. r, \$ q
    "GET" requests generally indicate an overloaded server. See "Timers" below; a7 n/ Z; G7 H" n' Y* s
    for more details.% R) l$ x; K* B
( y% L3 t* x+ q
  - "Tt" is the total time in milliseconds elapsed between the accept and the
) G3 U4 n, i/ K& ?# `6 }0 X    last close. It covers all possible processings. There is one exception, if
  P3 C( E9 {3 n    "option logasap" was specified, then the time counting stops at the moment$ B% r( x  T" C7 R5 q
    the log is emitted. In this case, a '+' sign is prepended before the value,
! D. p2 A5 G! u- ]" J4 C' J    indicating that the final one will be larger. See "Timers" below for more1 i! U) n* H; N% c+ N5 O; z" ~
    details.
3 ?# B% q/ f- x  i  f9 U
6 k" N$ `, b& w  - "status_code" is the HTTP status code returned to the client. This status) {, C4 Y- V* z5 l# a6 J
    is generally set by the server, but it might also be set by haproxy when# C/ c/ E' X: S: L  j( }
    the server cannot be reached or when its response is blocked by haproxy.
; S1 W4 f  P9 Z5 S6 R4 ]  e4 C% h' i3 D/ L
  - "bytes_read" is the total number of bytes transmitted to the client when! H+ @, d! I6 I
    the log is emitted. This does include HTTP headers. If "option logasap" is& a- g& Q. ]- @  v$ m, o+ [
    specified, the this value will be prefixed with a '+' sign indicating that
' M$ M8 t( k: J0 Z* K    the final one may be larger. Please note that this value is a 64-bit1 Y8 S) x# h" h7 a  ^1 G5 y
    counter, so log analysis tools must be able to handle it without
) }  v4 H# x1 m2 B    overflowing.- M% C7 r8 d5 p0 o

% M! i- c+ u9 {4 d1 r  - "captured_request_cookie" is an optional "name=value" entry indicating that5 ?: V! J. [5 {3 Q5 Q. J
    the client had this cookie in the request. The cookie name and its maximum
( F9 D' b$ o4 x4 V* x6 B3 r: {) p    length are defined by the "capture cookie" statement in the frontend
- L  {/ m* Z3 H8 m+ M    configuration. The field is a single dash ('-') when the option is not
6 u4 [. M5 M# V& B: J0 O% q  f    set. Only one cookie may be captured, it is generally used to track session
& f: u2 t/ w. ^! P  x$ G    ID exchanges between a client and a server to detect session crossing
2 T; a& ]9 w6 C- G" v    between clients due to application bugs. For more details, please consult$ q* D8 ~6 P# c7 M7 o, ^9 y& Y" r
    the section "Capturing HTTP headers and cookies" below.) ?$ a  q% a- r3 j8 ^1 o
# T" u& t. A3 V4 g; g- t
  - "captured_response_cookie" is an optional "name=value" entry indicating
  Z2 c& W' }& ?5 V: S, O    that the server has returned a cookie with its response. The cookie name
/ ?% j6 v  y5 B/ x" x. s- L    and its maximum length are defined by the "capture cookie" statement in the4 K; {0 n3 M9 y9 i: S
    frontend configuration. The field is a single dash ('-') when the option is
7 @5 F' U5 ?5 v' L    not set. Only one cookie may be captured, it is generally used to track( E7 h/ h3 \8 `' |5 U4 O0 ]
    session ID exchanges between a client and a server to detect session6 W/ v9 O" B; U, E
    crossing between clients due to application bugs. For more details, please
2 K% d, J1 E0 l" N$ B/ }: H8 a    consult the section "Capturing HTTP headers and cookies" below.
% ?# U8 u- b9 {! @! W
2 b: `' n4 x9 G8 ?# G; o  - "termination_state" is the condition the session was in when the session$ e: {0 Y. E2 j, r& s7 O& v
    ended. This indicates the session state, which side caused the end of
: d8 @1 Y( S, V8 L9 _, w    session to happen, for what reason (timeout, error, ...), just like in TCP6 E! r/ [& e: u* U/ b. s% D
    logs, and information about persistence operations on cookies in the last
8 }7 o" I' W/ T# ]: \    two characters. The normal flags should begin with "--", indicating the  F8 E3 V4 {  w
    session was closed by either end with no data remaining in buffers. See
& J. x3 B- D8 S- L1 A  _    below "Session state at disconnection" for more details.; W' V5 Z+ f$ w8 L+ E/ E8 C& c( J/ X% ^
2 f$ v# H6 I: u1 E# X# q
  - "actconn" is the total number of concurrent connections on the process when
1 |8 D, R# @2 H* @" c    the session was logged. It it useful to detect when some per-process system
" a! @* b- s" ^; W9 L; z    limits have been reached. For instance, if actconn is close to 512 or 1024
5 P# j, E6 X& O' E* k    when multiple connection errors occur, chances are high that the system
9 v! c$ O/ o5 c: u& w" m    limits the process to use a maximum of 1024 file descriptors and that all3 M) q0 `( L0 i6 G7 N7 `$ R" N
    of them are used. See section 3 "Global parameters" to find how to tune the
, Z0 b+ Z/ H/ s; W    system.
% K9 v; Z/ U" k) X
" e& V# S5 _! L& j6 A  - "feconn" is the total number of concurrent connections on the frontend when3 p: d- F6 C% T, n& a9 M3 F8 p- s
    the session was logged. It is useful to estimate the amount of resource- [1 f: X# C8 ~! Z; Z! _) S
    required to sustain high loads, and to detect when the frontend's "maxconn"3 C. V4 a9 R0 S5 C
    has been reached. Most often when this value increases by huge jumps, it is
* @# T7 F$ e. g6 v, y    because there is congestion on the backend servers, but sometimes it can be
0 h+ u+ j2 h$ l9 Y9 @8 y$ n' p    caused by a denial of service attack.% c% G# m. c/ w' c$ O% O* r
$ ]! d/ {; Z7 k- ~" k
  - "beconn" is the total number of concurrent connections handled by the
1 q: y" T2 p) }    backend when the session was logged. It includes the total number of5 Y0 x4 m: a; y+ n" S. g7 c- A
    concurrent connections active on servers as well as the number of
/ R& u% X9 q  D! u' r    connections pending in queues. It is useful to estimate the amount of7 R: ]" j8 L# P, _" R: g
    additional servers needed to support high loads for a given application.! a; L% s  t; {) j. R
    Most often when this value increases by huge jumps, it is because there is+ h8 u7 X8 Z' Y* c8 j+ K
    congestion on the backend servers, but sometimes it can be caused by a% F/ @, w' {( _! O/ W
    denial of service attack.8 f7 C: M/ h7 U) ?* Q

" D  D3 d$ S' A) n3 n# S  - "srv_conn" is the total number of concurrent connections still active on
- S: H9 T8 g5 i! z/ W    the server when the session was logged. It can never exceed the server's2 S% G% w9 x; I( i; {+ Q
    configured "maxconn" parameter. If this value is very often close or equal2 J# \! n3 S6 ^
    to the server's "maxconn", it means that traffic regulation is involved a
; j4 h- x/ t& A" \    lot, meaning that either the server's maxconn value is too low, or that
# h% e: d' S6 h. s$ A; w: ~6 W    there aren't enough servers to process the load with an optimal response( x) l1 X, M3 ^" V, v
    time. When only one of the server's "srv_conn" is high, it usually means
; t- R. e. _. u4 }    that this server has some trouble causing the requests to take longer to be
$ r, R8 H$ v  V# T& g$ u    processed than on other servers.  g: Y. c! X! W/ s" |( ?; `' h

2 h% k6 {  C' g- p) U; V  - "retries" is the number of connection retries experienced by this session
: |; v& u. H. D/ |/ W( [# D) ]8 j    when trying to connect to the server. It must normally be zero, unless a- r0 _6 Z, J% m7 d! i0 E- G
    server is being stopped at the same moment the connection was attempted.
9 i* `# B: G0 l: F    Frequent retries generally indicate either a network problem between' }- \# x' i. d' W$ t
    haproxy and the server, or a misconfigured system backlog on the server
2 `# j0 y; p. C& i8 A, N7 _  n4 n3 B    preventing new connections from being queued. This field may optionally be1 ?% T( }% o4 X' s( i* e6 p
    prefixed with a '+' sign, indicating that the session has experienced a2 k1 ~% R; M( u% h8 @  `
    redispatch after the maximal retry count has been reached on the initial* X. S' [$ h7 X( h
    server. In this case, the server name appearing in the log is the one the
7 f; X# ?+ X! t- E$ r1 s8 S    connection was redispatched to, and not the first one, though both may
9 ]+ J9 ~. n- E+ l5 I' b. }2 q    sometimes be the same in case of hashing for instance. So as a general rule1 B- ]5 k2 A0 b9 s( y+ d/ d
    of thumb, when a '+' is present in front of the retry count, this count% h8 i- [, h9 A" A
    should not be attributed to the logged server.
& c0 e: R$ u. k4 p6 g: D3 O, ?$ I% y- }5 o
  - "srv_queue" is the total number of requests which were processed before
7 e( Y; W" R& \( |$ D& S3 W& s    this one in the server queue. It is zero when the request has not gone, Q& r& G& x2 \5 h5 Q* P
    through the server queue. It makes it possible to estimate the approximate1 i3 g$ ~- f& D" o
    server's response time by dividing the time spent in queue by the number of; h, i% j1 ~; D; B( }3 A1 m5 q
    requests in the queue. It is worth noting that if a session experiences a
) f# r4 M* h7 B8 a$ _9 g6 _    redispatch and passes through two server queues, their positions will be2 F  m$ [! [6 c  k5 n
    cumulated. A request should not pass through both the server queue and the" r- U/ o2 Z7 U6 ~0 B6 N9 t; F; g
    backend queue unless a redispatch occurs.5 a- u/ {9 J. l9 S3 w
  A7 O, n; Q7 t* E
  - "backend_queue" is the total number of requests which were processed before6 K6 o" F( d( K1 `# _
    this one in the backend's global queue. It is zero when the request has not  T/ O; X5 @, S( Z! h0 _
    gone through the global queue. It makes it possible to estimate the average
5 E1 O+ `  T) d    queue length, which easily translates into a number of missing servers when( g5 i( K8 z+ D+ }
    divided by a server's "maxconn" parameter. It is worth noting that if a
. o* P  y( U% j2 Q    session experiences a redispatch, it may pass twice in the backend's queue,
. y7 x: ?8 [6 S) S6 w  [    and then both positions will be cumulated. A request should not pass. X  I  m" p& \2 E- _. D7 L. P' Y
    through both the server queue and the backend queue unless a redispatch1 U% v1 x, }6 W
    occurs." W- r% _) O6 u
6 z' j% t0 L* r! B- d8 _0 }
  - "captured_request_headers" is a list of headers captured in the request due
" P4 e8 N8 O, \" D- Z* U    to the presence of the "capture request header" statement in the frontend.
: s/ k" [7 Q& J    Multiple headers can be captured, they will be delimited by a vertical bar0 ^+ E, p% i* l: }! p2 l
    ('|'). When no capture is enabled, the braces do not appear, causing a
- q8 g! M9 k# N7 T4 \! V' ?% I    shift of remaining fields. It is important to note that this field may
3 f3 S$ h( p4 B    contain spaces, and that using it requires a smarter log parser than when3 F+ B+ }. I# q0 J* X
    it's not used. Please consult the section "Capturing HTTP headers and
0 |2 t2 X2 O8 f    cookies" below for more details.
8 K8 l* N* N  H" E9 J/ ]7 O# H& b& w+ I2 W% W8 o8 @9 J5 }
  - "captured_response_headers" is a list of headers captured in the response/ g  s) }+ w4 M' v- L  h4 Z
    due to the presence of the "capture response header" statement in the
; Z' P; b0 s; \# D! ]$ j    frontend. Multiple headers can be captured, they will be delimited by a+ F8 F1 t& M9 V3 o6 b) J/ \1 q
    vertical bar ('|'). When no capture is enabled, the braces do not appear,
# M& p( E& v) R/ n8 H0 Z9 L1 q& I    causing a shift of remaining fields. It is important to note that this
: ]+ e( p5 j  L* T8 Q3 F) t, i    field may contain spaces, and that using it requires a smarter log parser9 x  b1 B( m% M- {7 f* M' ]
    than when it's not used. Please consult the section "Capturing HTTP headers) S' x8 V" e3 T$ A6 b
    and cookies" below for more details.
# x8 Y  Y% a1 V' Q3 s/ p
  Y* r/ m7 m9 _8 L  - "http_request" is the complete HTTP request line, including the method,
8 k" P8 i( J; n: V5 J( U    request and HTTP version string. Non-printable characters are encoded (see6 A# I& Y* s! K  I3 m9 V
    below the section "Non-printable characters"). This is always the last
/ P' }/ l5 I0 L' D( z    field, and it is always delimited by quotes and is the only one which can2 b: x5 `. A9 R% R2 B
    contain quotes. If new fields are added to the log format, they will be
8 g% h6 s1 f7 d3 t+ p    added before this field. This field might be truncated if the request is
( y8 @* n+ L! k" H    huge and does not fit in the standard syslog buffer (1024 characters). This
1 X6 h( S* m0 D4 C& G" b    is the reason why this field must always remain the last one., ?+ |. @0 r, g8 _/ D
9 @& \7 P& `  A" w
+ d# J) U$ S3 L5 I8 {  F
8.3. Advanced logging options) a$ I4 a% g4 c2 c8 M' W
-----------------------------
% U2 e9 L- |# ^. J1 F
/ U# i8 E' s" `( T) |5 KSome advanced logging options are often looked for but are not easy to find out) J$ A: z& z2 b6 m# s9 n
just by looking at the various options. Here is an entry point for the few0 S# q# c  g: z1 z
options which can enable better logging. Please refer to the keywords reference
; E- B, ?# i5 E) t: U* Lfor more information about their usage.& X  ~, J5 E5 _/ c  U

4 V1 W  H7 [5 B6 W. K
& ^  b- _" {) ^8.3.1. Disabling logging of external tests- V( Q9 p( o# R) D
------------------------------------------
$ Y+ }" F% c: i2 m2 E  w/ ~8 j  R" R( }0 T2 L
It is quite common to have some monitoring tools perform health checks on$ n8 T9 Y5 l1 F3 g/ j% d/ F2 s- P
haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any
/ v% a/ n4 C/ z( {, ocommercial load-balancer, and sometimes it will simply be a more complete
# y9 F% ^" {/ H' B# T3 o8 B1 E. P' Rmonitoring system such as Nagios. When the tests are very frequent, users often9 H$ ]5 b  _% P8 M; }: Y* B+ p/ {, v
ask how to disable logging for those checks. There are three possibilities :% N5 v) u. @" V2 P* D; f  h
" u+ ?( A' D$ Q; `
  - if connections come from everywhere and are just TCP probes, it is often" S) r! s- _/ m3 m
    desired to simply disable logging of connections without data exchange, by. m8 L( [- M+ C9 }
    setting "option dontlognull" in the frontend. It also disables logging of- \  O: E% a9 C7 K# F) |0 h
    port scans, which may or may not be desired.) w5 d' B+ F% q
$ {2 S9 b, p* X' P: S- k( v
  - if the connection come from a known source network, use "monitor-net" to
/ j6 n# L6 U3 g% s    declare this network as monitoring only. Any host in this network will then3 T% y, E' q3 ?$ x# c4 u
    only be able to perform health checks, and their requests will not be
5 U; d1 M8 p7 S% w$ T% q    logged. This is generally appropriate to designate a list of equipments+ E# n; Y, m9 T
    such as other load-balancers.
( ~- W! o& a) o, O0 ]8 u: L: q1 |) q
  - if the tests are performed on a known URI, use "monitor-uri" to declare
9 q1 `2 F; X8 D* Z    this URI as dedicated to monitoring. Any host sending this request will
3 P* t. {' c" X: D0 r" `! |+ ^    only get the result of a health-check, and the request will not be logged.
, v7 ]) N' c! `
# ^& @' n9 O/ H# q. o
4 Q) f9 G7 c) S! a! [8.3.2. Logging before waiting for the session to terminate
8 l! d. ~9 i8 r----------------------------------------------------------& p6 Y4 y' E' Q% {0 `# I! a
; Z/ V& y8 c$ {7 }# [
The problem with logging at end of connection is that you have no clue about  X' y9 a. O; a
what is happening during very long sessions, such as remote terminal sessions
7 S+ n. M9 Q9 Eor large file downloads. This problem can be worked around by specifying
% @' V7 F# k3 p$ F% g' d2 G"option logasap" in the frontend. Haproxy will then log as soon as possible,! O7 ^/ F! A+ @8 X
just before data transfer begins. This means that in case of TCP, it will still
: U1 U* T6 m4 Xlog the connection status to the server, and in case of HTTP, it will log just6 o$ S. w  T6 X% Z( Q6 t$ f; {" v
after processing the server headers. In this case, the number of bytes reported2 I) j7 y  o* g8 p0 m5 y
is the number of header bytes sent to the client. In order to avoid confusion
) @: T2 [8 }- a9 Fwith normal logs, the total time field and the number of bytes are prefixed
( u6 [" D9 F8 J3 Swith a '+' sign which means that real numbers are certainly larger.7 U* a1 j' C0 P/ @
$ r% L1 P% h6 f6 l

) m1 r5 F- h- ~, t' G3 D8.3.3. Raising log level upon errors5 P7 ]( @- O7 x  l( t& P
------------------------------------) M/ l# U# P4 E/ O' Q

/ ?, M5 o( V& A7 L5 c4 MSometimes it is more convenient to separate normal traffic from errors logs,, V% v0 g1 c3 W0 ^6 N* K) `
for instance in order to ease error monitoring from log files. When the option2 h, Q  g- z7 E! Y" s
"log-separate-errors" is used, connections which experience errors, timeouts,
; ^( d9 o1 |( X0 |% f  H: j' U4 \; Nretries, redispatches or HTTP status codes 5xx will see their syslog level
) d+ s7 S% k2 C, A" J4 Zraised from "info" to "err". This will help a syslog daemon store the log in
7 n) l* o# p! m# Ba separate file. It is very important to keep the errors in the normal traffic2 z. I/ r2 B2 P7 E( q( h* k
file too, so that log ordering is not altered. You should also be careful if
% k7 B4 s; Z9 w0 Z$ }+ Lyou already have configured your syslog daemon to store all logs higher than# C* W$ L! _; w2 ]
"notice" in an "admin" file, because the "err" level is higher than "notice".
! R: S- q1 E$ Y# Q' O( x; M' q+ q7 d& R# x  }* |1 |* z  F
. r, R' g4 A" j$ z/ J
8.3.4. Disabling logging of successful connections9 D7 X* B) y" i
--------------------------------------------------9 ^/ C% X& z$ t% \: m
3 q. e4 ~8 V5 @2 Z. S! n, g
Although this may sound strange at first, some large sites have to deal with
  f' x" l/ |! Q1 r! ^8 u3 pmultiple thousands of logs per second and are experiencing difficulties keeping
9 {; {0 e7 Y3 D4 k- \them intact for a long time or detecting errors within them. If the option
8 @9 z( P3 C% @* g; t6 p) }; ["dontlog-normal" is set on the frontend, all normal connections will not be
9 w" r) w' h4 m8 Wlogged. In this regard, a normal connection is defined as one without any
5 p/ i6 L. H) `1 l6 S! Cerror, timeout, retry nor redispatch. In HTTP, the status code is checked too,
2 Q" W5 x# d2 ~6 c  y0 Xand a response with a status 5xx is not considered normal and will be logged4 N# ]" J6 k% o% w5 q+ U$ E0 R, t
too. Of course, doing is is really discouraged as it will remove most of the4 P' ]# d' i* Z( i3 C6 g+ z! L
useful information from the logs. Do this only if you have no other; p7 r. V: x! a  u: I. F# X
alternative.
- t) m+ w& |! q$ C6 E! `$ w; w! t. J9 n' Q3 w
5 h6 Q0 |; A3 B+ w" d
8.4. Timing events
. u) H& `& c- k5 w$ o5 K* L0 m------------------' t! a  s4 n& k" J2 [$ y

) v" g! H  I+ H& I5 e5 D7 vTimers provide a great help in troubleshooting network problems. All values are4 A8 x- O) z  n# z1 M
reported in milliseconds (ms). These timers should be used in conjunction with9 q$ ?1 R$ {2 d8 V
the session termination flags. In TCP mode with "option tcplog" set on the
2 u7 L" Y/ f2 P- V7 s9 y% ^& t" dfrontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP
5 T6 B. `5 _& p( L5 L* q' L! amode, 5 control points are reported under the form "Tq/Tw/Tc/Tr/Tt" :7 u- P9 ]" \9 F0 {: t# o
" \  Z7 |" Q6 a4 }4 S8 Z
  - Tq: total time to get the client request (HTTP mode only). It's the time
) D2 v/ m9 w. Q8 s+ o    elapsed between the moment the client connection was accepted and the5 j( h; f* O1 f+ w% M$ r3 A* d$ |
    moment the proxy received the last HTTP header. The value "-1" indicates
  p, `2 T  m1 f7 B( N    that the end of headers (empty line) has never been seen. This happens when
. l7 T3 Q; f$ Y; j9 f- g( ~    the client closes prematurely or times out.
% T1 B1 p+ N4 b: D- R7 K8 V
7 @" G3 v0 Q8 P8 B4 b; d  - Tw: total time spent in the queues waiting for a connection slot. It
/ }) H2 [# C- N( F( L! a$ Q' q    accounts for backend queue as well as the server queues, and depends on the  T; y2 J' n- W$ w6 @
    queue size, and the time needed for the server to complete previous
, f- W& P9 v2 f- J+ q    requests. The value "-1" means that the request was killed before reaching$ R" Q2 G2 U5 o& ~4 S! ?
    the queue, which is generally what happens with invalid or denied requests.. |0 t9 n' ?" o" m3 W7 m+ a5 y* M

4 W8 h8 c+ G$ k- z: B; P  - Tc: total time to establish the TCP connection to the server. It's the time' ~  h5 C2 `" |) Q8 q, c; p
    elapsed between the moment the proxy sent the connection request, and the
+ F9 N, r4 U9 {+ r, P' \    moment it was acknowledged by the server, or between the TCP SYN packet and  X- L7 ^0 W  K# l+ i  v4 @0 ^/ x9 n$ Z
    the matching SYN/ACK packet in return. The value "-1" means that the7 S6 Q! c$ K3 p) _) }) U
    connection never established.
; z" y' ?, m6 D' T, c% ]4 d6 g3 Y& S% C8 }
  - Tr: server response time (HTTP mode only). It's the time elapsed between' t* s5 ^! p# H' \# }& k+ E+ ~8 P) ?
    the moment the TCP connection was established to the server and the moment
9 D: S0 ?; C9 s8 ^    the server sent its complete response headers. It purely shows its request+ ?+ B# j, B6 k2 C3 b& Q
    processing time, without the network overhead due to the data transmission.
/ t* [. ^# e3 z: P2 o- `7 ?    It is worth noting that when the client has data to send to the server, for
4 V5 O0 A- Q) S1 I    instance during a POST request, the time already runs, and this can distort1 y$ P, X7 ]0 ^% e5 h* R& |) P
    apparent response time. For this reason, it's generally wise not to trust
- ~4 G$ Y5 b$ g- w( V( F    too much this field for POST requests initiated from clients behind an! _! R) J+ ]$ G1 y, V8 {- ^+ ^
    untrusted network. A value of "-1" here means that the last the response5 }* ]) V3 [& |* Z4 k- {* h; _8 X
    header (empty line) was never seen, most likely because the server timeout1 M! v% A% P2 `* |
    stroke before the server managed to process the request.
# d8 b' @% z: i  h3 E
% K! o/ [  F0 t+ c  - Tt: total session duration time, between the moment the proxy accepted it
, z, E  S" I$ h    and the moment both ends were closed. The exception is when the "logasap"2 T. q+ E/ D. A" x5 B0 u
    option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is$ O" ?$ E/ ?7 ^9 ~# l, z) B* k
    prefixed with a '+' sign. From this field, we can deduce "Td", the data
2 ]  l7 v' Q1 }- F' W# u8 w    transmission time, by substracting other timers when valid :
- B$ ^2 ?1 l* S. y1 z
( ]+ @$ S, @2 Y) t8 D* M$ O        Td = Tt - (Tq + Tw + Tc + Tr)
( _2 J" D% p) h3 R" ^2 d3 q! d" Z% p3 T' f2 F' G
    Timers with "-1" values have to be excluded from this equation. In TCP
2 j8 B1 {% B! N    mode, "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be
- x% i( x  z. o# `; f    negative.
) L+ S% t6 q/ d
, M- F4 m" u$ vThese timers provide precious indications on trouble causes. Since the TCP
  G+ W6 z2 H& v' P3 {7 Zprotocol defines retransmit delays of 3, 6, 12... seconds, we know for sure$ ^7 {0 I+ W* x5 K# a! s( a
that timers close to multiples of 3s are nearly always related to lost packets
6 t9 J, |7 N2 Z& Pdue to network problems (wires, negotiation, congestion). Moreover, if "Tt" is
) ]  j. t! T8 T8 c9 iclose to a timeout value specified in the configuration, it often means that a4 {9 X4 j) y7 P% ~+ s  S& t4 `1 o
session has been aborted on timeout.
/ x4 o9 p& p  j3 M7 @# S; ]5 e# y2 \
Most common cases :8 H: v9 c- \# S2 D' I

0 S' P1 K+ D! \" Q5 D  - If "Tq" is close to 3000, a packet has probably been lost between the3 b# Z0 z1 a5 e1 }  B' W0 X- J9 o
    client and the proxy. This is very rare on local networks but might happen4 f2 |# L6 a  c4 S3 W3 `* m
    when clients are on far remote networks and send large requests. It may; b, L5 |- D3 a; Y
    happen that values larger than usual appear here without any network cause.
1 D$ T! Y$ k9 T; m) h6 ]: o8 n    Sometimes, during an attack or just after a resource starvation has ended,
! {7 f: r3 U4 K) c    haproxy may accept thousands of connections in a few milliseconds. The time
: X* i/ Y+ }, Z/ }; X/ n3 W/ E5 N    spent accepting these connections will inevitably slightly delay processing& l! [/ @# o5 E) m) s' Z
    of other connections, and it can happen that request times in the order of/ s: N$ o9 E/ V6 R3 j1 u
    a few tens of milliseconds are measured after a few thousands of new! u% W! r' a  h2 i# B+ c, ~
    connections have been accepted at once. Setting "option http-server-close"
3 }2 h6 Y* ~# d8 f    may display larger request times since "Tq" also measures the time spent
5 o2 V1 ^/ B: @) l    waiting for additional requests.
/ M" j* y% ^/ T6 j
2 |  u% \1 M: i0 t: E  ~* d$ r  - If "Tc" is close to 3000, a packet has probably been lost between the2 v* P1 r5 ^) ^% a
    server and the proxy during the server connection phase. This value should
5 R" q9 w) X+ W3 p5 I1 h' x    always be very low, such as 1 ms on local networks and less than a few tens$ {# f$ z! A: y4 r
    of ms on remote networks.! t2 b& {+ Q: ]

" G$ B% g+ I) D5 S  q+ Q. B  - If "Tr" is nearly always lower than 3000 except some rare values which seem$ J  Q, ~* d2 G3 v
    to be the average majored by 3000, there are probably some packets lost
. O% C' w) v  E* j    between the proxy and the server.! R5 k& a3 O* R( Q' |
- ?: Q3 n/ n& r  @
  - If "Tt" is large even for small byte counts, it generally is because
. G% `# \0 w( G    neither the client nor the server decides to close the connection, for
4 f1 ^. o& Y9 [% D9 |7 j    instance because both have agreed on a keep-alive connection mode. In order% T2 [' `  y" _+ g: S2 H
    to solve this issue, it will be needed to specify "option httpclose" on+ j1 z% E5 N: l* y
    either the frontend or the backend. If the problem persists, it means that
6 J- j; ], [! M8 _    the server ignores the "close" connection mode and expects the client to
' P5 u& B2 u  X! V! r    close. Then it will be required to use "option forceclose". Having the
9 K/ P9 ^1 e# e; [& T    smallest possible 'Tt' is important when connection regulation is used with' G9 y' V! E1 l$ h( Y, V' q
    the "maxconn" option on the servers, since no new connection will be sent
# K6 k! r9 `! u9 B    to the server until another one is released.
2 C+ r% \5 H( G5 m' y" T. C
0 L, z, {6 d$ Z: m  R7 m& }1 iOther noticeable HTTP log cases ('xx' means any value to be ignored) :
" c9 t8 n( u* i. R8 U; M% H& _- c
  Tq/Tw/Tc/Tr/+Tt  The "option logasap" is present on the frontend and the log2 r) c9 c4 t" q( F& T2 x+ M
                   was emitted before the data phase. All the timers are valid
4 A6 |! c1 A6 o- b  `                   except "Tt" which is shorter than reality.
% |5 D& u' E6 a2 K& U' j' L+ T1 m9 g/ A' ?+ E# Y
  -1/xx/xx/xx/Tt   The client was not able to send a complete request in time
! G5 D# X/ q  k4 e, @& ~7 B                   or it aborted too early. Check the session termination flags1 R2 u* M8 G9 r! G5 @3 d
                   then "timeout http-request" and "timeout client" settings.
) U! N* T( L/ \; g
" E1 Y$ e" X+ R( Q. E, X0 Y  Tq/-1/xx/xx/Tt   It was not possible to process the request, maybe because5 C0 V4 E& M- I2 G
                   servers were out of order, because the request was invalid
1 A; O; A( c+ t* k1 c* _                   or forbidden by ACL rules. Check the session termination
8 _- m. }% C" R* Z                   flags.
" k6 q3 R/ |: E3 _- Y) U5 l9 T" T0 C
  Tq/Tw/-1/xx/Tt   The connection could not establish on the server. Either it
( B3 j$ g) D' i; @7 D                   actively refused it or it timed out after Tt-(Tq+Tw) ms.
4 x, I8 M: M: g. `                   Check the session termination flags, then check the& \) Y1 C8 U/ g  H1 h7 |
                   "timeout connect" setting. Note that the tarpit action might
7 P1 P, O  X, @/ p3 K3 h1 |# b: b1 m                   return similar-looking patterns, with "Tw" equal to the time. R! p( B( Y$ V3 e% ~
                   the client connection was maintained open.8 g% Q3 W5 ~9 l6 B7 P$ Q* l

- b+ X% j5 e8 u/ X8 ^) }3 |  Tq/Tw/Tc/-1/Tt   The server has accepted the connection but did not return+ q* t0 f. z2 Y
                   a complete response in time, or it closed its connexion8 I1 I; A; v" c; f) _# a6 N; x/ h" I
                   unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session
) b. ~8 l1 w4 S- L' Y# b0 w; o                   termination flags, then check the "timeout server" setting.
( c  ?5 v% ~2 `' z( }  I
$ Q' @  j0 d; z9 U5 E2 ~* D; \& G+ s% O5 p# t% j
8.5. Session state at disconnection
2 K( V& S( }$ m3 Q-----------------------------------3 C3 R: \% P( x, Y6 a5 ?+ y4 b

3 ?6 n0 S) M0 p$ W7 s$ N: ITCP and HTTP logs provide a session termination indicator in the
) Q+ i. i- z. Q% M: ^# N"termination_state" field, just before the number of active connections. It is9 w4 ?+ d# G" q8 u1 @4 W
2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,
$ o) U9 n3 X. d: X6 {0 heach of which has a special meaning :
# ]6 n& U' d. V3 l' A# p* g
6 d& E. h/ z- |8 B3 }: s6 H  H, O  - On the first character, a code reporting the first event which caused the
, A1 B8 ]+ Y6 f- T9 A    session to terminate :6 j8 Y! W& u  n# A

/ V- s0 @4 L+ j        C : the TCP session was unexpectedly aborted by the client.) N- e- D3 t$ C4 O$ r; j

. d8 f& c+ Q* |- }8 x        S : the TCP session was unexpectedly aborted by the server, or the3 A9 H( x8 I( [  ^7 S+ B0 X
            server explicitly refused it.$ n+ _% _$ _) ~

9 @, Y: b1 A# D        P : the session was prematurely aborted by the proxy, because of a2 E& z6 T! s  ~: b% x
            connection limit enforcement, because a DENY filter was matched,8 w. M9 p- r% _) q4 I
            because of a security check which detected and blocked a dangerous0 ?" h- k3 C; U5 O* i1 q+ m# M
            error in server response which might have caused information leak
) X% \$ j% n/ R! b            (eg: cacheable cookie), or because the response was processed by# G  m+ c$ L, {1 ?6 I6 F
            the proxy (redirect, stats, etc...).: N0 J" R# ?- q: g
; Q; |9 D* c+ K! e! L: T
        R : a resource on the proxy has been exhausted (memory, sockets, source
& d! n+ ^/ v# j' g            ports, ...). Usually, this appears during the connection phase, and
: z% T+ t( e* @7 [$ y            system logs should contain a copy of the precise error. If this& }- p# X! d  v/ h7 D/ `
            happens, it must be considered as a very serious anomaly which
% j6 r+ z" M& Z  I5 E- `4 j6 h! L0 D            should be fixed as soon as possible by any means.
$ t& x: G- N' ?+ V" a; L' I' e7 d5 d  H( k6 I9 ?2 E" b
        I : an internal error was identified by the proxy during a self-check.* g/ Y' V/ K; g8 g! Q$ w
            This should NEVER happen, and you are encouraged to report any log
: Y; h5 i' S1 Z# ^& p" v1 ?& I            containing this, because this would almost certainly be a bug. It  e. Y- @0 ~* b9 P% a1 \
            would be wise to preventively restart the process after such an
: [+ @% n# P. |0 H0 O/ s            event too, in case it would be caused by memory corruption.  h3 e/ ?9 a3 D
/ V& y1 _4 K0 O
        c : the client-side timeout expired while waiting for the client to
: Q$ w. r( s! w# S  Z            send or receive data.: ~; s# ~# i6 ^- F6 S/ c" k

/ d6 K: P) V8 Q; o9 w        s : the server-side timeout expired while waiting for the server to
1 X$ Q5 [: P. x# k0 d            send or receive data.1 v  q2 S& W+ T+ n6 L
- k  C0 Q- z9 m
        - : normal session completion, both the client and the server closed# L) G( R% ?5 f; [. q; V; B' q' D
            with nothing left in the buffers.. r. Y% g0 `/ o2 Q( N' [" }4 @
9 X) [, E( s" e0 b. x' K. m
  - on the second character, the TCP or HTTP session state when it was closed :
+ e4 r8 w) a! C& u  r( ]5 {' z# Q
        R : the proxy was waiting for a complete, valid REQUEST from the client
" ]) o) V: y. j! B  O# o1 B) J7 _            (HTTP mode only). Nothing was sent to any server.
4 Y! B' k/ T! W0 o/ S8 j7 K$ i! l3 K
        Q : the proxy was waiting in the QUEUE for a connection slot. This can9 H, \0 g# G7 q* W( e
            only happen when servers have a 'maxconn' parameter set. It can5 f5 y* e3 F$ P- f7 D
            also happen in the global queue after a redispatch consecutive to
$ Q* T2 O% ]) P( m; F& O            a failed attempt to connect to a dying server. If no redispatch is& b9 m: K6 g, Q: L2 G6 f
            reported, then no connection attempt was made to any server.
$ x" N3 ?1 P4 M8 i! L
0 T# `3 V: ?6 i4 W8 `! }- m' i* B" {; t        C : the proxy was waiting for the CONNECTION to establish on the4 S& G! U2 E1 o1 d; B* e. M8 l$ H
            server. The server might at most have noticed a connection attempt.0 Y. W2 A  D3 O/ V* R5 s

& A5 Z' H/ X  h4 `  R% c4 ?/ F        H : the proxy was waiting for complete, valid response HEADERS from the/ v# }+ F# r6 E& J' I2 \/ O( ~
            server (HTTP only).
! g/ ~, C" u, V" i5 ?
3 k3 N6 H6 m: G- D        D : the session was in the DATA phase." ?, p8 t. S4 k

5 q# H$ j/ f6 c3 k2 k) j        L : the proxy was still transmitting LAST data to the client while the. w* O+ ?9 L: P0 S: L* K# y
            server had already finished. This one is very rare as it can only
% @* B! N7 v' \, G            happen when the client dies while receiving the last packets./ |; ~( [0 S, A! j" B5 d
) R* X& n3 ]0 o1 U" W; a/ g! [6 a
        T : the request was tarpitted. It has been held open with the client5 Z( b2 H# t& d: H5 {
            during the whole "timeout tarpit" duration or until the client
$ J4 Z5 w0 w% n            closed, both of which will be reported in the "Tw" timer., p" y- }. M8 H

) I+ D  `0 D5 y4 [. d& H& @6 I        - : normal session completion after end of data transfer.  \! {9 E- ^8 w+ @: T. v6 ~

0 q0 s6 G8 w9 P- t0 _  - the third character tells whether the persistence cookie was provided by
- F7 z- N3 j" \/ O/ H    the client (only in HTTP mode) :0 w1 l% Q/ L  M  h1 [3 ]
4 j( z* r: F' J: g3 J% ?. R
        N : the client provided NO cookie. This is usually the case for new, O; b, `( K# e' I
            visitors, so counting the number of occurrences of this flag in the: n+ K# n% r/ _% H# ~& L  H+ j, \' U. z
            logs generally indicate a valid trend for the site frequentation.+ u7 J6 l9 ?0 W  U( y, h, c

- b" O0 r  Y; a! R  E& X9 `# R5 _        I : the client provided an INVALID cookie matching no known server.9 J- D/ O! ]9 [# Q, q
            This might be caused by a recent configuration change, mixed
* J4 K7 C* w" _            cookies between HTTP/HTTPS sites, persistence conditionally2 @, z& j, s( A% a& t
            ignored, or an attack./ O: B: O+ o, `# i5 j) L
: V0 Q  i, \) I6 @0 W
        D : the client provided a cookie designating a server which was DOWN,
; G& m! h: X$ [, }1 c- i: c            so either "option persist" was used and the client was sent to" ?$ x2 n6 F& H2 U& ?/ k& j
            this server, or it was not set and the client was redispatched to! T, c5 O8 l, {3 n3 I' s* d) k
            another server.- @% u$ I" B8 x+ F# Z1 Q1 w* O- Y

9 j) p4 t; b3 g) C        V : the client provided a VALID cookie, and was sent to the associated7 D' d5 j* K" I* c( H3 s7 w
            server.
! Z) f& r+ x; K$ f9 i$ B7 _
5 o2 c  z9 }1 L3 I: X        E : the client provided a valid cookie, but with a last date which was3 _8 p; G9 h# M$ c
            older than what is allowed by the "maxidle" cookie parameter, so
3 F; U( M- e. Y( m( R1 O& N! h4 A            the cookie is consider EXPIRED and is ignored. The request will be3 z/ N) P/ q% U# ~/ F
            redispatched just as if there was no cookie.- Z  P" L' G2 _- h9 D& ~
2 m8 `+ p7 ]* W0 B0 C$ p
        O : the client provided a valid cookie, but with a first date which was) u1 A6 l% u7 B* {$ k
            older than what is allowed by the "maxlife" cookie parameter, so
8 }" ^" e2 l. @7 v: _            the cookie is consider too OLD and is ignored. The request will be
( K' O' q! y. E% b6 z            redispatched just as if there was no cookie.( }' ]$ x! |" E: C& i8 k! P8 e2 R

! T+ f! j3 G' @5 f        - : does not apply (no cookie set in configuration).7 U5 Y  n7 d" M# M
  d3 A1 p$ {$ c/ L# P% x7 S$ W0 r( O
  - the last character reports what operations were performed on the persistence& x) R: u% w# }0 M4 d# K
    cookie returned by the server (only in HTTP mode) :
( ^# Z* I7 A# k4 u9 D. [  ]; ?6 B; ], A
        N : NO cookie was provided by the server, and none was inserted either.
! V( w( Q* u, p6 d& Y7 V& @9 d4 _
        I : no cookie was provided by the server, and the proxy INSERTED one.5 E) I; g+ h4 ]) N% F  ^6 a  `
            Note that in "cookie insert" mode, if the server provides a cookie,
, \/ j% D: B6 u- u/ k) w6 {            it will still be overwritten and reported as "I" here.0 E; ]1 K2 s% a  u' o

, v0 L# b, h  b+ z2 B  w2 U        U : the proxy UPDATED the last date in the cookie that was presented by0 q. k" q) `" r0 m* G2 y
            the client. This can only happen in insert mode with "maxidle". It. j  O' Z, `) r! R0 h+ b; Y
            happens everytime there is activity at a different date than the1 j3 ~" i- k' {' Y# K* x  Q
            date indicated in the cookie. If any other change happens, such as& o% x2 t, ?( @! H2 o  v
            a redispatch, then the cookie will be marked as inserted instead.
6 d  I% s; g0 T+ {( }+ z1 x  K7 x9 ]4 A( ~* t
        P : a cookie was PROVIDED by the server and transmitted as-is.' s; S" ~$ t; y0 A; b0 D

/ k$ t, a6 M; ]" t" a- t- k        R : the cookie provided by the server was REWRITTEN by the proxy, which- c8 j. ]* E" m; A, `& O9 S
            happens in "cookie rewrite" or "cookie prefix" modes.
* [/ J; `/ L, O9 l
1 f6 s$ A, T. r; I+ d2 J7 D        D : the cookie provided by the server was DELETED by the proxy.0 U; P: Y* E5 ]- X+ Q+ b

2 @3 Y! d, _' V- b" ~) |        - : does not apply (no cookie set in configuration).# m( r8 B2 F$ j. z

: H% P. F# O; q2 GThe combination of the two first flags gives a lot of information about what* J% U4 G2 S  O
was happening when the session terminated, and why it did terminate. It can be
! @3 _: d# f9 k5 vhelpful to detect server saturation, network troubles, local system resource# D; P" t: Z) J4 s/ \+ U
starvation, attacks, etc...* O' q  P" B/ t8 S* F" s

. n# {3 F9 o- Q( a3 j7 P" vThe most common termination flags combinations are indicated below. They are
4 I& |: }# p. j$ ~- ]alphabetically sorted, with the lowercase set just after the upper case for
# N, N# u0 h7 {* Ceasier finding and understanding.7 m# a: i% ?9 u9 M

# U; p- f( u0 q  Flags   Reason
& Q6 b* \, n( z3 k
: b7 x3 F1 ~: a$ T& Y     --   Normal termination.' Q' m9 K  B8 i: Y+ q+ |

. I& [0 O$ Y8 B( `8 r     CC   The client aborted before the connection could be established to the- t$ G! I: {8 u# z6 R! \2 q
          server. This can happen when haproxy tries to connect to a recently
3 r9 O, _$ W0 e! D0 L          dead (or unchecked) server, and the client aborts while haproxy is
8 q( F: [) b, U! P, P          waiting for the server to respond or for "timeout connect" to expire.% v; v! O: j" [$ H$ f- G: `5 h3 z( m

. Y  }: E6 t2 x1 p3 z, Z* g4 o8 E     CD   The client unexpectedly aborted during data transfer. This can be4 X8 j. f7 a/ ?
          caused by a browser crash, by an intermediate equipment between the' Q. n; O7 G# _+ |
          client and haproxy which decided to actively break the connection,) \3 Y  h- [. @5 V9 e& ~
          by network routing issues between the client and haproxy, or by a" F' m2 ~9 v/ N* f) I* c( e. E
          keep-alive session between the server and the client terminated first
$ T- z9 w0 j  L          by the client.3 {3 H8 D3 k8 A  l5 R/ a

3 g7 s/ v$ Q7 H     cD   The client did not send nor acknowledge any data for as long as the
( V, Q* K3 z+ V0 ^. ?1 @- l          "timeout client" delay. This is often caused by network failures on
' [& y3 X$ P# o. C: D  K$ X& G6 B8 G! e          the client side, or the client simply leaving the net uncleanly.* S  ^4 X; `1 S& S" ~+ [' l9 l- Q
& `2 n: M& j1 Y# e
     CH   The client aborted while waiting for the server to start responding.! R! A1 p8 F- J" }) d
          It might be the server taking too long to respond or the client. A6 H) l* j; }% j
          clicking the 'Stop' button too fast.
$ n* \0 T# P! n$ w
. t) }0 O% H3 W; i1 t# a     cH   The "timeout client" stroke while waiting for client data during a
& Q( X1 l  ~6 C7 O3 u" M, k          POST request. This is sometimes caused by too large TCP MSS values
, V" K0 [- C4 C% L3 {1 j/ [          for PPPoE networks which cannot transport full-sized packets. It can
; ]. i: u- q, B6 Y: x          also happen when client timeout is smaller than server timeout and
8 R( j$ h! f; F) S- B          the server takes too long to respond.
* x( h( G! g( a6 j3 ~- t: h$ {  y
     CQ   The client aborted while its session was queued, waiting for a server
0 L/ C! F/ V0 H. p% v          with enough empty slots to accept it. It might be that either all the3 J3 H& g! y) P3 c+ i, I6 ^
          servers were saturated or that the assigned server was taking too
3 p8 t/ o+ p! o0 v          long a time to respond.
& u' Q6 w8 K/ S* N: A
" }, a# Y5 [! F9 T/ M     CR   The client aborted before sending a full HTTP request. Most likely
" P8 Z2 |' K+ n( r( h+ R          the request was typed by hand using a telnet client, and aborted
# Q8 u/ p/ T1 `* I( ~2 q          too early. The HTTP status code is likely a 400 here. Sometimes this
: U: G2 ~. Y/ v  N) v          might also be caused by an IDS killing the connection between haproxy! Z' \5 I% Y2 L5 A
          and the client.8 [* p- G$ I+ _8 h  D+ a8 _
8 w: w$ n8 j( _# Z8 w
     cR   The "timeout http-request" stroke before the client sent a full HTTP
( i" o# }5 a" ?3 c/ s5 [: w; O          request. This is sometimes caused by too large TCP MSS values on the
; w! y. N) b) e# G& J& d          client side for PPPoE networks which cannot transport full-sized( X9 z% S/ X: Z- T% f9 p
          packets, or by clients sending requests by hand and not typing fast- P6 N7 ^  O' O/ n6 C% \
          enough, or forgetting to enter the empty line at the end of the
4 c) o# u& y3 G0 o$ ?) L" A          request. The HTTP status code is likely a 408 here.
& m7 G6 q" {' f* r2 B$ U! J; }. w/ L. l, w# _
     CT   The client aborted while its session was tarpitted. It is important to
' o9 Z  v* G) v3 j0 Q- r! n          check if this happens on valid requests, in order to be sure that no
; V" L: E5 a' ^  `- n          wrong tarpit rules have been written. If a lot of them happen, it
) _* i) P5 f) M          might make sense to lower the "timeout tarpit" value to something7 L) [7 H* _$ ^  H9 c& o7 _: F
          closer to the average reported "Tw" timer, in order not to consume
. m0 ^' n  k* t          resources for just a few attackers.
! G8 E$ d6 ?( v2 V- I
* r' i* J  n( X) F* I5 e     SC   The server or an equipment between it and haproxy explicitly refused
( M6 m9 m0 g/ |, Y& s2 ]9 [          the TCP connection (the proxy received a TCP RST or an ICMP message
" S+ I) h7 _2 p6 o          in return). Under some circumstances, it can also be the network
% I* z8 \* n, l* L          stack telling the proxy that the server is unreachable (eg: no route,# @  f7 S0 y" ]: l
          or no ARP response on local network). When this happens in HTTP mode,5 H3 e0 H$ t7 j& V3 ~
          the status code is likely a 502 or 503 here.7 V1 h0 R& a; Q5 A( I
) I9 M. K6 e1 u: [# }  _4 O
     sC   The "timeout connect" stroke before a connection to the server could
# K0 j! _. u. P' N, {2 n          complete. When this happens in HTTP mode, the status code is likely a
- a# F6 A. ^; t8 ?          503 or 504 here.
5 r) k& M0 i2 s3 ?/ r7 _* E) m1 T; ~, \8 M* N
     SD   The connection to the server died with an error during the data
( b$ V$ F+ u; K, A! I+ B          transfer. This usually means that haproxy has received an RST from
, u5 c7 H8 w; p% j4 @* \5 z          the server or an ICMP message from an intermediate equipment while
4 l. D9 a$ Q4 S/ L4 Q6 A. v0 c          exchanging data with the server. This can be caused by a server crash
7 O" _5 m6 J& q9 U( [  K' k4 {          or by a network issue on an intermediate equipment.7 z1 _, p- t8 c! ?- A* D

3 V4 f2 z* `" Y$ x. W& V& U& `     sD   The server did not send nor acknowledge any data for as long as the
: ~& B& _, z& e: }* |2 v          "timeout server" setting during the data phase. This is often caused
  p. z# N5 ?6 K; R          by too short timeouts on L4 equipments before the server (firewalls," L8 ~; \4 t( J; e# g6 Q; ]$ `
          load-balancers, ...), as well as keep-alive sessions maintained8 N% ]6 U. j& F1 O4 H: a$ g
          between the client and the server expiring first on haproxy.
* g0 ]2 {8 F  H2 q2 ]5 Z# L$ X' e. @% x
) z+ _& a, }' b$ o9 ^- c! m     SH   The server aborted before sending its full HTTP response headers, or
- `0 Q# T/ A# W* v' F          it crashed while processing the request. Since a server aborting at
* P6 k% T5 B! w& f/ w          this moment is very rare, it would be wise to inspect its logs to& b3 i  s+ c: q: H
          control whether it crashed and why. The logged request may indicate a
1 n( Y  ~: P; ~& H7 R          small set of faulty requests, demonstrating bugs in the application.9 c+ d4 g) r3 f3 ~) i" P: d
          Sometimes this might also be caused by an IDS killing the connection
0 E" Y, D% q2 x( e/ h/ A' X          between haproxy and the server.
/ w3 B! F$ x% c/ s$ H% d7 o2 J
- Y2 b; b, ?0 W! f     sH   The "timeout server" stroke before the server could return its- y" V( A/ W8 n1 w" Y+ e$ E
          response headers. This is the most common anomaly, indicating too
* x! W( A% h" G  V) k# G          long transactions, probably caused by server or database saturation.% c  o! m4 I$ b) x! n
          The immediate workaround consists in increasing the "timeout server"
0 J) f& G$ _3 B* }+ R* R/ \) G: d0 l          setting, but it is important to keep in mind that the user experience' I0 g! V3 r. {) I
          will suffer from these long response times. The only long term6 m" P- X/ S1 f. O- C+ V! N
          solution is to fix the application.2 A- j8 z+ U. _" z

. ~  \3 F- I$ p4 b% t; P     sQ   The session spent too much time in queue and has been expired. See5 v; F1 @* \1 A, d: f# u
          the "timeout queue" and "timeout connect" settings to find out how to8 f1 w4 E! C$ T" ^
          fix this if it happens too often. If it often happens massively in
0 l8 |9 o/ Z* z          short periods, it may indicate general problems on the affected' Q6 T  `1 R7 l' w! ?) W
          servers due to I/O or database congestion, or saturation caused by
4 s/ Y2 I: V% P* N6 T. Z          external attacks.2 _" W. g4 |$ l' X7 c/ V
6 X& b( @, R5 h  \$ X  _! Z0 _
     PC   The proxy refused to establish a connection to the server because the: a/ D  e# B7 L
          process' socket limit has been reached while attempting to connect.
6 s( e) ~7 M! k: O: i1 b          The global "maxconn" parameter may be increased in the configuration7 {# s9 N# g- u2 T4 q" v
          so that it does not happen anymore. This status is very rare and" f2 d9 n' E" r- r4 f/ N5 e) ?
          might happen when the global "ulimit-n" parameter is forced by hand.: Y" p, H1 G  |2 |* A
& _+ E1 H3 E. n. Q* U2 L! c( X
     PD   The proxy blocked an incorrectly formatted chunked encoded message in0 u& y( c! j0 A2 l
          a request or a response, after the server has emitted its headers. In2 p. |1 c6 A6 H( L+ V% D6 C
          most cases, this will indicate an invalid message from the server to
" O3 l. e) @- g0 W' a' _          the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647
$ u, q2 S" M% r, {          bytes). Any larger size will be considered as an error.
, F4 {3 g- Z4 w& e1 s9 i& t8 e7 f; G: \2 `0 C3 R- f* X
     PH   The proxy blocked the server's response, because it was invalid,
8 C: R: B5 n& v. l/ p          incomplete, dangerous (cache control), or matched a security filter.* h% T% Q2 Y" I/ `# w
          In any case, an HTTP 502 error is sent to the client. One possible
: B# D  \; e7 l, U4 {- g" U          cause for this error is an invalid syntax in an HTTP header name
- ]5 g, @' I$ ?+ ^7 Y          containing unauthorized characters. It is also possible but quite; v8 @( C7 }7 \6 a2 K) B
          rare, that the proxy blocked a chunked-encoding request from the
( O+ D  M  M1 M/ |          client due to an invalid syntax, before the server responded. In this  U% _' y- x& |/ h+ d
          case, an HTTP 400 error is sent to the client and reported in the
# }, g# N9 A$ W) |5 z2 T          logs., _! p# @9 g& K8 m, S& E

) }; M" ?, |1 o/ [; P; C+ D1 M# C     PR   The proxy blocked the client's HTTP request, either because of an
7 g& V! X/ Q# j, w8 t" i( n' x4 |+ F          invalid HTTP syntax, in which case it returned an HTTP 400 error to
2 W' c8 b' |6 I2 c          the client, or because a deny filter matched, in which case it6 H* Y) F7 N6 ?8 S7 W" n" K9 T& ]" X
          returned an HTTP 403 error.
/ |0 X8 G% O% g9 U! c' l
6 J8 |$ f7 j  \7 u     PT   The proxy blocked the client's request and has tarpitted its7 X% h, a" v+ x( p+ c: I( ]
          connection before returning it a 500 server error. Nothing was sent4 V  f/ g, _' b; E% q1 n
          to the server. The connection was maintained open for as long as
# _  Y3 U% j3 D; b% ~. T" u) c" ^          reported by the "Tw" timer field.
8 K" R  v2 n) a1 i6 F; F- y
. w9 P: z) L$ l: V' l     RC   A local resource has been exhausted (memory, sockets, source ports)
& U& w! P& V; F# l4 P          preventing the connection to the server from establishing. The error
: k$ S' @$ q# ~) D& \0 m. ^          logs will tell precisely what was missing. This is very rare and can. G! n1 w1 J+ O+ r+ q! J
          only be solved by proper system tuning.4 K5 i' m, N! O
4 ]4 I: F; n; w5 V4 D. J" s% d
The combination of the two last flags gives a lot of information about how
3 l# T* T( B, B3 ]) r" |persistence was handled by the client, the server and by haproxy. This is very, J* ?2 Y1 O/ t) o" ^
important to troubleshoot disconnections, when users complain they have to: i% y/ s* @8 ~* P, ?: i; S& w7 l  ~
re-authenticate. The commonly encountered flags are :, k- c( n8 G+ p1 X6 C

3 v" C7 S3 f( `! s' Q( _     --   Persistence cookie is not enabled.& I; ~, i  o" ]; L$ o! F0 c6 {

' J' U0 p; ~2 G# @$ o1 P; a     NN   No cookie was provided by the client, none was inserted in the1 J  `; f! x, K6 e
          response. For instance, this can be in insert mode with "postonly"
; }8 w! z7 z/ z  V" Z$ S! B, y          set on a GET request.
" M. [) P1 {) _2 U' u% `& m
# Z9 I2 a4 `( e+ b" p2 O9 @     II   A cookie designating an invalid server was provided by the client,
+ C! l" T, E3 C( d* H7 O          a valid one was inserted in the response. This typically happens when! n( F. b9 x% T  K7 I% X
          a "server" entry is removed from the configuraton, since its cookie( z' J3 N! e3 A' d- f$ w
          value can be presented by a client when no other server knows it.  `: b+ s5 e0 a) R8 k
  v5 {; p9 X' |! ]" ^4 q0 q
     NI   No cookie was provided by the client, one was inserted in the5 f# r( ^1 _- i4 f  c# @) ?- z7 _
          response. This typically happens for first requests from every user3 i+ \0 L* t; v* _
          in "insert" mode, which makes it an easy way to count real users.
- q+ F& l2 a& ?, K; T: {3 @8 I& K4 j: j* e; `  k. V$ g: h
     VN   A cookie was provided by the client, none was inserted in the
+ g1 O  K. g+ ~. i% j4 b+ u& c6 T0 I0 z          response. This happens for most responses for which the client has
6 y. ?& f3 P* @% |1 l4 P          already got a cookie.0 O9 r/ n3 ]8 c1 Y
# t) V& ^' V) s% Y+ y
     VU   A cookie was provided by the client, with a last visit date which is
0 r6 U& H: y: w2 F2 N9 F          not completely up-to-date, so an updated cookie was provided in
  @1 O3 h0 |! ~# c          response. This can also happen if there was no date at all, or if, Z5 ]1 G/ r' {) M: w* F' w7 e/ c
          there was a date but the "maxidle" parameter was not set, so that the3 z* D6 t1 A0 N% C6 W7 V0 O5 Q
          cookie can be switched to unlimited time.
; Q0 _# O* f7 C  F) t$ v9 a. @) N1 l0 R' B3 h/ [7 i6 E+ M
     EI   A cookie was provided by the client, with a last visit date which is
% v+ O: Q. q4 T& B, g3 \          too old for the "maxidle" parameter, so the cookie was ignored and a$ A1 v; P* ?2 k6 ^6 [* P1 [
          new cookie was inserted in the response.0 B- g0 [2 z3 b' d7 G
2 s9 B8 e8 y$ O4 C
     OI   A cookie was provided by the client, with a first visit date which is
2 |- ]- o9 Z0 I# _- |' U7 D' f8 ?# i          too old for the "maxlife" parameter, so the cookie was ignored and a
4 H5 m$ x4 [6 W5 a          new cookie was inserted in the response.9 F% I# Y6 M. M/ j( K

7 w  d4 g+ G. X$ `) t' Q8 j/ h     DI   The server designated by the cookie was down, a new server was: U' M: F* D& A8 w
          selected and a new cookie was emitted in the response.
2 a; O9 d! y( ~% r) _; f  X2 V3 N
5 l  _7 Z3 @1 O     VI   The server designated by the cookie was not marked dead but could not0 q3 q5 u- y, M: g, K
          be reached. A redispatch happened and selected another one, which was: u- O* s4 \& `1 S. @
          then advertised in the response.
9 Q( a$ n4 A( K1 p
+ Y* P* v# x4 n9 ]2 e  m7 g
: p5 F" u8 D/ S4 {+ B( e- v8.6. Non-printable characters5 W+ c0 k6 f4 J. ~0 b% {
-----------------------------
! Q: ^+ O9 @* V% b
3 [, d8 {' V: y7 p3 h, LIn order not to cause trouble to log analysis tools or terminals during log
* g7 G$ y  P+ G+ A: Nconsulting, non-printable characters are not sent as-is into log files, but are1 z9 ~4 {. a: w/ q4 B7 z
converted to the two-digits hexadecimal representation of their ASCII code,
; i5 V. F5 P) z8 k5 z* E! t8 v- ?prefixed by the character '#'. The only characters that can be logged without" M8 f& O1 p  [6 H
being escaped are comprised between 32 and 126 (inclusive). Obviously, the  @+ n& A% S% L7 s' J: s- N" a
escape character '#' itself is also encoded to avoid any ambiguity ("#23"). It
9 b' [3 _; x' Q' e: `2 S1 l: Xis the same for the character '"' which becomes "#22", as well as '{', '|' and
$ h6 ^8 K; z" C6 V'}' when logging headers.8 s, X- i! b: `( ]$ P

; c. [. `% x+ {Note that the space character (' ') is not encoded in headers, which can cause
) E% }, Q) q8 W" R  V* O! dissues for tools relying on space count to locate fields. A typical header1 I0 G) Z) c; N
containing spaces is "User-Agent".
2 K8 E: M$ p' X6 [7 c9 a# w0 i! f7 @( |  d/ H$ C. ]$ [  o
Last, it has been observed that some syslog daemons such as syslog-ng escape
# c: H" G% C. y" k& I; b/ }the quote ('"') with a backslash ('\'). The reverse operation can safely be7 C7 P6 ?4 I+ R" B( c7 w3 @1 @. Y
performed since no quote may appear anywhere else in the logs.
2 `5 X0 U- }- z2 v2 D) c3 V4 {
$ u. |) a& \1 _3 R
9 u  ^1 W; @. S1 }( M8.7. Capturing HTTP cookies
$ v. C& C8 b& H6 r9 n---------------------------
- g, J" N- a3 a1 _! ]" \& N" U3 r& a4 h" h
Cookie capture simplifies the tracking a complete user session. This can be
3 X0 q* P% T+ Z$ h3 u. l/ d$ }4 ~achieved using the "capture cookie" statement in the frontend. Please refer to
. G- p! U1 C) o( Psection 4.2 for more details. Only one cookie can be captured, and the same
. R0 }7 N' C7 d8 K  m( }cookie will simultaneously be checked in the request ("Cookie:" header) and in& f# j$ K% q; @
the response ("Set-Cookie:" header). The respective values will be reported in
' S# R- b* t& y8 B2 x- Jthe HTTP logs at the "captured_request_cookie" and "captured_response_cookie"4 n8 F: s5 ?* J' d. V, D1 u; J
locations (see section 8.2.3 about HTTP log format). When either cookie is+ Y. Y! F' z1 Z  \
not seen, a dash ('-') replaces the value. This way, it's easy to detect when a. k* N$ n4 U& M  r
user switches to a new session for example, because the server will reassign it$ l- I3 X/ m9 W0 w' o
a new cookie. It is also possible to detect if a server unexpectedly sets a
6 ^9 z: p. C/ j+ g9 l- E* Rwrong cookie to a client, leading to session crossing.6 ?# L  q; q1 s# v
5 n. v- @; H" a. C7 U, \
  Examples :/ ?6 \. @8 Y0 l0 x9 F1 w7 k
        # capture the first cookie whose name starts with "ASPSESSION"7 w5 q; q* w- n/ ?! }4 v( @  }
        capture cookie ASPSESSION len 32/ t7 Y& Y% |* ?! y

0 r! X7 r9 |+ x6 q5 T- r5 Y+ @        # capture the first cookie whose name is exactly "vgnvisitor"
& V! x) s) M* H6 g, ?; T        capture cookie vgnvisitor= len 32
1 _: O( J1 J& m
% ?6 d- s4 m9 I0 ?3 O9 @1 v: z$ b* t+ |& t
- W0 Q. z# _4 b$ C0 j. `8.8. Capturing HTTP headers
$ J+ y! B, V5 j6 C; u3 m---------------------------  f# y# v$ l8 `6 y; J
1 w  W! G  d$ ~( b4 D
Header captures are useful to track unique request identifiers set by an upper
. l3 z: t5 E% u' T( rproxy, virtual host names, user-agents, POST content-length, referrers, etc. In- h3 j/ f7 u& c& c& p( Y. b4 O. _
the response, one can search for information about the response length, how the
) s4 c8 m8 a$ m6 V* f  xserver asked the cache to behave, or an object location during a redirection.
$ P9 s) r6 R; X3 \1 [1 P, o, P: e6 E3 @1 `6 j4 p* ~* n2 [
Header captures are performed using the "capture request header" and "capture
2 d0 d6 E; b6 f$ k5 Sresponse header" statements in the frontend. Please consult their definition in
$ E% ?2 i  v: U, M/ d  Qsection 4.2 for more details.
( D* V7 k/ [5 s2 P- V4 K2 Q0 U3 b+ X' V, \) E: S. ]0 k
It is possible to include both request headers and response headers at the same
4 h1 L7 s0 g0 O' @" ctime. Non-existent headers are logged as empty strings, and if one header
4 R* ~) d  S& ?( Q: nappears more than once, only its last occurrence will be logged. Request headers" s; d7 u! w' s
are grouped within braces '{' and '}' in the same order as they were declared,
' [  w5 T0 p+ _& |" X: m$ @and delimited with a vertical bar '|' without any space. Response headers5 ], c4 ~9 ^( Q5 H" F) g1 J0 R  U7 s$ [
follow the same representation, but are displayed after a space following the
; h2 M" @% P; ]' J( V' jrequest headers block. These blocks are displayed just before the HTTP request# {- Y7 v( l$ I
in the logs.
* s$ P$ m6 d  V3 k# V" J) p7 Y' E! k: j$ [2 y2 M9 K
  Example :0 n) J, p7 E1 b) k! g  D
        # This instance chains to the outgoing proxy6 P& N% C: F3 o
        listen proxy-out
4 H7 A( f  _7 i( s* ?! ~            mode http& X# c6 M% C/ k8 ^
            option httplog+ }6 J# ^, n* W! ~7 A" i. j
            option logasap! F! _9 N2 B1 P; E2 d" j
            log global
- n  H0 l8 e# t5 A3 X' }% `            server cache1 192.168.1.1:3128' [7 Q/ I* R% D1 I  K  L
* O+ ?3 W& c! X8 X
            # log the name of the virtual server
) @9 Z7 I7 J& ^$ W% Y2 ~; _* \            capture request  header Host len 20, s' j+ ~' z& T, q# Q

( A5 E. B9 y0 a" y5 _3 [            # log the amount of data uploaded during a POST. B$ W4 Q; a$ k3 ], S! f# {, ^
            capture request  header Content-Length len 108 E9 A3 \2 f$ F2 A' z8 }
8 J, J; ]9 H5 C- A2 e
            # log the beginning of the referrer7 H1 v+ H) H0 V, i! s% B
            capture request  header Referer len 20* Y  d0 X: N  ^3 ~
* C' Q" a7 U" Y" b  x2 v
            # server name (useful for outgoing proxies only)
  O  H  r' C$ e            capture response header Server len 20* w" W1 o( z* F* q8 r9 k

/ V7 @& L  q* `% _! a            # logging the content-length is useful with "option logasap", V, J: P7 y8 }% H2 s
            capture response header Content-Length len 10' T2 D! {. ~$ A$ G' `
1 k/ t& r/ {& i: _
            # log the expected cache behaviour on the response3 b+ w8 E( G5 {2 R9 |  X) ]9 I
            capture response header Cache-Control len 8
" M% d9 p2 l* x
, ~! c8 h/ c3 e, j            # the Via header will report the next proxy's name
2 S, }' C- `* ~9 f" T5 X5 E  d            capture response header Via len 20
, p, {. A  k' }: J! |- T% e, [6 _( V% S" v3 x
            # log the URL location during a redirection) r8 l2 m& W0 I  X7 c7 h- b
            capture response header Location len 205 s. Q( |3 z7 {) t! ]+ _
4 j* g& w% W- o5 n/ U; z
    >>> Aug  9 20:26:09 localhost \4 D% \0 w5 W' [. v- b% T, Z3 D
          haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \! K  U  B4 A; b6 t0 V
          proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \, k; a- X+ R5 w: N/ o
          {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \+ d( U0 e8 S9 T9 M
          "GET http://fr.adserver.yahoo.com/"
" s2 u; d- P- \5 h: @* r# g. m( b; L: `
    >>> Aug  9 20:30:46 localhost \! l& G5 N4 s. ?( q/ j- A: B+ a
          haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \
6 y# ~3 |$ d7 n9 y7 Z          proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \( s. j; V9 S1 y4 ]5 e3 L
          {w.ods.org||} {Formilux/0.1.8|3495|||} \% G9 X$ _; z; J' f8 u. J
          "GET http://trafic.1wt.eu/ HTTP/1.1"
: ^  Z5 d+ `" J9 y2 a& ~. p
2 U" t" I, ~; o+ c1 H, m    >>> Aug  9 20:30:46 localhost \/ N5 n3 A9 x# B& p0 c, z- |9 {
          haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \
$ L, M' P+ n; C2 {! l, A          proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \7 @4 ^/ m- u1 g5 \  Z
          {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \" S- J7 z6 e( S$ N6 a9 B* N
          {Apache|230|||http://www.sytadin.} \( v' u5 N1 `& r& g- ]% |$ ?
          "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"
  v4 s) v2 O0 ?8 T' e' V! I
6 q+ ^+ V( c. c% i  ~2 A5 w# i  `8 ^  m1 U& ^# H+ G. `
8.9. Examples of logs; m' S# x; o9 M' I* s/ [
---------------------
+ L5 _: P6 k% n0 L  U1 ]) {) J2 ^! |) A
These are real-world examples of logs accompanied with an explanation. Some of
$ B$ m  B! }# c* Z7 r# Gthem have been made up by hand. The syslog part has been removed for better4 j! r5 w) e5 R5 Q
reading. Their sole purpose is to explain how to decipher them., F5 d. Y# x; _: M( |
* J0 O' p! R% z9 n) s1 `
    >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \5 `6 `/ b# C8 T2 F9 G$ E
          px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
& l2 f6 ^! o6 S( C7 e$ H          "HEAD / HTTP/1.0"4 o7 m4 p7 K6 N! o& A0 t  J2 S
' n! ]+ o/ C6 f6 u
    => long request (6.5s) entered by hand through 'telnet'. The server replied
7 E" y" g4 D2 D. g. f4 G       in 147 ms, and the session ended normally ('----')
1 Y" D- E! h. [( B: f& N( X2 |7 B$ V/ |! D7 C, {; q+ Y( H2 D" x
    >>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \
( p. t2 D8 m. c: L( h& X  p! m          px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \4 U' P1 l/ X% S8 x/ }
          0/9 "HEAD / HTTP/1.0"; [4 ], Y2 w( S! H. Q5 P
" K) L8 Y" S) D9 s1 q
    => Idem, but the request was queued in the global queue behind 9 other
2 I' W: A9 T1 [3 N       requests, and waited there for 1230 ms.
- p2 y4 P/ @, ^% ^1 C
$ d* B9 H) K- t5 `! H" w    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \# _( U: H7 a8 B0 G# R
          px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \0 z. u; N: U; g, E* x! V
          "GET /image.iso HTTP/1.0"
: R2 J' n, T. `1 L5 f9 {6 A7 q
    => request for a long data transfer. The "logasap" option was specified, so
  e) I4 k3 D) w7 v4 c       the log was produced just before transferring data. The server replied in, I: o$ h* Y" @
       14 ms, 243 bytes of headers were sent to the client, and total time from
$ U# i$ g4 [+ v5 ^- ?       accept to first data byte is 30 ms.4 \( n5 s0 s' p& i! W& y( w0 i

5 m; E3 ?- `, d) G3 z6 z    >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
$ z: [, n6 ?5 t1 Z# C9 R          px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \
- d$ [$ G' A; T          "GET /cgi-bin/bug.cgi? HTTP/1.0"6 g7 a2 y% T7 J- i- a" `8 q% U" {2 F
  I. m+ a( o- Q% @
    => the proxy blocked a server response either because of an "rspdeny" or) Z4 ?6 U6 S  G+ ~8 p% Q
       "rspideny" filter, or because the response was improperly formatted and
2 |/ C, l& I) K: n' U5 m       not HTTP-compliant, or because it blocked sensitive information which
0 X  [' P( r& N+ K       risked being cached. In this case, the response is replaced with a "502
- T+ z( h' G$ ]4 A5 [' b$ [2 ~) H2 ]       bad gateway". The flags ("PH--") tell us that it was haproxy who decided$ o  i7 t1 A0 x$ h8 F8 _: {6 c
       to return the 502 and not the server.1 |- p( P$ C3 V: X/ I# N

" Z" Z4 G# [+ ]0 L/ m0 V! B& m4 h    >>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \
, k* e, R7 D- e$ p2 V          px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""* a; J$ a6 {" |$ ^% y# U

8 y; H9 O3 P7 b7 ?, i' W    => the client never completed its request and aborted itself ("C---") after2 Y7 c1 m3 q, @: q
       8.5s, while the proxy was waiting for the request headers ("-R--").* o2 F; \1 e! }) @0 O
       Nothing was sent to any server.2 ]: h4 Q6 p) [9 F; o

7 y  L% ?6 [2 b+ z8 |    >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \. l& E1 C4 H# G9 r: R
         px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""6 N$ L: z$ k  \. g

& P" {/ E& H2 k# {# X    => The client never completed its request, which was aborted by the. J# X6 H  \0 U. h: k) Q( K1 w
       time-out ("c---") after 50s, while the proxy was waiting for the request
: |; ~6 R' Y6 o& {       headers ("-R--").  Nothing was sent to any server, but the proxy could
" W" t* s) W+ L$ a/ @3 h       send a 408 return code to the client./ A4 G# n' b* U* x4 o, [$ L1 v1 p( K

9 X( l- k1 H$ b6 r+ ]# _    >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \8 G0 n$ j; L$ a% E8 j
          px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
) [" ]6 V9 r8 }3 b) R5 T2 k) z! t1 ^  `  o
    => This log was produced with "option tcplog". The client timed out after  K# U! O8 z1 E4 R
       5 seconds ("c----").; p% t- W$ E) e7 a/ u% _

) @3 o7 p% P& e) W, J4 t    >>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
3 C1 A3 q0 `2 ^: R; \* g. d          px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \
) `0 @& U8 V: g! u+ d          0/0 "HEAD / HTTP/1.0"2 B$ B& H4 n& e$ k) V2 z

! ^6 r! p' q; |1 h& K. m2 |0 h    => The request took 3s to complete (probably a network problem), and the
' h5 p' l  O# s5 k8 ?       connection to the server failed ('SC--') after 4 attempts of 2 seconds
7 h& {4 n8 `; s. ]       (config says 'retries 3'), and no redispatch (otherwise we would have
9 D% ]" L; U3 {  N7 H5 x       seen "/+3"). Status code 503 was returned to the client. There were 1158 m  {6 ?" h: K6 q0 n: P
       connections on this server, 202 connections on this proxy, and 205 on* ]- V7 |: h5 I! ^5 @: w! @5 d
       the global process. It is possible that the server refused the
! c: f( A0 t; k; Q/ I1 ?/ k' H       connection because of too many already established.
9 B7 q' B- {& ]8 K; D5 o5 ~
  m: ?8 ?0 X) u) j5 W0 j# V# Q' |; o- B# t  ?( z6 @2 O- A
9. Statistics and monitoring
: u- s& s& g- k0 y% l----------------------------# ^4 G" I  T! [* ~
; b% p: m, u' Z( V
It is possible to query HAProxy about its status. The most commonly used
5 m9 U. @! L! f9 @/ V* smechanism is the HTTP statistics page. This page also exposes an alternative; Y' U& P! E; {- H% H
CSV output format for monitoring tools. The same format is provided on the
$ N9 E. }) h+ o5 {7 \, _Unix socket.' X& f; G$ a4 }8 Q6 P2 W& X- E
; M' b+ j" r: s5 Z( D

$ T7 W, K* m. k0 R5 t; ~9.1. CSV format
) s# P5 n: P9 }6 R---------------
0 e  i  n+ ]! H0 P6 N
$ t$ |: M: e( G' C$ nThe statistics may be consulted either from the unix socket or from the HTTP
. ~4 J: c0 h( Q: hpage. Both means provide a CSV format whose fields follow.
- F; r4 k" {- @! B' d4 U8 x+ B( a, O, q* Q- l% O% U1 Z# r
  0. pxname: proxy name7 a$ c4 p- L$ ^/ X3 y% ]. W
  1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
& P( y) h8 ~& T  h  [" i    for server)
5 c9 D+ S/ z' n# b1 F# f, X  2. qcur: current queued requests- J1 {( O/ N) y5 f$ W/ a1 j! u
  3. qmax: max queued requests$ Z# i! {& e4 v, ?
  4. scur: current sessions
( u  ^4 w  z3 `  5. smax: max sessions! O+ @7 N" u! v& q. f" l' e
  6. slim: sessions limit
/ W$ ~( R" I' [- ]& `3 j! }  7. stot: total sessions4 K  q8 S- ^% g, I$ O; V
  8. bin: bytes in+ ?5 P( j2 A4 o5 N) j3 \- ~
  9. bout: bytes out
; ~( z) }7 f' W3 ^+ `; A 10. dreq: denied requests
" A8 l. [9 v% X6 d  E' O 11. dresp: denied responses
9 u0 w; J, G/ t" y4 {5 }( } 12. ereq: request errors/ j9 m+ g4 P/ l& X
13. econ: connection errors
+ g7 p6 \" @5 W# B. U) K 14. eresp: response errors (among which srv_abrt)+ N! N+ L5 C2 I3 d% j% X0 V" \  N
15. wretr: retries (warning)7 w& c) I0 [) X& P: ]$ z! a+ E' A* u
16. wredis: redispatches (warning)" z+ w) C" t' l
17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)8 r8 i0 k: [8 B# |
18. weight: server weight (server), total weight (backend)
4 A3 R3 q# \' r" L: } 19. act: server is active (server), number of active servers (backend)) ^7 F% o! m( n& ]8 P
20. bck: server is backup (server), number of backup servers (backend)
; K0 M+ b4 O4 z1 E, J1 g 21. chkfail: number of failed checks
8 k6 l- y9 F, F: b6 [ 22. chkdown: number of UP->DOWN transitions
6 k. Q( A( I9 u. y5 P9 j3 a 23. lastchg: last status change (in seconds)
5 C$ k3 X/ g% Y: i 24. downtime: total downtime (in seconds)
- _( `! X) j5 h3 E( c7 w( D* P 25. qlimit: queue limit
+ g1 k/ y3 P% ~* j& I 26. pid: process id (0 for first instance, 1 for second, ...)
; p, L" B. D4 M2 o 27. iid: unique proxy id
) W, [: \) d1 u$ n4 I' Y5 P 28. sid: service id (unique inside a proxy)" M4 O; V7 h0 A9 p1 L
29. throttle: warm up status
2 [- Z3 n+ |% ~! h 30. lbtot: total number of times a server was selected
  u5 s4 m; ^% g4 s, E  Y) d6 C 31. tracked: id of proxy/server if tracking is enabled
, A/ ?: T3 x' u9 X; `! V  B  I0 n 32. type (0=frontend, 1=backend, 2=server, 3=socket)+ C5 N7 E% R# d/ h$ M
33. rate: number of sessions per second over last elapsed second
) N3 Z& S: O; ]3 P  E$ j 34. rate_lim: limit on new sessions per second
9 x( X( ~: g8 g1 Q7 } 35. rate_max: max number of new sessions per second. M8 h% p$ V! I( C
36. check_status: status of last health check, one of:* N0 i0 r0 f: F* E. @& H, ^
        UNK     -> unknown
( `! K+ ?) Q( H, H$ Y  ?$ z4 A' v        INI     -> initializing( |% n  ^4 ^/ z9 E
        SOCKERR -> socket error! a) y9 o  {0 ?
        L4OK    -> check passed on layer 4, no upper layers testing enabled
1 Y) ?6 {; u4 `8 F0 T2 k! x) O        L4TOUT  -> layer 1-4 timeout2 h$ Z+ v% K9 Y) L% Q+ i5 l
        L4CON   -> layer 1-4 connection problem, for example% J$ j- f, }, L( q, |
                   "Connection refused" (tcp rst) or "No route to host" (icmp)2 O2 e/ ?8 C: A6 |+ O* o+ Y* r
        L6OK    -> check passed on layer 6$ n# \4 O* l8 a# @, U4 X+ P
        L6TOUT  -> layer 6 (SSL) timeout. G. t: K" \* }( d5 W3 L, B& C
        L6RSP   -> layer 6 invalid response - protocol error8 R0 @8 D1 u- T0 p1 I' N$ v
        L7OK    -> check passed on layer 7
6 {6 P, m3 S- J4 R! a3 M  K) m+ r        L7OKC   -> check conditionally passed on layer 7, for example 404 with
, W7 W6 P' s/ b9 m2 N                   disable-on-404
; I( ^2 Q- {  H6 A; C+ i        L7TOUT  -> layer 7 (HTTP/SMTP) timeout% L' k5 O" K! K+ v* `
        L7RSP   -> layer 7 invalid response - protocol error* V4 @( T8 t& E
        L7STS   -> layer 7 response error, for example HTTP 5xx
1 l, Q" A. B; p. d( L 37. check_code: layer5-7 code, if available
: z1 D- k9 _6 d1 K3 m0 o  e 38. check_duration: time in ms took to finish last health check5 c- C5 N9 U( R6 a' m
39. hrsp_1xx: http responses with 1xx code
7 F  |& y" T8 A  _6 p( P 40. hrsp_2xx: http responses with 2xx code
3 ~: I0 O; p6 F 41. hrsp_3xx: http responses with 3xx code* |, {" {* I1 Y* Y: B
42. hrsp_4xx: http responses with 4xx code$ J7 G, c" p5 g
43. hrsp_5xx: http responses with 5xx code
! r  W- @% [0 O1 }2 b! C 44. hrsp_other: http responses with other codes (protocol error)
- N- Z3 x5 O" Z, @ 45. hanafail: failed health checks details
' J& D% i: g! V) i: k; ?; _ 46. req_rate: HTTP requests per second over last elapsed second
$ s) u2 f/ D/ i9 @- d& m8 P8 o 47. req_rate_max: max number of HTTP requests per second observed
5 h8 U* G& P7 w, i# @ 48. req_tot: total number of HTTP requests received
6 n9 y6 X  J/ Z8 l- x/ D 49. cli_abrt: number of data transfers aborted by the client
6 L+ T/ u" \, W4 z 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
3 z2 K2 D9 V0 w, W/ Y+ q5 B: g) H: I( P) M9 U. l+ _3 Q5 Z( @
! O3 ~1 @1 A8 |) ?/ w
9.2. Unix Socket commands0 v, ~9 P9 U7 C  l9 R& R
-------------------------6 I- J5 ]/ M; W+ q7 q7 k% J9 j  I2 [
& c+ n+ P$ }0 h+ J/ Y2 V% S
The following commands are supported on the UNIX stats socket ; all of them
9 n1 ~: R+ a# S8 g5 emust be terminated by a line feed. The socket supports pipelining, so that it5 w+ }5 P( W: e# q' e
is possible to chain multiple commands at once provided they are delimited by/ T. C! l9 f( ]$ R, b5 k
a semi-colon or a line feed, although the former is more reliable as it has no5 c4 X) C+ J' o
risk of being truncated over the network. The responses themselves will each be
- [) r/ t" Z' f! D- k+ c% Ufollowed by an empty line, so it will be easy for an external script to match a
& g# f* @  y3 w" v2 }+ V) B! kgiven response with a given request. By default one command line is processed
! C' ?" ~* X6 z1 T' y8 O7 }' Pthen the connection closes, but there is an interactive allowing multiple lines% @/ {9 [8 {  T6 c- Z% J
to be issued one at a time.
8 h! q2 z3 f4 F* t. k7 Q# k/ ~  {1 d$ E; W+ y  S
It is important to understand that when multiple haproxy processes are started
- t4 }+ `9 g( Z5 `' Q$ n" gon the same sockets, any process may pick up the request and will output its
& s) a8 l# _8 q- N% U. S5 b( W- }own stats.
5 i& h' A/ K' {+ s8 s
3 l+ l. B( j7 E0 N3 M  |clear counters; J* o/ V# g5 l, A- g2 g& n
  Clear the max values of the statistics counters in each proxy (frontend &. R4 L# C6 u8 e/ e; b
  backend) and in each server. The cumulated counters are not affected. This
2 a* ?0 k4 R# K  can be used to get clean counters after an incident, without having to+ y; h0 n# H+ y
  restart nor to clear traffic counters. This command is restricted and can
  |  _" N) T% O' O/ H$ c" q: H  only be issued on sockets configured for levels "operator" or "admin"., H+ `  x! ^' b! c3 Y

6 \* V! m1 I6 Z0 J: {. ~( Yclear counters all( Y' S0 p% e& a
  Clear all statistics counters in each proxy (frontend & backend) and in each
* K9 a% z5 F3 z  server. This has the same effect as restarting. This command is restricted9 p+ _5 z! N3 l
  and can only be issued on sockets configured for level "admin".
3 c0 R1 x8 ~& d9 ^" ~
+ J9 C/ S: n$ m) Ydisable server <backend>/<server>% K2 u3 P7 X; H! n/ @0 F
  Mark the server DOWN for maintenance. In this mode, no more checks will be% |5 w  U/ a! ~& s
  performed on the server until it leaves maintenance./ s1 H* ^9 B5 s! U9 Q! ]3 Q
  If the server is tracked by other servers, those servers will be set to DOWN
1 v4 N' {% o7 K3 }( M2 T1 ^  during the maintenance.$ E: V1 D2 w) ~% K8 E
) M$ n3 Y' g. ]* p5 f+ l; n- P
  In the statistics page, a server DOWN for maintenance will appear with a2 q; ~! ]( J- G% p% m! N: }
  "MAINT" status, its tracking servers with the "MAINT(via)" one.
7 Z' |3 ^: L9 v' @; T/ s0 K/ l% T* _% L
  Both the backend and the server may be specified either by their name or by
8 B+ A$ {( N/ z. L7 k, a  their numeric ID, prefixed with a sharp ('#').; j8 N  @- R/ u7 V
3 r) P" u! T2 l# a& f% _3 q. k
  This command is restricted and can only be issued on sockets configured for
5 K+ x6 K, M6 `  level "admin".
$ `3 e4 z" d7 r. v( }6 e+ m$ A9 N
& @5 @- k; r5 i: L( m" X' \8 }enable server <backend>/<server>2 r# S0 F4 [% ^) I8 g: s" `
  If the server was previously marked as DOWN for maintenance, this marks the
* l; ]4 E, ^% W. S/ f  server UP and checks are re-enabled.3 }# ~9 h9 r' h! g" X4 E& ]

4 b; ?6 M7 `' q2 I4 d; ?/ v  Both the backend and the server may be specified either by their name or by
0 s( d8 c2 `( {5 c5 A  their numeric ID, prefixed with a sharp ('#').8 N# z5 v; M8 }; A
9 f2 j* Y  @& P# j/ K- \0 s
  This command is restricted and can only be issued on sockets configured for
  t9 {: L+ n3 g3 u# g4 w  level "admin".
; r( Q9 s7 H+ D
% C  L1 ?1 \/ ^get weight <backend>/<server>  g) z" w7 _0 e( U2 u5 n
  Report the current weight and the initial weight of server <server> in: g% L# q7 `% m$ |# B- \6 }6 @
  backend <backend> or an error if either doesn't exist. The initial weight is8 f$ x  H7 ^6 v1 C
  the one that appears in the configuration file. Both are normally equal
) b- f6 [# `' v: o, K. g  unless the current weight has been changed. Both the backend and the server% L- b5 E, D% l2 G( ^6 S
  may be specified either by their name or by their numeric ID, prefixed with a
( q% t# q1 T/ U/ z9 r( E  sharp ('#').
- e" |$ |4 S7 K2 c
: U* E0 K* n9 f6 g: u+ F$ nhelp6 R2 p8 _& W1 T1 W! J
  Print the list of known keywords and their basic usage. The same help screen; Z/ e1 W& t$ @5 w* w" ^
  is also displayed for unknown commands.
" \6 ]% s+ `& b( i: a. J; \* u
' x4 M4 w0 R9 A; ~  |; zprompt
) W$ B, F2 o" j1 o# y# `! `  Toggle the prompt at the beginning of the line and enter or leave interactive9 V' o6 J$ o* v3 d
  mode. In interactive mode, the connection is not closed after a command
0 D/ m4 ]2 g: m1 c  completes. Instead, the prompt will appear again, indicating the user that
  [5 i; ^4 k1 ], I) ?3 a7 H  the interpreter is waiting for a new command. The prompt consists in a right
# C0 q/ g7 [% b" v, X$ M  angle bracket followed by a space "> ". This mode is particularly convenient1 s2 z( [  U; f) n0 `# F* ]
  when one wants to periodically check information such as stats or errors.& |& J  ?, X9 e6 Z% Z8 r, H
  It is also a good idea to enter interactive mode before issuing a "help"/ E) o$ T0 C9 E" S. b
  command.
: I* F; j1 }/ T- }8 w3 @+ B9 W6 f  j- ?. e; m* }- O, L" t
quit5 t3 C+ C* ]! Z( h. y0 {
  Close the connection when in interactive mode.) S- I* S' D1 ^+ J1 ~

$ l  p% o/ p9 p9 Q5 {0 _* m. wset timeout cli <delay>9 Y- A. |0 Q1 k8 Y1 a& \+ Z6 T- `
  Change the CLI interface timeout for current connection. This can be useful
5 A. J5 S( e7 A1 v8 ~  during long debugging sessions where the user needs to constantly inspect
: D- }. C9 s' d; h. X5 Y7 s! @& ]  some indicators without being disconnected. The delay is passed in seconds., Z- Z- t* D- O- z: Z
. [& W  Q+ O4 I$ M+ C/ H2 j3 Y
set weight <backend>/<server> <weight>[%]
: K1 z! c9 S* t  Change a server's weight to the value passed in argument. If the value ends2 c- \' G4 H9 N7 |3 b* F2 u* H
  with the '%' sign, then the new weight will be relative to the initially+ z# I- I' F  ~( @9 @, n$ Y
  configured weight. Relative weights are only permitted between 0 and 100%,6 k; d$ h/ N( x8 b8 P2 o% w) \# j6 ^
  and absolute weights are permitted between 0 and 256. Servers which are part
; j( E  }- \8 Z$ J' Q1 ~  of a farm running a static load-balancing algorithm have stricter limitations" l  i8 |3 v: F
  because the weight cannot change once set. Thus for these servers, the only
- |3 m' }% c& o! z7 ~  accepted values are 0 and 100% (or 0 and the initial weight). Changes take# q5 |% Q+ s9 @- L9 e
  effect immediately, though certain LB algorithms require a certain amount of. M3 g3 X' ^% k: z
  requests to consider changes. A typical usage of this command is to disable
0 s2 C0 H/ y: ^9 [- E$ C3 L  a server during an update by setting its weight to zero, then to enable it
  R' @/ q* R& s1 A8 ]; e  again after the update by setting it back to 100%. This command is restricted
: Q0 ?& N0 K: C  and can only be issued on sockets configured for level "admin". Both the
1 h4 g7 A) ~& z3 ~4 z8 ]5 e  backend and the server may be specified either by their name or by their
/ N5 s$ V( `7 v5 U  c+ A3 f  numeric ID, prefixed with a sharp ('#').
5 T& \- _2 T8 |& Y' C; C2 e" T/ A, e9 F, B3 R" T# H
show errors [<iid>]
: A0 T$ a: f2 B% G6 |! }  Dump last known request and response errors collected by frontends and' @7 l' |, r$ M# j$ M& k, Z; D
  backends. If <iid> is specified, the limit the dump to errors concerning$ Z& l  D) g8 S
  either frontend or backend whose ID is <iid>. This command is restricted
" j1 x5 c$ Q* i$ H  and can only be issued on sockets configured for levels "operator" or
4 f) M3 V; L5 K$ G3 m  "admin".* z! @5 y5 H3 L; S% Z, Q" ?9 w) w6 h

! }3 y  q4 Z8 I  The errors which may be collected are the last request and response errors- N/ j6 |" I2 N4 F' @& ]
  caused by protocol violations, often due to invalid characters in header  i# C% }4 [9 r1 B( n6 E1 [
  names. The report precisely indicates what exact character violated the1 `& p& k# J2 L
  protocol. Other important information such as the exact date the error was
# t$ t5 s$ y/ x0 G  detected, frontend and backend names, the server name (when known), the$ a9 d) Z* B( L" y
  internal session ID and the source address which has initiated the session
! U+ T; N2 a" k$ s( _) B% f/ U  are reported too.
3 C) T9 h+ i8 x9 F, m" ~& l, G) k* S# M7 i, o. `/ o$ q% |' ?
  All characters are returned, and non-printable characters are encoded. The/ t4 T. ?# P5 D
  most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one  o3 i! g7 B/ a, x$ E5 B  F
  letter following a backslash. The backslash itself is encoded as '\\' to0 B# [$ p$ j( c7 U% @2 ?5 w
  avoid confusion. Other non-printable characters are encoded '\xNN' where
% I; }( ^& z) o* ]  NN is the two-digits hexadecimal representation of the character's ASCII
/ y: o0 E  S4 l  code.3 D- X5 c8 E) I
! D- N: `" f1 ^) K4 w: K
  Lines are prefixed with the position of their first character, starting at 0
3 I2 U) q7 Y1 _7 G0 Y! x  for the beginning of the buffer. At most one input line is printed per line,, ~  d4 ^' C: k4 q; E& ^
  and large lines will be broken into multiple consecutive output lines so that
6 b0 m0 b5 e* b& K4 v; ]  the output never goes beyond 79 characters wide. It is easy to detect if a
5 g% o# v' u' u  line was broken, because it will not end with '\n' and the next line's offset8 w6 F1 w; y" T
  will be followed by a '+' sign, indicating it is a continuation of previous
5 V$ @* ]  \- R$ q. n/ x  line.
; U, X. ~# U& W- r* ^) B# X9 h( ^4 ]: d9 B5 \4 K# z6 h
  Example :- K$ V/ {, w2 k( f4 K
    >>> $ echo "show errors" | socat stdio /tmp/sock1
/ A6 W! K! ^2 i5 E9 [2 Q        [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response
  w8 ~( v3 h$ h3 g# M" O8 B          src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)8 `- z0 S' J& s1 k, P" p' ?# |
          response length 213 bytes, error at position 23:* F& u0 z4 y& d& i# }
+ ~1 g. @% R+ s
          00000  HTTP/1.0 200 OK\r\n
+ t8 v) a* |+ q; h8 \, `; t          00017  header/bizarre:blah\r\n
0 g! A$ g1 V5 Z) a0 ?; F. k! I          00038  Location: blah\r\n
( s- `* \6 R3 f7 u2 l2 n          00054  Long-line: this is a very long line which should b+ \1 _3 z& G* {) \6 i
          00104+ e broken into multiple lines on the output buffer,+ H) x! h7 A; @+ `4 m% V
          00154+  otherwise it would be too large to print in a ter9 M0 p$ d- q$ s1 H, ?7 L7 n' o: z
          00204+ minal\r\n4 H: P/ L$ D: S* @
          00211  \r\n
6 Z" \% J: i! c1 ]6 b- m  _: f3 ]$ ]1 B
    In the example above, we see that the backend "http-in" which has internal5 T+ }$ }# k1 P, ?/ M
    ID 2 has blocked an invalid response from its server s2 which has internal
1 c5 g, u4 u; ^    ID 1. The request was on session 54 initiated by source 127.0.0.1 and) f; |" ?% k: j* x- Y$ M
    received by frontend fe-eth0 whose ID is 1. The total response length was
5 e+ A* W0 X7 j  f3 f5 w    213 bytes when the error was detected, and the error was at byte 23. This
5 D' I, \+ ~& H5 o5 B2 _    is the slash ('/') in header name "header/bizarre", which is not a valid* p& r% l# ~1 W( I+ g2 J
    HTTP character for a header name.
6 {! Q: v+ q' t) X  k" {
# y5 Z+ C& o% ]  I" s2 Jshow info$ d% U3 q. B7 s: u- F
  Dump info about haproxy status on current process.
+ e8 S( n- t- t* Y. m
& k" D  O, ]& X1 p1 b0 J$ nshow sess' x3 Z, ~/ x* p9 S4 d
  Dump all known sessions. Avoid doing this on slow connections as this can( i6 D+ C9 S8 ?- d1 S# D; u) {+ s
  be huge. This command is restricted and can only be issued on sockets
9 w) D2 e# z" C0 P. u0 u+ l  configured for levels "operator" or "admin".- B, Z7 i# h( e

  V% ]3 G, F# _; G+ \; oshow sess <id>
, b4 A$ t* ?; ^- M  Display a lot of internal information about the specified session identifier.
) I3 a7 B) q* t  c  _  This identifier is the first field at the beginning of the lines in the dumps
4 B8 t8 Y) ?3 C5 n8 B) ?* i- S  of "show sess" (it corresponds to the session pointer). Those information are
' N) ]5 d* i, d1 \  useless to most users but may be used by haproxy developers to troubleshoot a6 v7 F6 Y3 a1 o; ~$ H
  complex bug. The output format is intentionally not documented so that it can
! }% }/ v) H; ?# P& C4 y) r6 K5 I  freely evolve depending on demands.$ G3 Z  ]+ ]- r9 b8 v: {
6 s, y! }+ S4 I3 D5 w2 N, g
show stat [<iid> <type> <sid>]
6 f: E% ~* a- Z- }* x  Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
. J' D6 T. }4 k  possible to dump only selected items :4 A# a% Z- q( g
    - <iid> is a proxy ID, -1 to dump everything& N$ `5 C$ N9 o: U3 s. T$ c
    - <type> selects the type of dumpable objects : 1 for frontends, 2 for
. Y  ^) ^# J- p: ~, Z0 ]       backends, 4 for servers, -1 for everything. These values can be ORed,/ D; }$ C; s" ?! H5 V  Y
       for example:
6 ~1 s2 g( j7 A: e- ]7 K; X          1 + 2     = 3   -> frontend + backend.
4 C% _  b$ S5 l3 g0 H          1 + 2 + 4 = 7   -> frontend + backend + server.5 V. K$ F0 ]$ [3 H/ T
    - <sid> is a server ID, -1 to dump everything from the selected proxy.
  V% m" G* [/ L- z
% ]) e) T, [# I& D  x% F  Example :. S8 B* D, T4 t9 O3 i# V
    >>> $ echo "show info;show stat" | socat stdio unix-connect:/tmp/sock1
7 L- [7 L% ]$ z1 _        Name: HAProxy
& b' t+ b1 j( i! ?& Q7 R  c        Version: 1.4-dev2-493 ^3 Z! ]9 j* m
        Release_date: 2009/09/23
9 _, \4 Q  K2 B' {' a. g& o+ }        Nbproc: 1
" R' ~, b6 ~; c* a$ F8 ~9 h$ o        Process_num: 1
4 Z# Y% a; [- d' a        (...)7 n* e- [& }- R1 r, Z" Y
) }' @; y! \, G0 M
        # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,  (...)+ m% G. F3 w4 H1 _8 |8 _3 s
        stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)7 J' C9 c2 x1 T# v: Z; O" _
        stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...)
9 X/ U: [$ L8 m1 h* T, W/ o7 K        (...)" y' Q( ^. t+ |0 y: r7 O$ ~: `
        www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)" }+ r& }" q0 S' S* k& D
3 X  D  s+ z/ b$ w" n* N
        $! j+ O. ~5 l2 L' n8 {# y

5 O. J+ J( ^5 K' M4 I2 J    Here, two commands have been issued at once. That way it's easy to find
$ K2 [4 Q% d4 f3 j  B' t9 B5 j    which process the stats apply to in multi-process mode. Notice the empty4 N2 {' x: _0 ]6 `3 G4 v
    line after the information output which marks the end of the first block.
3 q+ I: A' E! u    A similar empty line appears at the end of the second block (stats) so that
- E0 \4 L0 p+ h' e# ~; p( I8 ~    the reader knows the output has not been truncated.
1 y0 N+ l7 }2 {& e% b. p+ d7 n7 o6 K. N" z' y3 O2 u5 R  d1 X2 \6 J
$ Q$ h' A: V! l1 C9 S& ~  o
/*
& f+ z7 a, e$ d0 Q. m+ z7 |  W * Local variables:
0 M+ G! X% W8 U9 l2 P *  fill-column: 79% Q- K) e( R" P* O7 @# ?' ~3 _- w) Y
* End:
* ~4 ^/ u# y+ V  L9 k4 j  T */
% p6 W% o  e! l- h" u
/ R0 z) p( U. T% H7 o3 J0 d* h$ y% @" {# _- _; Q. p/ k
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-8 21:31 , Processed in 0.289992 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

快速回复 返回顶部 返回列表