设为首页 收藏本站
查看: 2266|回复: 0

[经验分享] haproxy 官方文档

[复制链接]

尚未签到

发表于 2015-11-20 09:53:03 | 显示全部楼层 |阅读模式
  HAProxy     Configuration Manual
version 1.5-dev24   willy tarreau       2014/04/26
  This document covers the configuration language as implemented in the version

specified above. It does not provide any hint, example or advice. For such

documentation, please refer to the Reference Manual or the Architecture Manual.

The summary below is meant to help you search sections by name and navigate

through the document.
  本文档涵盖了实现配置语言,它不提供任何提示,例子或者建议。 对于这样的文件,
  请参阅参考手册或建筑手册。

下面的摘要是为了帮助你搜索部分的名称和导航

通过文件.
  Note to documentation contributors :  注意文档的贡献者

This document is formatted with 80 columns per line, with even number of
spaces for indentation and without tabs. Please follow these rules strictly
so that it remains easily printable everywhere. If a line needs to be
printed verbatim and does not fit, please end each line with a backslash
('\') and continue on next line, indented by two characters. It is also
sometimes useful to prefix all output lines (logs, console outs) with 3
closing angle brackets ('>>>') in order to help get the difference between
inputs and outputs when it can become ambiguous. If you add sections,
please update the summary below for easier searching.

  Summary

1.Quick reminder about HTTP

1.1.The HTTP transaction model

1.2.HTTP request

1.2.1.The Request line

1.2.2.The request headers

1.3.HTTP response

1.3.1.The Response line

1.3.2.The response headers
  2.Configuring HAProxy

2.1.Configuration file format

2.2.Time format

2.3.Examples
  3.Global parameters

3.1.Process management and security

3.2.Performance tuning

3.3.Debugging

3.4.Userlists

3.5.Peers
  4.Proxies

4.1.Proxy keywords matrix

4.2.Alphabetically sorted keywords reference
  5.Bind and Server options

5.1.Bind options

5.2.Server and default-server options
  6.HTTP header manipulation

7.Using ACLs and fetching samples

7.1.ACL basics

7.1.1.Matching booleans

7.1.2.Matching integers

7.1.3.Matching strings

7.1.4.Matching regular expressions (regexes)

7.1.5.Matching arbitrary data blocks

7.1.6.Matching IPv4 and IPv6 addresses

7.2.Using ACLs to form conditions

7.3.Fetching samples

7.3.1.Converters

7.3.2.Fetching samples from internal states

7.3.3.Fetching samples at Layer 4

7.3.4.Fetching samples at Layer 5

7.3.5.Fetching samples from buffer contents (Layer 6)

7.3.6.Fetching HTTP samples (Layer 7)

7.4.Pre-defined ACLs
  8.Logging

8.1.Log levels

8.2.Log formats

8.2.1.Default log format

8.2.2.TCP log format

8.2.3.HTTP log format

8.2.4.Custom log format

8.2.5.Error log format

8.3.Advanced logging options

8.3.1.Disabling logging of external tests

8.3.2.Logging before waiting for the session to terminate

8.3.3.Raising log level upon errors

8.3.4.Disabling logging of successful connections

8.4.Timing events

8.5.Session state at disconnection

8.6.Non-printable characters

8.7.Capturing HTTP cookies

8.8.Capturing HTTP headers

8.9.

Examples of logs
  9.Statistics and monitoring

9.1.CSV format

9.2.Unix Socket commands

  • Quick reminder about HTTP  关于HTTP快速提示
  When haproxy is running in HTTP mode, both the request and the response are

fully analyzed and indexed, thus it becomes possible to build matching criteria

on almost anything found in the contents.
  当HAProxy 在HTTP模式运行,无论是请求和响应是充分的分析和索引,从而建立匹配的标准在几乎在内容里可以发现的任何内容。
  However, it is important to understand how HTTP requests and responses are

formed, and how HAProxy decomposes them. It will then become easier to write

correct rules and to debug existing configurations.

1.1. The HTTP transaction model
  然而, 了解HTTP请求和响应的形成是重要的,HAProxy 如何处理他们,它会变得容易写正确的规则和调试现有的配置
  1.1. HTTP事务模型
  The HTTP protocol is transaction-driven. This means that each request will lead

to one and only one response. Traditionally, a TCP connection is established

from the client to the server, a request is sent by the client on the

connection, the server responds and the connection is closed. A new request

will involve a new connection :
  HTTP 是事务驱动的,这意味着每个请求会lead to one and only one response。
  传统的,一个TCP 连接是建立从客户端到服务端, 请求是被客户端发送,server 响应,连接关闭。
  一个新的请求会调用新的连接:
  [CON1] [REQ1] … [RESP1] [CLO1] [CON2] [REQ2] … [RESP2] [CLO2] …
  In this mode, called the “HTTP close” mode, there are as many connection

establishments as there are HTTP transactions. Since the connection is closed

by the server after the response, the client does not need to know the content

length.
  在这种模式下,叫做HTTP close 模式,有多少HTTP连接就有多少连接,因为一个连接被server关闭在响应后,
  客户端不需要知道内容的长度。
  Due to the transactional nature of the protocol, it was possible to improve it

to avoid closing a connection between two subsequent transactions. In this mode

however, it is mandatory that the server indicates the content length for each

response so that the client does not wait indefinitely. For this, a special

header is used: “Content-length”. This mode is called the “keep-alive” mode :
  由于协议的的事务特性,它是可能来改善它避免关闭一个连接在两个随后的事务。
  在这种模式下,它是强制的server 表明每个响应的内容长度,让客户端不在等下去。为此,
  一个特殊的header 被使用:”Content-length” 这种模式叫做keep-alive
  [CON] [REQ1] … [RESP1] [REQ2] … [RESP2] [CLO] …
  Its advantages are a reduced latency between transactions, and less processing

power required on the server side. It is generally better than the close mode,

but not always because the clients often limit their concurrent connections to

a smaller value.
  它的优点是减少交易之间的延迟,减少了处理器的需要。它通常比close mode好,
  但并不总是因为客户端经常限制它们的并发连接到一个较小的值
  A last improvement in the communications is the pipelining mode. It still uses

keep-alive, but the client does not wait for the first response to send the

second request. This is useful for fetching large number of images composing a

page :
  一个最后的改善在通信中是在流水线模式, 它仍旧使用keep-alive,但客户端不等待第一个响应来发送第一个请求。
  这对于获取大量的图片组成的页。
  [CON] [REQ1] [REQ2] … [RESP1] [RESP2] [CLO] …
  This can obviously have a tremendous benefit on performance because the network

latency is eliminated between subsequent requests. Many HTTP agents do not

correctly support pipelining since there is no way to associate a response with

the corresponding request in HTTP. For this reason, it is mandatory for the

server to reply in the exact same order as the requests were received.
  这显然有一个巨大的好处在性能上,因为网络的潜在因素在随后的请求中被消除。
  很多的HTTP 代理不正确的支持流水线操作,因为没有办法来关联一个响应和相应的请求在HTTP里。
  对于这个原因, 它是强制性的对于server来响应以准确的顺序当请求被接收时
  By default HAProxy operates in keep-alive mode with regards to persistent

connections: for each connection it processes each request and response, and

leaves the connection idle on both sides between the end of a response and the

start of a new request.
  默认情况下, HAProxy 操作在keep-alive模式来强制保持连接:
  对于每个它处理的请求和响应, 让连接保持idle在响应的结束端和请求的发起端
  HAProxy supports 5 connection modes :
- keep alive    : all requests and responses are processed (default)  所有的请求和响应被处理(默认)
- tunnel        : only the first request and response are processed,   只有第一个请求和响应被处理, 其他的都被转发
everything else is forwarded with no analysis.
- passive close : tunnel with “Connection: close” added in both directions.
- server close  : the server-facing connection is closed after the response.
- forced close  : the connection is actively closed after end of response.
  1.2. HTTP request

First, let’s consider this HTTP request :  首先,让我们考虑这个HTTP请求
  Line     Contents
number
1     GET /serv/login.php?lang=en&profile=2 HTTP/1.1
2     Host: www.mydomain.com
3     User-agent: my small browser
4     Accept: image/jpeg, image/gif
5     Accept: image/png
  1.2.1. The Request line

Line 1 is the “request line”. It is always composed of 3 fields :

  • a METHOD      : GET
  • a URI         : /serv/login.php?lang=en&profile=2
  • a version tag : HTTP/1.1
  All of them are delimited by what the standard calls LWS (linear white spaces),

which are commonly spaces, but can also be tabs or line feeds/carriage returns

followed by spaces/tabs. The method itself cannot contain any colon (‘:’) and

is limited to alphabetic letters. All those various combinations make it

desirable that HAProxy performs the splitting itself rather than leaving it to

the user to write a complex or inaccurate regular expression.
  所有都遵循LWS标准,这里通常是空格,但也可以是tabs
  The URI itself can have several forms : URI本身可以有多种形式

  •   A “relative URI” : 相对URI
      /serv/login.php?lang=en&profile=2
      It is a complete URL without the host part. This is generally what is

    received by servers, reverse proxies and transparent proxies.
      它是一个完整的网址没有host部分,这通常是被服务器接收,反向代理或者透明代理。

  •   An “absolute URI”, also called a “URL” : 绝对URI 被叫做URL
      http://192.168.0.12:8080/serv/login.php?lang=en&profile=2
      It is composed of a “scheme” (the protocol name followed by ‘://’), a host

    name or address, optionally a colon (‘:’) followed by a port number, then

    a relative URI beginning at the first slash (‘/’) after the address part.

    This is generally what proxies receive, but a server supporting HTTP/1.1

    must accept this form too.
      它是有一个”scheme”(鞋子名字后面跟着’://’), 一个host name或者address,人选的一个colon(‘:’) 跟在一个端口号后面
      相对的URI 在第一个斜杠(/) 在地址部分后 这通常是代理接收,但服务器支持HTTP/1.1 必须接受这个格式

  •   a star (‘*’) : this form is only accepted in association with the OPTIONS

    method and is not relayable. It is used to inquiry a next hop’s

    capabilities.
      一个星号(‘*’): 这种格式只能在一个选项方法相关被接收,不是被废弃的。它用于查询吓一跳的能力

  •   an address:port combination : 192.168.0.12:80

    This is used with the CONNECT method, which is used to establish TCP

    tunnels through HTTP proxies, generally for HTTPS, but sometimes for

    other protocols too.
      一个地址:端口组合  192.168.0.12:80
      这个用于在连接方法,用于建立TCP隧道通过HTTP代理,通常用于HTTPS,但也用于其他协议。

  In a relative URI, two sub-parts are identified. The part before the question

mark is called the “path”. It is typically the relative path to static objects

on the server. The part after the question mark is called the “query string”.

It is mostly used with GET requests sent to dynamic scripts and is very

specific to the language, framework or application in use.
  在一个相对的URI,两个字部分被确定. 在查询表级前的部分称为path,
  它通常是是服务器上静态对象的相对路径。 请求表级后面的被称为  “query string”.
  它主要用于GET 请求发送动态的脚本,特定的语言,框架或者应用
  1.2.2. The request headers  请求Headers
  The headers start at the second line. They are composed of a name at the

beginning of the line, immediately followed by a colon (‘:’). Traditionally,

an LWS is added after the colon but that’s not required. Then come the values.

Multiple identical headers may be folded into one single line, delimiting the

values with commas, provided that their order is respected. This is commonly

encountered in the “Cookie:” field. A header may span over multiple lines if

the subsequent lines begin with an LWS. In the example in 1.2, lines 4 and 5

define a total of 3 values for the “Accept:” header.
  headers 从第2行开始, 他们是有一个名字在行开头组成,后面跟着一个colon(‘:’)
  传统上,一个LWS 是被增加在;后面 但不是必须的。 接来是只值,
  多个相同的页眉可以折腾成一个单一的行, 用逗号分隔,
  但他们的顺序是严格的。  这通常是”Cookie”  一个header 可以扩约多行。
  Contrary to a common mis-conception, header names are not case-sensitive, and

their values are not either if they refer to other header names (such as the

“Connection:” header).
  相反的一个常见的错误概念,header 名字不区分大小写,他们的值是不可能的 如果它们指向一个其他的header names
  The end of the headers is indicated by the first empty line. People often say

that it’s a double line feed, which is not exact, even if a double line feed

is one valid form of empty line.
  headers 表明第一个空行, 人们常说这是一个双线的feed,这是不准确的,即使一个双行feed 是一个有效的空行。
  Fortunately, HAProxy takes care of all these complex combinations when indexing

headers, checking values and counting them, so there is no reason to worry

about the way they could be written, but it is important not to accuse an

application of being buggy if it does unusual, valid things.
  幸运的是,HAProxy 照顾所有的复杂的组合当索引headers时,检查值和计数,
  因此没有理由担心关于它们写的方式,但重要的是不要指责一个应用被变得古怪的 如果它是不寻常的,有效的东西。
  Important note:
As suggested by RFC2616, HAProxy normalizes headers by replacing line breaks
in the middle of headers by LWS in order to join multi-line headers. This
is necessary for proper analysis and helps less capable HTTP parsers to work
correctly and not to be fooled by such complex constructs.
  重要说明;
  1.3. HTTP response HTTP 响应
  An HTTP response looks very much like an HTTP request. Both are called HTTP

messages. Let’s consider this HTTP response :
  一个HTTP 响应 看起来像一个HTTP请求, 都叫做HTTP 消息,让我们考虑一下这个HTTP响应:
  Line     Contents
number
1     HTTP/1.1 200 OK
2     Content-length: 350
3     Content-Type: text/html
  As a special case, HTTP supports so called “Informational responses” as status

codes 1xx. These messages are special in that they don’t convey any part of the

response, they’re just used as sort of a signaling message to ask a client to

continue to post its request for instance. In the case of a status 100 response

the requested information will be carried by the next non-100 response message

following the informational one. This implies that multiple responses may be

sent to a single request, and that this only works when keep-alive is enabled

(1xx messages are HTTP/1.1 only). HAProxy handles these messages and is able to

correctly forward and skip them, and only process the next non-100 response. As

such, these messages are neither logged nor transformed, unless explicitly

state otherwise. Status 101 messages indicate that the protocol is changing

over the same connection and that haproxy must switch to tunnel mode, just as

if a CONNECT had occurred. Then the Upgrade header would contain additional

information about the type of protocol the connection is switching to.
  作为一个特殊的情况下, HTTP支持所谓的’信息反应’是状态码1xx,这些消息是特别的,它们不传达响应的任何部分,
  他们只用于一组信号消息来告诉客户端来继续POST 它的请求。
  在状态100响应请求信息,将在下一个100响应信息执行在下面的信息里。
  这意味着, 多个响应可能发送一个单独的请求,它只工作于keep-alive启动的时候(1xx 消息是HTTP/1.1 only)
  HAProxy 处理那些消息,并能正确的转发和跳过它们,只会处理接下来的非100响应
  那些消息既不记录也不转换, 除非显示的规定。
  Status 101 消息表明协议是正在改变在相同的连接 ,haproxy 必须切换到隧道模式,
  正如

如果发生连接。升级头将包含其他

有关连接的协议类型的信息是切换到。
  1.3.1. The Response line   响应行
  Line 1 is the “response line”. It is always composed of 3 fields :  
  Line 1 是响应行, 它总是有3个部分组成:

  • a version tag : HTTP/1.1
  • a status code : 200
  • a reason      : OK
  The status code is always 3-digit. The first digit indicates a general status :
- 1xx = informational message to be skipped (eg: 100, 101)
- 2xx = OK, content is following   (eg: 200, 206)
- 3xx = OK, no content following   (eg: 302, 304)
- 4xx = error caused by the client (eg: 401, 403, 404)
- 5xx = error caused by the server (eg: 500, 502, 503)
  Please refer to RFC2616 for the detailed meaning of all such codes. The

“reason” field is just a hint, but is not parsed by clients. Anything can be

found there, but it’s a common practice to respect the well-established

messages. It can be composed of one or multiple words, such as “OK”, “Found”,

or “Authentication Required”.
  请参见RFC2616的所有代码的具体含义,这个原因字段只是一个提示,但是不被客户端解析。
  Haproxy may emit the following status codes by itself :
  HAProxy 可以发出以下状态代码本身:
  Code  When / reason
200  access to stats page, and when replying to monitoring requests
301  when performing a redirection, depending on the configured code
302  when performing a redirection, depending on the configured code
303  when performing a redirection, depending on the configured code
307  when performing a redirection, depending on the configured code
308  when performing a redirection, depending on the configured code
400  for an invalid or too large request
401  when an authentication is required to perform the action (when
accessing the stats page)
403  when a request is forbidden by a “block” ACL or “reqdeny” filter
408  when the request timeout strikes before the request is complete
500  when haproxy encounters an unrecoverable internal error, such as a
memory allocation failure, which should never happen
502  when the server returns an empty, invalid or incomplete response, or
when an “rspdeny” filter blocks the response.
503  when no server was available to handle the request, or in response to
monitoring requests which match the “monitor fail” condition
504  when the response timeout strikes before the server responds
  The error 4xx and 5xx codes above may be customized (see “errorloc” in section

4.2).
  1.3.2. The response headers 响应headers
  Response headers work exactly like request headers, and as such, HAProxy uses

the same parsing function for both. Please refer to paragraph 1.2.2 for more

details.
  响应头 工作和request头类似, 因此,HAProxy 使用相同的解析函数

  • Configuring HAProxy  配置HAProxy
  2.1. Configuration file format  配置文件格式
  HAProxy’s configuration process involves 3 major sources of parameters :
  HAProxy 的配置涉及的参数涉及3个主要的来源:

  •   the arguments from the command-line, which always take precedence
      来自命令行的参数, 它总是优先

  •   the “global” section, which sets process-wide parameters

    global 章节, 设置过程参数

  •   the proxies sections which can take form of “defaults”, “listen”,

    “frontend” and “backend”.
      代理章节 采取defaults,listen,frontend,backend

  The configuration file syntax consists in lines beginning with a keyword

referenced in this manual, optionally followed by one or several parameters

delimited by spaces. If spaces have to be entered in strings, then they must be

preceded by a backslash (‘\’) to be escaped. Backslashes also have to be

escaped by doubling them.
  配置文件的语法是以关键字开头的,选项后跟着一个或者多个参数有空格分隔。
  如果空格比需输入字符串,那么它们必须之前有一个转义\
  2.2. Time format 时间格式
  Some parameters involve values representing time, such as timeouts. These

values are generally expressed in milliseconds (unless explicitly stated

otherwise) but may be expressed in any other unit by suffixing the unit to the

numeric value. It is important to consider this because it will not be repeated

for every keyword. Supported units are :
  一些参数涉及表示时间值,比如timeout,这些值通常是表示以毫秒显示

  • us : microseconds. 1 microsecond = 1/1000000 second
  • ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.
  • s  : seconds. 1s = 1000ms
  • m  : minutes. 1m = 60s = 60000ms
  • h  : hours.   1h = 60m = 3600s = 3600000ms
  • d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
  2.3. Examples 例子
# Simple configuration for an HTTP proxy listening on port 80 on all
简单的配置用于HTTP 代理 侦听端口80

# interfaces and forwarding requests to a single backend "servers" with a
接口和转发请求到一个单独的backedn "server"用一个单独的server server1 侦听在127.0.0.1:8000
#single server "server1" listening on 127.0.0.1:8000
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend servers
backend servers
server server1 127.0.0.1:8000 maxconn 32

# The same configuration defined with a single listen block. Shorter but
# less expressive, especially in HTTP mode.
相同的配置定义一个单独的侦听块, 短且少的表达式,尤其是HTTP模式
global
daemon
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen http-in
bind *:80
server server1 127.0.0.1:8000 maxconn 32

  Assuming haproxy is in $PATH, test these configurations in a shell with:
  假设HAProxy 是在$PATH里, 测试那些配置在shell里:

$ sudo haproxy -f configuration.conf -c


  • Global parameters  全局参数

    Parameters in the “global” section are process-wide and often OS-specific. They

    are generally set once for all and do not need being changed once correct. Some

    of them have command-line equivalents.
  在全局部分的参数是处理广泛的,通常是OS指定的。它们通常只设置一次对于所有的,不需要被改变一旦正确的话。
  有些有命令行等价
  The following keywords are supported in the “global” section :
  下面的关键在”全局章节”

  •   Process management and security  处理管理和安全

    • ca-base
    • chroot
    • crt-base
    • daemon
    • gid
    • group
    • log
    • log-send-hostname
    • nbproc
    • pidfile
    • uid
    • ulimit-n
    • user
    • stats
    • ssl-server-verify
    • node
    • description
    • unix-bind

  •   Performance tuning   性能调优

    • max-spread-checks
    • maxconn
    • maxconnrate
    • maxcomprate
    • maxcompcpuusage
    • maxpipes
    • maxsessrate
    • maxsslconn
    • maxsslrate
    • noepoll
    • nokqueue
    • nopoll
    • nosplice
    • nogetaddrinfo
    • spread-checks
    • tune.bufsize
    • tune.chksize
    • tune.comp.maxlevel
    • tune.http.cookielen
    • tune.http.maxhdr
    • tune.idletimer
    • tune.maxaccept
    • tune.maxpollevents
    • tune.maxrewrite
    • tune.pipesize
    • tune.rcvbuf.client
    • tune.rcvbuf.server
    • tune.sndbuf.client
    • tune.sndbuf.server
    • tune.ssl.cachesize
    • tune.ssl.lifetime
    • tune.ssl.maxrecord
    • tune.zlib.memlevel
    • tune.zlib.windowsize

  •   Debugging

    • debug
    • quiet

  3.1. Process management and security  处理管理和安全

ca-base
  
  Assigns a default directory to fetch SSL CA certificates and CRLs from when a

relative path is used with “ca-file” or “crl-file” directives. Absolute

locations specified in “ca-file” and “crl-file” prevail and ignore “ca-base”.
  指定一个默认的获取SSL CA证书目录,CRLs从一个相对的路径被用于  “ca-file” or “crl-file” 目录。
  决定的路径在”ca-file” and “crl-file” 为准忽略”ca-base”.
  chroot
  Changes current directory to  and performs a chroot() there before

dropping privileges. This increases the security level in case an unknown

vulnerability would be exploited, since it would make it very hard for the

attacker to exploit the system. This only works when the process is started

with superuser privileges. It is important to ensure that  is both

empty and unwritable to anyone.
  改变当前目录到 执行一个chroot()  在放弃权限前。这个增加了安全级别万一一个未知的安全级别的
  漏洞被利用,因为它会使黑客变得苦难。
  cpu-map <”all”|”odd”|”even”|process_num> …

On Linux 2.6 and above, it is possible to bind a process to a specific CPU

set. This means that the process will never run on other CPUs. The “cpu-map”

directive specifies CPU sets for process sets. The first argument is the

process number to bind. This process must have a number between 1 and 32,

and any process IDs above nbproc are ignored. It is possible to specify all

processes at once using “all”, only odd numbers using “odd” or even numbers

using “even”, just like with the “bind-process” directive. The second and

forthcoming arguments are CPU sets. Each CPU set is either a unique number

between 0 and 31 or a range with two such numbers delimited by a dash (‘-‘).

Multiple CPU numbers or ranges may be specified, and the processes will be

allowed to bind to all of them. Obviously, multiple “cpu-map” directives may

be specified. Each “cpu-map” directive will replace the previous ones when

they overlap.
  在Linux 2.6以上版本, 它有可能将一个进程绑定到一个特别的CPU 集。
  这意味着进程不会运行在其他的CPUs上。

“cpu-map” 指令 特定的CPU集来处理。第一个参数是需要绑定的进程号,
  进程号必须有一个数字在1-32之间,任何进程IDs 在nbproc 被忽略。 可以指定所有的进程使用all
  只有奇数使用奇数或者偶数使用偶数,就像bind-process 指令。
  第二 即将到来的参数是CPU 集,每个CPU 集是一个唯一的数字在0-31 或者一个范围
  crt-base


Assigns a default directory to fetch SSL certificates from when a relative

path is used with “crtfile” directives. Absolute locations specified after

“crtfile” prevail and ignore “crt-base”.  
  指定一个默认的目录用来获取SSL 认证从一个相对路径使用 “crtfile” 目录,
  指定的决定路径在”crtfile” 为准
  daemon

Makes the process fork into background. This is the recommended mode of

operation. It is equivalent to the command line “-D” argument. It can be

disabled by the command line “-db” argument.
  让进程变成后台进程, 这是推荐的模式
  gid  

Changes the process’ group ID to . It is recommended that the group

ID is dedicated to HAProxy or to a small set of similar daemons. HAProxy must

be started with a user belonging to this group, or with superuser privileges.

Note that if haproxy is started from a user having supplementary groups, it

will only be able to drop these groups if started with superuser privileges.

See also “group” and “uid”.

改变进程的group ID, 建议goup ID 是单独的对于HAPorxy 或者一个小部分的守护进程。
  HAProxy 必须启用用户必须属于这个组,或者有超级用户权限。
  注意如果haproxy 从一个超级用户组启动
  group  

Similar to “gid” but uses the GID of group name  from /etc/group.

See also “gid” and “user”.

log
  [max level [min level]]

Adds a global syslog server. Up to two global servers can be defined. They

will receive logs for startups and exits, as well as all logs from proxies

configured with “log global”.  
  类似 “gid”  但使用group name 的GID 在/etc/group
  
can be one of:  

  - An IPv4 address optionally followed by a colon and a UDP port. If
no port is specified, 514 is used by default (the standard syslog
port).
- An IPv6 address followed by a colon and optionally a UDP port. If
no port is specified, 514 is used by default (the standard syslog
port).
- A filesystem path to a UNIX domain socket, keeping in mind
considerations for chroot (be sure the path is accessible inside
the chroot) and uid/gid (be sure the path is appropriately
writeable).
Any part of the address string may reference any number of environment
variables by preceding their name with a dollar sign ('$') and
optionally enclosing them with braces ('{}'), similarly to what is done
in Bourne shell.

  must be one of the 24 standard syslog facilities :  <设备>必须是24个标准的syslog设备

    kern   user   mail   daemon auth   syslog lpr    news
uucp   cron   auth2  ftp    ntp    audit  alert  cron2
local0 local1 local2 local3 local4 local5 local6 local7

  An optional level can be specified to filter outgoing messages. By default,

all messages are sent. If a maximum level is specified, only messages with a

severity at least as important as this level will be sent. An optional minimum

level can be specified. If it is set, logs emitted with a more severe level

than this one will be capped to this level. This is used to avoid sending

“emerg” messages on all terminals on some default syslog configurations.

Eight levels are known :
  一个额外的level可以被指定来过滤传出的消息。默认, 所有的消息发送 如果最大的level 被指定,
  则只有至少同样重要的的消息才会被发送。 一个可选的最小的level 可以被指定。
  如果被设置,记录发出一个多个严重level。

    emerg  alert  crit   err    warning notice info  debug

  log-send-hostname []

Sets the hostname field in the syslog header. If optional “string” parameter

is set the header is set to the string contents, otherwise uses the hostname

of the system. Generally used if one is not relaying logs through an

intermediate syslog server or for simply customizing the hostname printed in

the logs.
  设置hostname 域在syslog header, 如果选项”字符串” 参数设置header 设置了字符串内容,
  否则使用系统的hostname ,一般使用,如果一个不是中间日志通过一个中间的Syslog server

或者简单的定义主机打印日志
  log-tag  

Sets the tag field in the syslog header to this string. It defaults to the

program name as launched from the command line, which usually is “haproxy”.

Sometimes it can be useful to differentiate between multiple processes

running on the same host.
  在syslog header里设置tag 字段,默认是程序名 通常是haproxy  
  有些时候它是有用的 当有多个进程运行在一个主机
  nbproc  

Creates  processes when going daemon. This requires the “daemon”

mode. By default, only one process is created, which is the recommended mode

of operation. For systems limited to small sets of file descriptors per

process, it may be needed to fork multiple daemons. USING MULTIPLE PROCESSES

IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. See also “daemon”.
  创建 进程当运行在dsemon模式, 这个需要 “daemon” 模式,
  默认的,只有一个进程被创建,是推荐的操作模式。  系统限制到一个小的sets 对于每个进程的文件描述符
  它可能需要fork 多个daemons 使用多个进程是很难debug ,真的很沮丧
  pidfile
  Writes pids of all daemons into file . This option is equivalent to

the “-p” command line argument. The file must be accessible to the user

starting the process. See also “daemon”.
  写入所有的dsemons 到一个pidfile,这个选项相当于命令行的-p命令  这个文件必须是可读的
  stats bind-process [ all | odd | even | [-] ] …
  Limits the stats socket to a certain set of processes numbers. By default the

stats socket is bound to all processes, causing a warning to be emitted when

nbproc is greater than 1 because there is no way to select the target process

when connecting. However, by using this setting, it becomes possible to pin

the stats socket to a specific set of processes, typically the first one. The

warning will automatically be disabled when this setting is used, whatever

the number of processes used.
  限制统计 socket 到某个进程数,默认的统计的socket 是限定到所有的进程,
  导致一个警告当nbproc >1,因为没有办法来选择目标的处理器 当连接的时候。
  然而,通过使用设置, 是可能pin 统计的socket 到一个特定的CPU, 通常是第一个。
  ssl-default-bind-ciphers  

This setting is only available when support for OpenSSL was built in. It sets

the default string describing the list of cipher algorithms (“cipher suite”)

that are negotiated during the SSL/TLS handshake for all “bind” lines which

do not explicitly define theirs. The format of the string is defined in

“man 1 ciphers” from OpenSSL man pages, and can be for instance a string such

as “AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH” (without quotes). Please check the

“bind” keyword for more information.
  ssl-default-server-ciphers  

This setting is only available when support for OpenSSL was built in. It

sets the default string describing the list of cipher algorithms that are

negotiated during the SSL/TLS handshake with the server, for all “server”

lines which do not explicitly define theirs. The format of the string is

defined in “man 1 ciphers”. Please check the “server” keyword for more

information.
  ssl-server-verify [none|required]

The default behavior for SSL verify on servers side. If specified to ‘none’,

servers certificates are not verified. The default is ‘required’ except if

forced using cmdline option ‘-dV’.
  stats socket [|] [param*]

Binds a UNIX socket to  or a TCPv4/v6 address to .

Connections to this socket will return various statistics outputs and even

allow some commands to be issued to change some runtime settings. Please

consult section 9.2 “Unix Socket commands” for more details.
  All parameters supported by “bind” lines are supported, for instance to

restrict access to some users or their access rights. Please consult

section 5.1 for more information.

stats timeout
The servers will accept between 100 and 1000 concurrent connections each
and the maximum of 1000 will be reached when the backend reaches 10000
connections.
  backend dynamic
fullconn   10000
server     srv1   dyn1:80 minconn 100 maxconn 1000
server     srv2   dyn2:80 minconn 100 maxconn 1000

See also : “maxconn”, “server”

grace  

Maintain a proxy operational for some time after a soft stop

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :

    is the time (by default in milliseconds) for which the instance
will remain operational with the frontend sockets still listening
when a soft-stop is received via the SIGUSR1 signal.
  This may be used to ensure that the services disappear in a certain order.

This was designed so that frontends which are dedicated to monitoring by an

external equipment fail immediately while other ones remain up for the time

needed by the equipment to detect the failure.
  这个可能是用来确保服务在某个order中消失
  Note that currently, there is very little benefit in using this parameter,

and it may in fact complicate the soft-reconfiguration process more than

simplify it.
  注意,目前,使用这个参数有很少的好处.

hash-type   

Specify a method to use for mapping hashes to servers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the method used to select a server from the hash computed by
the  :
  map-based   the hash table is a static array containing all alive servers.
The hashes will be very smooth, will consider weights, but
will be static in that weight changes while a server is up
will be ignored. This means that there will be no slow start.
Also, since a server is selected by its position in the array,
most mappings are changed when the server count changes. This
means that when a server goes up or down, or when a server is
added to a farm, most connections will be redistributed to
different servers. This can be inconvenient with caches for
instance.
  consistent  the hash table is a tree filled with many occurrences of each
server. The hash key is looked up in the tree and the closest
server is chosen. This hash is dynamic, it supports changing
weights while the servers are up, so it is compatible with the
slow start feature. It has the advantage that when a server
goes up or down, only its associations are moved. When a
server is added to the farm, only a few part of the mappings
are redistributed, making it an ideal method for caches.
However, due to its principle, the distribution will never be
very smooth and it may sometimes be necessary to adjust a
server’s weight or its ID to get a more balanced distribution.
In order to get the same distribution on multiple load
balancers, it is important that all servers have the exact
same IDs. Note: consistent hash uses sdbm and avalanche if no
hash function is specified.
  is the hash function to be used :
  sdbm   this function was created initially for sdbm (a public-domain
reimplementation of ndbm) database library. It was found to do
well in scrambling bits, causing better distribution of the keys
and fewer splits. It also happens to be a good general hashing
function with good distribution, unless the total server weight
is a multiple of 64, in which case applying the avalanche
modifier may help.
  djb2   this function was first proposed by Dan Bernstein many years ago
on comp.lang.c. Studies have shown that for certain workload this
function provides a better distribution than sdbm. It generally
works well with text-based inputs though it can perform extremely
poorly with numeric-only input or when the total server weight is
a multiple of 33, unless the avalanche modifier is also used.
  wt6    this function was designed for haproxy while testing other
functions in the past. It is not as smooth as the other ones, but
is much less sensible to the input data set or to the number of
servers. It can make sense as an alternative to sdbm+avalanche or
djb2+avalanche for consistent hashing or when hashing on numeric
data such as a source IP address or a visitor identifier in a URL
parameter.
  indicates an optional method applied after hashing the key :
  avalanche   This directive indicates that the result from the hash
function above should not be used in its raw form but that
a 4-byte full avalanche hash must be applied first. The
purpose of this step is to mix the resulting bits from the
previous hash in order to avoid any undesired effect when
the input contains some limited values or when the number of
servers is a multiple of one of the hash’s components (64
for SDBM, 33 for DJB2). Enabling avalanche tends to make the
result less predictable, but it’s also not as smooth as when
using the original function. Some testing might be needed
with some workloads. This hash is one of the many proposed
by Bob Jenkins.

The default hash type is “map-based” and is recommended for most usages. The

default function is “sdbm”, the selection of a function should be based on

the range of the values being hashed.

See also : “balance”, “server”

http-check disable-on-404

Enable a maintenance mode upon HTTP/404 response to health-checks

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

When this option is set, a server which returns an HTTP code 404 will be

excluded from further load-balancing, but will still receive persistent

connections. This provides a very convenient method for Web administrators

to perform a graceful shutdown of their servers. It is also important to note

that a server which is detected as failed while it was in this mode will not

generate an alert, just a notice. If the server responds 2xx or 3xx again, it

will immediately be reinserted into the farm. The status on the stats page

reports “NOLB” for a server in this mode. It is important to note that this

option only works in conjunction with the “httpchk” option. If this option

is used with “http-check expect”, then it has precedence over it so that 404

responses will still be considered as soft-stop.
  当这个选项被设置后, 服务器返回一个HTTP code 404 将被排除,
  但是仍旧会收到持续的连接。
  See also : “option httpchk”, “http-check expect”

http-check expect [!]   

Make HTTP health checks consider response contents or specific status codes

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is a keyword indicating how to look for a specific pattern in the
response. The keyword may be one of “status”, “rstatus”,
“string”, or “rstring”. The keyword may be preceded by an
exclamation mark (“!”) to negate the match. Spaces are allowed
between the exclamation mark and the keyword. See below for more
details on the supported keywords.
  is the pattern to look for. It may be a string or a regular
expression. If the pattern contains spaces, they must be escaped
with the usual backslash (‘\’).

By default, “option httpchk” considers that response statuses 2xx and 3xx

are valid, and that others are invalid. When “http-check expect” is used,

it defines what is considered valid or invalid. Only one “http-check”

statement is supported in a backend. If a server fails to respond or times

out, the check obviously fails. The available matches are :
  status  : test the exact string match for the HTTP status code.
A health check response will be considered valid if the
response’s status code is exactly this string. If the
“status” keyword is prefixed with “!”, then the response
will be considered invalid if the status code matches.
  rstatus  : test a regular expression for the HTTP status code.
A health check response will be considered valid if the
response’s status code matches the expression. If the
“rstatus” keyword is prefixed with “!”, then the response
will be considered invalid if the status code matches.
This is mostly used to check for multiple codes.
  string  : test the exact string match in the HTTP response body.
A health check response will be considered valid if the
response’s body contains this exact string. If the
“string” keyword is prefixed with “!”, then the response
will be considered invalid if the body contains this
string. This can be used to look for a mandatory word at
the end of a dynamic page, or to detect a failure when a
specific error appears on the check page (eg: a stack
trace).
  rstring  : test a regular expression on the HTTP response body.
A health check response will be considered valid if the
response’s body matches this expression. If the “rstring”
keyword is prefixed with “!”, then the response will be
considered invalid if the body matches the expression.
This can be used to look for a mandatory word at the end
of a dynamic page, or to detect a failure when a specific
error appears on the check page (eg: a stack trace).
  It is important to note that the responses will be limited to a certain size

defined by the global “tune.chksize” option, which defaults to 16384 bytes.

Thus, too large responses may not contain the mandatory pattern when using

“string” or “rstring”. If a large response is absolutely required, it is

possible to change the default max size by setting the global variable.

However, it is worth keeping in mind that parsing very large responses can

waste some CPU cycles, especially when regular expressions are used, and that

it is always better to focus the checks on smaller resources.
  Last, if “http-check expect” is combined with “http-check disable-on-404”,

then this last one has precedence when the server responds with 404.

Examples :
only accept status 200 as valid
  http-check expect status 200
consider SQL errors as errors
  http-check expect ! string SQL\ Error
consider status 5xx only as errors
  http-check expect ! rstatus ^5
check that we have a correct hexadecimal tag before /html
  http-check expect rstring
addresses .252 and .253 are just probing us.
  frontend www
monitor-net 192.168.0.252/31

See also : “monitor fail”, “monitor-uri”

monitor-uri  

Intercept a URI used by external components’ monitor requests

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments :
is the exact URI which we want to intercept to return HAProxy’s
health status instead of forwarding the request.

When an HTTP request referencing  will be received on a frontend,

HAProxy will not forward it nor log it, but instead will return either

“HTTP/1.0 200 OK” or “HTTP/1.0 503 Service unavailable”, depending on failure

conditions defined with “monitor fail”. This is normally enough for any

front-end HTTP probe to detect that the service is UP and running without

forwarding the request to a backend server. Note that the HTTP method, the

version and all headers are ignored, but the request must at least be valid

at the HTTP level. This keyword may only be used with an HTTP-mode frontend.
  Monitor requests are processed very early. It is not possible to block nor

divert them using ACLs. They cannot be logged either, and it is the intended

purpose. They are only used to report HAProxy’s health to an upper component,

nothing more. However, it is possible to add any number of conditions using

“monitor fail” and ACLs so that the result can be adjusted to whatever check

can be imagined (most often the number of available servers in a backend).

Example :
Use /haproxy_test to report haproxy’s status
  frontend www
mode http
monitor-uri /haproxy_test

See also : “monitor fail”, “monitor-net”

option abortonclose

no option abortonclose

Enable or disable early dropping of aborted requests pending in queues.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

In presence of very high loads, the servers will take some time to respond.

The per-instance connection queue will inflate, and the response time will

increase respective to the size of the queue times the average per-session

response time. When clients will wait for more than a few seconds, they will

often hit the “STOP” button on their browser, leaving a useless request in

the queue, and slowing down other users, and the servers as well, because the

request will eventually be served, then aborted at the first error

encountered while delivering the response.
  As there is no way to distinguish between a full STOP and a simple output

close on the client side, HTTP agents should be conservative and consider

that the client might only have closed its output channel while waiting for

the response. However, this introduces risks of congestion when lots of users

do the same, and is completely useless nowadays because probably no client at

all will close the session while waiting for the response. Some HTTP agents

support this behaviour (Squid, Apache, HAProxy), and others do not (TUX, most

hardware-based load balancers). So the probability for a closed input channel

to represent a user hitting the “STOP” button is close to 100%, and the risk

of being the single component to break rare but valid traffic is extremely

low, which adds to the temptation to be able to abort a session early while

still not served and not pollute the servers.
  In HAProxy, the user can choose the desired behaviour using the option

“abortonclose”. By default (without the option) the behaviour is HTTP

compliant and aborted requests will be served. But when the option is

specified, a session with an incoming channel closed will be aborted while

it is still possible, either pending in the queue for a connection slot, or

during the connection establishment if the server has not yet acknowledged

the connection request. This considerably reduces the queue size and the load

on saturated servers when users are tempted to click on STOP, which in turn

reduces the response time for other users.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “timeout queue” and server’s “maxconn” and “maxqueue” parameters

option accept-invalid-http-request

no option accept-invalid-http-request

Enable or disable relaxing of HTTP request parsing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

By default, HAProxy complies with RFC2616 in terms of message parsing. This

means that invalid characters in header names are not permitted and cause an

error to be returned to the client. This is the desired behaviour as such

forbidden characters are essentially used to build attacks exploiting server

weaknesses, and bypass security filtering. Sometimes, a buggy browser or

server will emit invalid header names for whatever reason (configuration,

implementation) and the issue will not be immediately fixed. In such a case,

it is possible to relax HAProxy’s header name parser to accept any character

even if that does not make sense, by specifying this option. Similarly, the

list of characters allowed to appear in a URI is well defined by RFC3986, and

chars 0-31, 32 (space), 34 (‘”’), 60 (‘<’), 62 (‘>’), 92 (‘\’), 94 (‘^’), 96

(‘`’), 123 (‘{‘), 124 (‘|’), 125 (‘}’), 127 (delete) and anything above are

not allowed at all. Haproxy always blocks a number of them (0..32, 127). The

remaining ones are blocked by default unless this option is enabled.
  This option should never be enabled by default as it hides application bugs

and open security breaches. It should only be deployed after a problem has

been confirmed.
  When this option is enabled, erroneous header names will still be accepted in

requests, but the complete request will be captured in order to permit later

analysis using the “show errors” request on the UNIX stats socket. Similarly,

requests containing invalid chars in the URI part will be logged. Doing this

also helps confirming that the issue has been solved.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option accept-invalid-http-response” and “show errors” on the stats socket.

option accept-invalid-http-response

no option accept-invalid-http-response

Enable or disable relaxing of HTTP response parsing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

By default, HAProxy complies with RFC2616 in terms of message parsing. This

means that invalid characters in header names are not permitted and cause an

error to be returned to the client. This is the desired behaviour as such

forbidden characters are essentially used to build attacks exploiting server

weaknesses, and bypass security filtering. Sometimes, a buggy browser or

server will emit invalid header names for whatever reason (configuration,

implementation) and the issue will not be immediately fixed. In such a case,

it is possible to relax HAProxy’s header name parser to accept any character

even if that does not make sense, by specifying this option.
  This option should never be enabled by default as it hides application bugs

and open security breaches. It should only be deployed after a problem has

been confirmed.
  When this option is enabled, erroneous header names will still be accepted in

responses, but the complete response will be captured in order to permit

later analysis using the “show errors” request on the UNIX stats socket.

Doing this also helps confirming that the issue has been solved.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option accept-invalid-http-request” and “show errors” on the stats socket.

option allbackups

no option allbackups

Use either all backup servers at a time or only the first one

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

By default, the first operational backup server gets all traffic when normal

servers are all down. Sometimes, it may be preferred to use multiple backups

at once, because one will not be enough. When “option allbackups” is enabled,

the load balancing will be performed among all backup servers when all normal

ones are unavailable. The same load balancing algorithm will be used and the

servers’ weights will be respected. Thus, there will not be any priority

order between the backup servers anymore.
  默认情况下,第一个可操作的备份server 得到所有的流量当普通的servers 都down了。
  有时候,它可能优选使用多个备份
  This option is mostly used with static server farms dedicated to return a

“sorry” page when an application is completely offline.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

option checkcache

no option checkcache

Analyze all server responses and block responses with cacheable cookies

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

Some high-level frameworks set application cookies everywhere and do not

always let enough control to the developer to manage how the responses should

be cached. When a session cookie is returned on a cacheable object, there is a

high risk of session crossing or stealing between users traversing the same

caches. In some situations, it is better to block the response than to let

some sensitive session information go in the wild.
  The option “checkcache” enables deep inspection of all server responses for

strict compliance with HTTP specification in terms of cacheability. It

carefully checks “Cache-control”, “Pragma” and “Set-cookie” headers in server

response to check if there’s a risk of caching a cookie on a client-side

proxy. When this option is enabled, the only responses which can be delivered

to the client are :
- all those without “Set-Cookie” header ;
- all those with a return code other than 200, 203, 206, 300, 301, 410,
provided that the server has not set a “Cache-control: public” header ;
- all those that come from a POST request, provided that the server has not
set a ‘Cache-Control: public’ header ;
- those with a ‘Pragma: no-cache’ header
- those with a ‘Cache-control: private’ header
- those with a ‘Cache-control: no-store’ header
- those with a ‘Cache-control: max-age=0’ header
- those with a ‘Cache-control: s-maxage=0’ header
- those with a ‘Cache-control: no-cache’ header
- those with a ‘Cache-control: no-cache=”set-cookie”’ header
- those with a ‘Cache-control: no-cache=”set-cookie,’ header
(allowing other fields after set-cookie)
  If a response doesn’t respect these requirements, then it will be blocked

just as if it was from an “rspdeny” filter, with an “HTTP 502 bad gateway”.

The session state shows “PH–” meaning that the proxy blocked the response

during headers processing. Additionally, an alert will be sent in the logs so

that admins are informed that there’s something to be fixed.
  Due to the high impact on the application, the application should be tested

in depth with the option enabled before going to production. It is also a

good practice to always activate it during tests, even if it is not used in

production, as it will report potentially dangerous application behaviours.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

option clitcpka

no option clitcpka

Enable or disable the sending of TCP keepalive packets on the client side

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

When there is a firewall or any session-aware component between a client and

a server, and when the protocol involves very long sessions with long idle

periods (eg: remote desktops), there is a risk that one of the intermediate

components decides to expire a session which has remained idle for too long.
  当这里有一个防火墙或者任何session-aware组件在客户端和server之间,
  当协议涉及一个很长的会话 有很长的idle期限(例如 远程桌面),有一个风险,中间

组件决定过期一个会话,它一直处于闲置状态太长。
  Enabling socket-level TCP keep-alives makes the system regularly send packets

to the other end of the connection, leaving it active. The delay between

keep-alive probes is controlled by the system only and depends both on the

operating system and its tuning parameters.
  It is important to understand that keep-alive packets are neither emitted nor

received at the application level. It is only the network stacks which sees

them. For this reason, even if one side of the proxy already uses keep-alives

to maintain its connection alive, those keep-alive packets will not be

forwarded to the other side of the proxy.
  需要了解keep-alive 包既不是发出也不不接收在应用层面。
  Please note that this has nothing to do with HTTP keep-alive.
  Using option “clitcpka” enables the emission of TCP keep-alive probes on the

client side of a connection, which should help when session expirations are

noticed between HAProxy and a client.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option srvtcpka”, “option tcpka”

option contstats

Enable continuous traffic statistics updates

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

By default, counters used for statistics calculation are incremented

only when a session finishes. It works quite well when serving small

objects, but with big ones (for example large images or archives) or

with A/V streaming, a graph generated from haproxy counters looks like

a hedgehog. With this option enabled counters get incremented continuously,

during a whole session. Recounting touches a hotpath directly so

it is not enabled by default, as it has small performance impact (~0.5%).

option dontlog-normal

no option dontlog-normal

Enable or disable logging of normal, successful connections

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

There are large sites dealing with several thousand connections per second

and for which logging is a major pain. Some of them are even forced to turn

logs off and cannot debug production issues. Setting this option ensures that

normal connections, those which experience no error, no timeout, no retry nor

redispatch, will not be logged. This leaves disk space for anomalies. In HTTP

mode, the response status code is checked and return codes 5xx will still be

logged.
  It is strongly discouraged to use this option as most of the time, the key to

complex issues is in the normal logs which will not be logged here. If you

need to separate logs, see the “log-separate-errors” option instead.

See also : “log”, “dontlognull”, “log-separate-errors” and section 8 about logging.

option dontlognull

no option dontlognull

Enable or disable logging of null connections

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

In certain environments, there are components which will regularly connect to

various systems to ensure that they are still alive. It can be the case from

another load balancer as well as from monitoring systems. By default, even a

simple port probe or scan will produce a log. If those connections pollute

the logs too much, it is possible to enable option “dontlognull” to indicate

that a connection on which no data has been transferred will not be logged,

which typically corresponds to those probes.
  It is generally recommended not to use this option in uncontrolled

environments (eg: internet), otherwise scans and other malicious activities

would not be logged.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “log”, “monitor-net”, “monitor-uri” and section 8 about logging.

option forceclose

no option forceclose

Enable or disable active connection closing after response is transferred.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

Some HTTP servers do not necessarily close the connections when they receive

the “Connection: close” set by “option httpclose”, and if the client does not

close either, then the connection remains open till the timeout expires. This

causes high number of simultaneous connections on the servers and shows high

global session times in the logs.
  一些HTTP 服务器不需要关闭连接放它们接收到”Connection: close”(通过”option httpclose”)
  如果客户端不关闭,连接仍旧打开直到超时,这个会导致同时有大量的连接
  When this happens, it is possible to use “option forceclose”. It will

actively close the outgoing server channel as soon as the server has finished

to respond and release some resources earlier than with “option httpclose”.
  当这种情况发生时,可以使用”option forceclose”. 它将主动关闭 outgoing server channel
  只要server 已经完成响应和释放一些资源
  This option may also be combined with “option http-pretend-keepalive”, which

will disable sending of the “Connection: close” header, but will still cause

the connection to be closed once the whole response is received.
  这个选项可以结合 “option http-pretend-keepalive”, 会关闭发送”Connection: close” header,
  但是仍旧会导致连接被关闭当整个响应被接收后。
  This option disables and replaces any previous “option httpclose”, “option

http-server-close”, “option http-keep-alive”, or “option http-tunnel”.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option httpclose” and “option http-pretend-keepalive”

option forwardfor [ except  ] [ header  ] [ if-none ]

Enable insertion of the X-Forwarded-For header to requests sent to servers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is an optional argument used to disable this option for sources
matching  
an optional argument to specify a different “X-Forwarded-For”
header name.

Since HAProxy works in reverse-proxy mode, the servers see its IP address as

their client address. This is sometimes annoying when the client’s IP address

is expected in server logs. To solve this problem, the well-known HTTP header

“X-Forwarded-For” may be added by HAProxy to all requests sent to the server.

This header contains a value representing the client’s IP address. Since this

header is always appended at the end of the existing header list, the server

must be configured to always use the last occurrence of this header only. See

the server’s manual to find how to enable use of this standard header. Note

that only the last occurrence of the header must be used, since it is really

possible that the client has already brought one.
  The keyword “header” may be used to supply a different header name to replace

the default “X-Forwarded-For”. This can be useful where you might already

have a “X-Forwarded-For” header from a different application (eg: stunnel),

and you need preserve it. Also if your backend server doesn’t use the

“X-Forwarded-For” header and requires different one (eg: Zeus Web Servers

require “X-Cluster-Client-IP”).
  Sometimes, a same HAProxy instance may be shared between a direct client

access and a reverse-proxy access (for instance when an SSL reverse-proxy is

used to decrypt HTTPS traffic). It is possible to disable the addition of the

header for a known source address or network by adding the “except” keyword

followed by the network address. In this case, any source IP matching the

network will not cause an addition of this header. Most common uses are with

private networks or 127.0.0.1.
  Alternatively, the keyword “if-none” states that the header will only be

added if it is not present. This should only be used in perfectly trusted

environment, as this might cause a security issue if headers reaching haproxy

are under the control of the end-user.
  This option may be specified either in the frontend or in the backend. If at

least one of them uses it, the header will be added. Note that the backend’s

setting of the header subargument takes precedence over the frontend’s if

both are defined. In the case of the “if-none” argument, if at least one of

the frontend or the backend does not specify it, it wants the addition to be

mandatory, so it wins.

Examples :
Public HTTP address also used by stunnel on the same machine
  frontend www
mode http
option forwardfor except 127.0.0.1  # stunnel already adds the header
Those servers want the IP Address in X-Client
  backend www
mode http
option forwardfor header X-Client

See also : “option httpclose”, “option http-server-close”, “option forceclose”, “option http-keep-alive”

option http-keep-alive

no option http-keep-alive

Enable or disable HTTP keep-alive from client to server

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default HAProxy operates in keep-alive mode with regards to persistent

connections: for each connection it processes each request and response, and

leaves the connection idle on both sides between the end of a response and the

start of a new request. This mode may be changed by several options such as

“option http-server-close”, “option forceclose”, “option httpclose” or

“option http-tunnel”. This option allows to set back the keep-alive mode,

which can be useful when another mode was used in a defaults section.
  默认情况下,HAPorxy 操作在keep-alive 模式来保持持续连接:
  对于每个连接它处理每个请求和响应, 以及让连接idle 在启动新的请求和响应结束的两端。
  这种模式会被改变通过几个选项 比如”option http-server-close”, “option forceclose”, “option httpclose” or

“option http-tunnel”.
  Setting “option http-keep-alive” enables HTTP keep-alive mode on the client-

and server- sides. This provides the lowest latency on the client side (slow

network) and the fastest session reuse on the server side at the expense

of maintaining idle connections to the servers. In general, it is possible

with this option to achieve approximately twice the request rate that the

“http-server-close” option achieves on small objects. There are mainly two

situations where this option may be useful :
  设置  “option http-keep-alive” 启用HTTP keep-alive mode 在客户端个服务端
  这个提供了最低延迟在客户端(慢网络),最快的session重用在server端。
  在一般情况下,用这个选项来实现大约2倍的请求速度,”http-server-close”  选项完成在小的对象上。

  •   when the server is non-HTTP compliant and authenticates the connection

    instead of requests (eg: NTLM authentication)
      当服务器是non-HTTP 符合和认证连接代替请求

  •   when the cost of establishing the connection to the server is significant

    compared to the cost of retrieving the associated object from the server.

  当建立连接的成本是重要的比较 检索相关对象的成本
  This last case can happen when the server is a fast static server of cache.

In this case, the server will need to be properly tuned to support high enough

connection counts because connections will last until the client sends another

request.
  当服务器是缓存的快速静态服务器, 在这种情况下, 服务器需要进行适当的调整来支持更加足够的连接数
  因为连接会持续知道客户端发送另外一个请求。
  If the client request has to go to another backend or another server due to

content switching or the load balancing algorithm, the idle connection will

immediately be closed and a new one re-opened. Option “prefer-last-server” is

available to try optimize server selection so that if the server currently

attached to an idle connection is usable, it will be used.
  如果客户端请求需要到另外一个backend或者另外一个server 由于连接切换或者负载算法。
  空闲的连接会立即被关闭,一个新的会重新被打开。 选项”prefer-last-server”
  是可以尝试优化服务器
  In general it is preferred to use “option http-server-close” with application

servers, and some static servers might benefit from “option http-keep-alive”.
  一般来说,优先使用”option http-server-close” 一些静态的服务器可能从”option http-keep-alive”收益。
  At the moment, logs will not indicate whether requests came from the same

session or not. The accept date reported in the logs corresponds to the end

of the previous request, and the request time corresponds to the time spent

waiting for a new request. The keep-alive request time is still bound to the

timeout defined by “timeout http-keep-alive” or “timeout http-request” if

not set.
  在这一刻,日志不会显示青青是否来自相同的会话。接收的日期报告显示在日志
  This option disables and replaces any previous “option httpclose”, “option

http-server-close”, “option forceclose” or “option http-tunnel”. When backend

and frontend options differ, all of these 4 options have precedence over

“option http-keep-alive”.

See also : “option forceclose”, “option http-server-close”, “option prefer-last-server”, “option http-pretend-keepalive”, “option httpclose”, and “1.1. The HTTP transaction model”.

option http-no-delay

no option http-no-delay

Instruct the system to favor low interactive delays over performance in HTTP

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

In HTTP, each payload is unidirectional and has no notion of interactivity.

Any agent is expected to queue data somewhat for a reasonably low delay.

There are some very rare server-to-server applications that abuse the HTTP

protocol and expect the payload phase to be highly interactive, with many

interleaved data chunks in both directions within a single request. This is

absolutely not supported by the HTTP specification and will not work across

most proxies or servers. When such applications attempt to do this through

haproxy, it works but they will experience high delays due to the network

optimizations which favor performance by instructing the system to wait for

enough data to be available in order to only send full packets. Typical

delays are around 200 ms per round trip. Note that this only happens with

abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not

affected.
  When “option http-no-delay” is present in either the frontend or the backend

used by a connection, all such optimizations will be disabled in order to

make the exchanges as fast as possible. Of course this offers no guarantee on

the functionality, as it may break at any other place. But if it works via

HAProxy, it will work as fast as possible. This option should never be used

by default, and should never be used at all unless such a buggy application

is discovered. The impact of using this option is an increase of bandwidth

usage and CPU usage, which may significantly lower performance in high

latency environments.

option http-pretend-keepalive

no option http-pretend-keepalive

Define whether haproxy will announce keepalive to the server or not

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When running with “option http-server-close” or “option forceclose”, haproxy

adds a “Connection: close” header to the request forwarded to the server.

Unfortunately, when some servers see this header, they automatically refrain

from using the chunked encoding for responses of unknown length, while this

is totally unrelated. The immediate effect is that this prevents haproxy from

maintaining the client connection alive. A second effect is that a client or

a cache could receive an incomplete response without being aware of it, and

consider the response complete.
  By setting “option http-pretend-keepalive”, haproxy will make the server

believe it will keep the connection alive. The server will then not fall back

to the abnormal undesired above. When haproxy gets the whole response, it

will close the connection with the server just as it would do with the

“forceclose” option. That way the client gets a normal response and the

connection is correctly closed on the server side.
  It is recommended not to enable this option by default, because most servers

will more efficiently close the connection themselves after the last packet,

and release its buffers slightly earlier. Also, the added packet on the

network could slightly reduce the overall peak performance. However it is

worth noting that when this option is enabled, haproxy will have slightly

less work to do. So if haproxy is the bottleneck on the whole architecture,

enabling this option might save a few CPU cycles.
  This option may be set both in a frontend and in a backend. It is enabled if

at least one of the frontend or backend holding a connection has it enabled.

This option may be combined with “option httpclose”, which will cause

keepalive to be announced to the server and close to be announced to the

client. This practice is discouraged though.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option forceclose”, “option http-server-close”, and “option http-keep-alive”

option http-server-close

no option http-server-close

Enable or disable HTTP connection closing on the server side

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default HAProxy operates in keep-alive mode with regards to persistent

connections: for each connection it processes each request and response, and

leaves the connection idle on both sides between the end of a response and

the start of a new request. This mode may be changed by several options such

as “option http-server-close”, “option forceclose”, “option httpclose” or

“option http-tunnel”. Setting “option http-server-close” enables HTTP

connection-close mode on the server side while keeping the ability to support

HTTP keep-alive and pipelining on the client side.  This provides the lowest

latency on the client side (slow network) and the fastest session reuse on

the server side to save server resources, similarly to “option forceclose”.

It also permits non-keepalive capable servers to be served in keep-alive mode

to the clients if they conform to the requirements of RFC2616. Please note

that some servers do not always conform to those requirements when they see

“Connection: close” in the request. The effect will be that keep-alive will

never be used. A workaround consists in enabling “option

http-pretend-keepalive”.
  At the moment, logs will not indicate whether requests came from the same

session or not. The accept date reported in the logs corresponds to the end

of the previous request, and the request time corresponds to the time spent

waiting for a new request. The keep-alive request time is still bound to the

timeout defined by “timeout http-keep-alive” or “timeout http-request” if

not set.
  This option may be set both in a frontend and in a backend. It is enabled if

at least one of the frontend or backend holding a connection has it enabled.

It disables and replaces any previous “option httpclose”, “option forceclose”,

“option http-tunnel” or “option http-keep-alive”. Please check section 4

(“Proxies”) to see how this option combines with others when frontend and

backend options differ.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option forceclose”, “option http-pretend-keepalive”, “option httpclose”, “option http-keep-alive”, and “1.1. The HTTP transaction model”.

option http-tunnel

no option http-tunnel

Disable or enable HTTP connection processing after first transaction

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default HAProxy operates in keep-alive mode with regards to persistent

connections: for each connection it processes each request and response, and

leaves the connection idle on both sides between the end of a response and

the start of a new request. This mode may be changed by several options such

as “option http-server-close”, “option forceclose”, “option httpclose” or

“option http-tunnel”.
  Option “http-tunnel” disables any HTTP processing past the first request and

the first response. This is the mode which was used by default in versions

1.0 to 1.5-dev21. It is the mode with the lowest processing overhead, which

is normally not needed anymore unless in very specific cases such as when

using an in-house protocol that looks like HTTP but is not compatible, or

just to log one request per client in order to reduce log size. Note that

everything which works at the HTTP level, including header parsing/addition,

cookie processing or content switching will only work for the first request

and will be ignored after the first response.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option forceclose”, “option http-server-close”, “option httpclose”, “option http-keep-alive”, and “1.1. The HTTP transaction model”.

option http-use-proxy-header

no option http-use-proxy-header

Make use of non-standard Proxy-Connection header instead of Connection

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

While RFC2616 explicitly states that HTTP/1.1 agents must use the

Connection header to indicate their wish of persistent or non-persistent

connections, both browsers and proxies ignore this header for proxied

connections and make use of the undocumented, non-standard Proxy-Connection

header instead. The issue begins when trying to put a load balancer between

browsers and such proxies, because there will be a difference between what

haproxy understands and what the client and the proxy agree on.
  By setting this option in a frontend, haproxy can automatically switch to use

that non-standard header if it sees proxied requests. A proxied request is

defined here as one where the URI begins with neither a ‘/’ nor a ‘*’. The

choice of header only affects requests passing through proxies making use of

one of the “httpclose”, “forceclose” and “http-server-close” options. Note

that this option can only be specified in a frontend and will affect the

request along its whole life.
  Also, when this option is set, a request which requires authentication will

automatically switch to use proxy authentication headers if it is itself a

proxied request. That makes it possible to check or enforce authentication in

front of an existing proxy.
  This option should normally never be used, except in front of a proxy.

See also : “option httpclose”, “option forceclose” and “option http-server-close”.

option httpchk

option httpchk  

option httpchk   

option httpchk   

Enable HTTP protocol to check on the servers health

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the optional HTTP method used with the requests. When not set,
the “OPTIONS” method is used, as it generally requires low server
processing and is easy to filter out from the logs. Any method
may be used, though it is not recommended to invent non-standard
ones.
  is the URI referenced in the HTTP requests. It defaults to ” / ”
which is accessible by default on almost any server, but may be
changed to any other URI. Query strings are permitted.
  is the optional HTTP version string. It defaults to “HTTP/1.0”
but some servers might behave incorrectly in HTTP 1.0, so turning
it to HTTP/1.1 may sometimes help. Note that the Host field is
mandatory in HTTP/1.1, and as a trick, it is possible to pass it
after “\r\n” following the version string.

By default, server health checks only consist in trying to establish a TCP

connection. When “option httpchk” is specified, a complete HTTP request is

sent once the TCP connection is established, and responses 2xx and 3xx are

considered valid, while all other ones indicate a server failure, including

the lack of any response.
  The port and interval are specified in the server configuration.
  This option does not necessarily require an HTTP backend, it also works with

plain TCP backends. This is particularly useful to check simple scripts bound

to some dedicated ports using the inetd daemon.

Examples :
Relay HTTPS traffic to Apache instance and check service availability
using HTTP request “OPTIONS * HTTP/1.1” on port 80.
  backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80

See also : “option ssl-hello-chk”, “option smtpchk”, “option mysql-check”, “option pgsql-check”, “http-check” and the “check”, “port” and “inter” server options.

option httpclose

no option httpclose

Enable or disable passive HTTP connection closing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default HAProxy operates in keep-alive mode with regards to persistent

connections: for each connection it processes each request and response, and

leaves the connection idle on both sides between the end of a response and

the start of a new request. This mode may be changed by several options such

as “option http-server-close”, “option forceclose”, “option httpclose” or

“option http-tunnel”.
  If “option httpclose” is set, HAProxy will work in HTTP tunnel mode and check

if a “Connection: close” header is already set in each direction, and will

add one if missing. Each end should react to this by actively closing the TCP

connection after each transfer, thus resulting in a switch to the HTTP close

mode. Any “Connection” header different from “close” will also be removed.

Note that this option is deprecated since what it does is very cheap but not

reliable. Using “option http-server-close” or “option forceclose” is strongly

recommended instead.
  It seldom happens that some servers incorrectly ignore this header and do not

close the connection even though they reply “Connection: close”. For this

reason, they are not compatible with older HTTP 1.0 browsers. If this happens

it is possible to use the “option forceclose” which actively closes the

request connection once the server responds. Option “forceclose” also

releases the server connection earlier because it does not have to wait for

the client to acknowledge it.
  This option may be set both in a frontend and in a backend. It is enabled if

at least one of the frontend or backend holding a connection has it enabled.

It disables and replaces any previous “option http-server-close”,

“option forceclose”, “option http-keep-alive” or “option http-tunnel”. Please

check section 4 (“Proxies”) to see how this option combines with others when

frontend and backend options differ.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option forceclose”, “option http-server-close” and “1.1. The HTTP transaction model”.

option httplog [ clf ]

Enable logging of HTTP request, session state and timers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :

clf       if the “clf” argument is added, then the output format will be
the CLF format instead of HAProxy’s default HTTP format. You can
use this when you need to feed HAProxy’s logs through a specific
log analyser which only support the CLF format and which is not
extensible.

By default, the log output format is very poor, as it only contains the

source and destination addresses, and the instance name. By specifying

“option httplog”, each log line turns into a much richer format including,

but not limited to, the HTTP request, the connection timers, the session

status, the connections numbers, the captured headers and cookies, the

frontend, backend and server name, and of course the source address and

ports.
  This option may be set either in the frontend or the backend.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it. Specifying

only “option httplog” will automatically clear the ‘clf’ mode if it was set

by default.

See also : section 8 about logging.

option http_proxy

no option http_proxy

Enable or disable plain HTTP proxy mode

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

It sometimes happens that people need a pure HTTP proxy which understands

basic proxy requests without caching nor any fancy feature. In this case,

it may be worth setting up an HAProxy instance with the “option http_proxy”

set. In this mode, no server is declared, and the connection is forwarded to

the IP address and port found in the URL after the “http://” scheme.
  No host address resolution is performed, so this only works when pure IP

addresses are passed. Since this option’s usage perimeter is rather limited,

it will probably be used only by experts who know they need exactly it. Last,

if the clients are susceptible of sending keep-alive requests, it will be

needed to add “option httpclose” to ensure that all requests will correctly

be analyzed.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

Example :
this backend understands HTTP proxy requests and forwards them directly.
  backend direct_forward
option httpclose
option http_proxy

See also : “option httpclose”

option independent-streams

no option independent-streams

Enable or disable independent timeout processing for both directions

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default, when data is sent over a socket, both the write timeout and the

read timeout for that socket are refreshed, because we consider that there is

activity on that socket, and we have no other means of guessing if we should

receive data or not.
  While this default behaviour is desirable for almost all applications, there

exists a situation where it is desirable to disable it, and only refresh the

read timeout if there are incoming data. This happens on sessions with large

timeouts and low amounts of exchanged data such as telnet session. If the

server suddenly disappears, the output data accumulates in the system’s

socket buffers, both timeouts are correctly refreshed, and there is no way

to know the server does not receive them, so we don’t timeout. However, when

the underlying protocol always echoes sent data, it would be enough by itself

to detect the issue using the read timeout. Note that this problem does not

happen with more verbose protocols because data won’t accumulate long in the

socket buffers.
  When this option is set on the frontend, it will disable read timeout updates

on data sent to the client. There probably is little use of this case. When

the option is set on the backend, it will disable read timeout updates on

data sent to the server. Doing so will typically break large HTTP posts from

slow lines, so use it with caution.
  Note: older versions used to call this setting “option independent-streams”
with a spelling mistake. This spelling is still supported but
deprecated.

See also : “timeout client”, “timeout server” and “timeout tunnel”

option ldap-check

Use LDAPv3 health checks for server testing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

It is possible to test that the server correctly talks LDAPv3 instead of just

testing that it accepts the TCP connection. When this option is set, an

LDAPv3 anonymous simple bind message is sent to the server, and the response

is analyzed to find an LDAPv3 bind response message.
  The server is considered valid only when the LDAP response contains success

resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9).
  Logging of bind requests is server dependent see your documentation how to

configure it.

Example :

option ldap-check

See also : “option httpchk”

option log-health-checks

no option log-health-checks

Enable or disable logging of health checks

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

Enable health checks logging so it possible to check for example what

was happening before a server crash. Failed health check are logged if

server is UP and succeeded health checks if server is DOWN, so the amount

of additional information is limited.
  If health check logging is enabled no health check status is printed

when servers is set up UP/DOWN/ENABLED/DISABLED.

See also: “log” and section 8 about logging.

option log-separate-errors

no option log-separate-errors

Change log level for non-completely successful connections

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

Sometimes looking for errors in logs is not easy. This option makes haproxy

raise the level of logs containing potentially interesting information such

as errors, timeouts, retries, redispatches, or HTTP status codes 5xx. The

level changes from “info” to “err”. This makes it possible to log them

separately to a different file with most syslog daemons. Be careful not to

remove them from the original file, otherwise you would lose ordering which

provides very important information.
  Using this option, large sites dealing with several thousand connections per

second may log normal traffic to a rotating buffer and only archive smaller

error logs.

See also : “log”, “dontlognull”, “dontlog-normal” and section 8 about logging.

option logasap

no option logasap

Enable or disable early logging of HTTP requests

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

By default, HTTP requests are logged upon termination so that the total

transfer time and the number of bytes appear in the logs. When large objects

are being transferred, it may take a while before the request appears in the

logs. Using “option logasap”, the request gets logged as soon as the server

sends the complete headers. The only missing information in the logs will be

the total number of bytes which will indicate everything except the amount

of data transferred, and the total time which will not take the transfer

time into account. In such a situation, it’s a good practice to capture the

“Content-Length” response header so that the logs at least indicate how many

bytes are expected to be transferred.

Examples :
listen http_proxy 0.0.0.0:80
mode http
option httplog
option logasap
log 192.168.2.200 local3
  Feb  6 12:14:14 localhost \
haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
static/srv1 9/10/7/14/+30 200 +243 - - —- 3/1/1/1/0 1/0 \
“GET /image.iso HTTP/1.0”
See also : “option httplog”, “capture response header”, and section 8 about logging.
option mysql-check [ user  ]
Use MySQL health checks for server testing
May be used in sections :

  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
This is the username which will be used when connecting to MySQL
server.

If you specify a username, the check consists of sending two MySQL packet,

one Client Authentication packet, and one QUIT packet, to correctly close

MySQL session. We then parse the MySQL Handshake Initialisation packet and/or

Error packet. It is a basic but useful test which does not produce error nor

aborted connect on the server. However, it requires adding an authorization

in the MySQL table, like this :

USE mysql;
INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
FLUSH PRIVILEGES;

  If you don’t specify a username (it is deprecated and not recommended), the

check only consists in parsing the Mysql Handshake Initialisation packet or

Error packet, we don’t send anything in this mode. It was reported that it

can generate lockout if check is too frequent and/or if there is not enough

traffic. In fact, you need in this case to check MySQL “max_connect_errors”

value as if a connection is established successfully within fewer than MySQL

“max_connect_errors” attempts after a previous connection was interrupted,

the error count for the host is cleared to zero. If HAProxy’s server get

blocked, the “FLUSH HOSTS” statement is the only way to unblock it.
  Remember that this does not check database presence nor database consistency.

To do this, you can use an external check with xinetd for example.
  The check requires MySQL >=3.22, for older version, please use TCP check.
  Most often, an incoming MySQL server needs to see the client’s IP address for

various purposes, including IP privilege matching and connection logging.

When possible, it is often wise to masquerade the client’s IP address when

connecting to the server using the “usesrc” argument of the “source” keyword,

which requires the cttproxy feature to be compiled in, and the MySQL server

to route the client via the machine hosting haproxy.

See also: “option httpchk”

option nolinger

no option nolinger

Enable or disable immediate session resource cleaning after close

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When clients or servers abort connections in a dirty way (eg: they are

physically disconnected), the session timeouts triggers and the session is

closed. But it will remain in FIN_WAIT1 state for some time in the system,

using some resources and possibly limiting the ability to establish newer

connections.
  When this happens, it is possible to activate “option nolinger” which forces

the system to immediately remove any socket’s pending data on close. Thus,

the session is instantly purged from the system’s tables. This usually has

side effects such as increased number of TCP resets due to old retransmits

getting immediately rejected. Some firewalls may sometimes complain about

this too.
  For this reason, it is not recommended to use this option when not absolutely

needed. You know that you need it when you have thousands of FIN_WAIT1

sessions on your system (TIME_WAIT ones do not count).
  This option may be used both on frontends and backends, depending on the side

where it is required. Use it on the frontend for clients, and on the backend

for servers.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

option originalto [ except  ] [ header  ]

Enable insertion of the X-Original-To header to requests sent to servers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is an optional argument used to disable this option for sources
matching  
an optional argument to specify a different “X-Original-To”
header name.

Since HAProxy can work in transparent mode, every request from a client can

be redirected to the proxy and HAProxy itself can proxy every request to a

complex SQUID environment and the destination host from SO_ORIGINAL_DST will

be lost. This is annoying when you want access rules based on destination ip

addresses. To solve this problem, a new HTTP header “X-Original-To” may be

added by HAProxy to all requests sent to the server. This header contains a

value representing the original destination IP address. Since this must be

configured to always use the last occurrence of this header only. Note that

only the last occurrence of the header must be used, since it is really

possible that the client has already brought one.
  The keyword “header” may be used to supply a different header name to replace

the default “X-Original-To”. This can be useful where you might already

have a “X-Original-To” header from a different application, and you need

preserve it. Also if your backend server doesn’t use the “X-Original-To”

header and requires different one.
  Sometimes, a same HAProxy instance may be shared between a direct client

access and a reverse-proxy access (for instance when an SSL reverse-proxy is

used to decrypt HTTPS traffic). It is possible to disable the addition of the

header for a known source address or network by adding the “except” keyword

followed by the network address. In this case, any source IP matching the

network will not cause an addition of this header. Most common uses are with

private networks or 127.0.0.1.
  This option may be specified either in the frontend or in the backend. If at

least one of them uses it, the header will be added. Note that the backend’s

setting of the header subargument takes precedence over the frontend’s if

both are defined.

Examples :
Original Destination address
  frontend www
mode http
option originalto except 127.0.0.1
Those servers want the IP Address in X-Client-Dst
  backend www
mode http
option originalto header X-Client-Dst

See also : “option httpclose”, “option http-server-close”, “option forceclose”

option persist

no option persist

Enable or disable forced persistence on down servers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

When an HTTP request reaches a backend with a cookie which references a dead

server, by default it is redispatched to another server. It is possible to

force the request to be sent to the dead server first using “option persist”

if absolutely needed. A common use case is when servers are under extreme

load and spend their time flapping. In this case, the users would still be

directed to the server they opened the session on, in the hope they would be

correctly served. It is recommended to use “option redispatch” in conjunction

with this option so that in the event it would not be possible to connect to

the server at all (server definitely dead), the client would finally be

redirected to another valid server.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option redispatch”, “retries”, “force-persist”

option pgsql-check [ user  ]

Use PostgreSQL health checks for server testing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
This is the username which will be used when connecting to
PostgreSQL server.

The check sends a PostgreSQL StartupMessage and waits for either

Authentication request or ErrorResponse message. It is a basic but useful

test which does not produce error nor aborted connect on the server.

This check is identical with the “mysql-check”.

See also: “option httpchk”

option prefer-last-server

no option prefer-last-server

Allow multiple load balanced requests to remain on the same server

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

When the load balancing algorithm in use is not deterministic, and a previous

request was sent to a server to which haproxy still holds a connection, it is

sometimes desirable that subsequent requests on a same session go to the same

server as much as possible. Note that this is different from persistence, as

we only indicate a preference which haproxy tries to apply without any form

of warranty. The real use is for keep-alive connections sent to servers. When

this option is used, haproxy will try to reuse the same connection that is

attached to the server instead of rebalancing to another server, causing a

close of the connection. This can make sense for static file servers. It does

not make much sense to use this in combination with hashing algorithms. Note,

haproxy already automatically tries to stick to a server which sends a 401 or

to a proxy which sends a 407 (authentication required). This is mandatory for

use with the broken NTLM authentication challenge, and significantly helps in

troubleshooting some faulty applications. Option prefer-last-server might be

desirable in these environments as well, to avoid redistributing the traffic

after every other response.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also: “option http-keep-alive”

option redispatch

no option redispatch

Enable or disable session redistribution in case of connection failure

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

In HTTP mode, if a server designated by a cookie is down, clients may

definitely stick to it because they cannot flush the cookie, so they will not

be able to access the service anymore.
  Specifying “option redispatch” will allow the proxy to break their

persistence and redistribute them to a working server.
  It also allows to retry last connection to another server in case of multiple

connection failures. Of course, it requires having “retries” set to a nonzero

value.
  This form is the preferred form, which replaces both the “redispatch” and

“redisp” keywords.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “redispatch”, “retries”, “force-persist”

option redis-check

Use redis health checks for server testing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

It is possible to test that the server correctly talks REDIS protocol instead

of just testing that it accepts the TCP connection. When this option is set,

a PING redis command is sent to the server, and the response is analyzed to

find the “+PONG” response message.

Example :

option redis-check

See also : “option httpchk”

option smtpchk

option smtpchk   

Use SMTP health checks for server testing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is an optional argument. It is the “hello” command to use. It can
be either “HELO” (for SMTP) or “EHLO” (for ESTMP). All other
values will be turned into the default command (“HELO”).
  is the domain name to present to the server. It may only be
specified (and is mandatory) if the hello command has been
specified. By default, “localhost” is used.

When “option smtpchk” is set, the health checks will consist in TCP

connections followed by an SMTP command. By default, this command is

“HELO localhost”. The server’s return code is analyzed and only return codes

starting with a “2” will be considered as valid. All other responses,

including a lack of response will constitute an error and will indicate a

dead server.
  This test is meant to be used with SMTP servers or relays. Depending on the

request, it is possible that some servers do not log each connection attempt,

so you may want to experiment to improve the behaviour. Using telnet on port

25 is often easier than adjusting the configuration.
  Most often, an incoming SMTP server needs to see the client’s IP address for

various purposes, including spam filtering, anti-spoofing and logging. When

possible, it is often wise to masquerade the client’s IP address when

connecting to the server using the “usesrc” argument of the “source” keyword,

which requires the cttproxy feature to be compiled in.

Example :

option smtpchk HELO mydomain.org

See also : “option httpchk”, “source”

option socket-stats

no option socket-stats

Enable or disable collecting & providing separate statistics for each socket.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

option splice-auto

no option splice-auto

Enable or disable automatic kernel acceleration on sockets in both directions

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When this option is enabled either on a frontend or on a backend, haproxy

will automatically evaluate the opportunity to use kernel tcp splicing to

forward data between the client and the server, in either direction. Haproxy

uses heuristics to estimate if kernel splicing might improve performance or

not. Both directions are handled independently. Note that the heuristics used

are not much aggressive in order to limit excessive use of splicing. This

option requires splicing to be enabled at compile time, and may be globally

disabled with the global option “nosplice”. Since splice uses pipes, using it

requires that there are enough spare pipes.
  Important note: kernel-based TCP splicing is a Linux-specific feature which

first appeared in kernel 2.6.25. It offers kernel-based acceleration to

transfer data between sockets without copying these data to user-space, thus

providing noticeable performance gains and CPU cycles savings. Since many

early implementations are buggy, corrupt data and/or are inefficient, this

feature is not enabled by default, and it should be used with extreme care.

While it is not possible to detect the correctness of an implementation,

2.6.29 is the first version offering a properly working implementation. In

case of doubt, splicing may be globally disabled using the global “nosplice”

keyword.

Example :

option splice-auto

If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option splice-request”, “option splice-response”, and global options “nosplice” and “maxpipes”

option splice-request

no option splice-request

Enable or disable automatic kernel acceleration on sockets for requests

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When this option is enabled either on a frontend or on a backend, haproxy

will use kernel tcp splicing whenever possible to forward data going from

the client to the server. It might still use the recv/send scheme if there

are no spare pipes left. This option requires splicing to be enabled at

compile time, and may be globally disabled with the global option “nosplice”.

Since splice uses pipes, using it requires that there are enough spare pipes.
  Important note: see “option splice-auto” for usage limitations.

Example :

option splice-request

If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option splice-auto”, “option splice-response”, and global options “nosplice” and “maxpipes”

option splice-response

no option splice-response

Enable or disable automatic kernel acceleration on sockets for responses

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When this option is enabled either on a frontend or on a backend, haproxy

will use kernel tcp splicing whenever possible to forward data going from

the server to the client. It might still use the recv/send scheme if there

are no spare pipes left. This option requires splicing to be enabled at

compile time, and may be globally disabled with the global option “nosplice”.

Since splice uses pipes, using it requires that there are enough spare pipes.
  Important note: see “option splice-auto” for usage limitations.

Example :

option splice-response

If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option splice-auto”, “option splice-request”, and global options “nosplice” and “maxpipes”

option srvtcpka

no option srvtcpka

Enable or disable the sending of TCP keepalive packets on the server side

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

When there is a firewall or any session-aware component between a client and

a server, and when the protocol involves very long sessions with long idle

periods (eg: remote desktops), there is a risk that one of the intermediate

components decides to expire a session which has remained idle for too long.
  Enabling socket-level TCP keep-alives makes the system regularly send packets

to the other end of the connection, leaving it active. The delay between

keep-alive probes is controlled by the system only and depends both on the

operating system and its tuning parameters.
  It is important to understand that keep-alive packets are neither emitted nor

received at the application level. It is only the network stacks which sees

them. For this reason, even if one side of the proxy already uses keep-alives

to maintain its connection alive, those keep-alive packets will not be

forwarded to the other side of the proxy.
  Please note that this has nothing to do with HTTP keep-alive.
  Using option “srvtcpka” enables the emission of TCP keep-alive probes on the

server side of a connection, which should help when session expirations are

noticed between HAProxy and a server.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option clitcpka”, “option tcpka”

option ssl-hello-chk

Use SSLv3 client hello health checks for server testing

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

When some SSL-based protocols are relayed in TCP mode through HAProxy, it is

possible to test that the server correctly talks SSL instead of just testing

that it accepts the TCP connection. When “option ssl-hello-chk” is set, pure

SSLv3 client hello messages are sent once the connection is established to

the server, and the response is analyzed to find an SSL server hello message.

The server is considered valid only when the response contains this server

hello message.
  All servers tested till there correctly reply to SSLv3 client hello messages,

and most servers tested do not even log the requests containing only hello

messages, which is appreciable.
  Note that this check works even when SSL support was not built into haproxy

because it forges the SSL message. When SSL support is available, it is best

to use native SSL health checks instead of this one.

See also: “option httpchk”, “check-ssl”

option tcp-check

Perform health checks using tcp-check send/expect sequences

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

This health check method is intended to be combined with “tcp-check” command

lists in order to support send/expect types of health check sequences.
  TCP checks currently support 4 modes of operations :
- no “tcp-check” directive : the health check only consists in a connection
attempt, which remains the default mode.

  •   “tcp-check send” or “tcp-check send-binary” only is mentioned : this is

    used to send a string along with a connection opening. With some

    protocols, it helps sending a “QUIT” message for example that prevents

    the server from logging a connection error for each health check. The

    check result will still be based on the ability to open the connection

    only.

  •   “tcp-check expect” only is mentioned : this is used to test a banner.

    The connection is opened and haproxy waits for the server to present some

    contents which must validate some rules. The check result will be based

    on the matching between the contents and the rules. This is suited for

    POP, IMAP, SMTP, FTP, SSH, TELNET.

  •   both “tcp-check send” and “tcp-check expect” are mentioned : this is

    used to test a hello-type protocol. Haproxy sends a message, the server

    responds and its response is analysed. the check result will be based on

    the matching between the response contents and the rules. This is often

    suited for protocols which require a binding or a request/response model.

    LDAP, MySQL, Redis and SSL are example of such protocols, though they

    already all have their dedicated checks with a deeper understanding of

    the respective protocols.

    In this mode, many questions may be sent and many answers may be

    analysed.

    Examples :

perform a POP check (analyse only server’s banner)
  option tcp-check

tcp-check expect string +OK\ POP3\ ready
perform an IMAP check (analyse only server’s banner)
  option tcp-check

tcp-check expect string *\ OK\ IMAP4\ ready
look for the redis master server after ensuring it speaks well
redis protocol, then it exits properly.
(send a command then analyse the response 3 times)
  option tcp-check

tcp-check send PING\r\n

tcp-check expect +PONG

tcp-check send info\ replication\r\n

tcp-check expect string role:master

tcp-check send QUIT\r\n

tcp-check expect string +OK
  forge a HTTP request, then analyse the response

(send many headers before analyzing)

option tcp-check

tcp-check send HEAD\ /\ HTTP/1.1\r\n

tcp-check send Host:\ www.mydomain.com\r\n

tcp-check send User-Agent:\ HAProxy\ tcpcheck\r\n

tcp-check send \r\n

tcp-check expect rstring HTTP/1..\ (2..|3..)

See also : “tcp-check expect”, “tcp-check send”

option tcp-smart-accept

no option tcp-smart-accept

Enable or disable the saving of one ACK packet during the accept sequence

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments : none

When an HTTP connection request comes in, the system acknowledges it on

behalf of HAProxy, then the client immediately sends its request, and the

system acknowledges it too while it is notifying HAProxy about the new

connection. HAProxy then reads the request and responds. This means that we

have one TCP ACK sent by the system for nothing, because the request could

very well be acknowledged by HAProxy when it sends its response.
  For this reason, in HTTP mode, HAProxy automatically asks the system to avoid

sending this useless ACK on platforms which support it (currently at least

Linux). It must not cause any problem, because the system will send it anyway

after 40 ms if the response takes more time than expected to come.
  During complex network debugging sessions, it may be desirable to disable

this optimization because delayed ACKs can make troubleshooting more complex

when trying to identify where packets are delayed. It is then possible to

fall back to normal behaviour by specifying “no option tcp-smart-accept”.
  It is also possible to force it for non-HTTP proxies by simply specifying

“option tcp-smart-accept”. For instance, it can make sense with some services

such as SMTP where the server speaks first.
  It is recommended to avoid forcing this option in a defaults section. In case

of doubt, consider setting it back to automatic values by prepending the

“default” keyword before it, or disabling it using the “no” keyword.

See also : “option tcp-smart-connect”

option tcp-smart-connect

no option tcp-smart-connect

Enable or disable the saving of one ACK packet during the connect sequence

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

On certain systems (at least Linux), HAProxy can ask the kernel not to

immediately send an empty ACK upon a connection request, but to directly

send the buffer request instead. This saves one packet on the network and

thus boosts performance. It can also be useful for some servers, because they

immediately get the request along with the incoming connection.
  This feature is enabled when “option tcp-smart-connect” is set in a backend.

It is not enabled by default because it makes network troubleshooting more

complex.
  It only makes sense to enable it with protocols where the client speaks first

such as HTTP. In other situations, if there is no data to send in place of

the ACK, a normal ACK is sent.
  If this option has been enabled in a “defaults” section, it can be disabled

in a specific instance by prepending the “no” keyword before it.

See also : “option tcp-smart-accept”

option tcpka

Enable or disable the sending of TCP keepalive packets on both sides

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

When there is a firewall or any session-aware component between a client and

a server, and when the protocol involves very long sessions with long idle

periods (eg: remote desktops), there is a risk that one of the intermediate

components decides to expire a session which has remained idle for too long.
  Enabling socket-level TCP keep-alives makes the system regularly send packets

to the other end of the connection, leaving it active. The delay between

keep-alive probes is controlled by the system only and depends both on the

operating system and its tuning parameters.
  It is important to understand that keep-alive packets are neither emitted nor

received at the application level. It is only the network stacks which sees

them. For this reason, even if one side of the proxy already uses keep-alives

to maintain its connection alive, those keep-alive packets will not be

forwarded to the other side of the proxy.
  Please note that this has nothing to do with HTTP keep-alive.
  Using option “tcpka” enables the emission of TCP keep-alive probes on both

the client and server sides of a connection. Note that this is meaningful

only in “defaults” or “listen” sections. If this option is used in a

frontend, only the client side will get keep-alives, and if this option is

used in a backend, only the server side will get keep-alives. For this

reason, it is strongly recommended to explicitly use “option clitcpka” and

“option srvtcpka” when the configuration is split between frontends and

backends.

See also : “option clitcpka”, “option srvtcpka”

option tcplog

Enable advanced logging of TCP connections with session state and timers

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default, the log output format is very poor, as it only contains the

source and destination addresses, and the instance name. By specifying

“option tcplog”, each log line turns into a much richer format including, but

not limited to, the connection timers, the session status, the connections

numbers, the frontend, backend and server name, and of course the source

address and ports. This option is useful for pure TCP proxies in order to

find which of the client or server disconnects or times out. For normal HTTP

proxies, it’s better to use “option httplog” which is even more complete.
  This option may be set either in the frontend or the backend.

See also : “option httplog”, and section 8 about logging.

option transparent

no option transparent

Enable client-side transparent proxying

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

This option was introduced in order to provide layer 7 persistence to layer 3

load balancers. The idea is to use the OS’s ability to redirect an incoming

connection for a remote address to a local process (here HAProxy), and let

this process know what address was initially requested. When this option is

used, sessions without cookies will be forwarded to the original destination

IP address of the incoming request (which should match that of another

equipment), while requests with cookies will still be forwarded to the

appropriate server.
  Note that contrary to a common belief, this option does NOT make HAProxy

present the client’s IP to the server when establishing the connection.

See also: the “usesrc” argument of the “source” keyword, and the “transparent” option of the “bind” keyword.

persist rdp-cookie

persist rdp-cookie()

Enable RDP cookie-based persistence

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the optional name of the RDP cookie to check. If omitted, the
default cookie name “msts” will be used. There currently is no
valid reason to change this name.

This statement enables persistence based on an RDP cookie. The RDP cookie

contains all information required to find the server in the list of known

servers. So when this option is set in the backend, the request is analysed

and if an RDP cookie is found, it is decoded. If it matches a known server

which is still UP (or if “option persist” is set), then the connection is

forwarded to this server.
  Note that this only makes sense in a TCP backend, but for this to work, the

frontend must have waited long enough to ensure that an RDP cookie is present

in the request buffer. This is the same requirement as with the “rdp-cookie”

load-balancing method. Thus it is highly recommended to put all statements in

a single “listen” section.
  Also, it is important to understand that the terminal server will emit this

RDP cookie only if it is configured for “token redirection mode”, which means

that the “IP address redirection” option is disabled.

Example :

listen tse-farm
bind :3389
# wait up to 5s for an RDP cookie in the request
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
# apply RDP cookie persistence
persist rdp-cookie
# if server is unknown, let’s balance on the same cookie.
# alternatively, “balance leastconn” may be useful too.
balance rdp-cookie
server srv1 1.1.1.1:3389
server srv2 1.1.1.2:3389

See also : “balance rdp-cookie”, “tcp-request”, the “req_rdp_cookie” ACL and the rdp_cookie pattern fetch function.

rate-limit sessions  

Set a limit on the number of new sessions accepted per second on a frontend

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments :
The  parameter is an integer designating the maximum number
of new sessions per second to accept on the frontend.

When the frontend reaches the specified number of new sessions per second, it

stops accepting new connections until the rate drops below the limit again.

During this time, the pending sessions will be kept in the socket’s backlog

(in system buffers) and haproxy will not even be aware that sessions are

pending. When applying very low limit on a highly loaded service, it may make

sense to increase the socket’s backlog using the “backlog” keyword.
  This feature is particularly efficient at blocking connection-based attacks

or service abuse on fragile servers. Since the session rate is measured every

millisecond, it is extremely accurate. Also, the limit applies immediately,

no delay is needed at all to detect the threshold.

Example :

Limit the connection rate on SMTP to 10 per second max

listen smtp
mode tcp
bind :25
rate-limit sessions 10
server 127.0.0.1:1025

Note : when the maximum rate is reached, the frontend’s status is not changed
but its sockets appear as “WAITING” in the statistics if the
“socket-stats” option is enabled.

See also : the “backlog” keyword and the “fe_sess_rate” ACL criterion.

redirect location  [code ]  [{if | unless} ]

redirect prefix    [code ]  [{if | unless} ]

redirect scheme    [code ]  [{if | unless} ]

Return an HTTP redirection if/unless a condition is matched

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

If/unless the condition is matched, the HTTP request will lead to a redirect

response. If no condition is specified, the redirect applies unconditionally.

Arguments :
With “redirect location”, the exact value in  is placed into
the HTTP “Location” header. When used in an “http-request” rule,
value follows the log-format rules and can include some
dynamic values (see Custom Log Format in section 8.2.4).
  With “redirect prefix”, the “Location” header is built from the
concatenation of  and the complete URI path, including the
query string, unless the “drop-query” option is specified (see
below). As a special case, if  equals exactly “/”, then
nothing is inserted before the original URI. It allows one to
redirect to the same URL (for instance, to insert a cookie). When
used in an “http-request” rule,  value follows the log-format
rules and can include some dynamic values (see Custom Log Format
in section 8.2.4).
  With “redirect scheme”, then the “Location” header is built by
concatenating  with “://” then the first occurrence of the
“Host” header, and then the URI path, including the query string
unless the “drop-query” option is specified (see below). If no
path is found or if the path is “*”, then “/” is used instead. If
no “Host” header is found, then an empty host component will be
returned, which most recent browsers interpret as redirecting to
the same host. This directive is mostly used to redirect HTTP to
HTTPS. When used in an “http-request” rule,  value follows
the log-format rules and can include some dynamic values (see
Custom Log Format in section 8.2.4).
      The code is optional. It indicates which type of HTTP redirection
is desired. Only codes 301, 302, 303, 307 and 308 are supported,
with 302 used by default if no code is specified. 301 means
“Moved permanently”, and a browser may cache the Location. 302
means “Moved permanently” and means that the browser should not
cache the redirection. 303 is equivalent to 302 except that the
browser will fetch the location with a GET method. 307 is just
like 302 but makes it clear that the same method must be reused.
Likewise, 308 replaces 301 if the same method must be used.
  There are several options which can be specified to adjust the
expected behaviour of a redirection :

  •   “drop-query”

    When this keyword is used in a prefix-based redirection, then the

    location will be set without any possible query-string, which is useful

    for directing users to a non-secure page for instance. It has no effect

    with a location-type redirect.

  •   “append-slash”

    This keyword may be used in conjunction with “drop-query” to redirect

    users who use a URL not ending with a ‘/’ to the same one with the ‘/’.

    It can be useful to ensure that search engines will only see one URL.

    For this, a return code 301 is preferred.

  •   “set-cookie NAME[=value]”

    A “Set-Cookie” header will be added with NAME (and optionally “=value”)

    to the response. This is sometimes used to indicate that a user has

    been seen, for instance to protect against some types of DoS. No other

    cookie option is added, so the cookie will be a session cookie. Note

    that for a browser, a sole cookie name without an equal sign is

    different from a cookie with an equal sign.

  •   “clear-cookie NAME[=]”

    A “Set-Cookie” header will be added with NAME (and optionally “=”), but

    with the “Max-Age” attribute set to zero. This will tell the browser to

    delete this cookie. It is useful for instance on logout pages. It is

    important to note that clearing the cookie “NAME” will not remove a

    cookie set with “NAME=value”. You have to clear the cookie “NAME=” for

    that, because the browser makes the difference.

    Example:

    Move the login URL only to HTTPS.

    acl clear      dst_port  80

    acl secure     dst_port  8080

    acl login_page url_beg   /login

    acl logout     url_beg   /logout

    acl uid_given  url_reg   /login?userid=[^&]+

    acl cookie_set hdr_sub(cookie) SEEN=1

  redirect prefix   https://mysite.com set-cookie SEEN=1 if !cookie_set

redirect prefix   https://mysite.com           if login_page !secure

redirect prefix   http://mysite.com drop-query if login_page !uid_given

redirect location http://mysite.com/           if !login_page secure

redirect location / clear-cookie USERID=       if logout

Example:

Send redirects for request for articles without a ‘/’.

acl missing_slash path_reg ^/article/[^/]*$

redirect code 301 prefix / drop-query append-slash if missing_slash

Example:

Redirect all HTTP traffic to HTTPS when SSL is handled by haproxy.

redirect scheme https if !{ ssl_fc }

Example:

Append ‘www.’ prefix in front of all hosts not having it

http-request redirect code 301 location www.%[hdr(host)]%[req.uri] \
unless { hdr_beg(host) -i www }

See section 7 about ACL usage.

redisp (deprecated)

redispatch (deprecated)

Enable or disable session redistribution in case of connection failure

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

In HTTP mode, if a server designated by a cookie is down, clients may

definitely stick to it because they cannot flush the cookie, so they will not

be able to access the service anymore.
  Specifying “redispatch” will allow the proxy to break their persistence and

redistribute them to a working server.
  It also allows to retry last connection to another server in case of multiple

connection failures. Of course, it requires having “retries” set to a nonzero

value.
  This form is deprecated, do not use it in any new configuration, use the new

“option redispatch” instead.

See also : “option redispatch”

reqadd   [{if | unless} ]

Add a header at the end of the HTTP request

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the complete line to be added. Any space or known delimiter
must be escaped using a backslash (‘\’). Please refer to section
6 about HTTP header manipulation for more information.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A new line consisting in  followed by a line feed will be added after

the last header of an HTTP request.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses.

Example :

Add “X-Proto: SSL” to requests coming via port 81

acl is-ssl  dst_port       81

reqadd      X-Proto:\ SSL  if is-ssl

See also: “rspadd”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqallow   [{if | unless} ]

reqiallow  [{if | unless} ] (ignore case)

Definitely allow an HTTP request if a line matches a regular expression

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The
“reqallow” keyword strictly matches case while “reqiallow”
ignores case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A request containing any line which matches extended regular expression
will mark the request as allowed, even if any later test would

result in a deny. The test applies both to the request line and to request

headers. Keep in mind that URLs in request line are case-sensitive while

header names are not.
  It is easier, faster and more powerful to use ACLs to write access policies.

Reqdeny, reqallow and reqpass should be avoided in new designs.

Example :
allow www.* but refuse *.local
  reqiallow ^Host:\ www.

reqideny  ^Host:\ .*.local

See also: “reqdeny”, “block”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqdel   [{if | unless} ]

reqidel  [{if | unless} ]  (ignore case)

Delete all headers matching a regular expression in an HTTP request

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The “reqdel”
keyword strictly matches case while “reqidel” ignores case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

Any header line matching extended regular expression  in the request

will be completely deleted. Most common use of this is to remove unwanted

and/or dangerous headers or cookies from a request before passing it to the

next servers.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses. Keep in mind that header names are not case-sensitive.

Example :
remove X-Forwarded-For header and SERVER cookie
  reqidel ^X-Forwarded-For:.*

reqidel ^Cookie:.*SERVER=

See also: “reqadd”, “reqrep”, “rspdel”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqdeny   [{if | unless} ]

reqideny  [{if | unless} ]  (ignore case)

Deny an HTTP request if a line matches a regular expression

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The
“reqdeny” keyword strictly matches case while “reqideny” ignores
case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A request containing any line which matches extended regular expression
will mark the request as denied, even if any later test would

result in an allow. The test applies both to the request line and to request

headers. Keep in mind that URLs in request line are case-sensitive while

header names are not.
  A denied request will generate an “HTTP 403 forbidden” response once the

complete request has been parsed. This is consistent with what is practiced

using ACLs.
  It is easier, faster and more powerful to use ACLs to write access policies.

Reqdeny, reqallow and reqpass should be avoided in new designs.

Example :
refuse .local, then allow www.
  reqideny  ^Host:\ .*.local

reqiallow ^Host:\ www.

See also: “reqallow”, “rspdeny”, “block”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqpass   [{if | unless} ]

reqipass  [{if | unless} ]  (ignore case)

Ignore any HTTP request line matching a regular expression in next rules

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The
“reqpass” keyword strictly matches case while “reqipass” ignores
case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A request containing any line which matches extended regular expression
will skip next rules, without assigning any deny or allow verdict.

The test applies both to the request line and to request headers. Keep in

mind that URLs in request line are case-sensitive while header names are not.
  It is easier, faster and more powerful to use ACLs to write access policies.

Reqdeny, reqallow and reqpass should be avoided in new designs.

Example :
refuse .local, then allow www., but ignore “www.private.local”
  reqipass  ^Host:\ www.private.local

reqideny  ^Host:\ .*.local

reqiallow ^Host:\ www.

See also: “reqallow”, “reqdeny”, “block”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqrep    [{if | unless} ]

reqirep   [{if | unless} ]   (ignore case)

Replace a regular expression with a string in an HTTP request line

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The “reqrep”
keyword strictly matches case while “reqirep” ignores case.
  is the complete line to be added. Any space or known delimiter
must be escaped using a backslash (‘\’). References to matched
pattern groups are possible using the common \N form, with N
being a single digit between 0 and 9. Please refer to section
6 about HTTP header manipulation for more information.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

Any line matching extended regular expression  in the request (both

the request line and header lines) will be completely replaced with .

Most common use of this is to rewrite URLs or domain names in “Host” headers.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses. Note that for increased readability, it is suggested to add enough

spaces between the request and the response. Keep in mind that URLs in

request line are case-sensitive while header names are not.

Example :
replace “/static/” with “/” at the beginning of any request path.
  reqrep ^([^\ :])\ /static/(.)     \1\ /\2
replace “www.mydomain.com” with “www” in the host name.
  reqirep ^Host:\ www.mydomain.com   Host:\ www

See also: “reqadd”, “reqdel”, “rsprep”, “tune.bufsize”, section 6 about HTTP header manipulation, and section 7 about ACLs.

reqtarpit   [{if | unless} ]

reqitarpit  [{if | unless} ]  (ignore case)

Tarpit an HTTP request containing a line matching a regular expression

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
request line. This is an extended regular expression. Parenthesis
grouping is supported and no preliminary backslash is required.
Any space or known delimiter must be escaped using a backslash
(‘\’). The pattern applies to a full line at a time. The
“reqtarpit” keyword strictly matches case while “reqitarpit”
ignores case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A request containing any line which matches extended regular expression
will be tarpitted, which means that it will connect to nowhere, will

be kept open for a pre-defined time, then will return an HTTP error 500 so

that the attacker does not suspect it has been tarpitted. The status 500 will

be reported in the logs, but the completion flags will indicate “PT”. The

delay is defined by “timeout tarpit”, or “timeout connect” if the former is

not set.
  The goal of the tarpit is to slow down robots attacking servers with

identifiable requests. Many robots limit their outgoing number of connections

and stay connected waiting for a reply which can take several minutes to

come. Depending on the environment and attack, it may be particularly

efficient at reducing the load on the network and firewalls.

Examples :
ignore user-agents reporting any flavour of “Mozilla” or “MSIE”, but
block all others.
  reqipass   ^User-Agent:.*(Mozilla|MSIE)

reqitarpit ^User-Agent:
block bad guys
  acl badguys src 10.1.0.3 172.16.13.20/28

reqitarpit . if badguys

See also: “reqallow”, “reqdeny”, “reqpass”, section 6 about HTTP header manipulation, and section 7 about ACLs.

retries  

Set the number of retries to perform on a server after a connection failure

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the number of times a connection attempt should be retried on
a server when a connection either is refused or times out. The
default value is 3.

It is important to understand that this value applies to the number of

connection attempts, not full requests. When a connection has effectively

been established to a server, there will be no more retry.
  In order to avoid immediate reconnections to a server which is restarting,

a turn-around timer of 1 second is applied before a retry occurs.
  When “option redispatch” is set, the last retry may be performed on another

server even if a cookie references a different server.

See also : “option redispatch”

rspadd  [{if | unless} ]

Add a header at the end of the HTTP response

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the complete line to be added. Any space or known delimiter
must be escaped using a backslash (‘\’). Please refer to section
6 about HTTP header manipulation for more information.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A new line consisting in  followed by a line feed will be added after

the last header of an HTTP response.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses.

See also: “reqadd”, section 6 about HTTP header manipulation, and section 7 about ACLs.

rspdel   [{if | unless} ]

rspidel  [{if | unless} ]  (ignore case)

Delete all headers matching a regular expression in an HTTP response

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
response line. This is an extended regular expression, so
parenthesis grouping is supported and no preliminary backslash
is required. Any space or known delimiter must be escaped using
a backslash (‘\’). The pattern applies to a full line at a time.
The “rspdel” keyword strictly matches case while “rspidel”
ignores case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

Any header line matching extended regular expression  in the response

will be completely deleted. Most common use of this is to remove unwanted

and/or sensitive headers or cookies from a response before passing it to the

client.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses. Keep in mind that header names are not case-sensitive.

Example :
remove the Server header from responses
  rspidel ^Server:.*

See also: “rspadd”, “rsprep”, “reqdel”, section 6 about HTTP header manipulation, and section 7 about ACLs.

rspdeny   [{if | unless} ]

rspideny  [{if | unless} ]  (ignore case)

Block an HTTP response if a line matches a regular expression

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
response line. This is an extended regular expression, so
parenthesis grouping is supported and no preliminary backslash
is required. Any space or known delimiter must be escaped using
a backslash (‘\’). The pattern applies to a full line at a time.
The “rspdeny” keyword strictly matches case while “rspideny”
ignores case.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

A response containing any line which matches extended regular expression
will mark the request as denied. The test applies both to the

response line and to response headers. Keep in mind that header names are not

case-sensitive.
  Main use of this keyword is to prevent sensitive information leak and to

block the response before it reaches the client. If a response is denied, it

will be replaced with an HTTP 502 error so that the client never retrieves

any sensitive data.
  It is easier, faster and more powerful to use ACLs to write access policies.

Rspdeny should be avoided in new designs.

Example :
Ensure that no content type matching ms-word will leak
  rspideny  ^Content-type:.*/ms-word

See also: “reqdeny”, “acl”, “block”, section 6 about HTTP header manipulation and section 7 about ACLs.

rsprep    [{if | unless} ]

rspirep   [{if | unless} ]  (ignore case)

Replace a regular expression with a string in an HTTP response line

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the regular expression applied to HTTP headers and to the
response line. This is an extended regular expression, so
parenthesis grouping is supported and no preliminary backslash
is required. Any space or known delimiter must be escaped using
a backslash (‘\’). The pattern applies to a full line at a time.
The “rsprep” keyword strictly matches case while “rspirep”
ignores case.
  is the complete line to be added. Any space or known delimiter
must be escaped using a backslash (‘\’). References to matched
pattern groups are possible using the common \N form, with N
being a single digit between 0 and 9. Please refer to section
6 about HTTP header manipulation for more information.
  is an optional matching condition built from ACLs. It makes it
possible to ignore this rule when other conditions are not met.

Any line matching extended regular expression  in the response (both

the response line and header lines) will be completely replaced with

. Most common use of this is to rewrite Location headers.
  Header transformations only apply to traffic which passes through HAProxy,

and not to traffic generated by HAProxy, such as health-checks or error

responses. Note that for increased readability, it is suggested to add enough

spaces between the request and the response. Keep in mind that header names

are not case-sensitive.

Example :
replace “Location: 127.0.0.1:8080” with “Location: www.mydomain.com”
  rspirep ^Location:\ 127.0.0.1:8080    Location:\ www.mydomain.com

See also: “rspadd”, “rspdel”, “reqrep”, section 6 about HTTP header manipulation, and section 7 about ACLs.

server  
[:[port]] [param*]

Declare a server in a backend

May be used in sections :  
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is the internal name assigned to this server. This name will
appear in logs and alerts.  If “http-send-name-header” is
set, it will be added to the request header sent to the server.
  
is the IPv4 or IPv6 address of the server. Alternatively, a
resolvable hostname is supported, but this name will be resolved
during start-up. Address “0.0.0.0” or “*” has a special meaning.
It indicates that the connection will be forwarded to the same IP
address as the one from the client connection. This is useful in
transparent proxy architectures where the client’s connection is
intercepted and haproxy must forward to the original destination
address. This is more or less what the “transparent” keyword does
except that with a server it’s possible to limit concurrency and
to report statistics. Optionally, an address family prefix may be
used before the address to force the family regardless of the
address format, which can be useful to specify a path to a unix
socket with no slash (‘/’). Currently supported prefixes are :
- ‘ipv4@’  -> address is always IPv4
- ‘ipv6@’  -> address is always IPv6
- ‘unix@’  -> address is a path to a local unix socket
Any part of the address string may reference any number of
environment variables by preceding their name with a dollar
sign (‘$’) and optionally enclosing them with braces (‘{}’),
similarly to what is done in Bourne shell.  
  is an optional port specification. If set, all connections will
be sent to this port. If unset, the same port the client
connected to will be used. The port may also be prefixed by a “+”
or a “-“. In this case, the server’s port will be determined by
adding this value to the client’s port.
  
statistics admin level only for localhost
  backend stats_localhost
stats enable
stats admin if LOCALHOST

Example :
statistics admin level always enabled because of the authentication
  backend stats_auth
stats enable
stats auth  admin:AdMiN123
stats admin if TRUE

Example :
statistics admin level depends on the authenticated user
  userlist stats-auth
group admin    users admin
user  admin    insecure-password AdMiN123
group readonly users haproxy
user  haproxy  insecure-password haproxy
  backend stats_auth
stats enable
acl AUTH       http_auth(stats-auth)
acl AUTH_ADMIN http_auth_group(stats-auth) admin
stats http-request auth unless AUTH
stats admin if AUTH_ADMIN

See also : “stats enable”, “stats auth”, “stats http-request”, “nbproc”, “bind-process”, section 3.4 about userlists and section 7 about ACL usage.

stats auth :

Enable statistics with authentication and grant access to an account

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is a user name to grant access to
  is the cleartext password associated to this user

This statement enables statistics with default settings, and restricts access

to declared users only. It may be repeated as many times as necessary to

allow as many users as desired. When a user tries to access the statistics

without a valid account, a “401 Forbidden” response will be returned so that

the browser asks the user to provide a valid user and password. The real

which will be returned to the browser is configurable using “stats realm”.
  Since the authentication method is HTTP Basic Authentication, the passwords

circulate in cleartext on the network. Thus, it was decided that the

configuration file would also use cleartext passwords to remind the users

that those ones should not be sensitive and not shared with any other account.
  It is also possible to reduce the scope of the proxies which appear in the

report using “stats scope”.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats enable”, “stats realm”, “stats scope”, “stats uri”

stats enable

Enable statistics reporting with default settings

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

This statement enables statistics reporting with default settings defined

at build time. Unless stated otherwise, these settings are used :
- stats uri   : /haproxy?stats
- stats realm : “HAProxy Statistics”
- stats auth  : no authentication
- stats scope : no restriction
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats realm”, “stats uri”

stats hide-version

Enable statistics and hide HAProxy version reporting

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

By default, the stats page reports some useful status information along with

the statistics. Among them is HAProxy’s version. However, it is generally

considered dangerous to report precise version to anyone, as it can help them

target known weaknesses with specific attacks. The “stats hide-version”

statement removes the version from the statistics report. This is recommended

for public sites or any site with a weak login/password.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats enable”, “stats realm”, “stats uri”

stats http-request { allow | deny | auth [realm ] }
[ { if | unless }  ]

Access control for statistics

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

As “http-request”, these set of options allow to fine control access to

statistics. Each option may be followed by if/unless and acl.

First option with matched condition (or option without condition) is final.

For “deny” a 403 error will be returned, for “allow” normal processing is

performed, for “auth” a 401/407 error code is returned so the client

should be asked to enter a username and password.
  There is no fixed limit to the number of http-request statements per

instance.

See also : “http-request”, section 3.4 about userlists and section 7 about ACL usage.

stats realm  

Enable statistics and set authentication realm

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the name of the HTTP Basic Authentication realm reported to
the browser. The browser uses it to display it in the pop-up
inviting the user to enter a valid username and password.

The realm is read as a single word, so any spaces in it should be escaped

using a backslash (‘\’).
  This statement is useful only in conjunction with “stats auth” since it is

only related to authentication.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats enable”, “stats uri”

stats refresh  

Enable statistics with automatic refresh

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the suggested refresh delay, specified in seconds, which will
be returned to the browser consulting the report page. While the
browser is free to apply any delay, it will generally respect it
and refresh the page this every seconds. The refresh interval may
be specified in any other non-default time unit, by suffixing the
unit after the value, as explained at the top of this document.

This statement is useful on monitoring displays with a permanent page

reporting the load balancer’s activity. When set, the HTML report page will

include a link “refresh”/”stop refresh” so that the user can select whether

he wants automatic refresh of the page or not.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats enable”, “stats realm”, “stats uri”

stats scope {  | “.” }

Enable statistics and limit access scope

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the name of a listen, frontend or backend section to be
reported. The special name “.” (a single dot) designates the
section in which the statement appears.

When this statement is specified, only the sections enumerated with this

statement will appear in the report. All other ones will be hidden. This

statement may appear as many times as needed if multiple sections need to be

reported. Please note that the name checking is performed as simple string

comparisons, and that it is never checked that a give section name really

exists.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats enable”, “stats realm”, “stats uri”

stats show-desc [  ]

Enable reporting of a description on the statistics page.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes
is an optional description to be reported. If unspecified, the
description from global section is automatically used instead.
  This statement is useful for users that offer shared services to their

customers, where node or description should be different for each customer.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.  By default description is not shown.

Example :
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats show-desc Master node for Europe, Asia, Africa
stats uri       /admin?stats
stats refresh   5s

See also: “show-node”, “stats enable”, “stats uri” and “description” in global section.

stats show-legends

Enable reporting additional information on the statistics page

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments : none

Enable reporting additional information on the statistics page :
- cap: capabilities (proxy)
- mode: one of tcp, http or health (proxy)
- id: SNMP ID (proxy, socket, server)
- IP (socket, server)
- cookie (backend, server)
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.  Default behaviour is not to show this information.

See also: “stats enable”, “stats uri”.

stats show-node [  ]

Enable reporting of a host name on the statistics page.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments:
is an optional name to be reported. If unspecified, the
node name from global section is automatically used instead.

This statement is useful for users that offer shared services to their

customers, where node or description might be different on a stats page

provided for each customer.  Default behaviour is not to show host name.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example:
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats show-node Europe-1
stats uri       /admin?stats
stats refresh   5s

See also: “show-desc”, “stats enable”, “stats uri”, and “node” in global section.

stats uri  

Enable statistics and define the URI prefix to access them

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the prefix of any URI which will be redirected to stats. This
prefix may contain a question mark (‘?’) to indicate part of a
query string.

The statistics URI is intercepted on the relayed traffic, so it appears as a

page within the normal application. It is strongly advised to ensure that the

selected URI will never appear in the application, otherwise it will never be

possible to reach it in the application.
  The default URI compiled in haproxy is “/haproxy?stats”, but this may be

changed at build time, so it’s better to always explicitly specify it here.

It is generally a good idea to include a question mark in the URI so that

intermediate proxies refrain from caching the results. Also, since any string

beginning with the prefix will be accepted as a stats request, the question

mark helps ensuring that no valid URI will begin with the same words.
  It is sometimes very convenient to use “/” as the URI prefix, and put that

statement in a “listen” instance of its own. That makes it easy to dedicate

an address or a port to statistics only.
  Though this statement alone is enough to enable statistics reporting, it is

recommended to set all other settings in order to avoid relying on default

unobvious parameters.

Example :
public access (limited to this backend only)
  backend public_www
server srv1 192.168.0.1:80
stats enable
stats hide-version
stats scope   .
stats uri     /admin?stats
stats realm   Haproxy\ Statistics
stats auth    admin1:AdMiN123
stats auth    admin2:AdMiN321
internal monitoring access (unlimited)
  backend private_monitoring
stats enable
stats uri     /admin?stats
stats refresh 5s

See also : “stats auth”, “stats enable”, “stats realm”

stick match  [table
] [{if | unless} ]

Define a request pattern matching condition to stick a user to a server

May be used in sections :  
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is a pattern extraction rule as described in section 7.3. It
describes what elements of the incoming request or connection
will be analysed in the hope to find a matching entry in a
stickiness table. This rule is mandatory.
  
    is an optional stickiness table name. If unspecified, the same
backend’s table is used. A stickiness table is declared using
the “stick-table” statement.  
  is an optional matching condition. It makes it possible to match
on a certain criterion only when other conditions are met (or
not met). For instance, it could be used to match on a source IP
address except when a request passes through a known proxy, in
which case we’d match on a header containing that IP address.

Some protocols or applications require complex stickiness rules and cannot

always simply rely on cookies nor hashing. The “stick match” statement

describes a rule to extract the stickiness criterion from an incoming request

or connection. See section 7 for a complete list of possible patterns and

transformation rules.
  The table has to be declared using the “stick-table” statement. It must be of

a type compatible with the pattern. By default it is the one which is present

in the same backend. It is possible to share a table with other backends by

referencing it using the “table” keyword. If another table is referenced,

the server’s ID inside the backends are used. By default, all server IDs

start at 1 in each backend, so the server ordering is enough. But in case of

doubt, it is highly recommended to force server IDs using their “id” setting.
  It is possible to restrict the conditions where a “stick match” statement

will apply, using “if” or “unless” followed by a condition. See section 7 for

ACL based conditions.
  There is no limit on the number of “stick match” statements. The first that

applies and matches will cause the request to be directed to the same server

as was used for the request which created the entry. That way, multiple

matches can be used as fallbacks.
  The stick rules are checked after the persistence cookies, so they will not

affect stickiness if a cookie has already been used to select a server. That

way, it becomes very easy to insert cookies and match on IP addresses in

order to maintain stickiness between HTTP and HTTPS.
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
unless you know what you do : memory is not shared between the
processes, which can result in random behaviours.

Example :
forward SMTP users to the same server they just used for POP in the
last 30 minutes
  backend pop
mode tcp
balance roundrobin
stick store-request src
stick-table type ip size 200k expire 30m
server s1 192.168.1.1:110
server s2 192.168.1.1:110
  backend smtp
mode tcp
balance roundrobin
stick match src table pop
server s1 192.168.1.1:25
server s2 192.168.1.1:25

See also : “stick-table”, “stick on”, “nbproc”, “bind-process” and section 7 about ACLs and pattern extraction.

stick on  [table
] [{if | unless} ]

Define a request pattern to associate a user to a server

May be used in sections :  
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Note : This form is exactly equivalent to “stick match” followed by
“stick store-request”, all with the same arguments. Please refer
to both keywords for details. It is only provided as a convenience
for writing more maintainable configurations.
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
unless you know what you do : memory is not shared between the
processes, which can result in random behaviours.

Examples :
The following form …
  stick on src table pop if !localhost
…is strictly equivalent to this one :
  stick match src table pop if !localhost

stick store-request src table pop if !localhost
Use cookie persistence for HTTP, and stick on source address for HTTPS as
well as HTTP without cookie. Share the same table between both accesses.
  backend http
mode http
balance roundrobin
stick on src table https
cookie SRV insert indirect nocache
server s1 192.168.1.1:80 cookie s1
server s2 192.168.1.1:80 cookie s2
  backend https
mode tcp
balance roundrobin
stick-table type ip size 200k expire 30m
stick on src
server s1 192.168.1.1:443
server s2 192.168.1.1:443

See also : “stick match”, “stick store-request”, “nbproc” and “bind-process”.

stick store-request  [table
] [{if | unless} ]

Define a request pattern used to create an entry in a stickiness table

May be used in sections :  
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is a pattern extraction rule as described in section 7.3. It
describes what elements of the incoming request or connection
will be analysed, extracted and stored in the table once a
server is selected.
  
    is an optional stickiness table name. If unspecified, the same
backend’s table is used. A stickiness table is declared using
the “stick-table” statement.  
  is an optional storage condition. It makes it possible to store
certain criteria only when some conditions are met (or not met).
For instance, it could be used to store the source IP address
except when the request passes through a known proxy, in which
case we’d store a converted form of a header containing that IP
address.

Some protocols or applications require complex stickiness rules and cannot

always simply rely on cookies nor hashing. The “stick store-request” statement

describes a rule to decide what to extract from the request and when to do

it, in order to store it into a stickiness table for further requests to

match it using the “stick match” statement. Obviously the extracted part must

make sense and have a chance to be matched in a further request. Storing a

client’s IP address for instance often makes sense. Storing an ID found in a

URL parameter also makes sense. Storing a source port will almost never make

any sense because it will be randomly matched. See section 7 for a complete

list of possible patterns and transformation rules.
  The table has to be declared using the “stick-table” statement. It must be of

a type compatible with the pattern. By default it is the one which is present

in the same backend. It is possible to share a table with other backends by

referencing it using the “table” keyword. If another table is referenced,

the server’s ID inside the backends are used. By default, all server IDs

start at 1 in each backend, so the server ordering is enough. But in case of

doubt, it is highly recommended to force server IDs using their “id” setting.
  It is possible to restrict the conditions where a “stick store-request”

statement will apply, using “if” or “unless” followed by a condition. This

condition will be evaluated while parsing the request, so any criteria can be

used. See section 7 for ACL based conditions.
  There is no limit on the number of “stick store-request” statements, but

there is a limit of 8 simultaneous stores per request or response. This

makes it possible to store up to 8 criteria, all extracted from either the

request or the response, regardless of the number of rules. Only the 8 first

ones which match will be kept. Using this, it is possible to feed multiple

tables at once in the hope to increase the chance to recognize a user on

another protocol or access method. Using multiple store-request rules with

the same table is possible and may be used to find the best criterion to rely

on, by arranging the rules by decreasing preference order. Only the first

extracted criterion for a given table will be stored. All subsequent store-

request rules referencing the same table will be skipped and their ACLs will

not be evaluated.
  The “store-request” rules are evaluated once the server connection has been

established, so that the table will contain the real server that processed

the request.
  Note : Consider not using this feature in multi-process mode (nbproc > 1)
unless you know what you do : memory is not shared between the
processes, which can result in random behaviours.

Example :
forward SMTP users to the same server they just used for POP in the
last 30 minutes
  backend pop
mode tcp
balance roundrobin
stick store-request src
stick-table type ip size 200k expire 30m
server s1 192.168.1.1:110
server s2 192.168.1.1:110
  backend smtp
mode tcp
balance roundrobin
stick match src table pop
server s1 192.168.1.1:25
server s2 192.168.1.1:25

See also : “stick-table”, “stick on”, “nbproc”, “bind-process” and section 7 about ACLs and pattern extraction.

stick-table type {ip | integer | string [len ] | binary [len ]}
size  [expire ] [nopurge] [peers ]
[store ]*

Configure the stickiness table for the current section

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
ip         a table declared with “type ip” will only store IPv4 addresses.
This form is very compact (about 50 bytes per entry) and allows
very fast entry lookup and stores with almost no overhead. This
is mainly used to store client source IP addresses.
  ipv6       a table declared with “type ipv6” will only store IPv6 addresses.
This form is very compact (about 60 bytes per entry) and allows
very fast entry lookup and stores with almost no overhead. This
is mainly used to store client source IP addresses.
  integer    a table declared with “type integer” will store 32bit integers
which can represent a client identifier found in a request for
instance.
  string     a table declared with “type string” will store substrings of up
to  characters. If the string provided by the pattern
extractor is larger than , it will be truncated before
being stored. During matching, at most  characters will be
compared between the string in the table and the extracted
pattern. When not specified, the string is automatically limited
to 32 characters.
  binary     a table declared with “type binary” will store binary blocks
of  bytes. If the block provided by the pattern
extractor is larger than , it will be truncated before
being stored. If the block provided by the pattern extractor
is shorter than , it will be padded by 0. When not
specified, the block is automatically limited to 32 bytes.
  is the maximum number of characters that will be stored in a
“string” type table (See type “string” above). Or the number
of bytes of the block in “binary” type table. Be careful when
changing this parameter as memory usage will proportionally
increase.
  is the maximum number of entries that can fit in the table. This
value directly impacts memory usage. Count approximately
50 bytes per entry, plus the size of a string if any. The size
supports suffixes “k”, “m”, “g” for 2^10, 2^20 and 2^30 factors.
  [nopurge]  indicates that we refuse to purge older entries when the table
is full. When not specified and the table is full when haproxy
wants to store an entry in it, it will flush a few of the oldest
entries in order to release some space for the new ones. This is
most often the desired behaviour. In some specific cases, it
be desirable to refuse new entries instead of purging the older
ones. That may be the case when the amount of data to store is
far above the hardware limits and we prefer not to offer access
to new clients than to reject the ones already connected. When
using this parameter, be sure to properly set the “expire”
parameter (see below).
  is the name of the peers section to use for replication. Entries
which associate keys to server IDs are kept synchronized with
the remote peers declared in this section. All entries are also
automatically learned from the local peer (old process) during a
soft restart.

        NOTE : peers can't be used in multi-process mode.

  defines the maximum duration of an entry in the table since it
was last created, refreshed or matched. The expiration delay is
defined using the standard time format, similarly as the various
timeouts. The maximum duration is slightly above 24 days. See
section 2.2 for more information. If this delay is not specified,
the session won’t automatically expire, but older entries will
be removed once full. Be sure not to use the “nopurge” parameter
if not expiration delay is specified.
  is used to store additional information in the stick-table. This
may be used by ACLs in order to control various criteria related
to the activity of the client matching the stick-table. For each
item specified here, the size of each entry will be inflated so
that the additional data can fit. Several data types may be
stored with an entry. Multiple data types may be specified after
the “store” keyword, as a comma-separated list. Alternatively,
it is possible to repeat the “store” keyword followed by one or
several data types. Except for the “server_id” type which is
automatically detected and enabled, all data types must be
explicitly declared to be stored. If an ACL references a data
type which is not stored, the ACL will simply not match. Some
data types require an argument which must be passed just after
the type between parenthesis. See below for the supported data
types and their arguments.

The data types that can be stored with an entry are the following :
- server_id : this is an integer which holds the numeric ID of the server a
request was assigned to. It is used by the “stick match”, “stick store”,
and “stick on” rules. It is automatically enabled when referenced.

  •   gpc0 : first General Purpose Counter. It is a positive 32-bit integer

    integer which may be used for anything. Most of the time it will be used

    to put a special tag on some entries, for instance to note that a

    specific behaviour was detected and must be known for future matches.

  •   gpc0_rate() : increment rate of the first General Purpose Counter

    over a period. It is a positive 32-bit integer integer which may be used

    for anything. Just like , it counts events, but instead of keeping

    a cumulative count, it maintains the rate at which the counter is

    incremented. Most of the time it will be used to measure the frequency of

    occurrence of certain events (eg: requests to a specific URL).

  •   conn_cnt : Connection Count. It is a positive 32-bit integer which counts

    the absolute number of connections received from clients which matched

    this entry. It does not mean the connections were accepted, just that

    they were received.

  •   conn_cur : Current Connections. It is a positive 32-bit integer which

    stores the concurrent connection counts for the entry. It is incremented

    once an incoming connection matches the entry, and decremented once the

    connection leaves. That way it is possible to know at any time the exact

    number of concurrent connections for an entry.

  •   conn_rate() : frequency counter (takes 12 bytes). It takes an

    integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    incoming connection rate over that period, in connections per period. The

    result is an integer which can be matched using ACLs.

  •   sess_cnt : Session Count. It is a positive 32-bit integer which counts

    the absolute number of sessions received from clients which matched this

    entry. A session is a connection that was accepted by the layer 4 rules.

  •   sess_rate() : frequency counter (takes 12 bytes). It takes an

    integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    incoming session rate over that period, in sessions per period. The

    result is an integer which can be matched using ACLs.

  •   http_req_cnt : HTTP request Count. It is a positive 32-bit integer which

    counts the absolute number of HTTP requests received from clients which

    matched this entry. It does not matter whether they are valid requests or

    not. Note that this is different from sessions when keep-alive is used on

    the client side.

  •   http_req_rate() : frequency counter (takes 12 bytes). It takes an

    integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    HTTP request rate over that period, in requests per period. The result is

    an integer which can be matched using ACLs. It does not matter whether

    they are valid requests or not. Note that this is different from sessions

    when keep-alive is used on the client side.

  •   http_err_cnt : HTTP Error Count. It is a positive 32-bit integer which

    counts the absolute number of HTTP requests errors induced by clients

    which matched this entry. Errors are counted on invalid and truncated

    requests, as well as on denied or tarpitted requests, and on failed

    authentications. If the server responds with 4xx, then the request is

    also counted as an error since it’s an error triggered by the client

    (eg: vulnerability scan).

  •   http_err_rate() : frequency counter (takes 12 bytes). It takes an

    integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    HTTP request error rate over that period, in requests per period (see

    http_err_cnt above for what is accounted as an error). The result is an

    integer which can be matched using ACLs.

  •   bytes_in_cnt : client to server byte count. It is a positive 64-bit

    integer which counts the cumulated amount of bytes received from clients

    which matched this entry. Headers are included in the count. This may be

    used to limit abuse of upload features on photo or video servers.

  •   bytes_in_rate() : frequency counter (takes 12 bytes). It takes an

    integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    incoming bytes rate over that period, in bytes per period. It may be used

    to detect users which upload too much and too fast. Warning: with large

    uploads, it is possible that the amount of uploaded data will be counted

    once upon termination, thus causing spikes in the average transfer speed

    instead of having a smooth one. This may partially be smoothed with

    “option contstats” though this is not perfect yet. Use of byte_in_cnt is

    recommended for better fairness.

  •   bytes_out_cnt : server to client byte count. It is a positive 64-bit

    integer which counts the cumulated amount of bytes sent to clients which

    matched this entry. Headers are included in the count. This may be used

    to limit abuse of bots sucking the whole site.

  •   bytes_out_rate() : frequency counter (takes 12 bytes). It takes

    an integer parameter  which indicates in milliseconds the length

    of the period over which the average is measured. It reports the average

    outgoing bytes rate over that period, in bytes per period. It may be used

    to detect users which download too much and too fast. Warning: with large

    transfers, it is possible that the amount of transferred data will be

    counted once upon termination, thus causing spikes in the average

    transfer speed instead of having a smooth one. This may partially be

    smoothed with “option contstats” though this is not perfect yet. Use of

    byte_out_cnt is recommended for better fairness.

  There is only one stick-table per proxy. At the moment of writing this doc,

it does not seem useful to have multiple tables per proxy. If this happens

to be required, simply create a dummy backend with a stick-table in it and

reference it.
  It is important to understand that stickiness based on learning information

has some limitations, including the fact that all learned associations are

lost upon restart. In general it can be good as a complement but not always

as an exclusive stickiness.
  Last, memory requirements may be important when storing many data types.

Indeed, storing all indicators above at once in each entry requires 116 bytes

per entry, or 116 MB for a 1-million entries table. This is definitely not

something that can be ignored.

Example:
Keep track of counters of up to 1 million IP addresses over 5 minutes
and store a general purpose counter and the average connection rate
computed over a sliding window of 30 seconds.
  stick-table type ip size 1m expire 5m store gpc0,conn_rate(30s)

See also : “stick match”, “stick on”, “stick store-request”, section 2.2 about time format and section 7 about ACLs.

stick store-response  [table
] [{if | unless} ]

Define a request pattern used to create an entry in a stickiness table

May be used in sections :  
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is a pattern extraction rule as described in section 7.3. It
describes what elements of the response or connection will
be analysed, extracted and stored in the table once a
server is selected.
  
    is an optional stickiness table name. If unspecified, the same
backend’s table is used. A stickiness table is declared using
the “stick-table” statement.  
  is an optional storage condition. It makes it possible to store
certain criteria only when some conditions are met (or not met).
For instance, it could be used to store the SSL session ID only
when the response is a SSL server hello.

Some protocols or applications require complex stickiness rules and cannot

always simply rely on cookies nor hashing. The “stick store-response”

statement  describes a rule to decide what to extract from the response and

when to do it, in order to store it into a stickiness table for further

requests to match it using the “stick match” statement. Obviously the

extracted part must make sense and have a chance to be matched in a further

request. Storing an ID found in a header of a response makes sense.

See section 7 for a complete list of possible patterns and transformation

rules.
  The table has to be declared using the “stick-table” statement. It must be of

a type compatible with the pattern. By default it is the one which is present

in the same backend. It is possible to share a table with other backends by

referencing it using the “table” keyword. If another table is referenced,

the server’s ID inside the backends are used. By default, all server IDs

start at 1 in each backend, so the server ordering is enough. But in case of

doubt, it is highly recommended to force server IDs using their “id” setting.
  It is possible to restrict the conditions where a “stick store-response”

statement will apply, using “if” or “unless” followed by a condition. This

condition will be evaluated while parsing the response, so any criteria can

be used. See section 7 for ACL based conditions.
  There is no limit on the number of “stick store-response” statements, but

there is a limit of 8 simultaneous stores per request or response. This

makes it possible to store up to 8 criteria, all extracted from either the

request or the response, regardless of the number of rules. Only the 8 first

ones which match will be kept. Using this, it is possible to feed multiple

tables at once in the hope to increase the chance to recognize a user on

another protocol or access method. Using multiple store-response rules with

the same table is possible and may be used to find the best criterion to rely

on, by arranging the rules by decreasing preference order. Only the first

extracted criterion for a given table will be stored. All subsequent store-

response rules referencing the same table will be skipped and their ACLs will

not be evaluated. However, even if a store-request rule references a table, a

store-response rule may also use the same table. This means that each table

may learn exactly one element from the request and one element from the

response at once.
  The table will contain the real server that processed the request.

Example :
Learn SSL session ID from both request and response and create affinity.
  backend https
mode tcp
balance roundrobin
# maximum SSL session ID length is 32 bytes.
stick-table type binary len 32 size 30k expire 30m

acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
# use tcp content accepts to detects ssl client and server hello.
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
# no timeout on response inspect delay by default.
tcp-response content accept if serverhello
# SSL session ID (SSLID) may be present on a client or server hello.
# Its length is coded on 1 byte at offset 43 and its value starts
# at offset 44.
# Match and learn on request if client hello.
stick on payload_lv(43,1) if clienthello
# Learn on response if server hello.
stick store-response payload_lv(43,1) if serverhello
server s1 192.168.1.1:443
server s2 192.168.1.1:443

  See also : “stick-table”, “stick on”, and section 7 about ACLs and pattern extraction.

tcp-check connect [params*]

Opens a new connection

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

When an application lies on more than a single TCP port or when HAProxy

load-balance many services in a single backend, it makes sense to probe all

the services individually before considering a server as operational.
  When there are no TCP port configured on the server line neither server port

directive, then the ‘tcp-check connect port ’ must be the first step

of the sequence.
  In a tcp-check ruleset a ‘connect’ is required, it is also mandatory to start

the ruleset with a ‘connect’ rule. Purpose is to ensure admin know what they

do.
  Parameters :
They are optional and can be used to describe how HAProxy should open and
use the TCP connection.
  port      if not set, check port or server port is used.
It tells HAProxy where to open the connection to.
must be a valid TCP port source integer, from 1 to 65535.
  send-proxy   send a PROXY protocol string
  ssl          opens a ciphered connection

Examples:
check HTTP and HTTPs services on a server.
first open port 80 thanks to server line port directive, then
tcp-check opens port 443, ciphered and run a request on it:
  option tcp-check

tcp-check connect

tcp-check send GET\ /\ HTTP/1.0\r\n

tcp-check send Host:\ haproxy.1wt.eu\r\n

tcp-check send \r\n

tcp-check expect rstring (2..|3..)

tcp-check connect port 443 ssl

tcp-check send GET\ /\ HTTP/1.0\r\n

tcp-check send Host:\ haproxy.1wt.eu\r\n

tcp-check send \r\n

tcp-check expect rstring (2..|3..)

server www 10.0.0.1 check port 80
check both POP and IMAP from a single server:
  option tcp-check

tcp-check connect port 110

tcp-check expect string +OK\ POP3\ ready

tcp-check connect port 143

tcp-check expect string *\ OK\ IMAP4\ ready

server mail 10.0.0.1 check

See also : “option tcp-check”, “tcp-check send”, “tcp-check expect”

tcp-check expect [!]   

Specify data to be collected and analysed during a generic health check

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is a keyword indicating how to look for a specific pattern in the
response. The keyword may be one of “string”, “rstring” or
binary.
The keyword may be preceded by an exclamation mark (“!”) to negate
the match. Spaces are allowed between the exclamation mark and the
keyword. See below for more details on the supported keywords.
  is the pattern to look for. It may be a string or a regular
expression. If the pattern contains spaces, they must be escaped
with the usual backslash (‘\’).
If the match is set to binary, then the pattern must be passed as
a serie of hexadecimal digits in an even number. Each sequence of
two digits will represent a byte. The hexadecimal digits may be
used upper or lower case.

The available matches are intentionally similar to their http-check cousins :
  string  : test the exact string matches in the response buffer.
A health check response will be considered valid if the
response’s buffer contains this exact string. If the
“string” keyword is prefixed with “!”, then the response
will be considered invalid if the body contains this
string. This can be used to look for a mandatory pattern
in a protocol response, or to detect a failure when a
specific error appears in a protocol banner.
  rstring  : test a regular expression on the response buffer.
A health check response will be considered valid if the
response’s buffer matches this expression. If the
“rstring” keyword is prefixed with “!”, then the response
will be considered invalid if the body matches the
expression.
  binary  : test the exact string in its hexadecimal form matches
in the response buffer. A health check response will
be considered valid if the response’s buffer contains
this exact hexadecimal string.
Purpose is to match data on binary protocols.
  It is important to note that the responses will be limited to a certain size

defined by the global “tune.chksize” option, which defaults to 16384 bytes.

Thus, too large responses may not contain the mandatory pattern when using

“string”, “rstring” or binary. If a large response is absolutely required, it

is possible to change the default max size by setting the global variable.

However, it is worth keeping in mind that parsing very large responses can

waste some CPU cycles, especially when regular expressions are used, and that

it is always better to focus the checks on smaller resources. Also, in its

current state, the check will not find any string nor regex past a null

character in the response. Similarly it is not possible to request matching

the null character.

Examples :
perform a POP check
  option tcp-check

tcp-check expect string +OK\ POP3\ ready
perform an IMAP check
  option tcp-check

tcp-check expect string *\ OK\ IMAP4\ ready
look for the redis master server
  option tcp-check

tcp-check send PING\r\n

tcp-check expect +PONG

tcp-check send info\ replication\r\n

tcp-check expect string role:master

tcp-check send QUIT\r\n

tcp-check expect string +OK

See also : “option tcp-check”, “tcp-check connect”, “tcp-check send”, “tcp-check send-binary”, “http-check expect”, tune.chksize

tcp-check send  

Specify a string to be sent as a question during a generic health check

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes
: the data to be sent as a question during a generic health check
session. For now,  must be a string.

Examples :
look for the redis master server
  option tcp-check

tcp-check send info\ replication\r\n

tcp-check expect string role:master

See also : “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send-binary”, tune.chksize

tcp-check send-binary  

Specify an hexa digits string to be sent as a binary question during a raw

tcp health check

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes
: the data to be sent as a question during a generic health check
session. For now,  must be a string.
: test the exact string in its hexadecimal form matches in the
response buffer. A health check response will be considered
valid if the response’s buffer contains this exact
hexadecimal string.
Purpose is to send binary data to ask on binary protocols.

Examples :
redis check in binary
  option tcp-check

tcp-check send-binary 50494e470d0a # PING\r\n

tcp-check expect binary 2b504F4e47 # +PONG

See also : “option tcp-check”, “tcp-check connect”, “tcp-check expect”, “tcp-check send”, tune.chksize

tcp-request connection  [{if | unless} ]

Perform an action on an incoming connection depending on a layer 4 condition

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes no

no

Arguments :
defines the action to perform if the condition applies. Valid
actions include : “accept”, “reject”, “track-sc0”, “track-sc1”,
“track-sc2”, and “expect-proxy”. See below for more details.
  is a standard layer4-only ACL-based condition (see section 7).

Immediately after acceptance of a new incoming connection, it is possible to

evaluate some conditions to decide whether this connection must be accepted

or dropped or have its counters tracked. Those conditions cannot make use of

any data contents because the connection has not been read from yet, and the

buffers are not yet allocated. This is used to selectively and very quickly

accept or drop connections from various sources with a very low overhead. If

some contents need to be inspected in order to take the decision, the

“tcp-request content” statements must be used instead.
  The “tcp-request connection” rules are evaluated in their exact declaration

order. If no rule matches or if there is no rule, the default action is to

accept the incoming connection. There is no specific limit to the number of

rules which may be inserted.
  Three types of actions are supported :
- accept :
accepts the connection if the condition is true (when used with “if”)
or false (when used with “unless”). The first such rule executed ends
the rules evaluation.

  •   reject :
    rejects the connection if the condition is true (when used with “if”)
    or false (when used with “unless”). The first such rule executed ends
    the rules evaluation. Rejected connections do not even become a
    session, which is why they are accounted separately for in the stats,
    as “denied connections”. They are not considered for the session
    rate-limit and are not logged either. The reason is that these rules
    should only be used to filter extremely high connection rates such as
    the ones encountered during a massive DDoS attack. Under these extreme
    conditions, the simple action of logging each event would make the
    system collapse and would considerably lower the filtering capacity. If
    logging is absolutely desired, then “tcp-request content” rules should
    be used instead.

  •   expect-proxy layer4 :
    configures the client-facing connection to receive a PROXY protocol
    header before any byte is read from the socket. This is equivalent to
    having the “accept-proxy” keyword on the “bind” line, except that using
    the TCP rule allows the PROXY protocol to be accepted only for certain
    IP address ranges using an ACL. This is convenient when multiple layers
    of load balancers are passed through by traffic coming from public
    hosts.

  •   { track-sc0 | track-sc1 | track-sc2 }  [table
    ] :
    enables tracking of sticky counters from current connection. These
    rules do not stop evaluation and do not change default action. Two sets
    of counters may be simultaneously tracked by the same connection. The
    first “track-sc0” rule executed enables tracking of the counters of the
    specified table as the first set. The first “track-sc1” rule executed
    enables tracking of the counters of the specified table as the second
    set. The first “track-sc2” rule executed enables tracking of the
    counters of the specified table as the third set. It is a recommended
    practice to use the first set of counters for the per-frontend counters
    and the second set for the per-backend ones. But this is just a
    guideline, all may be used everywhere.  
      These actions take one or two arguments :
    is mandatory, and is a pattern extraction rule as described
    in section 7.3. It describes what elements of the incoming
    request or connection will be analysed, extracted, combined,
    and used to select which table entry to update the counters.
    Note that “tcp-request connection” cannot use content-based
    fetches.
      
      is an optional table to be used instead of the default one,
    which is the stick-table declared in the current proxy. All
    the counters for the matches and updates for the key will
    then be performed in that table until the session ends.  
      Once a “track-sc*” rule is executed, the key is looked up in the table
    and if it is not found, an entry is allocated for it. Then a pointer to
    that entry is kept during all the session’s life, and this entry’s
    counters are updated as often as possible, every time the session’s
    counters are updated, and also systematically when the session ends.
    Counters are only updated for events that happen after the tracking has
    been started. For example, connection counters will not be updated when
    tracking layer 7 information, since the connection event happens before
    layer7 information is extracted.
      If the entry tracks concurrent connection counters, one connection is
    counted for as long as the entry is tracked, and the entry will not
    expire during that time. Tracking counters also provides a performance
    advantage over just checking the keys, because only one table lookup is
    performed for all ACL checks that make use of it.

  Note that the “if/unless” condition is optional. If no condition is set on

the action, it is simply performed unconditionally. That can be useful for

“track-sc*” actions as well as for changing the default action to a reject.

Example:

Accept all connections from white-listed hosts, reject too fast connection without counting them, and track accepted connections. This results in connection rate being capped from abusive sources.

tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }

tcp-request connection reject if { src_conn_rate gt 10 }

tcp-request connection track-sc0 src

Example:

Accept all connections from white-listed hosts, count all other connections and reject too fast ones. This results in abusive ones being blocked as long as they don’t slow down.

tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }

tcp-request connection track-sc0 src

tcp-request connection reject if { sc0_conn_rate gt 10 }

Example:

Enable the PROXY protocol for traffic coming from all known proxies.

tcp-request connection expect-proxy layer4 if { src -f proxies.lst }

See section 7 about ACL usage.

See also : “tcp-request content”, “stick-table”

tcp-request content  [{if | unless} ]

Perform an action on a new session depending on a layer 4-7 condition

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
defines the action to perform if the condition applies. Valid
actions include : “accept”, “reject”, “track-sc0”, “track-sc1”,
and “track-sc2”. See “tcp-request connection” above for their
signification.
  is a standard layer 4-7 ACL-based condition (see section 7).

A request’s contents can be analysed at an early stage of request processing

called “TCP content inspection”. During this stage, ACL-based rules are

evaluated every time the request contents are updated, until either an

“accept” or a “reject” rule matches, or the TCP request inspection delay

expires with no matching rule.
  The first difference between these rules and “tcp-request connection” rules

is that “tcp-request content” rules can make use of contents to take a

decision. Most often, these decisions will consider a protocol recognition or

validity. The second difference is that content-based rules can be used in

both frontends and backends. In case of HTTP keep-alive with the client, all

tcp-request content rules are evaluated again, so haproxy keeps a record of

what sticky counters were assigned by a “tcp-request connection” versus a

“tcp-request content” rule, and flushes all the content-related ones after

processing an HTTP request, so that they may be evaluated again by the rules

being evaluated again for the next request. This is of particular importance

when the rule tracks some L7 information or when it is conditioned by an

L7-based ACL, since tracking may change between requests.
  Content-based rules are evaluated in their exact declaration order. If no

rule matches or if there is no rule, the default action is to accept the

contents. There is no specific limit to the number of rules which may be

inserted.
  Three types of actions are supported :
- accept :
- reject :
- { track-sc0 | track-sc1 | track-sc2 }  [table
]  
  They have the same meaning as their counter-parts in “tcp-request connection”

so please refer to that section for a complete description.
  While there is nothing mandatory about it, it is recommended to use the

track-sc0 in “tcp-request connection” rules, track-sc1 for “tcp-request

content” rules in the frontend, and track-sc2 for “tcp-request content”

rules in the backend, because that makes the configuration more readable

and easier to troubleshoot, but this is just a guideline and all counters

may be used everywhere.
  Note that the “if/unless” condition is optional. If no condition is set on

the action, it is simply performed unconditionally. That can be useful for

“track-sc*” actions as well as for changing the default action to a reject.
  It is perfectly possible to match layer 7 contents with “tcp-request content”

rules, since HTTP-specific ACL matches are able to preliminarily parse the

contents of a buffer before extracting the required data. If the buffered

contents do not parse as a valid HTTP message, then the ACL does not match.

The parser which is involved there is exactly the same as for all other HTTP

processing, so there is no risk of parsing something differently. In an HTTP

backend connected to from an HTTP frontend, it is guaranteed that HTTP

contents will always be immediately present when the rule is evaluated first.
  Tracking layer7 information is also possible provided that the information

are present when the rule is processed. The current solution for making the

rule engine wait for such information is to set an inspect delay and to

condition its execution with an ACL relying on such information.

Example:
Accept HTTP requests containing a Host header saying “example.com”
and reject everything else.
  acl is_host_com hdr(Host) -i example.com

tcp-request inspect-delay 30s

tcp-request content accept if is_host_com

tcp-request content reject

Example:
reject SMTP connection if client speaks first
  tcp-request inspect-delay 30s

acl content_present req_len gt 0

tcp-request content reject if content_present
Forward HTTPS connection only if client speaks
  tcp-request inspect-delay 30s

acl content_present req_len gt 0

tcp-request content accept if content_present

tcp-request content reject

Example:
Track the last IP from X-Forwarded-For
  tcp-request inspect-delay 10s

tcp-request content track-sc0 hdr(x-forwarded-for,-1) if HTTP

Example:
track request counts per “base” (concatenation of Host+URL)
  tcp-request inspect-delay 10s

tcp-request content track-sc0 base table req-rate if HTTP

Example:

Track per-frontend and per-backend counters, block abusers at the frontend when the backend detects abuse.

frontend http
# Use General Purpose Couter 0 in SC0 as a global abuse counter
# protecting all our sites
stick-table type ip size 1m expire 5m store gpc0
tcp-request connection track-sc0 src
tcp-request connection reject if { sc0_get_gpc0 gt 0 }

use_backend http_dynamic if { path_end .php }
  backend http_dynamic
# if a source makes too fast requests to this dynamic site (tracked
# by SC1), block it globally in the frontend.
stick-table type ip size 1m expire 5m store http_req_rate(10s)
acl click_too_fast sc1_http_req_rate gt 10
acl mark_as_abuser sc0_inc_gpc0 gt 0
tcp-request content track-sc1 src
tcp-request content reject if click_too_fast mark_as_abuser

See section 7 about ACL usage.

See also : “tcp-request connection”, “tcp-request inspect-delay”

tcp-request inspect-delay  

Set the maximum allowed time to wait for data during content inspection

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

People using haproxy primarily as a TCP relay are often worried about the

risk of passing any type of protocol to a server without any analysis. In

order to be able to analyze the request contents, we must first withhold

the data then analyze them. This statement simply enables withholding of

data for at most the specified amount of time.
  TCP content inspection applies very early when a connection reaches a

frontend, then very early when the connection is forwarded to a backend. This

means that a connection may experience a first delay in the frontend and a

second delay in the backend if both have tcp-request rules.
  Note that when performing content inspection, haproxy will evaluate the whole

rules for every new chunk which gets in, taking into account the fact that

those data are partial. If no rule matches before the aforementioned delay,

a last check is performed upon expiration, this time considering that the

contents are definitive. If no delay is set, haproxy will not wait at all

and will immediately apply a verdict based on the available information.

Obviously this is unlikely to be very useful and might even be racy, so such

setups are not recommended.
  As soon as a rule matches, the request is released and continues as usual. If

the timeout is reached and no rule matches, the default policy will be to let

it pass through unaffected.
  For most protocols, it is enough to set it to a few seconds, as most clients

send the full request immediately upon connection. Add 3 or more seconds to

cover TCP retransmits but that’s all. For some protocols, it may make sense

to use large values, for instance to ensure that the client never talks

before the server (eg: SMTP), or to wait for a client to talk before passing

data to the server (eg: SSL). Note that the client timeout must cover at

least the inspection delay, otherwise it will expire first. If the client

closes the connection or if the buffer is full, the delay immediately expires

since the contents will not be able to change anymore.

See also : “tcp-request content accept”, “tcp-request content reject”, “timeout client”.

tcp-response content  [{if | unless} ]

Perform an action on a session response depending on a layer 4-7 condition

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
defines the action to perform if the condition applies. Valid
actions include : “accept”, “close”, “reject”.
  is a standard layer 4-7 ACL-based condition (see section 7).

Response contents can be analysed at an early stage of response processing

called “TCP content inspection”. During this stage, ACL-based rules are

evaluated every time the response contents are updated, until either an

“accept”, “close” or a “reject” rule matches, or a TCP response inspection

delay is set and expires with no matching rule.
  Most often, these decisions will consider a protocol recognition or validity.
  Content-based rules are evaluated in their exact declaration order. If no

rule matches or if there is no rule, the default action is to accept the

contents. There is no specific limit to the number of rules which may be

inserted.
  Two types of actions are supported :
- accept :
accepts the response if the condition is true (when used with “if”)
or false (when used with “unless”). The first such rule executed ends
the rules evaluation.

  •   close :
    immediately closes the connection with the server if the condition is
    true (when used with “if”), or false (when used with “unless”). The
    first such rule executed ends the rules evaluation. The main purpose of
    this action is to force a connection to be finished between a client
    and a server after an exchange when the application protocol expects
    some long time outs to elapse first. The goal is to eliminate idle
    connections which take significant resources on servers with certain
    protocols.

  •   reject :
    rejects the response if the condition is true (when used with “if”)
    or false (when used with “unless”). The first such rule executed ends
    the rules evaluation. Rejected session are immediately closed.

  Note that the “if/unless” condition is optional. If no condition is set on

the action, it is simply performed unconditionally. That can be useful for

for changing the default action to a reject.
  It is perfectly possible to match layer 7 contents with “tcp-response

content” rules, but then it is important to ensure that a full response has

been buffered, otherwise no contents will match. In order to achieve this,

the best solution involves detecting the HTTP protocol during the inspection

period.
  See section 7 about ACL usage.

See also : “tcp-request content”, “tcp-response inspect-delay”

tcp-response inspect-delay  

Set the maximum allowed time to wait for a response during content inspection

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

See also : “tcp-response content”, “tcp-request inspect-delay”.

timeout check  

Set additional check timeout, but only after a connection has been already

established.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments:
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

If set, haproxy uses min(“timeout connect”, “inter”) as a connect timeout

for check and “timeout check” as an additional read timeout. The “min” is

used so that people running with very long “timeout connect” (eg. those

who needed this due to the queue or tarpit) do not slow down their checks.

(Please also note that there is no valid reason to have such long connect

timeouts, because “timeout queue” and “timeout tarpit” can always be used to

avoid that).
  If “timeout check” is not set haproxy uses “inter” for complete check

timeout (connect + read) exactly like all <1.3.15 version.
  In most cases check request is much simpler and faster to handle than normal

requests and people may want to kick out laggy servers so this timeout should

be smaller than “timeout server”.
  This parameter is specific to backends, but can be specified once for all in

“defaults” sections. This is in fact one of the easiest solutions not to

forget about it.

See also: “timeout connect”, “timeout queue”, “timeout server”, “timeout tarpit”.

timeout client  

timeout clitimeout  (deprecated)

Set the maximum inactivity time on the client side.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

The inactivity timeout applies when the client is expected to acknowledge or

send data. In HTTP mode, this timeout is particularly important to consider

during the first phase, when the client sends the request, and during the

response while it is reading data sent by the server. The value is specified

in milliseconds by default, but can be in any other unit if the number is

suffixed by the unit, as specified at the top of this document. In TCP mode

(and to a lesser extent, in HTTP mode), it is highly recommended that the

client timeout remains equal to the server timeout in order to avoid complex

situations to debug. It is a good practice to cover one or several TCP packet

losses by specifying timeouts that are slightly above multiples of 3 seconds

(eg: 4 or 5 seconds). If some long-lived sessions are mixed with short-lived

sessions (eg: WebSocket and HTTP), it’s worth considering “timeout tunnel”,

which overrides “timeout client” and “timeout server” for tunnels.
  This parameter is specific to frontends, but can be specified once for all in

“defaults” sections. This is in fact one of the easiest solutions not to

forget about it. An unspecified timeout results in an infinite timeout, which

is not recommended. Such a usage is accepted and works but reports a warning

during startup because it may results in accumulation of expired sessions in

the system if the system’s timeouts are not configured either.
  This parameter replaces the old, deprecated “clitimeout”. It is recommended

to use it to write new configurations. The form “timeout clitimeout” is

provided only by backwards compatibility but its use is strongly discouraged.

See also : “clitimeout”, “timeout server”, “timeout tunnel”.

timeout connect  

timeout contimeout  (deprecated)

Set the maximum time to wait for a connection attempt to a server to succeed.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

If the server is located on the same LAN as haproxy, the connection should be

immediate (less than a few milliseconds). Anyway, it is a good practice to

cover one or several TCP packet losses by specifying timeouts that are

slightly above multiples of 3 seconds (eg: 4 or 5 seconds). By default, the

connect timeout also presets both queue and tarpit timeouts to the same value

if these have not been specified.
  This parameter is specific to backends, but can be specified once for all in

“defaults” sections. This is in fact one of the easiest solutions not to

forget about it. An unspecified timeout results in an infinite timeout, which

is not recommended. Such a usage is accepted and works but reports a warning

during startup because it may results in accumulation of failed sessions in

the system if the system’s timeouts are not configured either.
  This parameter replaces the old, deprecated “contimeout”. It is recommended

to use it to write new configurations. The form “timeout contimeout” is

provided only by backwards compatibility but its use is strongly discouraged.

See also: “timeout check”, “timeout queue”, “timeout server”, “contimeout”, “timeout tarpit”.

timeout http-keep-alive  

Set the maximum allowed time to wait for a new HTTP request to appear

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

By default, the time to wait for a new request in case of keep-alive is set

by “timeout http-request”. However this is not always convenient because some

people want very short keep-alive timeouts in order to release connections

faster, and others prefer to have larger ones but still have short timeouts

once the request has started to present itself.
  The “http-keep-alive” timeout covers these needs. It will define how long to

wait for a new HTTP request to start coming after a response was sent. Once

the first byte of request has been seen, the “http-request” timeout is used

to wait for the complete request to come. Note that empty lines prior to a

new request do not refresh the timeout and are not counted as a new request.
  There is also another difference between the two timeouts : when a connection

expires during timeout http-keep-alive, no error is returned, the connection

just closes. If the connection expires in “http-request” while waiting for a

connection to complete, a HTTP 408 error is returned.
  In general it is optimal to set this value to a few tens to hundreds of

milliseconds, to allow users to fetch all objects of a page at once but

without waiting for further clicks. Also, if set to a very small value (eg:

1 millisecond) it will probably only accept pipelined requests but not the

non-pipelined ones. It may be a nice trade-off for very large sites running

with tens to hundreds of thousands of clients.
  If this parameter is not set, the “http-request” timeout applies, and if both

are not set, “timeout client” still applies at the lower level. It should be

set in the frontend to take effect, unless the frontend is in TCP mode, in

which case the HTTP backend’s timeout will be used.

See also : “timeout http-request”, “timeout client”.

timeout http-request  

Set the maximum allowed time to wait for a complete HTTP request

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

In order to offer DoS protection, it may be required to lower the maximum

accepted time to receive a complete HTTP request without affecting the client

timeout. This helps protecting against established connections on which

nothing is sent. The client timeout cannot offer a good protection against

this abuse because it is an inactivity timeout, which means that if the

attacker sends one character every now and then, the timeout will not

trigger. With the HTTP request timeout, no matter what speed the client

types, the request will be aborted if it does not complete in time.
  Note that this timeout only applies to the header part of the request, and

not to any data. As soon as the empty line is received, this timeout is not

used anymore. It is used again on keep-alive connections to wait for a second

request if “timeout http-keep-alive” is not set.
  Generally it is enough to set it to a few seconds, as most clients send the

full request immediately upon connection. Add 3 or more seconds to cover TCP

retransmits but that’s all. Setting it to very low values (eg: 50 ms) will

generally work on local networks as long as there are no packet losses. This

will prevent people from sending bare HTTP requests using telnet.
  If this parameter is not set, the client timeout still applies between each

chunk of the incoming request. It should be set in the frontend to take

effect, unless the frontend is in TCP mode, in which case the HTTP backend’s

timeout will be used.

See also : “timeout http-keep-alive”, “timeout client”.

timeout queue  

Set the maximum time to wait in the queue for a connection slot to be free

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

When a server’s maxconn is reached, connections are left pending in a queue

which may be server-specific or global to the backend. In order not to wait

indefinitely, a timeout is applied to requests pending in the queue. If the

timeout is reached, it is considered that the request will almost never be

served, so it is dropped and a 503 error is returned to the client.
  The “timeout queue” statement allows to fix the maximum time for a request to

be left pending in a queue. If unspecified, the same value as the backend’s

connection timeout (“timeout connect”) is used, for backwards compatibility

with older versions with no “timeout queue” parameter.

See also : “timeout connect”, “contimeout”.

timeout server  

timeout srvtimeout  (deprecated)

Set the maximum inactivity time on the server side.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

The inactivity timeout applies when the server is expected to acknowledge or

send data. In HTTP mode, this timeout is particularly important to consider

during the first phase of the server’s response, when it has to send the

headers, as it directly represents the server’s processing time for the

request. To find out what value to put there, it’s often good to start with

what would be considered as unacceptable response times, then check the logs

to observe the response time distribution, and adjust the value accordingly.
  The value is specified in milliseconds by default, but can be in any other

unit if the number is suffixed by the unit, as specified at the top of this

document. In TCP mode (and to a lesser extent, in HTTP mode), it is highly

recommended that the client timeout remains equal to the server timeout in

order to avoid complex situations to debug. Whatever the expected server

response times, it is a good practice to cover at least one or several TCP

packet losses by specifying timeouts that are slightly above multiples of 3

seconds (eg: 4 or 5 seconds minimum). If some long-lived sessions are mixed

with short-lived sessions (eg: WebSocket and HTTP), it’s worth considering

“timeout tunnel”, which overrides “timeout client” and “timeout server” for

tunnels.
  This parameter is specific to backends, but can be specified once for all in

“defaults” sections. This is in fact one of the easiest solutions not to

forget about it. An unspecified timeout results in an infinite timeout, which

is not recommended. Such a usage is accepted and works but reports a warning

during startup because it may results in accumulation of expired sessions in

the system if the system’s timeouts are not configured either.
  This parameter replaces the old, deprecated “srvtimeout”. It is recommended

to use it to write new configurations. The form “timeout srvtimeout” is

provided only by backwards compatibility but its use is strongly discouraged.

See also : “srvtimeout”, “timeout client” and “timeout tunnel”.

timeout tarpit  

Set the duration for which tarpitted connections will be maintained

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes yes

yes

Arguments :
is the tarpit duration specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

When a connection is tarpitted using “reqtarpit”, it is maintained open with

no activity for a certain amount of time, then closed. “timeout tarpit”

defines how long it will be maintained open.
  The value is specified in milliseconds by default, but can be in any other

unit if the number is suffixed by the unit, as specified at the top of this

document. If unspecified, the same value as the backend’s connection timeout

(“timeout connect”) is used, for backwards compatibility with older versions

with no “timeout tarpit” parameter.

See also : “timeout connect”, “contimeout”.

timeout tunnel  

Set the maximum inactivity time on the client and server side for tunnels.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments :
is the timeout value specified in milliseconds by default, but
can be in any other unit if the number is suffixed by the unit,
as explained at the top of this document.

The tunnel timeout applies when a bidirectional connection is established

between a client and a server, and the connection remains inactive in both

directions. This timeout supersedes both the client and server timeouts once

the connection becomes a tunnel. In TCP, this timeout is used as soon as no

analyser remains attached to either connection (eg: tcp content rules are

accepted). In HTTP, this timeout is used when a connection is upgraded (eg:

when switching to the WebSocket protocol, or forwarding a CONNECT request

to a proxy), or after the first response when no keepalive/close option is

specified.
  The value is specified in milliseconds by default, but can be in any other

unit if the number is suffixed by the unit, as specified at the top of this

document. Whatever the expected normal idle time, it is a good practice to

cover at least one or several TCP packet losses by specifying timeouts that

are slightly above multiples of 3 seconds (eg: 4 or 5 seconds minimum).
  This parameter is specific to backends, but can be specified once for all in

“defaults” sections. This is in fact one of the easiest solutions not to

forget about it.

Example :

defaults http
option http-server-close
timeout connect 5s
timeout client 30s
timeout client 30s
timeout server 30s
timeout tunnel  1h    # timeout to use with WebSocket and CONNECT

See also : “timeout client”, “timeout server”.

transparent (deprecated)

Enable client-side transparent proxying

May be used in sections :
  defaults    frontend    listen  backend

yes

yes no

no  yes

yes yes

yes

Arguments : none

This keyword was introduced in order to provide layer 7 persistence to layer

3 load balancers. The idea is to use the OS’s ability to redirect an incoming

connection for a remote address to a local process (here HAProxy), and let

this process know what address was initially requested. When this option is

used, sessions without cookies will be forwarded to the original destination

IP address of the incoming request (which should match that of another

equipment), while requests with cookies will still be forwarded to the

appropriate server.
  The “transparent” keyword is deprecated, use “option transparent” instead.
  Note that contrary to a common belief, this option does NOT make HAProxy

present the client’s IP to the server when establishing the connection.

See also: “option transparent”

unique-id-format  

Generate a unique ID for each request.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments :
is a log-format string.

This keyword creates a ID for each request using the custom log format. A

unique ID is useful to trace a request passing through many components of

a complex infrastructure. The newly created ID may also be logged using the

%ID tag the log-format string.
  The format should be composed from elements that are guaranteed to be

unique when combined together. For instance, if multiple haproxy instances

are involved, it might be important to include the node name. It is often

needed to log the incoming connection’s source and destination addresses

and ports. Note that since multiple requests may be performed over the same

connection, including a request counter may help differentiate them.

Similarly, a timestamp may protect against a rollover of the counter.

Logging the process ID will avoid collisions after a service restart.
  It is recommended to use hexadecimal notation for many fields since it

makes them more compact and saves space in logs.

Example:

unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
  will generate:

   7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A

  See also: “unique-id-header”

unique-id-header  

Add a unique ID header in the HTTP request.

May be used in sections :
  defaults    frontend    listen  backend

yes

yes yes

yes yes

yes no

no

Arguments :
is the name of the header.

Add a unique-id header in the HTTP request sent to the server, using the

unique-id-format. It can’t work if the unique-id-format doesn’t exist.

Example:
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
unique-id-header X-Unique-ID

will generate:
X-Unique-ID: 7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A

  See also: “unique-id-format”

use_backend  [{if | unless} ]

Switch to a specific backend if/unless an ACL-based condition is matched.

May be used in sections :
  defaults    frontend    listen  backend

no

no  yes

yes yes

yes no

no

Arguments :
is the name of a valid backend or “listen” section, or a
“log-format” string resolving to a backend name.
  is a condition composed of ACLs, as described in section 7. If
it is omitted, the rule is unconditionally applied.

When doing content-switching, connections arrive on a frontend and are then

dispatched to various backends depending on a number of conditions. The

relation between the conditions and the backends is described with the

“use_backend” keyword. While it is normally used with HTTP processing, it can

also be used in pure TCP, either without content using stateless ACLs (eg:

source address validation) or combined with a “tcp-request” rule to wait for

some payload.
  There may be as many “use_backend” rules as desired. All of these rules are

evaluated in their declaration order, and the first one which matches will

assign the backend.
  In the first form, the backend will be used if the condition is met. In the

second form, the backend will be used if the condition is not met. If no

condition is valid, the backend defined with “default_backend” will be used.

If no default backend is defined, either the servers in the same section are

used (in case of a “listen” section) or, in case of a frontend, no server is

used and a 503 service unavailable response is returned.
  Note that it is possible to switch from a TCP frontend to an HTTP backend. In

this case, either the frontend has already checked that the protocol is HTTP,

and backend processing will immediately follow, or the backend will wait for

a complete HTTP request to get in. This feature is useful when a frontend

must decode several protocols on a unique port, one of them being HTTP.
  When  is a simple name, it is resolved at configuration time, and an

error is reported if the specified backend does not exist. If  is

a log-format string instead, no check may be done at configuration time, so

the backend name is resolved dynamically at run time. If the resulting

backend name does not correspond to any valid backend, no other rule is

evaluated, and the default_backend directive is applied instead. Note that

when using dynamic backend names, it is highly recommended to use a prefix

that no other backend uses in order to ensure that an unauthorized backend

cannot be forced from the request.
  It is worth mentioning that “use_backend” rules with an explicit name are

used to detect the association between frontends and backends to compute the

backend’s “fullconn” setting. This cannot be done for dynamic names.

See also: “default_backend”, “tcp-request”, “fullconn”, “log-format”, and section 7 about ACLs.

use-server  if  

use-server  unless  

Only use a specific server if/unless an ACL-based condition is matched.

May be used in sections :
  defaults    frontend    listen  backend

no

no  no

no  yes

yes yes

yes

Arguments :
is the name of a valid server in the same backend section.
  is a condition composed of ACLs, as described in section 7.

By default, connections which arrive to a backend are load-balanced across

the available servers according to the configured algorithm, unless a

persistence mechanism such as a cookie is used and found in the request.
  Sometimes it is desirable to forward a particular request to a specific

server without having to declare a dedicated backend for this server. This

can be achieved using the “use-server” rules. These rules are evaluated after

the “redirect” rules and before evaluating cookies, and they have precedence

on them. There may be as many “use-server” rules as desired. All of these

rules are evaluated in their declaration order, and the first one which

matches will assign the server.
  If a rule designates a server which is down, and “option persist” is not used

and no force-persist rule was validated, it is ignored and evaluation goes on

with the next rules until one matches.
  In the first form, the server will be used if the condition is met. In the

second form, the server will be used if the condition is not met. If no

condition is valid, the processing continues and the server will be assigned

according to other persistence mechanisms.
  Note that even if a rule is matched, cookie processing is still performed but

does not assign the server. This allows prefixed cookies to have their prefix

stripped.
  The “use-server” statement works both in HTTP and TCP mode. This makes it

suitable for use with content-based inspection. For instance, a server could

be selected in a farm according to the TLS SNI field. And if these servers

have their weight set to zero, they will not be used for other traffic.

Example :
intercept incoming TLS requests based on the SNI field
  use-server www if { req_ssl_sni -i www.example.com }

server     www 192.168.0.1:443 weight 0

use-server mail if { req_ssl_sni -i mail.example.com }

server     mail 192.168.0.1:587 weight 0

use-server imap if { req_ssl_sni -i imap.example.com }

server     mail 192.168.0.1:993 weight 0
all the rest is forwarded to this server
  server  default 192.168.0.2:443 check

See also: “use_backend”, section 5 about server and section 7 about ACLs.

5. Bind and Server options

The “bind”, “server” and “default-server” keywords support a number of settings

depending on some build options and on the system HAProxy was built on. These

settings generally each consist in one word sometimes followed by a value,

written on the same line as the “bind” or “server” line. All these options are

described in this section.

5.1. Bind options

The “bind” keyword supports a certain number of settings which are all passed

as arguments on the same line. The order in which those arguments appear makes

no importance, provided that they appear after the bind address. All of these

parameters are optional. Some of them consist in a single words (booleans),

while other ones expect a value after them. In this case, the value must be

provided immediately after the setting name.
  The currently supported settings are the following ones.

accept-proxy

Enforces the use of the PROXY protocol over any connection accepted by any of

the sockets declared on the same line. The PROXY protocol dictates the layer

3/4 addresses of the incoming connection to be used everywhere an address is

used, with the only exception of “tcp-request connection” rules which will

only see the real connection address. Logs will reflect the addresses

indicated in the protocol, unless it is violated, in which case the real

address will still be used.  This keyword combined with support from external

components can be used as an efficient and reliable alternative to the

X-Forwarded-For mechanism which is not always reliable and not even always

usable. See also “tcp-request connection expect-proxy” for a finer-grained

setting of which client is allowed to use the protocol.

alpn  

This enables the TLS ALPN extension and advertises the specified protocol

list as supported on top of ALPN. The protocol list consists in a comma-

delimited list of protocol names, for instance: “http/1.1,http/1.0” (without

quotes). This requires that the SSL library is build with support for TLS

extensions enabled (check with haproxy -vv). The ALPN extension replaces the

initial NPN extension.

backlog  

Sets the socket’s backlog to this value. If unspecified, the frontend’s

backlog is used instead, which generally defaults to the maxconn value.

ecdhe  

This setting is only available when support for OpenSSL was built in. It sets

the named curve (RFC 4492) used to generate ECDH ephemeral keys. By default,

used named curve is prime256v1.

ca-file  

This setting is only available when support for OpenSSL was built in. It

designates a PEM file from which to load CA certificates used to verify

client’s certificate.

ca-ignore-err [all|,…]

This setting is only available when support for OpenSSL was built in.

Sets a comma separated list of errorIDs to ignore during verify at depth > 0.

If set to ‘all’, all errors are ignored. SSL handshake is not aborted if an

error is ignored.

ciphers  

This setting is only available when support for OpenSSL was built in. It sets

the string describing the list of cipher algorithms (“cipher suite”) that are

negotiated during the SSL/TLS handshake. The format of the string is defined

in “man 1 ciphers” from OpenSSL man pages, and can be for instance a string

such as “AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH” (without quotes).

crl-file  

This setting is only available when support for OpenSSL was built in. It

designates a PEM file from which to load certificate revocation list used

to verify client’s certificate.

crt  

This setting is only available when support for OpenSSL was built in. It

designates a PEM file containing both the required certificates and any

associated private keys. This file can be built by concatenating multiple

PEM files into one (e.g. cat cert.pem key.pem > combined.pem). If your CA

requires an intermediate certificate, this can also be concatenated into this

file.
  If the OpenSSL used supports Diffie-Hellman, parameters present in this file

are loaded.
  If a directory name is used instead of a PEM file, then all files found in

that directory will be loaded. This directive may be specified multiple times

in order to load certificates from multiple files or directories. The

certificates will be presented to clients who provide a valid TLS Server Name

Indication field matching one of their CN or alt subjects. Wildcards are

supported, where a wildcard character ‘*’ is used instead of the first

hostname component (eg: *.example.org matches www.example.org but not

www.sub.example.org).
  If no SNI is provided by the client or if the SSL library does not support

TLS extensions, or if the client provides an SNI hostname which does not

match any certificate, then the first loaded certificate will be presented.

This means that when loading certificates from a directory, it is highly

recommended to load the default one first as a file.
  Note that the same cert may be loaded multiple times without side effects.
  Some CAs (such as Godaddy) offer a drop down list of server types that do not

include HAProxy when obtaining a certificate. If this happens be sure to

choose a webserver that the CA believes requires an intermediate CA (for

Godaddy, selection Apache Tomcat will get the correct bundle, but many

others, e.g. nginx, result in a wrong bundle that will not work for some

clients).

crt-ignore-err  

This setting is only available when support for OpenSSL was built in. Sets a

comma separated list of errorIDs to ignore during verify at depth == 0.  If

set to ‘all’, all errors are ignored. SSL handshake is not aborted if an error

is ignored.

crt-list  

This setting is only available when support for OpenSSL was built in. It

designates a list of PEM file with an optional list of SNI filter per

certificate, with the following format for each line :

  <crtfile> [[!]<snifilter> ...]

  Wildcards are supported in the SNI filter. Negative filter are also supported,

only useful in combination with a wildcard filter to exclude a particular SNI.

The certificates will be presented to clients who provide a valid TLS Server

Name Indication field matching one of the SNI filters. If no SNI filter is

specified, the CN and alt subjects are used. This directive may be specified

multiple times. See the “crt” option for more information. The default

certificate is still needed to meet OpenSSL expectations. If it is not used,

the ‘strict-sni’ option may be used.

defer-accept

Is an optional keyword which is supported only on certain Linux kernels. It

states that a connection will only be accepted once some data arrive on it,

or at worst after the first retransmit. This should be used only on protocols

for which the client talks first (eg: HTTP). It can slightly improve

performance by ensuring that most of the request is already available when

the connection is accepted. On the other hand, it will not be able to detect

connections which don’t talk. It is important to note that this option is

broken in all kernels up to 2.6.31, as the connection is never accepted until

the client talks. This can cause issues with front firewalls which would see

an established connection while the proxy will only see it in SYN_RECV. This

option is only supported on TCPv4/TCPv6 sockets and ignored by other ones.

force-sslv3

This option enforces use of SSLv3 only on SSL connections instantiated from

this listener. SSLv3 is generally less expensive than the TLS counterparts

for high connection rates. See also “force-tls*”, “no-sslv3”, and “no-tls*”.

force-tlsv10

This option enforces use of TLSv1.0 only on SSL connections instantiated from

this listener. See also “force-tls*”, “no-sslv3”, and “no-tls*”.

force-tlsv11

This option enforces use of TLSv1.1 only on SSL connections instantiated from

this listener. See also “force-tls*”, “no-sslv3”, and “no-tls*”.

force-tlsv12

This option enforces use of TLSv1.2 only on SSL connections instantiated from

this listener. See also “force-tls*”, “no-sslv3”, and “no-tls*”.

gid  

Sets the group of the UNIX sockets to the designated system gid. It can also

be set by default in the global section’s “unix-bind” statement. Note that

some platforms simply ignore this. This setting is equivalent to the “group”

setting except that the group ID is used instead of its name. This setting is

ignored by non UNIX sockets.

group  

Sets the group of the UNIX sockets to the designated system group. It can

also be set by default in the global section’s “unix-bind” statement. Note

that some platforms simply ignore this. This setting is equivalent to the

“gid” setting except that the group name is used instead of its gid. This

setting is ignored by non UNIX sockets.

id  

Fixes the socket ID. By default, socket IDs are automatically assigned, but

sometimes it is more convenient to fix them to ease monitoring. This value

must be strictly positive and unique within the listener/frontend. This

option can only be used when defining only a single socket.

interface  

Restricts the socket to a specific interface. When specified, only packets

received from that particular interface are processed by the socket. This is

currently only supported on Linux. The interface must be a primary system

interface, not an aliased interface. It is also possible to bind multiple

frontends to the same address if they are bound to different interfaces. Note

that binding to a network interface requires root privileges. This parameter

is only compatible with TCPv4/TCPv6 sockets.

level  

This setting is used with the stats sockets only to restrict the nature of

the commands that can be issued on the socket. It is ignored by other

sockets.  can be one of :

- “user” is the least privileged level ; only non-sensitive stats can be
read, and no change is allowed. It would make sense on systems where it
is not easy to restrict access to the socket.

- “operator” is the default level and fits most common uses. All data can
be read, and only non-sensitive changes are permitted (eg: clear max
counters).

- “admin” should be used with care, as everything is permitted (eg: clear
all counters).

maxconn  

Limits the sockets to this number of concurrent connections. Extraneous

connections will remain in the system’s backlog until a connection is

released. If unspecified, the limit will be the same as the frontend’s

maxconn. Note that in case of port ranges or multiple addresses, the same

value will be applied to each socket. This setting enables different

limitations on expensive sockets, for instance SSL entries which may easily

eat all memory.

mode  

Sets the octal mode used to define access permissions on the UNIX socket. It

can also be set by default in the global section’s “unix-bind” statement.

Note that some platforms simply ignore this. This setting is ignored by non

UNIX sockets.

mss  

Sets the TCP Maximum Segment Size (MSS) value to be advertised on incoming

connections. This can be used to force a lower MSS for certain specific

ports, for instance for connections passing through a VPN. Note that this

relies on a kernel feature which is theoretically supported under Linux but

was buggy in all versions prior to 2.6.28. It may or may not work on other

operating systems. It may also not change the advertised value but change the

effective size of outgoing segments. The commonly advertised value for TCPv4

over Ethernet networks is 1460 = 1500(MTU) - 40(IP+TCP). If this value is

positive, it will be used as the advertised MSS. If it is negative, it will

indicate by how much to reduce the incoming connection’s advertised MSS for

outgoing segments. This parameter is only compatible with TCP v4/v6 sockets.

name  

Sets an optional name for these sockets, which will be reported on the stats

page.

nice  

Sets the ‘niceness’ of connections initiated from the socket. Value must be

in the range -1024..1024 inclusive, and defaults to zero. Positive values

means that such connections are more friendly to others and easily offer

their place in the scheduler. On the opposite, negative values mean that

connections want to run with a higher priority than others. The difference

only happens under high loads when the system is close to saturation.

Negative values are appropriate for low-latency or administration services,

and high values are generally recommended for CPU intensive tasks such as SSL

processing or bulk transfers which are less sensible to latency. For example,

it may make sense to use a positive value for an SMTP socket and a negative

one for an RDP socket.

no-sslv3

This setting is only available when support for OpenSSL was built in. It

disables support for SSLv3 on any sockets instantiated from the listener when

SSL is supported. Note that SSLv2 is forced disabled in the code and cannot

be enabled using any configuration option. See also “force-tls*”,

and “force-sslv3”.

no-tls-tickets

This setting is only available when support for OpenSSL was built in. It

disables the stateless session resumption (RFC 5077 TLS Ticket

extension) and force to use stateful session resumption. Stateless

session resumption is more expensive in CPU usage.

no-tlsv10

This setting is only available when support for OpenSSL was built in. It

disables support for TLSv1.0 on any sockets instantiated from the listener

when SSL is supported. Note that SSLv2 is forced disabled in the code and

cannot be enabled using any configuration option. See also “force-tls*”,

and “force-sslv3”.

no-tlsv11

This setting is only available when support for OpenSSL was built in. It

disables support for TLSv1.1 on any sockets instantiated from the listener

when SSL is supported. Note that SSLv2 is forced disabled in the code and

cannot be enabled using any configuration option. See also “force-tls*”,

and “force-sslv3”.

no-tlsv12

This setting is only available when support for OpenSSL was built in. It

disables support for TLSv1.2 on any sockets instantiated from the listener

when SSL is supported. Note that SSLv2 is forced disabled in the code and

cannot be enabled using any configuration option. See also “force-tls*”,

and “force-sslv3”.

npn  

This enables the NPN TLS extension and advertises the specified protocol list

as supported on top of NPN. The protocol list consists in a comma-delimited

list of protocol names, for instance: “http/1.1,http/1.0” (without quotes).

This requires that the SSL library is build with support for TLS extensions

enabled (check with haproxy -vv). Note that the NPN extension has been

replaced with the ALPN extension (see the “alpn” keyword).

ssl

This setting is only available when support for OpenSSL was built in. It

enables SSL deciphering on connections instantiated from this listener. A

certificate is necessary (see “crt” above). All contents in the buffers will

appear in clear text, so that ACLs and HTTP processing will only have access

to deciphered contents.

strict-sni

This setting is only available when support for OpenSSL was built in. The

SSL/TLS negotiation is allow only if the client provided an SNI which match

a certificate. The default certificate is not used.

See the “crt” option for more information.

tfo

Is an optional keyword which is supported only on Linux kernels >= 3.7. It

enables TCP Fast Open on the listening socket, which means that clients which

support this feature will be able to send a request and receive a response

during the 3-way handshake starting from second connection, thus saving one

round-trip after the first connection. This only makes sense with protocols

that use high connection rates and where each round trip matters. This can

possibly cause issues with many firewalls which do not accept data on SYN

packets, so this option should only be enabled once well tested. This option

is only supported on TCPv4/TCPv6 sockets and ignored by other ones. You may

need to build HAProxy with USE_TFO=1 if your libc doesn’t define

TCP_FASTOPEN.

transparent

Is an optional keyword which is supported only on certain Linux kernels. It

indicates that the addresses will be bound even if they do not belong to the

local machine, and that packets targeting any of these addresses will be

intercepted just as if the addresses were locally configured. This normally

requires that IP forwarding is enabled. Caution! do not use this with the

default address ‘*’, as it would redirect any traffic for the specified port.

This keyword is available only when HAProxy is built with USE_LINUX_TPROXY=1.

This parameter is only compatible with TCPv4 and TCPv6 sockets, depending on

kernel version. Some distribution kernels include backports of the feature,

so check for support with your vendor.

v4v6

Is an optional keyword which is supported only on most recent systems

including Linux kernels >= 2.4.21. It is used to bind a socket to both IPv4

and IPv6 when it uses the default address. Doing so is sometimes necessary

on systems which bind to IPv6 only by default. It has no effect on non-IPv6

sockets, and is overridden by the “v6only” option.

v6only

Is an optional keyword which is supported only on most recent systems

including Linux kernels >= 2.4.21. It is used to bind a socket to IPv6 only

when it uses the default address. Doing so is sometimes preferred to doing it

system-wide as it is per-listener. It has no effect on non-IPv6 sockets and

has precedence over the “v4v6” option.

uid  

Sets the owner of the UNIX sockets to the designated system uid. It can also

be set by default in the global section’s “unix-bind” statement. Note that

some platforms simply ignore this. This setting is equivalent to the “user”

setting except that the user numeric ID is used instead of its name. This

setting is ignored by non UNIX sockets.

user  

Sets the owner of the UNIX sockets to the designated system user. It can also

be set by default in the global section’s “unix-bind” statement. Note that

some platforms simply ignore this. This setting is equivalent to the “uid”

setting except that the user name is used instead of its uid. This setting is

ignored by non UNIX sockets.

verify [none|optional|required]

This setting is only available when support for OpenSSL was built in. If set

to ‘none’, client certificate is not requested. This is the default. In other

cases, a client certificate is requested. If the client does not provide a

certificate after the request and if ‘verify’ is set to ‘required’, then the

handshake is aborted, while it would have succeeded if set to ‘optional’. The

certificate provided by the client is always verified using CAs from

‘ca-file’ and optional CRLs from ‘crl-file’. On verify failure the handshake

is aborted, regardless of the ‘verify’ option, unless the error code exactly

matches one of those listed with ‘ca-ignore-err’ or ‘crt-ignore-err’.

5.2. Server and default-server options

The “server” and “default-server” keywords support a certain number of settings

which are all passed as arguments on the server line. The order in which those

arguments appear does not count, and they are all optional. Some of those

settings are single words (booleans) while others expect one or several values

after them. In this case, the values must immediately follow the setting name.

Except default-server, all those settings must be specified after the server’s

address if they are used:
  server  
[:port] [settings …]
default-server [settings …]  
  The currently supported settings are the following ones.

addr
match “Hello\n” in the input stream (\x48 \x65 \x6c \x6c \x6f \x0a)
  acl hello payload(0,6) -m bin 48656c6c6f0a

7.1.6. Matching IPv4 and IPv6 addresses

IPv4 addresses values can be specified either as plain addresses or with a

netmask appended, in which case the IPv4 address matches whenever it is

within the network. Plain addresses may also be replaced with a resolvable

host name, but this practice is generally discouraged as it makes it more

difficult to read and debug configurations. If hostnames are used, you should

at least ensure that they are present in /etc/hosts so that the configuration

does not depend on any random DNS match at the moment the configuration is

parsed.
  IPv6 may be entered in their usual form, with or without a netmask appended.

Only bit counts are accepted for IPv6 netmasks. In order to avoid any risk of

trouble with randomly resolved IP addresses, host names are never allowed in

IPv6 patterns.
  HAProxy is also able to match IPv4 addresses with IPv6 addresses in the

following situations :
- tested address is IPv4, pattern address is IPv4, the match applies
in IPv4 using the supplied mask if any.
- tested address is IPv6, pattern address is IPv6, the match applies
in IPv6 using the supplied mask if any.
- tested address is IPv6, pattern address is IPv4, the match applies in IPv4
using the pattern’s mask if the IPv6 address matches with 2002:IPV4::,
::IPV4 or ::ffff:IPV4, otherwise it fails.
- tested address is IPv4, pattern address is IPv6, the IPv4 address is first
converted to IPv6 by prefixing ::ffff: in front of it, then the match is
applied in IPv6 using the supplied IPv6 mask.

7.2. Using ACLs to form conditions

Some actions are only performed upon a valid condition. A condition is a

combination of ACLs with operators. 3 operators are supported :

  • AND (implicit)
  • OR  (explicit with the “or” keyword or the “||” operator)
  • Negation with the exclamation mark (“!”)
  A condition is formed as a disjunctive form:
  [!]acl1 [!]acl2 … [!]acln  { or [!]acl1 [!]acl2 … [!]acln } …
  Such conditions are generally used after an “if” or “unless” statement,

indicating when the condition will trigger the action.
  For instance, to block HTTP requests to the “*” URL with methods other than

“OPTIONS”, as well as POST requests without content-length, and GET or HEAD

requests with a content-length greater than 0, and finally every request which

is not either GET/HEAD/POST/OPTIONS !
  acl missing_cl hdr_cnt(Content-length) eq 0
block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
block if METH_GET HTTP_CONTENT
block unless METH_GET or METH_POST or METH_OPTIONS
  To select a different backend for requests to static contents on the “www” site

and to every request on the “img”, “video”, “download” and “ftp” hosts :
  acl url_static  path_beg         /static /images /img /css
acl url_static  path_end         .gif .png .jpg .css .js
acl host_www    hdr_beg(host) -i www
acl host_static hdr_beg(host) -i img. video. download. ftp.
  # now use backend “static” for all static-only hosts, and for static urls
# of host “www”. Use backend “www” for the rest.
use_backend static if host_static or host_www url_static
use_backend www    if host_www
  It is also possible to form rules using “anonymous ACLs”. Those are unnamed ACL

expressions that are built on the fly without needing to be declared. They must

be enclosed between braces, with a space before and after each brace (because

Example :

The following rule :

acl missing_cl hdr_cnt(Content-length) eq 0
block if METH_POST missing_cl

  Can also be written that way :

block if METH_POST { hdr_cnt(Content-length) eq 0 }

  It is generally not recommended to use this construct because it’s a lot easier

to leave errors in the configuration when written that way. However, for very

simple rules matching only one source IP address for instance, it can make more

sense to use them than to declare ACLs with random names. Another example of

good use is the following :
  With named ACLs :

    acl site_dead nbsrv(dynamic) lt 2
acl site_dead nbsrv(static)  lt 2
monitor fail  if site_dead

  With anonymous ACLs :

    monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }

  See section 4.2 for detailed help on the “block” and “use_backend” keywords.

7.3. Fetching samples

Historically, sample fetch methods were only used to retrieve data to match

against patterns using ACLs. With the arrival of stick-tables, a new class of

sample fetch methods was created, most often sharing the same syntax as their

ACL counterpart. These sample fetch methods are also known as “fetches”. As

of now, ACLs and fetches have converged. All ACL fetch methods have been made

available as fetch methods, and ACLs may use any sample fetch method as well.
  This section details all available sample fetch methods and their output type.

Some sample fetch methods have deprecated aliases that are used to maintain

compatibility with existing configurations. They are then explicitly marked as

deprecated and should not be used in new setups.
  The ACL derivatives are also indicated when available, with their respective

matching methods. These ones all have a well defined default pattern matching

method, so it is never necessary (though allowed) to pass the “-m” option to

indicate how the sample will be matched using ACLs.
  As indicated in the sample type versus matching compatibility matrix above,

when using a generic sample fetch method in an ACL, the “-m” option is

mandatory unless the sample type is one of boolean, integer, IPv4 or IPv6. When

the same keyword exists as an ACL keyword and as a standard fetch method, the

ACL engine will automatically pick the ACL-only one by default.
  Some of these keywords support one or multiple mandatory arguments, and one or

multiple optional arguments. These arguments are strongly typed and are checked

when the configuration is parsed so that there is no risk of running with an

incorrect argument (eg: an unresolved backend name). Fetch function arguments

are passed between parenthesis and are delimited by commas.  When an argument

is optional, it will be indicated below between square brackets (‘[ ]’). When

all arguments are optional, the parenthesis may be omitted.
  Thus, the syntax of a standard sample fetch method is one of the following :
- name
- name(arg1)
- name(arg1,arg2)

7.3.1. Converters

Sample fetch methods may be combined with transformations to be applied on top

of the fetched sample (also called “converters”). These combinations form what

is called “sample expressions” and the result is a “sample”. Initially this

was only supported by “stick on” and “stick store-request” directives but this

has now be extended to all places where samples may be used (acls, log-format,

unique-id-format, add-header, …).
  These transformations are enumerated as a series of specific keywords after the

sample fetch method. These keywords may equally be appended immediately after

the fetch keyword’s argument, delimited by a comma. These keywords can also

support some arguments (eg: a netmask) which must be passed in parenthesis.
  The currently available list of transformation keywords include :

lower

Convert a string sample to lower case. This can only be placed after a string

sample fetch function or after a transformation keyword returning a string

type. The result is of type string.

upper

Convert a string sample to upper case. This can only be placed after a string

sample fetch function or after a transformation keyword returning a string

type. The result is of type string.

hex

Converts a binary input sample to an hex string containing two hex digits per

input byte. It is used to log or transfer hex dumps of some binary input data

in a way that can be reliably transferred (eg: an SSL ID can be copied in a

header).

ipmask()

Apply a mask to an IPv4 address, and use the result for lookups and storage.

This can be used to make all hosts within a certain mask to share the same

table entries and as such use the same server. The mask can be passed in

dotted form (eg: 255.255.255.0) or in CIDR form (eg: 24).

http_date([])

Converts an integer supposed to contain a date since epoch to a string

representing this date in a format suitable for use in HTTP header fields. If

an offset value is specified, then it is a number of seconds that is added to

the date before the conversion is operated. This is particularly useful to

emit Date header fields, Expires values in responses when combined with a

positive offset, or Last-Modified values when the offset is negative.

language([,])

Returns the value with the highest q-factor from a list as extracted from the

“accept-language” header using “req.fhdr”. Values with no q-factor have a

q-factor of 1. Values with a q-factor of 0 are dropped. Only values which

belong to the list of semi-colon delimited  will be considered. The

argument  syntax is “lang[;lang[;lang[;…]]]”. If no value matches the

given list and a default value is provided, it is returned. Note that language

names may have a variant after a dash (‘-‘). If this variant is present in the

list, it will be matched, but if it is not, only the base language is checked.

The match is case-sensitive, and the output string is always one of those

provided in arguments.  The ordering of arguments is meaningless, only the

ordering of the values in the request counts, as the first value among

multiple sharing the same q-factor is used.

Example :
this configuration switches to the backend matching a
given language based on the request :
  acl es req.fhdr(accept-language),language(es;fr;en) -m str es

acl fr req.fhdr(accept-language),language(es;fr;en) -m str fr

acl en req.fhdr(accept-language),language(es;fr;en) -m str en

use_backend spanish if es

use_backend french  if fr

use_backend english if en

default_backend choose_your_language

map([,])

map_([,])

map__([,])
Search the input value from  using the  matching method,
and return the associated value converted to the type . If the
input value cannot be found in the , the converter returns the
. If the  is not set, the converter fails and
acts as if no input value could be fetched. If the  is not set, it
defaults to “str”. Likewise, if the  is not set, it defaults to
“str”. For convenience, the “map” keyword is an alias for “map_str” and maps a
string to another string.
  It is important to avoid overlapping between the keys : IP addresses and
strings are stored in trees, so the first of the finest match will be used.
Other keys are stored in lists, so the first matching occurrence will be used.
  The following array contains the list of all map functions avalaible sorted by
input type, match type and output type.

input type  match method    output type str output type int output type ip

str str map_str map_str_int map_str_ip

str sub map_sub map_sub_int map_sub_ip

str dir map_dir map_dir_int map_dir_ip

str dom map_dom map_dom_int map_dom_ip

str end map_end map_end_int map_end_ip

str reg map_reg map_reg_int map_reg_ip

int int map_int map_int_int map_int_ip

ip  ip  map_ip  map_ip_int  map_ip_ip

The file contains one key + value per line. Lines which start with ‘#’ are

ignored, just like empty lines. Leading tabs and spaces are stripped. The key

is then the first “word” (series of non-space/tabs characters), and the value

is what follows this series of space/tab till the end of the line excluding

trailing spaces/tabs.

Example :
this is a comment and is ignored
  2.22.246.0/23    United Kingdom      \n

<-><———–><–><————><—->
|       |       |         |        - trailing spaces ignored
|       |       |———- value
|       |       -------------------- middle spaces ignored
|—————————- key
`———————————— leading spaces ignored

7.3.2. Fetching samples from internal states

A first set of sample fetch methods applies to internal information which does

not even relate to any client information. These ones are sometimes used with

“monitor-fail” directives to report an internal status to external watchers.

The sample fetch methods described in this section are usable anywhere.

always_false : boolean

Always returns the boolean “false” value. It may be used with ACLs as a

temporary replacement for another one when adjusting configurations.

always_true : boolean

Always returns the boolean “true” value. It may be used with ACLs as a

temporary replacement for another one when adjusting configurations.

avg_queue([]) : integer

Returns the total number of queued connections of the designated backend

divided by the number of active servers. The current backend is used if no

backend is specified. This is very similar to “queue” except that the size of

the farm is considered, in order to give a more accurate measurement of the

time it may take for a new connection to be processed. The main usage is with

ACL to return a sorry page to new users when it becomes certain they will get

a degraded service, or to pass to the backend servers in a header so that

they decide to work in degraded mode or to disable some functions to speed up

the processing a bit. Note that in the event there would not be any active

server anymore, twice the number of queued connections would be considered as

the measured value. This is a fair estimate, as we expect one server to get

back soon anyway, but we still prefer to send new traffic to another backend

if in better shape. See also the “queue”, “be_conn”, and “be_sess_rate”

sample fetches.

be_conn([]) : integer

Applies to the number of currently established connections on the backend,

possibly including the connection being evaluated. If no backend name is

specified, the current one is used. But it is also possible to check another

backend. It can be used to use a specific farm when the nominal one is full.

See also the “fe_conn”, “queue” and “be_sess_rate” criteria.

be_sess_rate([]) : integer

Returns an integer value corresponding to the sessions creation rate on the

backend, in number of new sessions per second. This is used with ACLs to

switch to an alternate backend when an expensive or fragile one reaches too

high a session rate, or to limit abuse of service (eg. prevent sucking of an

online dictionary). It can also be useful to add this element to logs using a

log-format directive.

Example :
Redirect to an error page if the dictionary is requested too often
  backend dynamic
mode http
acl being_scanned be_sess_rate gt 100
redirect location /denied.html if being_scanned

connslots([]) : integer

Returns an integer value corresponding to the number of connection slots

still available in the backend, by totaling the maximum amount of

connections on all servers and the maximum queue size. This is probably only

used with ACLs.
  The basic idea here is to be able to measure the number of connection “slots”

still available (connection + queue), so that anything beyond that (intended

usage; see “use_backend” keyword) can be redirected to a different backend.
  ‘connslots’ = number of available server connection slots, + number of

available server queue slots.
  Note that while “fe_conn” may be used, “connslots” comes in especially

useful when you have a case of traffic going to one single ip, splitting into

multiple backends (perhaps using ACLs to do name-based load balancing) and

you want to be able to differentiate between different backends, and their

available “connslots”.  Also, whereas “nbsrv” only measures servers that are

actually down, this fetch is more fine-grained and looks into the number of

available connection slots as well. See also “queue” and “avg_queue”.
  OTHER CAVEATS AND NOTES: at this point in time, the code does not take care

of dynamic connections. Also, if any of the server maxconn, or maxqueue is 0,

then this fetch clearly does not make sense, in which case the value returned

will be -1.

date([]) : integer

Returns the current date as the epoch (number of seconds since 01/01/1970).

If an offset value is specified, then it is a number of seconds that is added

to the current date before returning the value. This is particularly useful

to compute relative dates, as both positive and negative offsets are allowed.

It is useful combined with the http_date converter.

Example :
set an expires header to now+1 hour in every response
  http-response set-header Expires %[date(3600),http_date]

env() : string

Returns a string containing the value of environment variable . As a

reminder, environment variables are per-process and are sampled when the

process starts. This can be useful to pass some information to a next hop

server, or with ACLs to take specific action when the process is started a

certain way.

Examples :
Pass the Via header to next hop with the local hostname in it
  http-request add-header Via 1.1\ %[env(HOSTNAME)]
reject cookie-less requests when the STOP environment variable is set
  http-request deny if !{ cook(SESSIONID) -m found } { env(STOP) -m found }

fe_conn([]) : integer

Returns the number of currently established connections on the frontend,

possibly including the connection being evaluated. If no frontend name is

specified, the current one is used. But it is also possible to check another

frontend. It can be used to return a sorry page before hard-blocking, or to

use a specific backend to drain new requests when the farm is considered

full.  This is mostly used with ACLs but can also be used to pass some

statistics to servers in HTTP headers. See also the “dst_conn”, “be_conn”,

“fe_sess_rate” fetches.

fe_sess_rate([]) : integer

Returns an integer value corresponding to the sessions creation rate on the

frontend, in number of new sessions per second. This is used with ACLs to

limit the incoming session rate to an acceptable range in order to prevent

abuse of service at the earliest moment, for example when combined with other

layer 4 ACLs in order to force the clients to wait a bit for the rate to go

down below the limit. It can also be useful to add this element to logs using

a log-format directive. See also the “rate-limit sessions” directive for use

in frontends.

Example :
This frontend limits incoming mails to 10/s with a max of 100
concurrent connections. We accept any connection below 10/s, and
force excess clients to wait for 100 ms. Since clients are limited to
100 max, there cannot be more than 10 incoming mails per second.
  frontend mail
bind :25
mode tcp
maxconn 100
acl too_fast fe_sess_rate ge 10
tcp-request inspect-delay 100ms
tcp-request content accept if ! too_fast
tcp-request content accept if WAIT_END

nbsrv([]) : integer

Returns an integer value corresponding to the number of usable servers of

either the current backend or the named backend. This is mostly used with

ACLs but can also be useful when added to logs. This is normally used to

switch to an alternate backend when the number of servers is too low to

to handle some load. It is useful to report a failure when combined with

“monitor fail”.

queue([]) : integer

Returns the total number of queued connections of the designated backend,

including all the connections in server queues. If no backend name is

specified, the current one is used, but it is also possible to check another

one. This is useful with ACLs or to pass statistics to backend servers. This

can be used to take actions when queuing goes above a known level, generally

indicating a surge of traffic or a massive slowdown on the servers. One

possible action could be to reject new users but still accept old ones. See

also the “avg_queue”, “be_conn”, and “be_sess_rate” fetches.

rand([]) : integer

Returns a random integer value within a range of  possible values,

starting at zero. If the range is not specified, it defaults to 2^32, which

gives numbers between 0 and 4294967295. It can be useful to pass some values

needed to take some routing decisions for example, or just for debugging

purposes. This random must not be used for security purposes.

srv_conn([/]) : integer

Returns an integer value corresponding to the number of currently established

connections on the designated server, possibly including the connection being

evaluated. If  is omitted, then the server is looked up in the

current backend. It can be used to use a specific farm when one server is

full, or to inform the server about our view of the number of active

connections with it. See also the “fe_conn”, “be_conn” and “queue” fetch

methods.

srv_is_up([/]) : boolean

Returns true when the designated server is UP, and false when it is either

DOWN or in maintenance mode. If  is omitted, then the server is

looked up in the current backend. It is mainly used to take action based on

an external status reported via a health check (eg: a geographical site’s

availability). Another possible use which is more of a hack consists in

using dummy servers as boolean variables that can be enabled or disabled from

the CLI, so that rules depending on those ACLs can be tweaked in realtime.

srv_sess_rate([/]) : integer

Returns an integer corresponding to the sessions creation rate on the

designated server, in number of new sessions per second. If  is

omitted, then the server is looked up in the current backend. This is mostly

used with ACLs but can make sense with logs too. This is used to switch to an

alternate backend when an expensive or fragile one reaches too high a session

rate, or to limit abuse of service (eg. prevent latent requests from

overloading servers).

Example :
Redirect to a separate back
  acl srv1_full srv_sess_rate(be1/srv1) gt 50

acl srv2_full srv_sess_rate(be1/srv2) gt 50

use_backend be2 if srv1_full or srv2_full

table_avl([
]) : integer

Returns the total number of available entries in the current proxy’s

stick-table or in the designated stick-table. See also table_cnt.

table_cnt([]) : integer

Returns the total number of entries currently in use in the current proxy’s

stick-table or in the designated stick-table. See also src_conn_cnt and

table_avl for other entry counting methods.

7.3.3. Fetching samples at Layer 4

The layer 4 usually describes just the transport layer which in haproxy is

closest to the connection, where no content is yet made available. The fetch

methods described here are usable as low as the “tcp-request connection” rule

sets unless they require some future information. Those generally include

TCP/IP addresses and ports, as well as elements from stick-tables related to

the incoming connection. For retrieving a value from a sticky counters, the

counter number can be explicitly set as 0, 1, or 2 using the pre-defined

“sc0_”, “sc1_”, or “sc2_” prefix, or it can be specified as the first integer

argument when using the “sc_” prefix. An optional table may be specified with

the “sc*” form, in which case the currently tracked key will be looked up into

this alternate table instead of the table currently being tracked.

be_id : integer

Returns an integer containing the current backend’s id. It can be used in

frontends with responses to check which backend processed the request.

dst : ip

This is the destination IPv4 address of the connection on the client side,

which is the address the client connected to. It can be useful when running

in transparent mode. It is of type IP and works on both IPv4 and IPv6 tables.

On IPv6 tables, IPv4 address is mapped to its IPv6 equivalent, according to

RFC 4291.

dst_conn : integer

Returns an integer value corresponding to the number of currently established

connections on the same socket including the one being evaluated. It is

normally used with ACLs but can as well be used to pass the information to

servers in an HTTP header or in logs. It can be used to either return a sorry

page before hard-blocking, or to use a specific backend to drain new requests

when the socket is considered saturated. This offers the ability to assign

different limits to different listening ports or addresses. See also the

“fe_conn” and “be_conn” fetches.

dst_port : integer

Returns an integer value corresponding to the destination TCP port of the

connection on the client side, which is the port the client connected to.

This might be used when running in transparent mode, when assigning dynamic

ports to some clients for a whole application session, to stick all users to

a same server, or to pass the destination port information to a server using

an HTTP header.

fe_id : integer

Returns an integer containing the current frontend’s id. It can be used in

backends to check from which backend it was called, or to stick all users

coming via a same frontend to the same server.

sc_bytes_in_rate([,]) : integer

sc0_bytes_in_rate([]) : integer

sc1_bytes_in_rate([]) : integer

sc2_bytes_in_rate([]) : integer

Returns the average client-to-server bytes rate from the currently tracked

counters, measured in amount of bytes over the period configured in the

table. See also src_bytes_in_rate.

sc_bytes_out_rate([,]) : integer

sc0_bytes_out_rate([]) : integer

sc1_bytes_out_rate([]) : integer

sc2_bytes_out_rate([]) : integer

Returns the average server-to-client bytes rate from the currently tracked

counters, measured in amount of bytes over the period configured in the

table. See also src_bytes_out_rate.

sc_clr_gpc0([,]) : integer

sc0_clr_gpc0([]) : integer

sc1_clr_gpc0([]) : integer

sc2_clr_gpc0([]) : integer

Clears the first General Purpose Counter associated to the currently tracked

counters, and returns its previous value. Before the first invocation, the

stored value is zero, so first invocation will always return zero. This is

typically used as a second ACL in an expression in order to mark a connection

when a first ACL was verified :  

  # block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse sc0_http_req_rate gt 10
acl kill  sc0_inc_gpc0 gt 5
acl save  sc0_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

  sc_conn_cnt([,
]) : integer

sc0_conn_cnt([]) : integer

sc1_conn_cnt([]) : integer

sc2_conn_cnt([]) : integer

Returns the cumulated number of incoming connections from currently tracked

counters. See also src_conn_cnt.

sc_conn_cur([,]) : integer

sc0_conn_cur([]) : integer

sc1_conn_cur([]) : integer

sc2_conn_cur([]) : integer

Returns the current amount of concurrent connections tracking the same

tracked counters. This number is automatically incremented when tracking

begins and decremented when tracking stops. See also src_conn_cur.

sc_conn_rate([,]) : integer

sc0_conn_rate([]) : integer

sc1_conn_rate([]) : integer

sc2_conn_rate([]) : integer

Returns the average connection rate from the currently tracked counters,

measured in amount of connections over the period configured in the table.

See also src_conn_rate.

sc_get_gpc0([,]) : integer

sc0_get_gpc0([]) : integer

sc1_get_gpc0([]) : integer

sc2_get_gpc0([]) : integer

Returns the value of the first General Purpose Counter associated to the

currently tracked counters. See also src_get_gpc0 and sc/sc0/sc1/sc2_inc_gpc0.

sc_gpc0_rate([,]) : integer

sc0_gpc0_rate([]) : integer

sc1_gpc0_rate([]) : integer

sc2_gpc0_rate([]) : integer

Returns the average increment rate of the first General Purpose Counter

associated to the currently tracked counters. It reports the frequency

which the gpc0 counter was incremented over the configured period. See also

src_gpc0_rate, sc/sc0/sc1/sc2_get_gpc0, and sc/sc0/sc1/sc2_inc_gpc0. Note

that the “gpc0_rate” counter must be stored in the stick-table for a value to

be returned, as “gpc0” only holds the event count.

sc_http_err_cnt([,]) : integer

sc0_http_err_cnt([]) : integer

sc1_http_err_cnt([]) : integer

sc2_http_err_cnt([]) : integer

Returns the cumulated number of HTTP errors from the currently tracked

counters. This includes the both request errors and 4xx error responses.

See also src_http_err_cnt.

sc_http_err_rate([,]) : integer

sc0_http_err_rate([]) : integer

sc1_http_err_rate([]) : integer

sc2_http_err_rate([]) : integer

Returns the average rate of HTTP errors from the currently tracked counters,

measured in amount of errors over the period configured in the table. This

includes the both request errors and 4xx error responses. See also

src_http_err_rate.

sc_http_req_cnt([,]) : integer

sc0_http_req_cnt([]) : integer

sc1_http_req_cnt([]) : integer

sc2_http_req_cnt([]) : integer

Returns the cumulated number of HTTP requests from the currently tracked

counters. This includes every started request, valid or not. See also

src_http_req_cnt.

sc_http_req_rate([,]) : integer

sc0_http_req_rate([]) : integer

sc1_http_req_rate([]) : integer

sc2_http_req_rate([]) : integer

Returns the average rate of HTTP requests from the currently tracked

counters, measured in amount of requests over the period configured in

the table. This includes every started request, valid or not. See also

src_http_req_rate.

sc_inc_gpc0([,]) : integer

sc0_inc_gpc0([]) : integer

sc1_inc_gpc0([]) : integer

sc2_inc_gpc0([]) : integer

Increments the first General Purpose Counter associated to the currently

tracked counters, and returns its new value. Before the first invocation,

the stored value is zero, so first invocation will increase it to 1 and will

return 1. This is typically used as a second ACL in an expression in order

to mark a connection when a first ACL was verified :  

  acl abuse sc0_http_req_rate gt 10
acl kill  sc0_inc_gpc0 gt 0
tcp-request connection reject if abuse kill

  sc_kbytes_in([,
]) : integer

sc0_kbytes_in([]) : integer

sc1_kbytes_in([]) : integer

sc2_kbytes_in([]) : integer

Returns the amount of client-to-server data from the currently tracked

counters, measured in kilobytes over the period configured in the table. The

test is currently performed on 32-bit integers, which limits values to 4

terabytes. See also src_kbytes_in.

sc_kbytes_out([,]) : integer

sc0_kbytes_out([]) : integer

sc1_kbytes_out([]) : integer

sc2_kbytes_out([]) : integer

Returns the amount of server-to-client data from the currently tracked

counters, measured in kilobytes over the period configured in the table. The

test is currently performed on 32-bit integers, which limits values to 4

terabytes. See also src_kbytes_out.

sc_sess_cnt([,]) : integer

sc0_sess_cnt([]) : integer

sc1_sess_cnt([]) : integer

sc2_sess_cnt([]) : integer

Returns the cumulated number of incoming connections that were transformed

into sessions, which means that they were accepted by a “tcp-request

connection” rule, from the currently tracked counters. A backend may count

more sessions than connections because each connection could result in many

backend sessions if some HTTP keep-alive is performed over the connection

with the client. See also src_sess_cnt.

sc_sess_rate([,]) : integer

sc0_sess_rate([]) : integer

sc1_sess_rate([]) : integer

sc2_sess_rate([]) : integer

Returns the average session rate from the currently tracked counters,

measured in amount of sessions over the period configured in the table. A

session is a connection that got past the early “tcp-request connection”

rules. A backend may count more sessions than connections because each

connection could result in many backend sessions if some HTTP keep-alive is

performed over the connection with the client. See also src_sess_rate.

sc_tracked([,]) : boolean

sc0_tracked([]) : boolean

sc1_tracked([]) : boolean

sc2_tracked([]) : boolean

Returns true if the designated session counter is currently being tracked by

the current session. This can be useful when deciding whether or not we want

to set some values in a header passed to the server.

sc_trackers([,]) : integer

sc0_trackers([]) : integer

sc1_trackers([]) : integer

sc2_trackers([]) : integer

Returns the current amount of concurrent connections tracking the same

tracked counters. This number is automatically incremented when tracking

begins and decremented when tracking stops. It differs from sc0_conn_cur in

that it does not rely on any stored information but on the table’s reference

count (the “use” value which is returned by “show table” on the CLI). This

may sometimes be more suited for layer7 tracking. It can be used to tell a

server how many concurrent connections there are from a given address for

example.

so_id : integer

Returns an integer containing the current listening socket’s id. It is useful

in frontends involving many “bind” lines, or to stick all users coming via a

same socket to the same server.

src : ip

This is the source IPv4 address of the client of the session.  It is of type

IP and works on both IPv4 and IPv6 tables. On IPv6 tables, IPv4 addresses are

mapped to their IPv6 equivalent, according to RFC 4291. Note that it is the

TCP-level source address which is used, and not the address of a client

behind a proxy. However if the “accept-proxy” bind directive is used, it can

be the address of a client behind another PROXY-protocol compatible component

for all rule sets except “tcp-request connection” which sees the real address.

Example:  
add an HTTP header in requests with the originating address’ country
  http-request set-header X-Country %[src,map_ip(geoip.lst)]

src_bytes_in_rate([
]) : integer

Returns the average bytes rate from the incoming connection’s source address

in the current proxy’s stick-table or in the designated stick-table, measured

in amount of bytes over the period configured in the table. If the address is

not found, zero is returned. See also sc/sc0/sc1/sc2_bytes_in_rate.

src_bytes_out_rate([]) : integer

Returns the average bytes rate to the incoming connection’s source address in

the current proxy’s stick-table or in the designated stick-table, measured in

amount of bytes over the period configured in the table. If the address is

not found, zero is returned. See also sc/sc0/sc1/sc2_bytes_out_rate.

src_clr_gpc0([]) : integer

Clears the first General Purpose Counter associated to the incoming

connection’s source address in the current proxy’s stick-table or in the

designated stick-table, and returns its previous value. If the address is not

found, an entry is created and 0 is returned. This is typically used as a

second ACL in an expression in order to mark a connection when a first ACL

was verified :  

  # block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill  src_inc_gpc0 gt 5
acl save  src_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

  src_conn_cnt([
]) : integer

Returns the cumulated number of connections initiated from the current

incoming connection’s source address in the current proxy’s stick-table or in

the designated stick-table. If the address is not found, zero is returned.

See also sc/sc0/sc1/sc2_conn_cnt.

src_conn_cur([]) : integer

Returns the current amount of concurrent connections initiated from the

current incoming connection’s source address in the current proxy’s

stick-table or in the designated stick-table. If the address is not found,

zero is returned. See also sc/sc0/sc1/sc2_conn_cur.

src_conn_rate([]) : integer

Returns the average connection rate from the incoming connection’s source

address in the current proxy’s stick-table or in the designated stick-table,

measured in amount of connections over the period configured in the table. If

the address is not found, zero is returned. See also sc/sc0/sc1/sc2_conn_rate.

src_get_gpc0([]) : integer

Returns the value of the first General Purpose Counter associated to the

incoming connection’s source address in the current proxy’s stick-table or in

the designated stick-table. If the address is not found, zero is returned.

See also sc/sc0/sc1/sc2_get_gpc0 and src_inc_gpc0.

src_gpc0_rate([]) : integer

Returns the average increment rate of the first General Purpose Counter

associated to the incoming connection’s source address in the current proxy’s

stick-table or in the designated stick-table. It reports the frequency

which the gpc0 counter was incremented over the configured period. See also

sc/sc0/sc1/sc2_gpc0_rate, src_get_gpc0, and sc/sc0/sc1/sc2_inc_gpc0. Note

that the “gpc0_rate” counter must be stored in the stick-table for a value to

be returned, as “gpc0” only holds the event count.

src_http_err_cnt([]) : integer

Returns the cumulated number of HTTP errors from the incoming connection’s

source address in the current proxy’s stick-table or in the designated

stick-table. This includes the both request errors and 4xx error responses.

See also sc/sc0/sc1/sc2_http_err_cnt. If the address is not found, zero is

returned.

src_http_err_rate([]) : integer

Returns the average rate of HTTP errors from the incoming connection’s source

address in the current proxy’s stick-table or in the designated stick-table,

measured in amount of errors over the period configured in the table. This

includes the both request errors and 4xx error responses. If the address is

not found, zero is returned. See also sc/sc0/sc1/sc2_http_err_rate.

src_http_req_cnt([]) : integer

Returns the cumulated number of HTTP requests from the incoming connection’s

source address in the current proxy’s stick-table or in the designated stick-

table. This includes every started request, valid or not. If the address is

not found, zero is returned. See also sc/sc0/sc1/sc2_http_req_cnt.

src_http_req_rate([]) : integer

Returns the average rate of HTTP requests from the incoming connection’s

source address in the current proxy’s stick-table or in the designated stick-

table, measured in amount of requests over the period configured in the

table. This includes every started request, valid or not. If the address is

not found, zero is returned. See also sc/sc0/sc1/sc2_http_req_rate.

src_inc_gpc0([]) : integer

Increments the first General Purpose Counter associated to the incoming

connection’s source address in the current proxy’s stick-table or in the

designated stick-table, and returns its new value. If the address is not

found, an entry is created and 1 is returned. See also sc0/sc2/sc2_inc_gpc0.

This is typically used as a second ACL in an expression in order to mark a

connection when a first ACL was verified :  

  acl abuse src_http_req_rate gt 10
acl kill  src_inc_gpc0 gt 0
tcp-request connection reject if abuse kill

  src_kbytes_in([
]) : integer

Returns the amount of data received from the incoming connection’s source

address in the current proxy’s stick-table or in the designated stick-table,

measured in kilobytes over the period configured in the table. If the address

is not found, zero is returned. The test is currently performed on 32-bit

integers, which limits values to 4 terabytes. See also

sc/sc0/sc1/sc2_kbytes_in.

src_kbytes_out([]) : integer

Returns the amount of data sent to the incoming connection’s source address

in the current proxy’s stick-table or in the designated stick-table, measured

in kilobytes over the period configured in the table. If the address is not

found, zero is returned. The test is currently performed on 32-bit integers,

which limits values to 4 terabytes. See also sc/sc0/sc1/sc2_kbytes_out.

src_port : integer

Returns an integer value corresponding to the TCP source port of the

connection on the client side, which is the port the client connected from.

Usage of this function is very limited as modern protocols do not care much

about source ports nowadays.

src_sess_cnt([]) : integer

Returns the cumulated number of connections initiated from the incoming

connection’s source IPv4 address in the current proxy’s stick-table or in the

designated stick-table, that were transformed into sessions, which means that

they were accepted by “tcp-request” rules. If the address is not found, zero

is returned. See also sc/sc0/sc1/sc2_sess_cnt.

src_sess_rate([]) : integer

Returns the average session rate from the incoming connection’s source

address in the current proxy’s stick-table or in the designated stick-table,

measured in amount of sessions over the period configured in the table. A

session is a connection that went past the early “tcp-request” rules. If the

address is not found, zero is returned. See also sc/sc0/sc1/sc2_sess_rate.

src_updt_conn_cnt([]) : integer

Creates or updates the entry associated to the incoming connection’s source

address in the current proxy’s stick-table or in the designated stick-table.

This table must be configured to store the “conn_cnt” data type, otherwise

the match will be ignored. The current count is incremented by one, and the

expiration timer refreshed. The updated count is returned, so this match

can’t return zero. This was used to reject service abusers based on their

source address. Note: it is recommended to use the more complete “track-sc*”

actions in “tcp-request” rules instead.

Example :  
This frontend limits incoming SSH connections to 3 per 10 second for
each source address, and rejects excess connections until a 10 second
silence is observed. At most 20 addresses are tracked.
  listen ssh
bind :22
mode tcp
maxconn 100
stick-table type ip size 20 expire 10s store conn_cnt
tcp-request content reject if { src_updt_conn_cnt gt 3 }
server local 127.0.0.1:22

srv_id : integer

Returns an integer containing the server’s id when processing the response.

While it’s almost only used with ACLs, it may be used for logging or

debugging.

7.3.4. Fetching samples at Layer 5

The layer 5 usually describes just the session layer which in haproxy is

closest to the session once all the connection handshakes are finished, but

when no content is yet made available. The fetch methods described here are

usable as low as the “tcp-request content” rule sets unless they require some

future information. Those generally include the results of SSL negotiations.

ssl_c_ca_err : integer

When the incoming connection was made over an SSL/TLS transport layer,

returns the ID of the first error detected during verification of the client

certificate at depth > 0, or 0 if no error was encountered during this

verification process. Please refer to your SSL library’s documentation to

find the exhaustive list of error codes.

ssl_c_ca_err_depth : integer

When the incoming connection was made over an SSL/TLS transport layer,

returns the depth in the CA chain of the first error detected during the

verification of the client certificate. If no error is encountered, 0 is

returned.

ssl_c_err : integer

When the incoming connection was made over an SSL/TLS transport layer,

returns the ID of the first error detected during verification at depth 0, or

0 if no error was encountered during this verification process. Please refer

to your SSL library’s documentation to find the exhaustive list of error

codes.

ssl_c_i_dn([[,]]) : string

When the incoming connection was made over an SSL/TLS transport layer,

returns the full distinguished name of the issuer of the certificate

presented by the client when no  is specified, or the value of the

first given entry found from the beginning of the DN. If a positive/negative

occurrence number is specified as the optional second argument, it returns

the value of the nth given entry value from the beginning/end of the DN.

For instance, “ssl_c_i_dn(OU,2)” the second organization unit, and

“ssl_c_i_dn(CN)” retrieves the common name.
  ACL derivatives :
ssl_c_i_dn([[,]]) : exact string match

ssl_c_key_alg : string

Returns the name of the algorithm used to generate the key of the certificate

presented by the client when the incoming connection was made over an SSL/TLS

transport layer.
  ACL derivatives :
ssl_c_key_alg : exact string match

ssl_c_notafter : string

Returns the end date presented by the client as a formatted string

YYMMDDhhmmss[Z] when the incoming connection was made over an SSL/TLS

transport layer.
  ACL derivatives :
ssl_c_notafter : exact string match

ssl_c_notbefore : string

Returns the start date presented by the client as a formatted string

YYMMDDhhmmss[Z] when the incoming connection was made over an SSL/TLS

transport layer.
  ACL derivatives :
ssl_c_notbefore : exact string match

ssl_c_s_dn([[,]]) : string

When the incoming connection was made over an SSL/TLS transport layer,

returns the full distinguished name of the subject of the certificate

presented by the client when no  is specified, or the value of the

first given entry found from the beginning of the DN. If a positive/negative

occurrence number is specified as the optional second argument, it returns

the value of the nth given entry value from the beginning/end of the DN.

For instance, “ssl_c_s_dn(OU,2)” the second organization unit, and

“ssl_c_s_dn(CN)” retrieves the common name.
  ACL derivatives :
ssl_c_s_dn([[,]]) : exact string match

ssl_c_serial : binary

Returns the serial of the certificate presented by the client when the

incoming connection was made over an SSL/TLS transport layer. When used for

an ACL, the value(s) to match against can be passed in hexadecimal form.
  ACL derivatives :
ssl_c_serial : hex block match

ssl_c_sha1 : binary

Returns the SHA-1 fingerprint of the certificate presented by the client when

the incoming connection was made over an SSL/TLS transport layer. This can be

used to stick a client to a server, or to pass this information to a server.

ssl_c_sig_alg : string

Returns the name of the algorithm used to sign the certificate presented by

the client when the incoming connection was made over an SSL/TLS transport

layer.
  ACL derivatives :
ssl_c_sig_alg : exact string match

ssl_c_used : boolean

Returns true if current SSL session uses a client certificate even if current

connection uses SSL session resumption. See also “ssl_fc_has_crt”.

ssl_c_verify : integer

Returns the verify result error ID when the incoming connection was made over

an SSL/TLS transport layer, otherwise zero if no error is encountered. Please

refer to your SSL library’s documentation for an exhaustive list of error

codes.

ssl_c_version : integer

Returns the version of the certificate presented by the client when the

incoming connection was made over an SSL/TLS transport layer.

ssl_f_i_dn([[,]]) : string

When the incoming connection was made over an SSL/TLS transport layer,

returns the full distinguished name of the issuer of the certificate

presented by the frontend when no  is specified, or the value of the

first given entry found from the beginning of the DN. If a positive/negative

occurrence number is specified as the optional second argument, it returns

the value of the nth given entry value from the beginning/end of the DN.

For instance, “ssl_f_i_dn(OU,2)” the second organization unit, and

“ssl_f_i_dn(CN)” retrieves the common name.
  ACL derivatives :
ssl_f_i_dn([[,]]) : exact string match

ssl_f_key_alg : string

Returns the name of the algorithm used to generate the key of the certificate

presented by the frontend when the incoming connection was made over an

SSL/TLS transport layer.
  ACL derivatives :
ssl_f_key_alg : exact string match

ssl_f_notafter : string

Returns the end date presented by the frontend as a formatted string

YYMMDDhhmmss[Z] when the incoming connection was made over an SSL/TLS

transport layer.
  ACL derivatives :
ssl_f_notafter : exact string match

ssl_f_notbefore : string

Returns the start date presented by the frontend as a formatted string

YYMMDDhhmmss[Z] when the incoming connection was made over an SSL/TLS

transport layer.
  ACL derivatives :
ssl_f_notbefore : exact string match

ssl_f_s_dn([[,]]) : string

When the incoming connection was made over an SSL/TLS transport layer,

returns the full distinguished name of the subject of the certificate

presented by the frontend when no  is specified, or the value of the

first given entry found from the beginning of the DN. If a positive/negative

occurrence number is specified as the optional second argument, it returns

the value of the nth given entry value from the beginning/end of the DN.

For instance, “ssl_f_s_dn(OU,2)” the second organization unit, and

“ssl_f_s_dn(CN)” retrieves the common name.
  ACL derivatives :
ssl_f_s_dn([[,]]) : exact string match

ssl_f_serial : binary

Returns the serial of the certificate presented by the frontend when the

incoming connection was made over an SSL/TLS transport layer. When used for

an ACL, the value(s) to match against can be passed in hexadecimal form.
  ACL derivatives :
ssl_f_serial : hex block match

ssl_f_sig_alg : string

Returns the name of the algorithm used to sign the certificate presented by

the frontend when the incoming connection was made over an SSL/TLS transport

layer.
  ACL derivatives :
ssl_f_sig_alg : exact string match

ssl_f_version : integer

Returns the version of the certificate presented by the frontend when the

incoming connection was made over an SSL/TLS transport layer.

ssl_fc : boolean

Returns true when the front connection was made via an SSL/TLS transport

layer and is locally deciphered. This means it has matched a socket declared

with a “bind” line having the “ssl” option.

Example :
This passes “X-Proto: https” to servers when client connects over SSL
  listen http-https
bind :80
bind :443 ssl crt /etc/haproxy.pem
http-request add-header X-Proto https if { ssl_fc }

ssl_fc_alg_keysize : integer

Returns the symmetric cipher key size supported in bits when the incoming

connection was made over an SSL/TLS transport layer.

ssl_fc_alpn : string

This extracts the Application Layer Protocol Negotiation field from an

incoming connection made via a TLS transport layer and locally deciphered by

haproxy. The result is a string containing the protocol name advertised by

the client. The SSL library must have been built with support for TLS

extensions enabled (check haproxy -vv). Note that the TLS ALPN extension is

not advertised unless the “alpn” keyword on the “bind” line specifies a

protocol list. Also, nothing forces the client to pick a protocol from this

list, any other one may be requested. The TLS ALPN extension is meant to

replace the TLS NPN extension. See also “ssl_fc_npn”.
  ACL derivatives :
ssl_fc_alpn : exact string match

ssl_fc_cipher : string

Returns the name of the used cipher when the incoming connection was made

over an SSL/TLS transport layer.
  ACL derivatives :
ssl_fc_cipher : exact string match

ssl_fc_has_crt : boolean

Returns true if a client certificate is present in an incoming connection over

SSL/TLS transport layer. Useful if ‘verify’ statement is set to ‘optional’.

Note: on SSL session resumption with Session ID or TLS ticket, client

certificate is not present in the current connection but may be retrieved

from the cache or the ticket. So prefer “ssl_c_used” if you want to check if

current SSL session uses a client certificate.

ssl_fc_has_sni : boolean

This checks for the presence of a Server Name Indication TLS extension (SNI)

in an incoming connection was made over an SSL/TLS transport layer. Returns

true when the incoming connection presents a TLS SNI field. This requires

that the SSL library is build with support for TLS extensions enabled (check

haproxy -vv).

ssl_fc_npn : string

This extracts the Next Protocol Negotiation field from an incoming connection

made via a TLS transport layer and locally deciphered by haproxy. The result

is a string containing the protocol name advertised by the client. The SSL

library must have been built with support for TLS extensions enabled (check

haproxy -vv). Note that the TLS NPN extension is not advertised unless the

“npn” keyword on the “bind” line specifies a protocol list. Also, nothing

forces the client to pick a protocol from this list, any other one may be

requested. Please note that the TLS NPN extension was replaced with ALPN.
  ACL derivatives :
ssl_fc_npn : exact string match

ssl_fc_protocol : string

Returns the name of the used protocol when the incoming connection was made

over an SSL/TLS transport layer.
  ACL derivatives :
ssl_fc_protocol : exact string match

ssl_fc_unique_id : string

When the incoming connection was made over an SSL/TLS transport layer,

returns a base64 encoded string containing the TLS unique ID as defined

in RFC5929 section 3.

ssl_fc_session_id : binary

Returns the SSL ID of the front connection when the incoming connection was

made over an SSL/TLS transport layer. It is useful to stick a given client to

a server. It is important to note that some browsers refresh their session ID

every few minutes.

ssl_fc_sni : string

This extracts the Server Name Indication TLS extension (SNI) field from an

incoming connection made via an SSL/TLS transport layer and locally

deciphered by haproxy. The result (when present) typically is a string

matching the HTTPS host name (253 chars or less). The SSL library must have

been built with support for TLS extensions enabled (check haproxy -vv).
  This fetch is different from “req_ssl_sni” above in that it applies to the

connection being deciphered by haproxy and not to SSL contents being blindly

forwarded. See also “ssl_fc_sni_end” and “ssl_fc_sni_reg” below. This

requires that the SSL library is build with support for TLS extensions

enabled (check haproxy -vv).
  ACL derivatives :
ssl_fc_sni     : exact string match
ssl_fc_sni_end : suffix match
ssl_fc_sni_reg : regex match

ssl_fc_use_keysize : integer

Returns the symmetric cipher key size used in bits when the incoming

connection was made over an SSL/TLS transport layer.

7.3.5. Fetching samples from buffer contents (Layer 6)

Fetching samples from buffer contents is a bit different from the previous

sample fetches above because the sampled data are ephemeral. These data can

only be used when they’re available and will be lost when they’re forwarded.

For this reason, samples fetched from buffer contents during a request cannot

be used in a response for example. Even while the data are being fetched, they

can change. Sometimes it is necessary to set some delays or combine multiple

sample fetch methods to ensure that the expected data are complete and usable,

for example through TCP request content inspection. Please see the “tcp-request

content” keyword for more detailed information on the subject.

payload(,) : binary (deprecated)

This is an alias for “req.payload” when used in the context of a request (eg:

“stick on”, “stick match”), and for “res.payload” when used in the context of

a response such as in “stick store response”.

payload_lv(,[,]) : binary (deprecated)

This is an alias for “req.payload_lv” when used in the context of a request

(eg: “stick on”, “stick match”), and for “res.payload_lv” when used in the

context of a response such as in “stick store response”.

req.len : integer

req_len : integer (deprecated)

Returns an integer value corresponding to the number of bytes present in the

request buffer. This is mostly used in ACL. It is important to understand

that this test does not return false as long as the buffer is changing. This

means that a check with equality to zero will almost always immediately match

at the beginning of the session, while a test for more data will wait for

that data to come in and return false only when haproxy is certain that no

more data will come in. This test was designed to be used with TCP request

content inspection.

req.payload(,) : binary

This extracts a binary block of  bytes and starting at byte  

in the request buffer. As a special case, if the  argument is zero,

the the whole buffer from  to the end is extracted. This can be used

with ACLs in order to check for the presence of some content in a buffer at

any location.
  ACL alternatives :
payload(,) : hex binary match

req.payload_lv(,[,]) : binary

This extracts a binary block whose size is specified at  for  

bytes, and which starts at  if specified or just after the length in

the request buffer. The  parameter also supports relative offsets if

prepended with a ‘+’ or ‘-’ sign.
  ACL alternatives :
payload_lv(,[,]) : hex binary match

Example :

please consult the example from the “stick store-response” keyword.

req.proto_http : boolean

req_proto_http : boolean (deprecated)

Returns true when data in the request buffer look like HTTP and correctly

parses as such. It is the same parser as the common HTTP request parser which

is used so there should be no surprises. The test does not match until the

request is complete, failed or timed out. This test may be used to report the

protocol in TCP logs, but the biggest use is to block TCP request analysis

until a complete HTTP request is present in the buffer, for example to track

a header.

Example:
track request counts per “base” (concatenation of Host+URL)
  tcp-request inspect-delay 10s

tcp-request content reject if !HTTP

tcp-request content track-sc0 base table req-rate

req.rdp_cookie([]) : string

rdp_cookie([]) : string (deprecated)

When the request buffer looks like the RDP protocol, extracts the RDP cookie

, or any cookie if unspecified. The parser only checks for the first

cookie, as illustrated in the RDP protocol specification. The cookie name is

case insensitive. Generally the “MSTS” cookie name will be used, as it can

contain the user name of the client connecting to the server if properly

configured on the client. The “MSTSHASH” cookie is often used as well for

session stickiness to servers.
  This differs from “balance rdp-cookie” in that any balancing algorithm may be

used and thus the distribution of clients to backend servers is not linked to

a hash of the RDP cookie. It is envisaged that using a balancing algorithm

such as “balance roundrobin” or “balance leastconn” will lead to a more even

distribution of clients to backend servers than the hash used by “balance

rdp-cookie”.
  ACL derivatives :
req_rdp_cookie([]) : exact string match

Example :

listen tse-farm
bind 0.0.0.0:3389
# wait up to 5s for an RDP cookie in the request
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
# apply RDP cookie persistence
persist rdp-cookie
# Persist based on the mstshash cookie
# This is only useful makes sense if
# balance rdp-cookie is not used
stick-table type string size 204800
stick on req.rdp_cookie(mstshash)
server srv1 1.1.1.1:3389
server srv1 1.1.1.2:3389

See also : “balance rdp-cookie”, “persist rdp-cookie”, “tcp-request” and the “req_rdp_cookie” ACL.

req.rdp_cookie_cnt([name]) : integer

rdp_cookie_cnt([name]) : integer (deprecated)

Tries to parse the request buffer as RDP protocol, then returns an integer

corresponding to the number of RDP cookies found. If an optional cookie name

is passed, only cookies matching this name are considered. This is mostly

used in ACL.
  ACL derivatives :
req_rdp_cookie_cnt([]) : integer match

req.ssl_hello_type : integer

req_ssl_hello_type : integer (deprecated)

Returns an integer value containing the type of the SSL hello message found

in the request buffer if the buffer contains data that parse as a complete

SSL (v3 or superior) client hello message. Note that this only applies to raw

contents found in the request buffer and not to contents deciphered via an

SSL data layer, so this will not work with “bind” lines having the “ssl”

option. This is mostly used in ACL to detect presence of an SSL hello message

that is supposed to contain an SSL session ID usable for stickiness.

req.ssl_sni : string

req_ssl_sni : string (deprecated)

Returns a string containing the value of the Server Name TLS extension sent

by a client in a TLS stream passing through the request buffer if the buffer

contains data that parse as a complete SSL (v3 or superior) client hello

message. Note that this only applies to raw contents found in the request

buffer and not to contents deciphered via an SSL data layer, so this will not

work with “bind” lines having the “ssl” option. SNI normally contains the

name of the host the client tries to connect to (for recent browsers). SNI is

useful for allowing or denying access to certain hosts when SSL/TLS is used

by the client. This test was designed to be used with TCP request content

inspection. If content switching is needed, it is recommended to first wait

for a complete client hello (type 1), like in the example below. See also

“ssl_fc_sni”.
  ACL derivatives :
req_ssl_sni : exact string match

Examples :
Wait for a client hello for at most 5 seconds
  tcp-request inspect-delay 5s

tcp-request content accept if { req_ssl_hello_type 1 }

use_backend bk_allow if { req_ssl_sni -f allowed_sites }

default_backend bk_sorry_page

res.ssl_hello_type : integer

rep_ssl_hello_type : integer (deprecated)

Returns an integer value containing the type of the SSL hello message found

in the response buffer if the buffer contains data that parses as a complete

SSL (v3 or superior) hello message. Note that this only applies to raw

contents found in the response buffer and not to contents deciphered via an

SSL data layer, so this will not work with “server” lines having the “ssl”

option. This is mostly used in ACL to detect presence of an SSL hello message

that is supposed to contain an SSL session ID usable for stickiness.

req.ssl_ver : integer

req_ssl_ver : integer (deprecated)

Returns an integer value containing the version of the SSL/TLS protocol of a

stream present in the request buffer. Both SSLv2 hello messages and SSLv3

messages are supported. TLSv1 is announced as SSL version 3.1. The value is

composed of the major version multiplied by 65536, added to the minor

version. Note that this only applies to raw contents found in the request

buffer and not to contents deciphered via an SSL data layer, so this will not

work with “bind” lines having the “ssl” option. The ACL version of the test

matches against a decimal notation in the form MAJOR.MINOR (eg: 3.1). This

fetch is mostly used in ACL.
  ACL derivatives :
req_ssl_ver : decimal match

res.len : integer

Returns an integer value corresponding to the number of bytes present in the

response buffer. This is mostly used in ACL. It is important to understand

that this test does not return false as long as the buffer is changing. This

means that a check with equality to zero will almost always immediately match

at the beginning of the session, while a test for more data will wait for

that data to come in and return false only when haproxy is certain that no

more data will come in. This test was designed to be used with TCP response

content inspection.

res.payload(,) : binary

This extracts a binary block of  bytes and starting at byte  

in the response buffer. As a special case, if the  argument is zero,

the the whole buffer from  to the end is extracted. This can be used

with ACLs in order to check for the presence of some content in a buffer at

any location.

res.payload_lv(,[,]) : binary

This extracts a binary block whose size is specified at  for  

bytes, and which starts at  if specified or just after the length in

the response buffer. The  parameter also supports relative offsets

if prepended with a ‘+’ or ‘-’ sign.

Example :

please consult the example from the “stick store-response” keyword.

wait_end : boolean

This fetch either returns true when the inspection period is over, or does

not fetch. It is only used in ACLs, in conjunction with content analysis to

avoid returning a wrong verdict early.  It may also be used to delay some

actions, such as a delayed reject for some special addresses. Since it either

stops the rules evaluation or immediately returns true, it is recommended to

use this acl as the last one in a rule.  Please note that the default ACL

“WAIT_END” is always usable without prior declaration. This test was designed

to be used with TCP request content inspection.

Examples :
delay every incoming request by 2 seconds
  tcp-request inspect-delay 2s

tcp-request content accept if WAIT_END
don’t immediately tell bad guys they are rejected
  tcp-request inspect-delay 10s

acl goodguys src 10.0.0.0/24

acl badguys  src 10.0.1.0/24

tcp-request content accept if goodguys

tcp-request content reject if badguys WAIT_END

tcp-request content reject

7.3.6. Fetching HTTP samples (Layer 7)

It is possible to fetch samples from HTTP contents, requests and responses.

This application layer is also called layer 7. It is only possible to fetch the

data in this section when a full HTTP request or response has been parsed from

its respective request or response buffer. This is always the case with all

HTTP specific rules and for sections running with “mode http”. When using TCP

content inspection, it may be necessary to support an inspection delay in order

to let the request or response come in first. These fetches may require a bit

more CPU resources than the layer 4 ones, but not much since the request and

response are indexed.

base : string

This returns the concatenation of the first Host header and the path part of

the request, which starts at the first slash and ends before the question

mark. It can be useful in virtual hosted environments to detect URL abuses as

well as to improve shared caches efficiency. Using this with a limited size

stick table also allows one to collect statistics about most commonly

requested objects by host/path. With ACLs it can allow simple content

switching rules involving the host and the path at the same time, such as

“www.example.com/favicon.ico”. See also “path” and “uri”.
  ACL derivatives :
base     : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match

base32 : integer
This returns a 32-bit hash of the value returned by the “base” fetch method
above. This is useful to track per-URL activity on high traffic sites without
having to store all URLs. Instead a shorter hash is stored, saving a lot of
memory. The output type is an unsigned integer.
  base32+src : binary
This returns the concatenation of the base32 fetch above and the src fetch
below. The resulting type is of type binary, with a size of 8 or 20 bytes
depending on the source address family. This can be used to track per-IP,
per-URL counters.

capture.req.hdr() : string

This extracts the content of the header captured by the “capture request

header”, idx is the position of the capture keyword in the configuration.

See also: “capture request header”.

capture.req.method : string

This extracts the METHOD of an HTTP request. It can be used in both request

and response. Unlike “method”, it can be used in both request and response

because it’s allocated.

capture.req.uri : string

This extracts the request’s URI, which starts at the first slash and ends

before the first space in the request (without the host part). Unlike “path”

and “url”, it can be used in both request and response because it’s

allocated.

capture.req.ver : string

This extracts the request’s HTTP version and returns either “HTTP/1.0” or

“HTTP/1.1”. Unlike “req.ver”, it can be used in both request, response, and

logs because it relies on a persistent flag.

capture.res.hdr() : string

This extracts the content of the header captured by the “capture response

header”, idx is the position of the capture keyword in the configuration.

The first entry is an index of 0.

See also: “capture response header”

capture.res.ver : string

This extracts the response’s HTTP version and returns either “HTTP/1.0” or

“HTTP/1.1”. Unlike “res.ver”, it can be used in logs because it relies on a

persistent flag.

req.cook([]) : string

cook([]) : string (deprecated)

This extracts the last occurrence of the cookie name  on a “Cookie”

header line from the request, and returns its value as string. If no name is

specified, the first cookie value is returned. When used with ACLs, all

matching cookies are evaluated. Spaces around the name and the value are

ignored as requested by the Cookie header specification (RFC6265). The cookie

name is case-sensitive. Empty cookies are valid, so an empty cookie may very

well return an empty value if it is present. Use the “found” match to detect

presence. Use the res.cook() variant for response cookies sent by the server.
  ACL derivatives :
cook([])     : exact string match
cook_beg([]) : prefix match
cook_dir([]) : subdir match
cook_dom([]) : domain match
cook_end([]) : suffix match
cook_len([]) : length match
cook_reg([]) : regex match
cook_sub([]) : substring match

req.cook_cnt([]) : integer

cook_cnt([]) : integer (deprecated)

Returns an integer value representing the number of occurrences of the cookie
in the request, or all cookies if  is not specified.

req.cook_val([]) : integer

cook_val([]) : integer (deprecated)

This extracts the last occurrence of the cookie name  on a “Cookie”

header line from the request, and converts its value to an integer which is

returned. If no name is specified, the first cookie value is returned. When

used in ACLs, all matching names are iterated over until a value matches.

cookie([]) : string (deprecated)

This extracts the last occurrence of the cookie name  on a “Cookie”

header line from the request, or a “Set-Cookie” header from the response, and

returns its value as a string. A typical use is to get multiple clients

sharing a same profile use the same server. This can be similar to what

“appsession” does with the “request-learn” statement, but with support for

multi-peer synchronization and state keeping across restarts. If no name is

specified, the first cookie value is returned. This fetch should not be used

anymore and should be replaced by req.cook() or res.cook() instead as it

ambiguously uses the direction based on the context where it is used.

See also : “appsession”.

hdr([[,]]) : string

This is equivalent to req.hdr() when used on requests, and to res.hdr() when

used on responses. Please refer to these respective fetches for more details.

In case of doubt about the fetch direction, please use the explicit ones.

Note that contrary to the hdr() sample fetch method, the hdr_* ACL keywords

unambiguously apply to the request headers.

req.fhdr([,]) : string

This extracts the last occurrence of header  in an HTTP request. When

used from an ACL, all occurrences are iterated over until a match is found.

Optionally, a specific occurrence might be specified as a position number.

Positive values indicate a position from the first occurrence, with 1 being

the first one. Negative values indicate positions relative to the last one,

with -1 being the last one. It differs from req.hdr() in that any commas

present in the value are returned and are not used as delimiters. This is

sometimes useful with headers such as User-Agent.

req.fhdr_cnt([]) : integer

Returns an integer value representing the number of occurrences of request

header field name , or the total number of header fields if  is

not specified. Contrary to its req.hdr_cnt() cousin, this function returns

the number of full line headers and does not stop on commas.

req.hdr([[,]]) : string

This extracts the last occurrence of header  in an HTTP request. When

used from an ACL, all occurrences are iterated over until a match is found.

Optionally, a specific occurrence might be specified as a position number.

Positive values indicate a position from the first occurrence, with 1 being

the first one. Negative values indicate positions relative to the last one,

with -1 being the last one. A typical use is with the X-Forwarded-For header

once converted to IP, associated with an IP stick-table. The function

considers any comma as a delimiter for distinct values. If full-line headers

are desired instead, use req.fhdr(). Please carefully check RFC2616 to know

how certain headers are supposed to be parsed. Also, some of them are case

insensitive (eg: Connection).
  ACL derivatives :
hdr([[,]])     : exact string match
hdr_beg([[,]]) : prefix match
hdr_dir([[,]]) : subdir match
hdr_dom([[,]]) : domain match
hdr_end([[,]]) : suffix match
hdr_len([[,]]) : length match
hdr_reg([[,]]) : regex match
hdr_sub([[,]]) : substring match

req.hdr_cnt([]) : integer

hdr_cnt([
]) : integer (deprecated)

Returns an integer value representing the number of occurrences of request

header field name , or the total number of header field values if
is not specified. It is important to remember that one header line may

count as several headers if it has several values. The function considers any

comma as a delimiter for distinct values. If full-line headers are desired

instead, req.fhdr_cnt() should be used instead. With ACLs, it can be used to

detect presence, absence or abuse of a specific header, as well as to block

request smuggling attacks by rejecting requests which contain more than one

of certain headers. See “req.hdr” for more information on header matching.

req.hdr_ip([[,]]) : ip

hdr_ip([[,]]) : ip (deprecated)

This extracts the last occurrence of header  in an HTTP request,

converts it to an IPv4 or IPv6 address and returns this address. When used

with ACLs, all occurrences are checked, and if  is omitted, every value

of every header is checked. Optionally, a specific occurrence might be

specified as a position number. Positive values indicate a position from the

first occurrence, with 1 being the first one.  Negative values indicate

positions relative to the last one, with -1 being the last one. A typical use

is with the X-Forwarded-For and X-Client-IP headers.

req.hdr_val([[,]]) : integer

hdr_val([[,]]) : integer (deprecated)

This extracts the last occurrence of header  in an HTTP request, and

converts it to an integer value. When used with ACLs, all occurrences are

checked, and if  is omitted, every value of every header is checked.

Optionally, a specific occurrence might be specified as a position number.

Positive values indicate a position from the first occurrence, with 1 being

the first one. Negative values indicate positions relative to the last one,

with -1 being the last one. A typical use is with the X-Forwarded-For header.

http_auth() : boolean

Returns a boolean indicating whether the authentication data received from

the client match a username & password stored in the specified userlist. This

fetch function is not really useful outside of ACLs. Currently only http

basic auth is supported.

http_auth_group() : string

Returns a string corresponding to the user name found in the authentication

data received from the client if both the user name and password are valid

according to the specified userlist. The main purpose is to use it in ACLs

where it is then checked whether the user belongs to any group within a list.

This fetch function is not really useful outside of ACLs. Currently only http

basic auth is supported.  
  ACL derivatives :
http_auth_group() : group …
Returns true when the user extracted from the request and whose password is
valid according to the specified userlist belongs to at least one of the
groups.

http_first_req : boolean

Returns true when the request being processed is the first one of the

connection. This can be used to add or remove headers that may be missing

from some requests when a request is not the first one, or to help grouping

requests in the logs.

method : integer + string

Returns an integer value corresponding to the method in the HTTP request. For

example, “GET” equals 1 (check sources to establish the matching). Value 9

means “other method” and may be converted to a string extracted from the

stream. This should not be used directly as a sample, this is only meant to

be used from ACLs, which transparently convert methods from patterns to these

integer + string values. Some predefined ACL already check for most common

methods.
  ACL derivatives :
method : case insensitive method match

Example :
only accept GET and HEAD requests
  acl valid_method method GET HEAD

http-request deny if ! valid_method

path : string

This extracts the request’s URL path, which starts at the first slash and

ends before the question mark (without the host part). A typical use is with

prefetch-capable caches, and with portals which need to aggregate multiple

information from databases and keep them in caches. Note that with outgoing

caches, it would be wiser to use “url” instead. With ACLs, it’s typically

used to match exact file names (eg: “/login.php”), or directory parts using

the derivative forms. See also the “url” and “base” fetch methods.
  ACL derivatives :
path     : exact string match
path_beg : prefix match
path_dir : subdir match
path_dom : domain match
path_end : suffix match
path_len : length match
path_reg : regex match
path_sub : substring match

req.ver : string

req_ver : string (deprecated)

Returns the version string from the HTTP request, for example “1.1”. This can

be useful for logs, but is mostly there for ACL. Some predefined ACL already

check for versions 1.0 and 1.1.
  ACL derivatives :
req_ver : exact string match

res.comp : boolean

Returns the boolean “true” value if the response has been compressed by

HAProxy, otherwise returns boolean “false”. This may be used to add

information in the logs.

res.comp_algo : string

Returns a string containing the name of the algorithm used if the response

was compressed by HAProxy, for example : “deflate”. This may be used to add

some information in the logs.

res.cook([]) : string

scook([]) : string (deprecated)

This extracts the last occurrence of the cookie name  on a “Set-Cookie”

header line from the response, and returns its value as string. If no name is

specified, the first cookie value is returned.
  ACL derivatives :
scook([] : exact string match

res.cook_cnt([]) : integer

scook_cnt([]) : integer (deprecated)

Returns an integer value representing the number of occurrences of the cookie
in the response, or all cookies if  is not specified. This is

mostly useful when combined with ACLs to detect suspicious responses.

res.cook_val([]) : integer

scook_val([]) : integer (deprecated)

This extracts the last occurrence of the cookie name  on a “Set-Cookie”

header line from the response, and converts its value to an integer which is

returned. If no name is specified, the first cookie value is returned.

res.fhdr([[,]]) : string

This extracts the last occurrence of header  in an HTTP response, or of

the last header if no  is specified. Optionally, a specific occurrence

might be specified as a position number. Positive values indicate a position

from the first occurrence, with 1 being the first one. Negative values

indicate positions relative to the last one, with -1 being the last one. It

differs from res.hdr() in that any commas present in the value are returned

and are not used as delimiters. If this is not desired, the res.hdr() fetch

should be used instead. This is sometimes useful with headers such as Date or

Expires.

res.fhdr_cnt([]) : integer

Returns an integer value representing the number of occurrences of response

header field name , or the total number of header fields if  is

not specified. Contrary to its res.hdr_cnt() cousin, this function returns

the number of full line headers and does not stop on commas. If this is not

desired, the res.hdr_cnt() fetch should be used instead.

res.hdr([[,]]) : string

shdr([[,]]) : string (deprecated)

This extracts the last occurrence of header  in an HTTP response, or of

the last header if no  is specified. Optionally, a specific occurrence

might be specified as a position number. Positive values indicate a position

from the first occurrence, with 1 being the first one. Negative values

indicate positions relative to the last one, with -1 being the last one. This

can be useful to learn some data into a stick-table. The function considers

any comma as a delimiter for distinct values. If this is not desired, the

res.fhdr() fetch should be used instead.
  ACL derivatives :
shdr([[,]])     : exact string match
shdr_beg([[,]]) : prefix match
shdr_dir([[,]]) : subdir match
shdr_dom([[,]]) : domain match
shdr_end([[,]]) : suffix match
shdr_len([[,]]) : length match
shdr_reg([[,]]) : regex match
shdr_sub([[,]]) : substring match

res.hdr_cnt([]) : integer

shdr_cnt([]) : integer (deprecated)

Returns an integer value representing the number of occurrences of response

header field name , or the total number of header fields if  is

not specified. The function considers any comma as a delimiter for distinct

values. If this is not desired, the res.fhdr_cnt() fetch should be used

instead.

res.hdr_ip([[,]]) : ip

shdr_ip([[,]]) : ip (deprecated)

This extracts the last occurrence of header  in an HTTP response,

convert it to an IPv4 or IPv6 address and returns this address. Optionally, a

specific occurrence might be specified as a position number. Positive values

indicate a position from the first occurrence, with 1 being the first one.

Negative values indicate positions relative to the last one, with -1 being

the last one. This can be useful to learn some data into a stick table.

res.hdr_val([[,]]) : integer

shdr_val([[,]]) : integer (deprecated)

This extracts the last occurrence of header  in an HTTP response, and

converts it to an integer value. Optionally, a specific occurrence might be

specified as a position number. Positive values indicate a position from the

first occurrence, with 1 being the first one. Negative values indicate

positions relative to the last one, with -1 being the last one. This can be

useful to learn some data into a stick table.

res.ver : string

resp_ver : string (deprecated)

Returns the version string from the HTTP response, for example “1.1”. This

can be useful for logs, but is mostly there for ACL.
  ACL derivatives :
resp_ver : exact string match

set-cookie([]) : string (deprecated)

This extracts the last occurrence of the cookie name  on a “Set-Cookie”

header line from the response and uses the corresponding value to match. This

can be comparable to what “appsession” does with default options, but with

support for multi-peer synchronization and state keeping across restarts.
  This fetch function is deprecated and has been superseded by the “res.cook”

fetch. This keyword will disappear soon.

See also : “appsession”

status : integer

Returns an integer containing the HTTP status code in the HTTP response, for

example, 302. It is mostly used within ACLs and integer ranges, for example,

to remove any Location header if the response is not a 3xx.

url : string

This extracts the request’s URL as presented in the request. A typical use is

with prefetch-capable caches, and with portals which need to aggregate

multiple information from databases and keep them in caches. With ACLs, using

“path” is preferred over using “url”, because clients may send a full URL as

is normally done with proxies. The only real use is to match “*” which does

not match in “path”, and for which there is already a predefined ACL. See

also “path” and “base”.
  ACL derivatives :
url     : exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match

url_ip : ip

This extracts the IP address from the request’s URL when the host part is

presented as an IP address. Its use is very limited. For instance, a

monitoring system might use this field as an alternative for the source IP in

order to test what path a given source address would follow, or to force an

entry in a table for a given source address. With ACLs it can be used to

restrict access to certain systems through a proxy, for example when combined

with option “http_proxy”.

url_port : integer

This extracts the port part from the request’s URL. Note that if the port is

not specified in the request, port 80 is assumed. With ACLs it can be used to

restrict access to certain systems through a proxy, for example when combined

with option “http_proxy”.

urlp([,]) : string

url_param([,]) : string

This extracts the first occurrence of the parameter  in the query

string, which begins after either ‘?’ or , and which ends before ‘&’,

‘;’ or . The parameter name is case-sensitive. The result is a string

corresponding to the value of the parameter  as presented in the

request (no URL decoding is performed). This can be used for session

stickiness based on a client ID, to extract an application cookie passed as a

URL parameter, or in ACLs to apply some checks. Note that the ACL version of

this fetch do not iterate over multiple parameters and stop at the first one

as well.
  ACL derivatives :
urlp([,])     : exact string match
urlp_beg([,]) : prefix match
urlp_dir([,]) : subdir match
urlp_dom([,]) : domain match
urlp_end([,]) : suffix match
urlp_len([,]) : length match
urlp_reg([,]) : regex match
urlp_sub([,]) : substring match

Example :
match http://example.com/foo?PHPSESSIONID=some_id
  stick on urlp(PHPSESSIONID)
match http://example.com/foo;JSESSIONID=some_id
  stick on urlp(JSESSIONID,;)

urlp_val([,]) : integer

See “urlp” above. This one extracts the URL parameter  in the request

and converts it to an integer value. This can be used for session stickiness

based on a user ID for example, or with ACLs to match a page number or price.

7.4. Pre-defined ACLs

Some predefined ACLs are hard-coded so that they do not have to be declared in

every frontend which needs them. They all have their names in upper case in

order to avoid confusion. Their equivalence is provided below.

ACL name    Equivalent to   Usage

FALSE   always_false    never match

HTTP    req_proto_http  match if protocol is valid HTTP

HTTP_1.0    req_ver 1.0 match HTTP version 1.0

HTTP_1.1    req_ver 1.1 match HTTP version 1.1

HTTP_CONTENT    hdr_val(content-length) gt 0    match an existing content-length

HTTP_URL_ABS    url_reg ^[^/:]*://  match absolute URL with scheme

HTTP_URL_SLASH  url_beg /   match URL beginning with “/”

HTTP_URL_STAR   url *   match URL equal to “*”

LOCALHOST   src 127.0.0.1/8 match connection from local host

METH_CONNECT    method CONNECT  match HTTP CONNECT method

METH_GET    method GET HEAD match HTTP GET or HEAD method

METH_HEAD   method HEAD match HTTP HEAD method

METH_OPTIONS    method OPTIONS  match HTTP OPTIONS method

METH_POST   method POST match HTTP POST method

METH_TRACE  method TRACE    match HTTP TRACE method

RDP_COOKIE  req_rdp_cookie_cnt gt 0 match presence of an RDP cookie

REQ_CONTENT req_len gt 0    match data in the request buffer

TRUE    always_true always match

WAIT_END    wait_end    wait for end of content analysis

8. Logging

One of HAProxy’s strong points certainly lies is its precise logs. It probably

provides the finest level of information available for such a product, which is

very important for troubleshooting complex environments. Standard information

provided in logs include client ports, TCP/HTTP state timers, precise session

state at termination and precise termination cause, information about decisions

to direct traffic to a server, and of course the ability to capture arbitrary

headers.
  In order to improve administrators reactivity, it offers a great transparency

about encountered problems, both internal and external, and it is possible to

send logs to different sources at the same time with different level filters :

  • global process-level logs (system errors, start/stop, etc..)
  • per-instance system and internal errors (lack of resource, bugs, …)
  • per-instance external troubles (servers up/down, max connections)
  • per-instance activity (client connections), either at the establishment or

    at the termination.
  The ability to distribute different levels of logs to different log servers

allow several production teams to interact and to fix their problems as soon

as possible. For example, the system team might monitor system-wide errors,

while the application team might be monitoring the up/down for their servers in

real time, and the security team might analyze the activity logs with one hour

delay.

8.1. Log levels

TCP and HTTP connections can be logged with information such as the date, time,

source IP address, destination address, connection duration, response times,

HTTP request, HTTP return code, number of bytes transmitted, conditions

in which the session ended, and even exchanged cookies values. For example

track a particular user’s problems. All messages may be sent to up to two

syslog servers. Check the “log” keyword in section 4.2 for more information

about log facilities.

8.2. Log formats

HAProxy supports 5 log formats. Several fields are common between these formats

and will be detailed in the following sections. A few of them may vary

slightly with the configuration, due to indicators specific to certain

options. The supported formats are as follows :

  •   the default format, which is very basic and very rarely used. It only

    provides very basic information about the incoming connection at the moment

    it is accepted : source IP:port, destination IP:port, and frontend-name.

    This mode will eventually disappear so it will not be described to great

    extents.

  •   the TCP format, which is more advanced. This format is enabled when “option

    tcplog” is set on the frontend. HAProxy will then usually wait for the

    connection to terminate before logging. This format provides much richer

    information, such as timers, connection counts, queue size, etc… This

    format is recommended for pure TCP proxies.

  •   the HTTP format, which is the most advanced for HTTP proxying. This format

    is enabled when “option httplog” is set on the frontend. It provides the

    same information as the TCP format with some HTTP-specific fields such as

    the request, the status code, and captures of headers and cookies. This

    format is recommended for HTTP proxies.

  •   the CLF HTTP format, which is equivalent to the HTTP format, but with the

    fields arranged in the same order as the CLF format. In this mode, all

    timers, captures, flags, etc… appear one per field after the end of the

    common fields, in the same order they appear in the standard HTTP format.

  •   the custom log format, allows you to make your own log line.

  Next sections will go deeper into details for each of these formats. Format

specification will be performed on a “field” basis. Unless stated otherwise, a

field is a portion of text delimited by any number of spaces. Since syslog

servers are susceptible of inserting fields at the beginning of a line, it is

always assumed that the first field is the one containing the process name and

identifier.
  Note : Since log lines may be quite long, the log examples in sections below
might be broken into multiple lines. The example log lines will be
prefixed with 3 closing angle brackets (‘>>>’) and each time a log is
broken into multiple lines, each non-final line will end with a
backslash (‘\’) and the next line will start indented by two characters.

8.2.1. Default log format

This format is used when no specific option is set. The log is emitted as soon

as the connection is accepted. One should note that this currently is the only

format which logs the request’s destination IP and ports.

Example :
listen www
mode http
log global
server srv1 127.0.0.1:8000
  Feb  6 12:12:09 localhost \
haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \
(www/HTTP)
Field   Format                                Extract from the example above
1   process_name ‘[’ pid ‘]:’                            haproxy[14385]:
2   ‘Connect from’                                          Connect from
3   source_ip ‘:’ source_port                             10.0.1.2:33312
4   ‘to’                                                              to
5   destination_ip ‘:’ destination_port                   10.0.3.31:8012
6   ‘(’ frontend_name ‘/’ mode ‘)’                            (www/HTTP)

  Detailed fields description :
- “source_ip” is the IP address of the client which initiated the connection.
- “source_port” is the TCP port of the client which initiated the connection.
- “destination_ip” is the IP address the client connected to.
- “destination_port” is the TCP port the client connected to.
- “frontend_name” is the name of the frontend (or listener) which received
and processed the connection.
- “mode is the mode the frontend is operating (TCP or HTTP).
  In case of a UNIX socket, the source and destination addresses are marked as

“unix:” and the ports reflect the internal ID of the socket which accepted the

connection (the same ID as reported in the stats).
  It is advised not to use this deprecated format for newer installations as it

will eventually disappear.

8.2.2. TCP log format

The TCP format is used when “option tcplog” is specified in the frontend, and

is the recommended format for pure TCP proxies. It provides a lot of precious

information for troubleshooting. Since this format includes timers and byte

counts, the log is normally emitted at the end of the session. It can be

emitted earlier if “option logasap” is specified, which makes sense in most

environments with long sessions such as remote terminals. Sessions which match

the “monitor” rules are never logged. It is also possible not to emit logs for

sessions for which no data were exchanged between the client and the server, by

specifying “option dontlognull” in the frontend. Successful connections will

not be logged if “option dontlog-normal” is specified in the frontend. A few

fields may slightly vary depending on some configuration options, those are

marked with a star (‘*’) after the field name below.

Example :
frontend fnt
mode tcp
option tcplog
log global
default_backend bck

backend bck
server srv1 127.0.0.1:8000

  Feb  6 12:12:56 localhost \
haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \
bck/srv1 0/0/5007 212 – 0/0/0/0/3 0/0
Field   Format                                Extract from the example above
1   process_name ‘[’ pid ‘]:’                            haproxy[14387]:
2   client_ip ‘:’ client_port                             10.0.1.2:33313
3   ‘[’ accept_date ‘]’                       [06/Feb/2009:12:12:51.443]
4   frontend_name                                                    fnt
5   backend_name ‘/’ server_name                                bck/srv1
6   Tw ‘/’ Tc ‘/’ Tt*                                           0/0/5007
7   bytes_read*                                                      212
8   termination_state                                                 –
9   actconn ‘/’ feconn ‘/’ beconn ‘/’ srv_conn ‘/’ retries*    0/0/0/0/3
10   srv_queue ‘/’ backend_queue                                      0/0

  Detailed fields description :
- “client_ip” is the IP address of the client which initiated the TCP
connection to haproxy. If the connection was accepted on a UNIX socket
instead, the IP address would be replaced with the word “unix”. Note that
when the connection is accepted on a socket configured with “accept-proxy”
and the PROXY protocol is correctly used, then the logs will reflect the
forwarded connection’s information.

  •   “client_port” is the TCP port of the client which initiated the connection.

    If the connection was accepted on a UNIX socket instead, the port would be

    replaced with the ID of the accepting socket, which is also reported in the

    stats interface.

  •   “accept_date” is the exact date when the connection was received by haproxy

    (which might be very slightly different from the date observed on the

    network if there was some queuing in the system’s backlog). This is usually

    the same date which may appear in any upstream firewall’s log.

  •   “frontend_name” is the name of the frontend (or listener) which received

    and processed the connection.

  •   “backend_name” is the name of the backend (or listener) which was selected

    to manage the connection to the server. This will be the same as the

    frontend if no switching rule has been applied, which is common for TCP

    applications.

  •   “server_name” is the name of the last server to which the connection was

    sent, which might differ from the first one if there were connection errors

    and a redispatch occurred. Note that this server belongs to the backend

    which processed the request. If the connection was aborted before reaching

    a server, “” is indicated instead of a server name.

  •   “Tw” is the total time in milliseconds spent waiting in the various queues.

    It can be “-1” if the connection was aborted before reaching the queue.

    See “Timers” below for more details.

  •   “Tc” is the total time in milliseconds spent waiting for the connection to

    establish to the final server, including retries. It can be “-1” if the

    connection was aborted before a connection could be established. See

    “Timers” below for more details.

  •   “Tt” is the total time in milliseconds elapsed between the accept and the

    last close. It covers all possible processing. There is one exception, if

    “option logasap” was specified, then the time counting stops at the moment

    the log is emitted. In this case, a ‘+’ sign is prepended before the value,

    indicating that the final one will be larger. See “Timers” below for more

    details.

  •   “bytes_read” is the total number of bytes transmitted from the server to

    the client when the log is emitted. If “option logasap” is specified, the

    this value will be prefixed with a ‘+’ sign indicating that the final one

    may be larger. Please note that this value is a 64-bit counter, so log

    analysis tools must be able to handle it without overflowing.

  •   “termination_state” is the condition the session was in when the session

    ended. This indicates the session state, which side caused the end of

    session to happen, and for what reason (timeout, error, …). The normal

    flags should be “–”, indicating the session was closed by either end with

    no data remaining in buffers. See below “Session state at disconnection”

    for more details.

  •   “actconn” is the total number of concurrent connections on the process when

    the session was logged. It is useful to detect when some per-process system

    limits have been reached. For instance, if actconn is close to 512 when

    multiple connection errors occur, chances are high that the system limits

    the process to use a maximum of 1024 file descriptors and that all of them

    are used. See section 3 “Global parameters” to find how to tune the system.

  •   “feconn” is the total number of concurrent connections on the frontend when

    the session was logged. It is useful to estimate the amount of resource

    required to sustain high loads, and to detect when the frontend’s “maxconn”

    has been reached. Most often when this value increases by huge jumps, it is

    because there is congestion on the backend servers, but sometimes it can be

    caused by a denial of service attack.

  •   “beconn” is the total number of concurrent connections handled by the

    backend when the session was logged. It includes the total number of

    concurrent connections active on servers as well as the number of

    connections pending in queues. It is useful to estimate the amount of

    additional servers needed to support high loads for a given application.

    Most often when this value increases by huge jumps, it is because there is

    congestion on the backend servers, but sometimes it can be caused by a

    denial of service attack.

  •   “srv_conn” is the total number of concurrent connections still active on

    the server when the session was logged. It can never exceed the server’s

    configured “maxconn” parameter. If this value is very often close or equal

    to the server’s “maxconn”, it means that traffic regulation is involved a

    lot, meaning that either the server’s maxconn value is too low, or that

    there aren’t enough servers to process the load with an optimal response

    time. When only one of the server’s “srv_conn” is high, it usually means

    that this server has some trouble causing the connections to take longer to

    be processed than on other servers.

  •   “retries” is the number of connection retries experienced by this session

    when trying to connect to the server. It must normally be zero, unless a

    server is being stopped at the same moment the connection was attempted.

    Frequent retries generally indicate either a network problem between

    haproxy and the server, or a misconfigured system backlog on the server

    preventing new connections from being queued. This field may optionally be

    prefixed with a ‘+’ sign, indicating that the session has experienced a

    redispatch after the maximal retry count has been reached on the initial

    server. In this case, the server name appearing in the log is the one the

    connection was redispatched to, and not the first one, though both may

    sometimes be the same in case of hashing for instance. So as a general rule

    of thumb, when a ‘+’ is present in front of the retry count, this count

    should not be attributed to the logged server.

  •   “srv_queue” is the total number of requests which were processed before

    this one in the server queue. It is zero when the request has not gone

    through the server queue. It makes it possible to estimate the approximate

    server’s response time by dividing the time spent in queue by the number of

    requests in the queue. It is worth noting that if a session experiences a

    redispatch and passes through two server queues, their positions will be

    cumulated. A request should not pass through both the server queue and the

    backend queue unless a redispatch occurs.

  •   “backend_queue” is the total number of requests which were processed before

    this one in the backend’s global queue. It is zero when the request has not

    gone through the global queue. It makes it possible to estimate the average

    queue length, which easily translates into a number of missing servers when

    divided by a server’s “maxconn” parameter. It is worth noting that if a

    session experiences a redispatch, it may pass twice in the backend’s queue,

    and then both positions will be cumulated. A request should not pass

    through both the server queue and the backend queue unless a redispatch

    occurs.

    8.2.3. HTTP log format

    The HTTP format is the most complete and the best suited for HTTP proxies. It

    is enabled by when “option httplog” is specified in the frontend. It provides

    the same level of information as the TCP format with additional features which

    are specific to the HTTP protocol. Just like the TCP format, the log is usually

    emitted at the end of the session, unless “option logasap” is specified, which

    generally only makes sense for download sites. A session which matches the

    “monitor” rules will never logged. It is also possible not to log sessions for

    which no data were sent by the client by specifying “option dontlognull” in the

    frontend. Successful connections will not be logged if “option dontlog-normal”

    is specified in the frontend.

  Most fields are shared with the TCP log, some being different. A few fields may

slightly vary depending on some configuration options. Those ones are marked

with a star (‘*’) after the field name below.

Example :
frontend http-in
mode http
option httplog
log global
default_backend bck

backend static
server srv1 127.0.0.1:8000

  Feb  6 12:14:14 localhost \
haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \
static/srv1 10/0/30/69/109 200 2750 - - —- 1/1/1/1/0 0/0 {1wt.eu} \
{} “GET /index.html HTTP/1.1”
Field   Format                                Extract from the example above
1   process_name ‘[’ pid ‘]:’                            haproxy[14389]:
2   client_ip ‘:’ client_port                             10.0.1.2:33317
3   ‘[’ accept_date ‘]’                       [06/Feb/2009:12:14:14.655]
4   frontend_name                                                http-in
5   backend_name ‘/’ server_name                             static/srv1
6   Tq ‘/’ Tw ‘/’ Tc ‘/’ Tr ‘/’ Tt*                       10/0/30/69/109
7   status_code                                                      200
8   bytes_read*                                                     2750
9   captured_request_cookie                                            -
10   captured_response_cookie                                           -
11   termination_state                                               —-
12   actconn ‘/’ feconn ‘/’ beconn ‘/’ srv_conn ‘/’ retries*    1/1/1/1/0
13   srv_queue ‘/’ backend_queue                                      0/0
14   ‘{’ captured_request_headers* ‘}’                   {haproxy.1wt.eu}
15   ‘{’ captured_response_headers* ‘}’                                {}
16   ‘”’ http_request ‘”’                      “GET /index.html HTTP/1.1”

  Detailed fields description :
- “client_ip” is the IP address of the client which initiated the TCP
connection to haproxy. If the connection was accepted on a UNIX socket
instead, the IP address would be replaced with the word “unix”. Note that
when the connection is accepted on a socket configured with “accept-proxy”
and the PROXY protocol is correctly used, then the logs will reflect the
forwarded connection’s information.

  •   “client_port” is the TCP port of the client which initiated the connection.

    If the connection was accepted on a UNIX socket instead, the port would be

    replaced with the ID of the accepting socket, which is also reported in the

    stats interface.

  •   “accept_date” is the exact date when the TCP connection was received by

    haproxy (which might be very slightly different from the date observed on

    the network if there was some queuing in the system’s backlog). This is

    usually the same date which may appear in any upstream firewall’s log. This

    does not depend on the fact that the client has sent the request or not.

  •   “frontend_name” is the name of the frontend (or listener) which received

    and processed the connection.

  •   “backend_name” is the name of the backend (or listener) which was selected

    to manage the connection to the server. This will be the same as the

    frontend if no switching rule has been applied.

  •   “server_name” is the name of the last server to which the connection was

    sent, which might differ from the first one if there were connection errors

    and a redispatch occurred. Note that this server belongs to the backend

    which processed the request. If the request was aborted before reaching a

    server, “” is indicated instead of a server name. If the request was

    intercepted by the stats subsystem, “” is indicated instead.

  •   “Tq” is the total time in milliseconds spent waiting for the client to send

    a full HTTP request, not counting data. It can be “-1” if the connection

    was aborted before a complete request could be received. It should always

    be very small because a request generally fits in one single packet. Large

    times here generally indicate network trouble between the client and

    haproxy. See “Timers” below for more details.

  •   “Tw” is the total time in milliseconds spent waiting in the various queues.

    It can be “-1” if the connection was aborted before reaching the queue.

    See “Timers” below for more details.

  •   “Tc” is the total time in milliseconds spent waiting for the connection to

    establish to the final server, including retries. It can be “-1” if the

    request was aborted before a connection could be established. See “Timers”

    below for more details.

  •   “Tr” is the total time in milliseconds spent waiting for the server to send

    a full HTTP response, not counting data. It can be “-1” if the request was

    aborted before a complete response could be received. It generally matches

    the server’s processing time for the request, though it may be altered by

    the amount of data sent by the client to the server. Large times here on

    “GET” requests generally indicate an overloaded server. See “Timers” below

    for more details.

  •   “Tt” is the total time in milliseconds elapsed between the accept and the

    last close. It covers all possible processing. There is one exception, if

    “option logasap” was specified, then the time counting stops at the moment

    the log is emitted. In this case, a ‘+’ sign is prepended before the value,

    indicating that the final one will be larger. See “Timers” below for more

    details.

  •   “status_code” is the HTTP status code returned to the client. This status

    is generally set by the server, but it might also be set by haproxy when

    the server cannot be reached or when its response is blocked by haproxy.

  •   “bytes_read” is the total number of bytes transmitted to the client when

    the log is emitted. This does include HTTP headers. If “option logasap” is

    specified, the this value will be prefixed with a ‘+’ sign indicating that

    the final one may be larger. Please note that this value is a 64-bit

    counter, so log analysis tools must be able to handle it without

    overflowing.

  •   “captured_request_cookie” is an optional “name=value” entry indicating that

    the client had this cookie in the request. The cookie name and its maximum

    length are defined by the “capture cookie” statement in the frontend

    configuration. The field is a single dash (‘-‘) when the option is not

    set. Only one cookie may be captured, it is generally used to track session

    ID exchanges between a client and a server to detect session crossing

    between clients due to application bugs. For more details, please consult

    the section “Capturing HTTP headers and cookies” below.

  •   “captured_response_cookie” is an optional “name=value” entry indicating

    that the server has returned a cookie with its response. The cookie name

    and its maximum length are defined by the “capture cookie” statement in the

    frontend configuration. The field is a single dash (‘-‘) when the option is

    not set. Only one cookie may be captured, it is generally used to track

    session ID exchanges between a client and a server to detect session

    crossing between clients due to application bugs. For more details, please

    consult the section “Capturing HTTP headers and cookies” below.

  •   “termination_state” is the condition the session was in when the session

    ended. This indicates the session state, which side caused the end of

    session to happen, for what reason (timeout, error, …), just like in TCP

    logs, and information about persistence operations on cookies in the last

    two characters. The normal flags should begin with “–”, indicating the

    session was closed by either end with no data remaining in buffers. See

    below “Session state at disconnection” for more details.

  •   “actconn” is the total number of concurrent connections on the process when

    the session was logged. It is useful to detect when some per-process system

    limits have been reached. For instance, if actconn is close to 512 or 1024

    when multiple connection errors occur, chances are high that the system

    limits the process to use a maximum of 1024 file descriptors and that all

    of them are used. See section 3 “Global parameters” to find how to tune the

    system.

  •   “feconn” is the total number of concurrent connections on the frontend when

    the session was logged. It is useful to estimate the amount of resource

    required to sustain high loads, and to detect when the frontend’s “maxconn”

    has been reached. Most often when this value increases by huge jumps, it is

    because there is congestion on the backend servers, but sometimes it can be

    caused by a denial of service attack.

  •   “beconn” is the total number of concurrent connections handled by the

    backend when the session was logged. It includes the total number of

    concurrent connections active on servers as well as the number of

    connections pending in queues. It is useful to estimate the amount of

    additional servers needed to support high loads for a given application.

    Most often when this value increases by huge jumps, it is because there is

    congestion on the backend servers, but sometimes it can be caused by a

    denial of service attack.

  •   “srv_conn” is the total number of concurrent connections still active on

    the server when the session was logged. It can never exceed the server’s

    configured “maxconn” parameter. If this value is very often close or equal

    to the server’s “maxconn”, it means that traffic regulation is involved a

    lot, meaning that either the server’s maxconn value is too low, or that

    there aren’t enough servers to process the load with an optimal response

    time. When only one of the server’s “srv_conn” is high, it usually means

    that this server has some trouble causing the requests to take longer to be

    processed than on other servers.

  •   “retries” is the number of connection retries experienced by this session

    when trying to connect to the server. It must normally be zero, unless a

    server is being stopped at the same moment the connection was attempted.

    Frequent retries generally indicate either a network problem between

    haproxy and the server, or a misconfigured system backlog on the server

    preventing new connections from being queued. This field may optionally be

    prefixed with a ‘+’ sign, indicating that the session has experienced a

    redispatch after the maximal retry count has been reached on the initial

    server. In this case, the server name appearing in the log is the one the

    connection was redispatched to, and not the first one, though both may

    sometimes be the same in case of hashing for instance. So as a general rule

    of thumb, when a ‘+’ is present in front of the retry count, this count

    should not be attributed to the logged server.

  •   “srv_queue” is the total number of requests which were processed before

    this one in the server queue. It is zero when the request has not gone

    through the server queue. It makes it possible to estimate the approximate

    server’s response time by dividing the time spent in queue by the number of

    requests in the queue. It is worth noting that if a session experiences a

    redispatch and passes through two server queues, their positions will be

    cumulated. A request should not pass through both the server queue and the

    backend queue unless a redispatch occurs.

  •   “backend_queue” is the total number of requests which were processed before

    this one in the backend’s global queue. It is zero when the request has not

    gone through the global queue. It makes it possible to estimate the average

    queue length, which easily translates into a number of missing servers when

    divided by a server’s “maxconn” parameter. It is worth noting that if a

    session experiences a redispatch, it may pass twice in the backend’s queue,

    and then both positions will be cumulated. A request should not pass

    through both the server queue and the backend queue unless a redispatch

    occurs.

  •   “captured_request_headers” is a list of headers captured in the request due

    to the presence of the “capture request header” statement in the frontend.

    Multiple headers can be captured, they will be delimited by a vertical bar

    (‘|’). When no capture is enabled, the braces do not appear, causing a

    shift of remaining fields. It is important to note that this field may

    contain spaces, and that using it requires a smarter log parser than when

    it’s not used. Please consult the section “Capturing HTTP headers and

    cookies” below for more details.

  •   “captured_response_headers” is a list of headers captured in the response

    due to the presence of the “capture response header” statement in the

    frontend. Multiple headers can be captured, they will be delimited by a

    vertical bar (‘|’). When no capture is enabled, the braces do not appear,

    causing a shift of remaining fields. It is important to note that this

    field may contain spaces, and that using it requires a smarter log parser

    than when it’s not used. Please consult the section “Capturing HTTP headers

    and cookies” below for more details.

  •   “http_request” is the complete HTTP request line, including the method,

    request and HTTP version string. Non-printable characters are encoded (see

    below the section “Non-printable characters”). This is always the last

    field, and it is always delimited by quotes and is the only one which can

    contain quotes. If new fields are added to the log format, they will be

    added before this field. This field might be truncated if the request is

    huge and does not fit in the standard syslog buffer (1024 characters). This

    is the reason why this field must always remain the last one.

    8.2.4. Custom log format

    The directive log-format allows you to customize the logs in http mode and tcp

    mode. It takes a string as argument.

  HAproxy understands some log format variables. % precedes log format variables.

Variables can take arguments using braces (‘{}’), and multiple arguments are

separated by commas within the braces. Flags may be added or removed by

prefixing them with a ‘+’ or ‘-’ sign.
  Special variable “%o” may be used to propagate its flags to all other

variables on the same format string. This is particularly handy with quoted

string formats (“Q”).
  If a variable is named between square brackets (‘[’ .. ‘]’) then it is used

as a pattern extraction rule (see section 7.3). This it useful to add some

less common information such as the client’s SSL certificate’s DN, or to log

the key that would be used to store an entry into a stick table.
  Note: spaces must be escaped. A space character is considered as a separator.

In order to emit a verbatim ‘%’, it must be preceded by another ‘%’ resulting

in ‘%%’. HAProxy will automatically merge consecutive separators.
  Flags are :
* Q: quote a string
* X: hexadecimal representation (IPs, Ports, %Ts, %rt, %pid)

Example:

log-format %T\ %t\ Some\ Text

log-format %{+Q}o\ %t\ %s\ %{-Q}r

At the moment, the default HTTP format is defined this way :

log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ \
%CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r

  the default CLF format is defined this way :

log-format %{+Q}o\ %{-Q}ci\ -\ -\ [%T]\ %r\ %ST\ %B\ \"\"\ \"\"\ %cp\ \
%ms\ %ft\ %b\ %s\ \%Tq\ %Tw\ %Tc\ %Tr\ %Tt\ %tsc\ %ac\ %fc\ \
%bc\ %sc\ %rc\ %sq\ %bq\ %CC\ %CS\ \%hrl\ %hsl

  and the default TCP format is defined this way :

log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tw/%Tc/%Tt\ %B\ %ts\ \
%ac/%fc/%bc/%sc/%rc\ %sq/%bq

  Please refer to the table below for currently defined variables :
  +—+——+———————————————–+————-+
| R | var  | field name (8.2.2 and 8.2.3 for description)  | type        |
+—+——+———————————————–+————-+
|   | %o   | special variable, apply flags on all next var |             |
+—+——+———————————————–+————-+
|   | %B   | bytes_read           (from server to client)  | numeric     |
| H | %CC  | captured_request_cookie                       | string      |
| H | %CS  | captured_response_cookie                      | string      |
|   | %H   | hostname                                      | string      |
|   | %ID  | unique-id                                     | string      |
| H | %ST  | status_code                                   | numeric     |
|   | %T   | gmt_date_time                                 | date        |
|   | %Tc  | Tc                                            | numeric     |
|   | %Tl  | local_date_time                               | date        |
| H | %Tq  | Tq                                            | numeric     |
| H | %Tr  | Tr                                            | numeric     |
|   | %Ts  | timestamp                                     | numeric     |
|   | %Tt  | Tt                                            | numeric     |
|   | %Tw  | Tw                                            | numeric     |
|   | %U   | bytes_uploaded       (from client to server)  | numeric     |
|   | %ac  | actconn                                       | numeric     |
|   | %b   | backend_name                                  | string      |
|   | %bc  | beconn      (backend concurrent connections)  | numeric     |
|   | %bi  | backend_source_ip       (connecting address)  | IP          |
|   | %bp  | backend_source_port     (connecting address)  | numeric     |
|   | %bq  | backend_queue                                 | numeric     |
|   | %ci  | client_ip                 (accepted address)  | IP          |
|   | %cp  | client_port               (accepted address)  | numeric     |
|   | %f   | frontend_name                                 | string      |
|   | %fc  | feconn     (frontend concurrent connections)  | numeric     |
|   | %fi  | frontend_ip              (accepting address)  | IP          |
|   | %fp  | frontend_port            (accepting address)  | numeric     |
|   | %ft  | frontend_name_transport (‘~’ suffix for SSL)  | string      |
| H | %hr  | captured_request_headers default style        | string      |
| H | %hrl | captured_request_headers CLF style            | string list |
| H | %hs  | captured_response_headers default style       | string      |
| H | %hsl | captured_response_headers CLF style           | string list |
|   | %ms  | accept date milliseconds                      | numeric     |
|   | %pid | PID                                           | numeric     |
| H | %r   | http_request                                  | string      |
|   | %rc  | retries                                       | numeric     |
|   | %rt  | request_counter (HTTP req or TCP session)     | numeric     |
|   | %s   | server_name                                   | string      |
|   | %sc  | srv_conn     (server concurrent connections)  | numeric     |
|   | %si  | server_IP                   (target address)  | IP          |
|   | %sp  | server_port                 (target address)  | numeric     |
|   | %sq  | srv_queue                                     | numeric     |
| S | %sslc| ssl_ciphers (ex: AES-SHA)                     | string      |
| S | %sslv| ssl_version (ex: TLSv1)                       | string      |
|   | %t   | date_time      (with millisecond resolution)  | date        |
|   | %ts  | termination_state                             | string      |
| H | %tsc | termination_state with cookie status          | string      |
+—+——+———————————————–+————-+

R = Restrictions : H = mode http only ; S = SSL only

  8.2.5. Error log format

When an incoming connection fails due to an SSL handshake or an invalid PROXY

protocol header, haproxy will log the event using a shorter, fixed line format.

By default, logs are emitted at the LOG_INFO level, unless the option

“log-separate-errors” is set in the backend, in which case the LOG_ERR level

will be used. Connections on which no data are exchanged (eg: probes) are not

logged if the “dontlognull” option is set.
  The format looks like this :

>>> Dec  3 18:27:14 localhost \
haproxy[6103]: 127.0.0.1:56059 [03/Dec/2012:17:35:10.380] frt/f1: \
Connection error during SSL handshake

  Field   Format                                Extract from the example above
1   process_name ‘[’ pid ‘]:’                             haproxy[6103]:
2   client_ip ‘:’ client_port                            127.0.0.1:56059
3   ‘[’ accept_date ‘]’                       [03/Dec/2012:17:35:10.380]
4   frontend_name “/” bind_name “:”                              frt/f1:
5   message                        Connection error during SSL handshake
  These fields just provide minimal information to help debugging connection

failures.

8.3. Advanced logging options

Some advanced logging options are often looked for but are not easy to find out

just by looking at the various options. Here is an entry point for the few

options which can enable better logging. Please refer to the keywords reference

for more information about their usage.

8.3.1. Disabling logging of external tests

It is quite common to have some monitoring tools perform health checks on

haproxy. Sometimes it will be a layer 3 load-balancer such as LVS or any

commercial load-balancer, and sometimes it will simply be a more complete

monitoring system such as Nagios. When the tests are very frequent, users often

ask how to disable logging for those checks. There are three possibilities :

  •   if connections come from everywhere and are just TCP probes, it is often

    desired to simply disable logging of connections without data exchange, by

    setting “option dontlognull” in the frontend. It also disables logging of

    port scans, which may or may not be desired.

  •   if the connection come from a known source network, use “monitor-net” to

    declare this network as monitoring only. Any host in this network will then

    only be able to perform health checks, and their requests will not be

    logged. This is generally appropriate to designate a list of equipment

    such as other load-balancers.

  •   if the tests are performed on a known URI, use “monitor-uri” to declare

    this URI as dedicated to monitoring. Any host sending this request will

    only get the result of a health-check, and the request will not be logged.

    8.3.2. Logging before waiting for the session to terminate

    The problem with logging at end of connection is that you have no clue about

    what is happening during very long sessions, such as remote terminal sessions

    or large file downloads. This problem can be worked around by specifying

    “option logasap” in the frontend. Haproxy will then log as soon as possible,

    just before data transfer begins. This means that in case of TCP, it will still

    log the connection status to the server, and in case of HTTP, it will log just

    after processing the server headers. In this case, the number of bytes reported

    is the number of header bytes sent to the client. In order to avoid confusion

    with normal logs, the total time field and the number of bytes are prefixed

    with a ‘+’ sign which means that real numbers are certainly larger.

    8.3.3. Raising log level upon errors

    Sometimes it is more convenient to separate normal traffic from errors logs,

    for instance in order to ease error monitoring from log files. When the option

    “log-separate-errors” is used, connections which experience errors, timeouts,

    retries, redispatches or HTTP status codes 5xx will see their syslog level

    raised from “info” to “err”. This will help a syslog daemon store the log in

    a separate file. It is very important to keep the errors in the normal traffic

    file too, so that log ordering is not altered. You should also be careful if

    you already have configured your syslog daemon to store all logs higher than

    “notice” in an “admin” file, because the “err” level is higher than “notice”.

    8.3.4. Disabling logging of successful connections

    Although this may sound strange at first, some large sites have to deal with

    multiple thousands of logs per second and are experiencing difficulties keeping

    them intact for a long time or detecting errors within them. If the option

    “dontlog-normal” is set on the frontend, all normal connections will not be

    logged. In this regard, a normal connection is defined as one without any

    error, timeout, retry nor redispatch. In HTTP, the status code is checked too,

    and a response with a status 5xx is not considered normal and will be logged

    too. Of course, doing is is really discouraged as it will remove most of the

    useful information from the logs. Do this only if you have no other

    alternative.

    8.4. Timing events

    Timers provide a great help in troubleshooting network problems. All values are

    reported in milliseconds (ms). These timers should be used in conjunction with

    the session termination flags. In TCP mode with “option tcplog” set on the

    frontend, 3 control points are reported under the form “Tw/Tc/Tt”, and in HTTP

    mode, 5 control points are reported under the form “Tq/Tw/Tc/Tr/Tt” :

  •   Tq: total time to get the client request (HTTP mode only). It’s the time

    elapsed between the moment the client connection was accepted and the

    moment the proxy received the last HTTP header. The value “-1” indicates

    that the end of headers (empty line) has never been seen. This happens when

    the client closes prematurely or times out.

  •   Tw: total time spent in the queues waiting for a connection slot. It

    accounts for backend queue as well as the server queues, and depends on the

    queue size, and the time needed for the server to complete previous

    requests. The value “-1” means that the request was killed before reaching

    the queue, which is generally what happens with invalid or denied requests.

  •   Tc: total time to establish the TCP connection to the server. It’s the time

    elapsed between the moment the proxy sent the connection request, and the

    moment it was acknowledged by the server, or between the TCP SYN packet and

    the matching SYN/ACK packet in return. The value “-1” means that the

    connection never established.

  •   Tr: server response time (HTTP mode only). It’s the time elapsed between

    the moment the TCP connection was established to the server and the moment

    the server sent its complete response headers. It purely shows its request

    processing time, without the network overhead due to the data transmission.

    It is worth noting that when the client has data to send to the server, for

    instance during a POST request, the time already runs, and this can distort

    apparent response time. For this reason, it’s generally wise not to trust

    too much this field for POST requests initiated from clients behind an

    untrusted network. A value of “-1” here means that the last the response

    header (empty line) was never seen, most likely because the server timeout

    stroke before the server managed to process the request.

  •   Tt: total session duration time, between the moment the proxy accepted it

    and the moment both ends were closed. The exception is when the “logasap”

    option is specified. In this case, it only equals (Tq+Tw+Tc+Tr), and is

    prefixed with a ‘+’ sign. From this field, we can deduce “Td”, the data

    transmission time, by subtracting other timers when valid :

    Td = Tt - (Tq + Tw + Tc + Tr)

      Timers with “-1” values have to be excluded from this equation. In TCP

    mode, “Tq” and “Tr” have to be excluded too. Note that “Tt” can never be

    negative.

  These timers provide precious indications on trouble causes. Since the TCP

protocol defines retransmit delays of 3, 6, 12… seconds, we know for sure

that timers close to multiples of 3s are nearly always related to lost packets

due to network problems (wires, negotiation, congestion). Moreover, if “Tt” is

close to a timeout value specified in the configuration, it often means that a

session has been aborted on timeout.
  Most common cases :

  •   If “Tq” is close to 3000, a packet has probably been lost between the

    client and the proxy. This is very rare on local networks but might happen

    when clients are on far remote networks and send large requests. It may

    happen that values larger than usual appear here without any network cause.

    Sometimes, during an attack or just after a resource starvation has ended,

    haproxy may accept thousands of connections in a few milliseconds. The time

    spent accepting these connections will inevitably slightly delay processing

    of other connections, and it can happen that request times in the order of

    a few tens of milliseconds are measured after a few thousands of new

    connections have been accepted at once. Setting “option http-server-close”

    may display larger request times since “Tq” also measures the time spent

    waiting for additional requests.

  •   If “Tc” is close to 3000, a packet has probably been lost between the

    server and the proxy during the server connection phase. This value should

    always be very low, such as 1 ms on local networks and less than a few tens

    of ms on remote networks.

  •   If “Tr” is nearly always lower than 3000 except some rare values which seem

    to be the average majored by 3000, there are probably some packets lost

    between the proxy and the server.

  •   If “Tt” is large even for small byte counts, it generally is because

    neither the client nor the server decides to close the connection, for

    instance because both have agreed on a keep-alive connection mode. In order

    to solve this issue, it will be needed to specify “option httpclose” on

    either the frontend or the backend. If the problem persists, it means that

    the server ignores the “close” connection mode and expects the client to

    close. Then it will be required to use “option forceclose”. Having the

    smallest possible ‘Tt’ is important when connection regulation is used with

    the “maxconn” option on the servers, since no new connection will be sent

    to the server until another one is released.

  Other noticeable HTTP log cases (‘xx’ means any value to be ignored) :
  Tq/Tw/Tc/Tr/+Tt  The “option logasap” is present on the frontend and the log
was emitted before the data phase. All the timers are valid
except “Tt” which is shorter than reality.
  -1/xx/xx/xx/Tt   The client was not able to send a complete request in time
or it aborted too early. Check the session termination flags
then “timeout http-request” and “timeout client” settings.
  Tq/-1/xx/xx/Tt   It was not possible to process the request, maybe because
servers were out of order, because the request was invalid
or forbidden by ACL rules. Check the session termination
flags.
  Tq/Tw/-1/xx/Tt   The connection could not establish on the server. Either it
actively refused it or it timed out after Tt-(Tq+Tw) ms.
Check the session termination flags, then check the
“timeout connect” setting. Note that the tarpit action might
return similar-looking patterns, with “Tw” equal to the time
the client connection was maintained open.
  Tq/Tw/Tc/-1/Tt   The server has accepted the connection but did not return
a complete response in time, or it closed its connection
unexpectedly after Tt-(Tq+Tw+Tc) ms. Check the session
termination flags, then check the “timeout server” setting.

8.5. Session state at disconnection

TCP and HTTP logs provide a session termination indicator in the

“termination_state” field, just before the number of active connections. It is

2-characters long in TCP mode, and is extended to 4 characters in HTTP mode,

each of which has a special meaning :

  •   On the first character, a code reporting the first event which caused the

    session to terminate :

    C : the TCP session was unexpectedly aborted by the client.
    S : the TCP session was unexpectedly aborted by the server, or the
    server explicitly refused it.
    P : the session was prematurely aborted by the proxy, because of a
    connection limit enforcement, because a DENY filter was matched,
    because of a security check which detected and blocked a dangerous
    error in server response which might have caused information leak
    (eg: cacheable cookie).
    L : the session was locally processed by haproxy and was not passed to
    a server. This is what happens for stats and redirects.
    R : a resource on the proxy has been exhausted (memory, sockets, source
    ports, ...). Usually, this appears during the connection phase, and
    system logs should contain a copy of the precise error. If this
    happens, it must be considered as a very serious anomaly which
    should be fixed as soon as possible by any means.
    I : an internal error was identified by the proxy during a self-check.
    This should NEVER happen, and you are encouraged to report any log
    containing this, because this would almost certainly be a bug. It
    would be wise to preventively restart the process after such an
    event too, in case it would be caused by memory corruption.
    D : the session was killed by haproxy because the server was detected
    as down and was configured to kill all connections when going down.
    U : the session was killed by haproxy on this backup server because an
    active server was detected as up and was configured to kill all
    backup connections when going up.
    K : the session was actively killed by an admin operating on haproxy.
    c : the client-side timeout expired while waiting for the client to
    send or receive data.
    s : the server-side timeout expired while waiting for the server to
    send or receive data.
    - : normal session completion, both the client and the server closed
    with nothing left in the buffers.
  •   on the second character, the TCP or HTTP session state when it was closed :

    R : the proxy was waiting for a complete, valid REQUEST from the client
    (HTTP mode only). Nothing was sent to any server.
    Q : the proxy was waiting in the QUEUE for a connection slot. This can
    only happen when servers have a 'maxconn' parameter set. It can
    also happen in the global queue after a redispatch consecutive to
    a failed attempt to connect to a dying server. If no redispatch is
    reported, then no connection attempt was made to any server.
    C : the proxy was waiting for the CONNECTION to establish on the
    server. The server might at most have noticed a connection attempt.
    H : the proxy was waiting for complete, valid response HEADERS from the
    server (HTTP only).
    D : the session was in the DATA phase.
    L : the proxy was still transmitting LAST data to the client while the
    server had already finished. This one is very rare as it can only
    happen when the client dies while receiving the last packets.
    T : the request was tarpitted. It has been held open with the client
    during the whole "timeout tarpit" duration or until the client
    closed, both of which will be reported in the "Tw" timer.
    - : normal session completion after end of data transfer.
  •   the third character tells whether the persistence cookie was provided by

    the client (only in HTTP mode) :

    N : the client provided NO cookie. This is usually the case for new
    visitors, so counting the number of occurrences of this flag in the
    logs generally indicate a valid trend for the site frequentation.
    I : the client provided an INVALID cookie matching no known server.
    This might be caused by a recent configuration change, mixed
    cookies between HTTP/HTTPS sites, persistence conditionally
    ignored, or an attack.
    D : the client provided a cookie designating a server which was DOWN,
    so either "option persist" was used and the client was sent to
    this server, or it was not set and the client was redispatched to
    another server.
    V : the client provided a VALID cookie, and was sent to the associated
    server.
    E : the client provided a valid cookie, but with a last date which was
    older than what is allowed by the "maxidle" cookie parameter, so
    the cookie is consider EXPIRED and is ignored. The request will be
    redispatched just as if there was no cookie.
    O : the client provided a valid cookie, but with a first date which was
    older than what is allowed by the "maxlife" cookie parameter, so
    the cookie is consider too OLD and is ignored. The request will be
    redispatched just as if there was no cookie.
    U : a cookie was present but was not used to select the server because
    some other server selection mechanism was used instead (typically a
    "use-server" rule).
    - : does not apply (no cookie set in configuration).
  •   the last character reports what operations were performed on the persistence

    cookie returned by the server (only in HTTP mode) :

    N : NO cookie was provided by the server, and none was inserted either.
    I : no cookie was provided by the server, and the proxy INSERTED one.
    Note that in "cookie insert" mode, if the server provides a cookie,
    it will still be overwritten and reported as "I" here.
    U : the proxy UPDATED the last date in the cookie that was presented by
    the client. This can only happen in insert mode with "maxidle". It
    happens every time there is activity at a different date than the
    date indicated in the cookie. If any other change happens, such as
    a redispatch, then the cookie will be marked as inserted instead.
    P : a cookie was PROVIDED by the server and transmitted as-is.
    R : the cookie provided by the server was REWRITTEN by the proxy, which
    happens in "cookie rewrite" or "cookie prefix" modes.
    D : the cookie provided by the server was DELETED by the proxy.
    - : does not apply (no cookie set in configuration).
  The combination of the two first flags gives a lot of information about what

was happening when the session terminated, and why it did terminate. It can be

helpful to detect server saturation, network troubles, local system resource

starvation, attacks, etc…
  The most common termination flags combinations are indicated below. They are

alphabetically sorted, with the lowercase set just after the upper case for

easier finding and understanding.
  Flags   Reason

--   Normal termination.
CC   The client aborted before the connection could be established to the
server. This can happen when haproxy tries to connect to a recently
dead (or unchecked) server, and the client aborts while haproxy is
waiting for the server to respond or for "timeout connect" to expire.
CD   The client unexpectedly aborted during data transfer. This can be
caused by a browser crash, by an intermediate equipment between the
client and haproxy which decided to actively break the connection,
by network routing issues between the client and haproxy, or by a
keep-alive session between the server and the client terminated first
by the client.
cD   The client did not send nor acknowledge any data for as long as the
"timeout client" delay. This is often caused by network failures on
the client side, or the client simply leaving the net uncleanly.
CH   The client aborted while waiting for the server to start responding.
It might be the server taking too long to respond or the client
clicking the 'Stop' button too fast.
cH   The "timeout client" stroke while waiting for client data during a
POST request. This is sometimes caused by too large TCP MSS values
for PPPoE networks which cannot transport full-sized packets. It can
also happen when client timeout is smaller than server timeout and
the server takes too long to respond.
CQ   The client aborted while its session was queued, waiting for a server
with enough empty slots to accept it. It might be that either all the
servers were saturated or that the assigned server was taking too
long a time to respond.
CR   The client aborted before sending a full HTTP request. Most likely
the request was typed by hand using a telnet client, and aborted
too early. The HTTP status code is likely a 400 here. Sometimes this
might also be caused by an IDS killing the connection between haproxy
and the client.
cR   The "timeout http-request" stroke before the client sent a full HTTP
request. This is sometimes caused by too large TCP MSS values on the
client side for PPPoE networks which cannot transport full-sized
packets, or by clients sending requests by hand and not typing fast
enough, or forgetting to enter the empty line at the end of the
request. The HTTP status code is likely a 408 here.
CT   The client aborted while its session was tarpitted. It is important to
check if this happens on valid requests, in order to be sure that no
wrong tarpit rules have been written. If a lot of them happen, it
might make sense to lower the "timeout tarpit" value to something
closer to the average reported "Tw" timer, in order not to consume
resources for just a few attackers.
LR   The request was intercepted and locally handled by haproxy. Generally
it means that this was a redirect or a stats request.
SC   The server or an equipment between it and haproxy explicitly refused
the TCP connection (the proxy received a TCP RST or an ICMP message
in return). Under some circumstances, it can also be the network
stack telling the proxy that the server is unreachable (eg: no route,
or no ARP response on local network). When this happens in HTTP mode,
the status code is likely a 502 or 503 here.
sC   The "timeout connect" stroke before a connection to the server could
complete. When this happens in HTTP mode, the status code is likely a
503 or 504 here.
SD   The connection to the server died with an error during the data
transfer. This usually means that haproxy has received an RST from
the server or an ICMP message from an intermediate equipment while
exchanging data with the server. This can be caused by a server crash
or by a network issue on an intermediate equipment.
sD   The server did not send nor acknowledge any data for as long as the
"timeout server" setting during the data phase. This is often caused
by too short timeouts on L4 equipments before the server (firewalls,
load-balancers, ...), as well as keep-alive sessions maintained
between the client and the server expiring first on haproxy.
SH   The server aborted before sending its full HTTP response headers, or
it crashed while processing the request. Since a server aborting at
this moment is very rare, it would be wise to inspect its logs to
control whether it crashed and why. The logged request may indicate a
small set of faulty requests, demonstrating bugs in the application.
Sometimes this might also be caused by an IDS killing the connection
between haproxy and the server.
sH   The "timeout server" stroke before the server could return its
response headers. This is the most common anomaly, indicating too
long transactions, probably caused by server or database saturation.
The immediate workaround consists in increasing the "timeout server"
setting, but it is important to keep in mind that the user experience
will suffer from these long response times. The only long term
solution is to fix the application.
sQ   The session spent too much time in queue and has been expired. See
the "timeout queue" and "timeout connect" settings to find out how to
fix this if it happens too often. If it often happens massively in
short periods, it may indicate general problems on the affected
servers due to I/O or database congestion, or saturation caused by
external attacks.
PC   The proxy refused to establish a connection to the server because the
process' socket limit has been reached while attempting to connect.
The global "maxconn" parameter may be increased in the configuration
so that it does not happen anymore. This status is very rare and
might happen when the global "ulimit-n" parameter is forced by hand.
PD   The proxy blocked an incorrectly formatted chunked encoded message in
a request or a response, after the server has emitted its headers. In
most cases, this will indicate an invalid message from the server to
the client. Haproxy supports chunk sizes of up to 2GB - 1 (2147483647
bytes). Any larger size will be considered as an error.
PH   The proxy blocked the server's response, because it was invalid,
incomplete, dangerous (cache control), or matched a security filter.
In any case, an HTTP 502 error is sent to the client. One possible
cause for this error is an invalid syntax in an HTTP header name
containing unauthorized characters. It is also possible but quite
rare, that the proxy blocked a chunked-encoding request from the
client due to an invalid syntax, before the server responded. In this
case, an HTTP 400 error is sent to the client and reported in the
logs.
PR   The proxy blocked the client's HTTP request, either because of an
invalid HTTP syntax, in which case it returned an HTTP 400 error to
the client, or because a deny filter matched, in which case it
returned an HTTP 403 error.
PT   The proxy blocked the client's request and has tarpitted its
connection before returning it a 500 server error. Nothing was sent
to the server. The connection was maintained open for as long as
reported by the "Tw" timer field.
RC   A local resource has been exhausted (memory, sockets, source ports)
preventing the connection to the server from establishing. The error
logs will tell precisely what was missing. This is very rare and can
only be solved by proper system tuning.

  The combination of the two last flags gives a lot of information about how

persistence was handled by the client, the server and by haproxy. This is very

important to troubleshoot disconnections, when users complain they have to

re-authenticate. The commonly encountered flags are :

--   Persistence cookie is not enabled.
NN   No cookie was provided by the client, none was inserted in the
response. For instance, this can be in insert mode with "postonly"
set on a GET request.
II   A cookie designating an invalid server was provided by the client,
a valid one was inserted in the response. This typically happens when
a "server" entry is removed from the configuration, since its cookie
value can be presented by a client when no other server knows it.
NI   No cookie was provided by the client, one was inserted in the
response. This typically happens for first requests from every user
in "insert" mode, which makes it an easy way to count real users.
VN   A cookie was provided by the client, none was inserted in the
response. This happens for most responses for which the client has
already got a cookie.
VU   A cookie was provided by the client, with a last visit date which is
not completely up-to-date, so an updated cookie was provided in
response. This can also happen if there was no date at all, or if
there was a date but the "maxidle" parameter was not set, so that the
cookie can be switched to unlimited time.
EI   A cookie was provided by the client, with a last visit date which is
too old for the "maxidle" parameter, so the cookie was ignored and a
new cookie was inserted in the response.
OI   A cookie was provided by the client, with a first visit date which is
too old for the "maxlife" parameter, so the cookie was ignored and a
new cookie was inserted in the response.
DI   The server designated by the cookie was down, a new server was
selected and a new cookie was emitted in the response.
VI   The server designated by the cookie was not marked dead but could not
be reached. A redispatch happened and selected another one, which was
then advertised in the response.

  8.6. Non-printable characters

In order not to cause trouble to log analysis tools or terminals during log

consulting, non-printable characters are not sent as-is into log files, but are

converted to the two-digits hexadecimal representation of their ASCII code,

prefixed by the character ‘#’. The only characters that can be logged without

being escaped are comprised between 32 and 126 (inclusive). Obviously, the

escape character ‘#’ itself is also encoded to avoid any ambiguity (“#23”). It

is the same for the character ‘”’ which becomes “#22”, as well as ‘{‘, ‘|’ and

‘}’ when logging headers.
  Note that the space character (’ ‘) is not encoded in headers, which can cause

issues for tools relying on space count to locate fields. A typical header

containing spaces is “User-Agent”.
  Last, it has been observed that some syslog daemons such as syslog-ng escape

the quote (‘”’) with a backslash (‘\’). The reverse operation can safely be

performed since no quote may appear anywhere else in the logs.

8.7. Capturing HTTP cookies

Cookie capture simplifies the tracking a complete user session. This can be

achieved using the “capture cookie” statement in the frontend. Please refer to

section 4.2 for more details. Only one cookie can be captured, and the same

cookie will simultaneously be checked in the request (“Cookie:” header) and in

the response (“Set-Cookie:” header). The respective values will be reported in

the HTTP logs at the “captured_request_cookie” and “captured_response_cookie”

locations (see section 8.2.3 about HTTP log format). When either cookie is

not seen, a dash (‘-‘) replaces the value. This way, it’s easy to detect when a

user switches to a new session for example, because the server will reassign it

a new cookie. It is also possible to detect if a server unexpectedly sets a

wrong cookie to a client, leading to session crossing.

Examples :
capture the first cookie whose name starts with “ASPSESSION”
  capture cookie ASPSESSION len 32
capture the first cookie whose name is exactly “vgnvisitor”
  capture cookie vgnvisitor= len 32

8.8. Capturing HTTP headers

Header captures are useful to track unique request identifiers set by an upper

proxy, virtual host names, user-agents, POST content-length, referrers, etc. In

the response, one can search for information about the response length, how the

server asked the cache to behave, or an object location during a redirection.
  Header captures are performed using the “capture request header” and “capture

response header” statements in the frontend. Please consult their definition in

section 4.2 for more details.
  It is possible to include both request headers and response headers at the same

time. Non-existent headers are logged as empty strings, and if one header

appears more than once, only its last occurrence will be logged. Request headers

are grouped within braces ‘{’ and ‘}’ in the same order as they were declared,

and delimited with a vertical bar ‘|’ without any space. Response headers

follow the same representation, but are displayed after a space following the

request headers block. These blocks are displayed just before the HTTP request

in the logs.

Example :
# This instance chains to the outgoing proxy
listen proxy-out
mode http
option httplog
option logasap
log global
server cache1 192.168.1.1:3128

    # log the name of the virtual server
capture request  header Host len 20
# log the amount of data uploaded during a POST
capture request  header Content-Length len 10
# log the beginning of the referrer
capture request  header Referer len 20
# server name (useful for outgoing proxies only)
capture response header Server len 20
# logging the content-length is useful with "option logasap"
capture response header Content-Length len 10
# log the expected cache behaviour on the response
capture response header Cache-Control len 8
# the Via header will report the next proxy's name
capture response header Via len 20
# log the URL location during a redirection
capture response header Location len 20

  Aug  9 20:26:09 localhost \
haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \
proxy-out/cache1 0/0/0/162/+162 200 +350 - - —- 0/0/0/0/0 0/0 \
{fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \
“GET http://fr.adserver.yahoo.com/”
  Aug  9 20:30:46 localhost \
haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \
proxy-out/cache1 0/0/0/182/+182 200 +279 - - —- 0/0/0/0/0 0/0 \
{w.ods.org||} {Formilux/0.1.8|3495|||} \
“GET http://trafic.1wt.eu/ HTTP/1.1”
  Aug  9 20:30:46 localhost \
haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \
proxy-out/cache1 0/0/2/126/+128 301 +223 - - —- 0/0/0/0/0 0/0 \
{www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \
{Apache|230|||http://www.sytadin.} \
“GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1”
8.9. Examples of logs
These are real-world examples of logs accompanied with an explanation. Some of
them have been made up by hand. The syslog part has been removed for better
reading. Their sole purpose is to explain how to decipher them.


>>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \
px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \
"HEAD / HTTP/1.0"
=> long request (6.5s) entered by hand through 'telnet'. The server replied
in 147 ms, and the session ended normally ('----')
>>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \
px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \
0/9 "HEAD / HTTP/1.0"
=> Idem, but the request was queued in the global queue behind 9 other
requests, and waited there for 1230 ms.
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \
px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \
"GET /image.iso HTTP/1.0"
=> request for a long data transfer. The "logasap" option was specified, so
the log was produced just before transferring data. The server replied in
14 ms, 243 bytes of headers were sent to the client, and total time from
accept to first data byte is 30 ms.
>>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \
px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \
"GET /cgi-bin/bug.cgi? HTTP/1.0"
=> the proxy blocked a server response either because of an "rspdeny" or
"rspideny" filter, or because the response was improperly formatted and
not HTTP-compliant, or because it blocked sensitive information which
risked being cached. In this case, the response is replaced with a "502
bad gateway". The flags ("PH--") tell us that it was haproxy who decided
to return the 502 and not the server.
>>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \
px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 ""
=> the client never completed its request and aborted itself ("C---") after
8.5s, while the proxy was waiting for the request headers ("-R--").
Nothing was sent to any server.
>>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \
px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 ""
=> The client never completed its request, which was aborted by the
time-out ("c---") after 50s, while the proxy was waiting for the request
headers ("-R--").  Nothing was sent to any server, but the proxy could
send a 408 return code to the client.
>>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \
px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0
=> This log was produced with "option tcplog". The client timed out after
5 seconds ("c----").
>>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \
px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \
0/0 "HEAD / HTTP/1.0"
=> The request took 3s to complete (probably a network problem), and the
connection to the server failed ('SC--') after 4 attempts of 2 seconds
(config says 'retries 3'), and no redispatch (otherwise we would have
seen "/+3"). Status code 503 was returned to the client. There were 115
connections on this server, 202 connections on this proxy, and 205 on
the global process. It is possible that the server refused the
connection because of too many already established.

  9. Statistics and monitoring

It is possible to query HAProxy about its status. The most commonly used

mechanism is the HTTP statistics page. This page also exposes an alternative

CSV output format for monitoring tools. The same format is provided on the

Unix socket.

9.1. CSV format

The statistics may be consulted either from the unix socket or from the HTTP

page. Both means provide a CSV format whose fields follow.

  • pxname: proxy name
  • svname: service name (FRONTEND for frontend, BACKEND for backend, any name

    for server)
  • qcur: current queued requests
  • qmax: max queued requests
  • scur: current sessions
  • smax: max sessions
  • slim: sessions limit
  • stot: total sessions
  • bin: bytes in
  •   bout: bytes out

    • dreq: denied requests
    • dresp: denied responses
    • ereq: request errors
    • econ: connection errors
    • eresp: response errors (among which srv_abrt)
    • wretr: retries (warning)
    • wredis: redispatches (warning)
    • status: status (UP/DOWN/NOLB/MAINT/MAINT(via)…)
    • weight: server weight (server), total weight (backend)
    • act: server is active (server), number of active servers (backend)
    • bck: server is backup (server), number of backup servers (backend)
    • chkfail: number of failed checks
    • chkdown: number of UP->DOWN transitions
    • lastchg: last status change (in seconds)
    • downtime: total downtime (in seconds)
    • qlimit: queue limit
    • pid: process id (0 for first instance, 1 for second, …)
    • iid: unique proxy id
    • sid: service id (unique inside a proxy)
    • throttle: warm up status
    • lbtot: total number of times a server was selected
    • tracked: id of proxy/server if tracking is enabled
    • type (0=frontend, 1=backend, 2=server, 3=socket)
    • rate: number of sessions per second over last elapsed second
    • rate_lim: limit on new sessions per second
    • rate_max: max number of new sessions per second
    • check_status: status of last health check, one of:

      UNK     -> unknown

      INI     -> initializing

      SOCKERR -> socket error

      L4OK    -> check passed on layer 4, no upper layers testing enabled

      L4TMOUT -> layer 1-4 timeout

      L4CON   -> layer 1-4 connection problem, for example
      “Connection refused” (tcp rst) or “No route to host” (icmp)

      L6OK    -> check passed on layer 6

      L6TOUT  -> layer 6 (SSL) timeout

      L6RSP   -> layer 6 invalid response - protocol error

      L7OK    -> check passed on layer 7

      L7OKC   -> check conditionally passed on layer 7, for example 404 with
      disable-on-404

      L7TOUT  -> layer 7 (HTTP/SMTP) timeout

      L7RSP   -> layer 7 invalid response - protocol error

      L7STS   -> layer 7 response error, for example HTTP 5xx
    • check_code: layer5-7 code, if available
    • check_duration: time in ms took to finish last health check
    • hrsp_1xx: http responses with 1xx code
    • hrsp_2xx: http responses with 2xx code
    • hrsp_3xx: http responses with 3xx code
    • hrsp_4xx: http responses with 4xx code
    • hrsp_5xx: http responses with 5xx code
    • hrsp_other: http responses with other codes (protocol error)
    • hanafail: failed health checks details
    • req_rate: HTTP requests per second over last elapsed second
    • req_rate_max: max number of HTTP requests per second observed
    • req_tot: total number of HTTP requests received
    • cli_abrt: number of data transfers aborted by the client
    • srv_abrt: number of data transfers aborted by the server (inc. in eresp)
    • comp_in: number of HTTP response bytes fed to the compressor
    • comp_out: number of HTTP response bytes emitted by the compressor
    • comp_byp: number of bytes that bypassed the HTTP compressor (CPU/BW limit)
    • comp_rsp: number of HTTP responses that were compressed
    • lastsess: number of seconds since last session assigned to server/backend

      9.2. Unix Socket commands

      The stats socket is not enabled by default. In order to enable it, it is

      necessary to add one line in the global section of the haproxy configuration.

      A second line is recommended to set a larger timeout, always appreciated when

      issuing commands by hand :
      global
    stats socket /var/run/haproxy.sock mode 600 level admin
    stats timeout 2m

  It is also possible to add multiple instances of the stats socket by repeating

the line, and make them listen to a TCP port instead of a UNIX socket. This is

never done by default because this is dangerous, but can be handy in some

situations :

global
stats socket /var/run/haproxy.sock mode 600 level admin
stats socket ipv4@192.168.0.1:9999 level admin
stats timeout 2m

  To access the socket, an external utility such as “socat” is required. Socat is a

swiss-army knife to connect anything to anything. We use it to connect terminals

to the socket, or a couple of stdin/stdout pipes to it for scripts. The two main

syntaxes we’ll use are the following :

# socat /var/run/haproxy.sock stdio
# socat /var/run/haproxy.sock readline

  The first one is used with scripts. It is possible to send the output of a

script to haproxy, and pass haproxy’s output to another script. That’s useful

for retrieving counters or attack traces for example.
  The second one is only useful for issuing commands by hand. It has the benefit

that the terminal is handled by the readline library which supports line

editing and history, which is very convenient when issuing repeated commands

(eg: watch a counter).
  The socket supports two operation modes :
- interactive
- non-interactive
  The non-interactive mode is the default when socat connects to the socket. In

this mode, a single line may be sent. It is processed as a whole, responses are

sent back, and the connection closes after the end of the response. This is the

mode that scripts and monitoring tools use. It is possible to send multiple

commands in this mode, they need to be delimited by a semi-colon (‘;’). For

example :

# echo "show info;show stat;show table" | socat /var/run/haproxy stdio

  The interactive mode displays a prompt (‘>’) and waits for commands to be

entered on the line, then processes them, and displays the prompt again to wait

for a new command. This mode is entered via the “prompt” command which must be

sent on the first line in non-interactive mode. The mode is a flip switch, if

“prompt” is sent in interactive mode, it is disabled and the connection closes

after processing the last command of the same line.
  For this reason, when debugging by hand, it’s quite common to start with the

“prompt” command :
  # socat /var/run/haproxy readline
prompt
  show info


  Since multiple commands may be issued at once, haproxy uses the empty line as a

delimiter to mark an end of output for each command, and takes care of ensuring

that no command can emit an empty line on output. A script can thus easily

parse the output even when multiple commands were pipelined on a single line.
  It is important to understand that when multiple haproxy processes are started

on the same sockets, any process may pick up the request and will output its

own stats.
  The list of commands currently supported on the stats socket is provided below.

If an unknown command is sent, haproxy displays the usage message which reminds

all supported commands. Some commands support a more complex syntax, generally

it will explain what part of the command is invalid when this happens.

add acl   

Add an entry into the acl .  is the # or the  returned by

“show acl”. This command does not verify if the entry already exists. This

command cannot be used if the reference  is a file also used with a map.

In this case, you must use the command “add map” in place of “add acl”.

add map   

Add an entry into the map  to associate the value  to the key

. This command does not verify if the entry already exists. It is

mainly used to fill a map after a clear operation. Note that if the reference

is a file and is shared with a map, this map will contain also a new

pattern entry.

clear counters

Clear the max values of the statistics counters in each proxy (frontend &

backend) and in each server. The cumulated counters are not affected. This

can be used to get clean counters after an incident, without having to

restart nor to clear traffic counters. This command is restricted and can

only be issued on sockets configured for levels “operator” or “admin”.

clear counters all

Clear all statistics counters in each proxy (frontend & backend) and in each

server. This has the same effect as restarting. This command is restricted

and can only be issued on sockets configured for level “admin”.

clear acl  

Remove all entries from the acl .  is the # or the  

returned by “show acl”. Note that if the reference  is a file and is

shared with a map, this map will be also cleared.

clear map  

Remove all entries from the map .  is the # or the  

returned by “show map”. Note that if the reference  is a file and is

shared with a acl, this acl will be also cleared.

clear table
[ data.   ] | [ key  ]

Remove entries from the stick-table .  
  This is typically used to unblock some users complaining they have been

abusively denied access to a service, but this can also be used to clear some

stickiness entries matching a server that is going to be replaced (see “show

table” below for details).  Note that sometimes, removal of an entry will be

refused because it is currently tracked by a session. Retrying a few seconds

later after the session ends is usual enough.
  In the case where no options arguments are given all entries will be removed.
  When the “data.” form is used entries matching a filter applied using the

stored data (see “stick-table” in section 4.2) are removed.  A stored data

type must be specified in , and this data type must be stored in the

table otherwise an error is reported. The data is compared according to
with the 64-bit integer .  Operators are the same as with

the ACLs :

  • eq : match entries whose data is equal to this value
  • ne : match entries whose data is not equal to this value
  • le : match entries whose data is less than or equal to this value
  • ge : match entries whose data is greater than or equal to this value
  • lt : match entries whose data is less than this value
  • gt : match entries whose data is greater than this value
  When the key form is used the entry  is removed.  The key must be of the

same type as the table, which currently is limited to IPv4, IPv6, integer and

string.

Example :
$ echo “show table http_proxy” | socat stdio /tmp/sock1
table: http_proxy, type: ip, size:204800, used:2
  0x80e6a4c: key=127.0.0.1 use=0 exp=3594729 gpc0=0 conn_rate(30000)=1 \
bytes_out_rate(60000)=187
0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191


$ echo "clear table http_proxy key 127.0.0.1" | socat stdio /tmp/sock1
$ echo "show table http_proxy" | socat stdio /tmp/sock1

table: http_proxy, type: ip, size:204800, used:1
  0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191
[size=123%]echocleartablehttp[size=70.7%]proxydata.gpc0eq1|socatstdio/tmp/sock1 echo “show table http_proxy” | socat stdio /tmp/sock1
table: http_proxy, type: ip, size:204800, used:1
  del acl  [|#]
Delete all the acl entries from the acl  corresponding to the key .
is the # or the  returned by “show acl”. If the  is used,
this command delete only the listed reference. The reference can be found with
listing the content of the acl. Note that if the reference  is a file and
is shared with a map, the entry will be also deleted in the map.
del map  [|#]
Delete all the map entries from the map  corresponding to the key .
is the # or the  returned by “show map”. If the  is used,
this command delete only the listed reference. The reference can be found with
listing the content of the map. Note that if the reference  is a file and
is shared with a acl, the entry will be also deleted in the map.
disable agent /
Mark the auxiliary agent check as temporarily stopped.

  In the case where an agent check is being run as a auxiliary check, due

to the agent-check parameter of a server directive, new checks are only

initialised when the agent is in the enabled. Thus, disable agent will

prevent any new agent checks from begin initiated until the agent

re-enabled using enable agent.
  When an agent is disabled the processing of an auxiliary agent check that

was initiated while the agent was set as enabled is as follows: All

results that would alter the weight, specifically “drain” or a weight

returned by the agent, are ignored. The processing of agent check is

otherwise unchanged.
  The motivation for this feature is to allow the weight changing effects

of the agent checks to be paused to allow the weight of a server to be

configured using set weight without being overridden by the agent.
  This command is restricted and can only be issued on sockets configured for

level “admin”.

disable frontend  

Mark the frontend as temporarily stopped. This corresponds to the mode which

is used during a soft restart : the frontend releases the port but can be

enabled again if needed. This should be used with care as some non-Linux OSes

are unable to enable it back. This is intended to be used in environments

where stopping a proxy is not even imaginable but a misconfigured proxy must

be fixed. That way it’s possible to release the port and bind it into another

process to restore operations. The frontend will appear with status “STOP”

on the stats page.
  The frontend may be specified either by its name or by its numeric ID,

prefixed with a sharp (‘#’).
  This command is restricted and can only be issued on sockets configured for

level “admin”.

disable server /

Mark the server DOWN for maintenance. In this mode, no more checks will be

performed on the server until it leaves maintenance.

If the server is tracked by other servers, those servers will be set to DOWN

during the maintenance.
  In the statistics page, a server DOWN for maintenance will appear with a

“MAINT” status, its tracking servers with the “MAINT(via)” one.
  Both the backend and the server may be specified either by their name or by

their numeric ID, prefixed with a sharp (‘#’).
  This command is restricted and can only be issued on sockets configured for

level “admin”.

enable agent /

Resume auxiliary agent check that was temporarily stopped.
  See “disable agent” for details of the effect of temporarily starting

and stopping an auxiliary agent.
  This command is restricted and can only be issued on sockets configured for

level “admin”.

enable frontend  

Resume a frontend which was temporarily stopped. It is possible that some of

the listening ports won’t be able to bind anymore (eg: if another process

took them since the ‘disable frontend’ operation). If this happens, an error

is displayed. Some operating systems might not be able to resume a frontend

which was disabled.
  The frontend may be specified either by its name or by its numeric ID,

prefixed with a sharp (‘#’).
  This command is restricted and can only be issued on sockets configured for

level “admin”.

enable server /

If the server was previously marked as DOWN for maintenance, this marks the

server UP and checks are re-enabled.
  Both the backend and the server may be specified either by their name or by

their numeric ID, prefixed with a sharp (‘#’).
  This command is restricted and can only be issued on sockets configured for

level “admin”.

get map   

get acl   

Lookup the value  in the map  or in the ACL .  or  

are the # or the  returned by “show map” or “show acl”. This command

returns all the matching patterns associated with this map. This is useful for

debugging maps and ACLs. The output format is composed by one line par

matching type. Each line is composed by space-delimited series of words.
  The first two words are:
  :   The match method applied. It can be “found”, “bool”,
“int”, “ip”, “bin”, “len”, “str”, “beg”, “sub”, “dir”,
“dom”, “end” or “reg”.
  :   The result. Can be “match” or “no-match”.
  The following words are returned only if the pattern matches an entry.
  :     “tree” or “list”. The internal lookup algorithm.
  :           “case-insensitive” or “case-sensitive”. The
interpretation of the case.
  :  match=””. Return the matched pattern. It is
useful with regular expressions.
  The two last word are used to show the returned value and its type. With the

“acl” case, the pattern doesn’t exist.
  return=nothing:        No return because there are no “map”.
return=””:      The value returned in the string format.
return=cannot-display: The value cannot be converted as string.
  type=””:         The type of the returned sample.

get weight /

Report the current weight and the initial weight of server  in

backend  or an error if either doesn’t exist. The initial weight is

the one that appears in the configuration file. Both are normally equal

unless the current weight has been changed. Both the backend and the server

may be specified either by their name or by their numeric ID, prefixed with a

sharp (‘#’).

help

Print the list of known keywords and their basic usage. The same help screen

is also displayed for unknown commands.

prompt

Toggle the prompt at the beginning of the line and enter or leave interactive

mode. In interactive mode, the connection is not closed after a command

completes. Instead, the prompt will appear again, indicating the user that

the interpreter is waiting for a new command. The prompt consists in a right

angle bracket followed by a space “> “. This mode is particularly convenient

when one wants to periodically check information such as stats or errors.

It is also a good idea to enter interactive mode before issuing a “help”

command.

quit

Close the connection when in interactive mode.

set map  [|#]  

Modify the value corresponding to each key  in a map .  is the
or  returned by “show map”. If the  is used in place of
  , only the entry pointed by  is changed. The new value is .

set maxconn frontend   

Dynamically change the specified frontend’s maxconn setting. Any positive

value is allowed including zero, but setting values larger than the global

maxconn does not make much sense. If the limit is increased and connections

were pending, they will immediately be accepted. If it is lowered to a value

below the current number of connections, new connections acceptation will be

delayed until the threshold is reached. The frontend might be specified by

either its name or its numeric ID prefixed with a sharp (‘#’).

set maxconn global  

Dynamically change the global maxconn setting within the range defined by the

initial global maxconn setting. If it is increased and connections were

pending, they will immediately be accepted. If it is lowered to a value below

the current number of connections, new connections acceptation will be

delayed until the threshold is reached. A value of zero restores the initial

setting.

set rate-limit connections global  

Change the process-wide connection rate limit, which is set by the global

‘maxconnrate’ setting. A value of zero disables the limitation. This limit

applies to all frontends and the change has an immediate effect. The value

is passed in number of connections per second.

set rate-limit http-compression global  

Change the maximum input compression rate, which is set by the global

‘maxcomprate’ setting. A value of zero disables the limitation. The value is

passed in number of kilobytes per second. The value is available in the “show

info” on the line “CompressBpsRateLim” in bytes.

set rate-limit sessions global  

Change the process-wide session rate limit, which is set by the global

‘maxsessrate’ setting. A value of zero disables the limitation. This limit

applies to all frontends and the change has an immediate effect. The value

is passed in number of sessions per second.

set rate-limit ssl-sessions global  

Change the process-wide SSL session rate limit, which is set by the global

‘maxsslrate’ setting. A value of zero disables the limitation. This limit

applies to all frontends and the change has an immediate effect. The value

is passed in number of sessions per second sent to the SSL stack. It applies

before the handshake in order to protect the stack against handshake abuses.

set table
key  [data. ]*

Create or update a stick-table entry in the table. If the key is not present,

an entry is inserted. See stick-table in section 4.2 to find all possible

values for . The most likely use consists in dynamically entering

entries for source IP addresses, with a flag in gpc0 to dynamically block an

IP address or affect its quality of service. It is possible to pass multiple

data_types in a single call.

set timeout cli  

Change the CLI interface timeout for current connection. This can be useful

during long debugging sessions where the user needs to constantly inspect

some indicators without being disconnected. The delay is passed in seconds.

set weight / [%]

Change a server’s weight to the value passed in argument. If the value ends

with the ‘%’ sign, then the new weight will be relative to the initially

configured weight.  Absolute weights are permitted between 0 and 256.

Relative weights must be positive with the resulting absolute weight is

capped at 256.  Servers which are part of a farm running a static

load-balancing algorithm have stricter limitations because the weight

cannot change once set. Thus for these servers, the only accepted values

are 0 and 100% (or 0 and the initial weight). Changes take effect

immediately, though certain LB algorithms require a certain amount of

requests to consider changes. A typical usage of this command is to

disable a server during an update by setting its weight to zero, then to

enable it again after the update by setting it back to 100%. This command

is restricted and can only be issued on sockets configured for level

“admin”. Both the backend and the server may be specified either by their

name or by their numeric ID, prefixed with a sharp (‘#’).

show errors []

Dump last known request and response errors collected by frontends and

backends. If  is specified, the limit the dump to errors concerning

either frontend or backend whose ID is . This command is restricted

and can only be issued on sockets configured for levels “operator” or

“admin”.  
  The errors which may be collected are the last request and response errors

caused by protocol violations, often due to invalid characters in header

names. The report precisely indicates what exact character violated the

protocol. Other important information such as the exact date the error was

detected, frontend and backend names, the server name (when known), the

internal session ID and the source address which has initiated the session

are reported too.
  All characters are returned, and non-printable characters are encoded. The

most common ones (\t = 9, \n = 10, \r = 13 and \e = 27) are encoded as one

letter following a backslash. The backslash itself is encoded as ‘\’ to

avoid confusion. Other non-printable characters are encoded ‘\xNN’ where

NN is the two-digits hexadecimal representation of the character’s ASCII

code.
  Lines are prefixed with the position of their first character, starting at 0

for the beginning of the buffer. At most one input line is printed per line,

and large lines will be broken into multiple consecutive output lines so that

the output never goes beyond 79 characters wide. It is easy to detect if a

line was broken, because it will not end with ‘\n’ and the next line’s offset

will be followed by a ‘+’ sign, indicating it is a continuation of previous

line.

Example :
$ echo “show errors” | socat stdio /tmp/sock1
  [04/Mar/2009:15:46:56.081] backend http-in (#2) : invalid response
src 127.0.0.1, session #54, frontend fe-eth0 (#1), server s2 (#1)
response length 213 bytes, error at position 23:


  00000  HTTP/1.0 200 OK\r\n
00017  header/bizarre:blah\r\n
00038  Location: blah\r\n
00054  Long-line: this is a very long line which should b
00104+ e broken into multiple lines on the output buffer,
00154+  otherwise it would be too large to print in a ter
00204+ minal\r\n
00211  \r\n

  In the example above, we see that the backend “http-in” which has internal

ID 2 has blocked an invalid response from its server s2 which has internal

ID 1. The request was on session 54 initiated by source 127.0.0.1 and

received by frontend fe-eth0 whose ID is 1. The total response length was

213 bytes when the error was detected, and the error was at byte 23. This

is the slash (‘/’) in header name “header/bizarre”, which is not a valid

HTTP character for a header name.

show info

Dump info about haproxy status on current process.

show map []

Dump info about map converters. Without argument, the list of all available

maps is returned. If a  is specified, its contents are dumped.  is

the # or . The first column is a unique identifier. It can be used

as reference for the operation “del map” and “set map”. The second column is

the pattern and the third column is the sample if available. The data returned

are not directly a list of available maps, but are the list of all patterns

composing any map. Many of these patterns can be shared with ACL.

show acl []

Dump info about acl converters. Without argument, the list of all available

acls is returned. If a  is specified, its contents are dumped.  if

the # or . The dump format is the same than the map even for the

sample value. The data returned are not a list of available ACL, but are the

list of all patterns composing any ACL. Many of these patterns can be shared

with maps.

show pools

Dump the status of internal memory pools. This is useful to track memory

usage when suspecting a memory leak for example. It does exactly the same

as the SIGQUIT when running in foreground except that it does not flush

the pools.

show sess

Dump all known sessions. Avoid doing this on slow connections as this can

be huge. This command is restricted and can only be issued on sockets

configured for levels “operator” or “admin”.

show sess  

Display a lot of internal information about the specified session identifier.

This identifier is the first field at the beginning of the lines in the dumps

of “show sess” (it corresponds to the session pointer). Those information are

useless to most users but may be used by haproxy developers to troubleshoot a

complex bug. The output format is intentionally not documented so that it can

freely evolve depending on demands. The special id “all” dumps the states of

all sessions, which can be avoided as much as possible as it is highly CPU

intensive and can take a lot of time.

show stat [  ]

Dump statistics in the CSV format. By passing ,  and , it is

possible to dump only selected items :
-  is a proxy ID, -1 to dump everything
-  selects the type of dumpable objects : 1 for frontends, 2 for
backends, 4 for servers, -1 for everything. These values can be ORed,
for example:
1 + 2     = 3   -> frontend + backend.
1 + 2 + 4 = 7   -> frontend + backend + server.
-  is a server ID, -1 to dump everything from the selected proxy.

Example :
$ echo “show info;show stat” | socat stdio unix-connect:/tmp/sock1
  Name: HAProxy
Version: 1.4-dev2-49
Release_date: 2009/09/23
Nbproc: 1
Process_num: 1
(…)


# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,  (...)
stats,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0, (...)
stats,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,250,(...)
(...)
www1,BACKEND,0,0,0,0,1000,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,250, (...)
$

  Here, two commands have been issued at once. That way it’s easy to find

which process the stats apply to in multi-process mode. Notice the empty

line after the information output which marks the end of the first block.

A similar empty line appears at the end of the second block (stats) so that

the reader knows the output has not been truncated.

show table

Dump general information on all known stick-tables. Their name is returned

(the name of the proxy which holds them), their type (currently zero, always

IP), their size in maximum possible number of entries, and the number of

entries currently in use.

Example :
$ echo “show table” | socat stdio /tmp/sock1
table: front_pub, type: ip, size:204800, used:171454
table: back_rdp, type: ip, size:204800, used:0
  show table  [ data.   ] | [ key  ]
Dump contents of stick-table . In this mode, a first line of generic
information about the table is reported as with “show table”, then all
entries are dumped. Since this can be quite heavy, it is possible to specify
a filter in order to specify what entries to display.

  When the “data.” form is used the filter applies to the stored data (see

“stick-table” in section 4.2).  A stored data type must be specified

in , and this data type must be stored in the table otherwise an

error is reported. The data is compared according to  with the

64-bit integer .  Operators are the same as with the ACLs :

  • eq : match entries whose data is equal to this value
  • ne : match entries whose data is not equal to this value
  • le : match entries whose data is less than or equal to this value
  • ge : match entries whose data is greater than or equal to this value
  • lt : match entries whose data is less than this value
  • gt : match entries whose data is greater than this value
  When the key form is used the entry  is shown.  The key must be of the

same type as the table, which currently is limited to IPv4, IPv6, integer,

and string.

Example :
$ echo “show table http_proxy” | socat stdio /tmp/sock1
table: http_proxy, type: ip, size:204800, used:2
  0x80e6a4c: key=127.0.0.1 use=0 exp=3594729 gpc0=0 conn_rate(30000)=1  \
bytes_out_rate(60000)=187
0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191


$ echo "show table http_proxy data.gpc0 gt 0" | socat stdio /tmp/sock1

table: http_proxy, type: ip, size:204800, used:2
  0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191


$ echo "show table http_proxy data.conn_rate gt 5" | \
socat stdio /tmp/sock1

table: http_proxy, type: ip, size:204800, used:2
  0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191


$ echo "show table http_proxy key 127.0.0.2" | \
socat stdio /tmp/sock1

table: http_proxy, type: ip, size:204800, used:2
  0x80e6a80: key=127.0.0.2 use=0 exp=3594740 gpc0=1 conn_rate(30000)=10 \
bytes_out_rate(60000)=191
When the data criterion applies to a dynamic value dependent on time such as
a bytes rate, the value is dynamically computed during the evaluation of the
entry in order to decide whether it has to be dumped or not. This means that
such a filter could match for some time then not match anymore because as
time goes, the average event rate drops.

  It is possible to use this to extract lists of IP addresses abusing the

service, in order to monitor them or even blacklist them in a firewall.

Example :

echo “show table http_proxy data.gpc0 gt 0” \  
  | socat stdio /tmp/sock1 \  
  | fgrep ‘key=’ | cut -d’ ’ -f2 | cut -d= -f2 > abusers-ip.txt  
  ( or | awk ‘/key/{ print a[split(2,a,”=”)]; }’ )

shutdown frontend  

Completely delete the specified frontend. All the ports it was bound to will

be released. It will not be possible to enable the frontend anymore after

this operation. This is intended to be used in environments where stopping a

proxy is not even imaginable but a misconfigured proxy must be fixed. That

way it’s possible to release the port and bind it into another process to

restore operations. The frontend will not appear at all on the stats page

once it is terminated.
  The frontend may be specified either by its name or by its numeric ID,

prefixed with a sharp (‘#’).
  This command is restricted and can only be issued on sockets configured for

level “admin”.

shutdown session  

Immediately terminate the session matching the specified session identifier.

This identifier is the first field at the beginning of the lines in the dumps

of “show sess” (it corresponds to the session pointer). This can be used to

terminate a long-running session without waiting for a timeout or when an

endless transfer is ongoing. Such terminated sessions are reported with a ‘K’

flag in the logs.

shutdown sessions /

Immediately terminate all the sessions attached to the specified server. This

can be used to terminate long-running sessions after a server is put into

maintenance mode, for instance. Such terminated sessions are reported with a

‘K’ flag in the logs.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-141397-1-1.html 上篇帖子: 负载均衡(haproxy+keepalive) 下篇帖子: lvs+haproxy的一种方式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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