haproxy 官方文档
HAProxy Configuration Manualversion 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 响应,连接关闭。
一个新的请求会调用新的连接:
… … …
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
… … …
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,但客户端不等待第一个响应来发送第一个请求。
这对于获取大量的图片组成的页。
… …
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 可以发出以下状态代码本身:
CodeWhen / reason
200access to stats page, and when replying to monitoring requests
301when performing a redirection, depending on the configured code
302when performing a redirection, depending on the configured code
303when performing a redirection, depending on the configured code
307when performing a redirection, depending on the configured code
308when performing a redirection, depending on the configured code
400for an invalid or too large request
401when an authentication is required to perform the action (when
accessing the stats page)
403when a request is forbidden by a “block” ACL or “reqdeny” filter
408when the request timeout strikes before the request is complete
500when haproxy encounters an unrecoverable internal error, such as a
memory allocation failure, which should never happen
502when the server returns an empty, invalid or incomplete response, or
when an “rspdeny” filter blocks the response.
503when no server was available to handle the request, or in response to
monitoring requests which match the “monitor fail” condition
504when 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 toand 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 thatis 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 namefrom /etc/group.
See also “gid” and “user”.
log
]
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 auth2ftp ntp auditalertcron2
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。
emergalertcrit err warning notice infodebug
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
Createsprocesses 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
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 [|]
Binds a UNIX socket toor 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 listenbackend
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 listenbackend
yes
yes no
noyes
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.
consistentthe 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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 referencingwill 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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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
Feb6 12:14:14 localhost \
haproxy: 10.0.1.2:33317 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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes yes
yes yes
yes no
no
Arguments :
Theparameter 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[{if | unless} ]
redirect prefix [{if | unless} ]
redirect scheme [{if | unless} ]
Return an HTTP redirection if/unless a condition is matched
May be used in sections :
defaults frontend listenbackend
no
noyes
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 inis 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 ofand the complete URI path, including the
query string, unless the “drop-query” option is specified (see
below). As a special case, ifequals 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
concatenatingwith “://” 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_port80
acl secure dst_port8080
acl login_page url_beg /login
acl logout url_beg /logout
acl uid_givenurl_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.%% \
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 listenbackend
yes
yes no
noyes
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 listenbackend
no
noyes
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 infollowed 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-ssldst_port 81
reqadd X-Proto:\ SSLif 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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 expressionin 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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 expressionin 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 listenbackend
no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
no
noyes
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 infollowed 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 listenbackend
no
noyes
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 expressionin 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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 expressionin 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
[:]
Declare a server in a backend
May be used in sections :
defaults frontend listenbackend
no
nono
noyes
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 authadmin:AdMiN123
stats admin if TRUE
Example :
statistics admin level depends on the authenticated user
userlist stats-auth
group admin users admin
useradmin insecure-password AdMiN123
group readonly users haproxy
userhaproxyinsecure-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 listenbackend
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 listenbackend
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 listenbackend
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 }
[ { if | unless }]
Access control for statistics
May be used in sections :
defaults frontend listenbackend
no
nono
noyes
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
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 listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 | binary }
size
*
Configure the stickiness table for the current section
May be used in sections :
defaults frontend listenbackend
no
noyes
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
tocharacters. If the string provided by the pattern
extractor is larger than , it will be truncated before
being stored. During matching, at mostcharacters 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
ofbytes. 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.
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 parameterwhich 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 parameterwhich 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 parameterwhich 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 parameterwhich 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 parameterwhich 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 parameterwhich 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 listenbackend
no
nono
noyes
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”
statementdescribes 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
Opens a new connection
May be used in sections :
defaults frontend listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 listenbackend
no
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
no
nono
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
yes
yes no
noyes
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 tunnel1h # 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 listenbackend
yes
yes no
noyes
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 listenbackend
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 listenbackend
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 listenbackend
no
noyes
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.
Whenis a simple name, it is resolved at configuration time, and an
error is reported if the specified backend does not exist. Ifis
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-serverif
use-serverunless
Only use a specific server if/unless an ACL-based condition is matched.
May be used in sections :
defaults frontend listenbackend
no
nono
noyes
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
serverdefault 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
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
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]
default-server
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_staticpath_beg /static /images /img /css
acl url_staticpath_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 failif 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 delimitedwill be considered. The
argumentsyntax 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 frenchif fr
use_backend english if en
default_backend choose_your_language
map([,])
map_([,])
map__([,])
Search the input value fromusing thematching method,
and return the associated value converted to the type . If the
input value cannot be found in the , the converter returns the
. If theis not set, the converter fails and
acts as if no input value could be fetched. If theis not set, it
defaults to “str”. Likewise, if theis 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 typematch 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
ipipmap_ipmap_ip_intmap_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 %
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\ %
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 ofpossible 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. Ifis 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. Ifis 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. Ifis
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 killsc0_inc_gpc0 gt 5
acl savesc0_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 killsc0_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_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 killsrc_inc_gpc0 gt 5
acl savesrc_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 killsrc_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 nois 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 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 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 nois 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 nois 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 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 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 nois 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 ofbytes and starting at byte
in the request buffer. As a special case, if theargument is zero,
the the whole buffer fromto 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 atfor
bytes, and which starts atif specified or just after the length in
the request buffer. Theparameter 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() : integer
rdp_cookie_cnt() : 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 ofbytes and starting at byte
in the response buffer. As a special case, if theargument is zero,
the the whole buffer fromto 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 atfor
bytes, and which starts atif specified or just after the length in
the response buffer. Theparameter 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 badguyssrc 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 nameon 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 ifis not specified.
req.cook_val([]) : integer
cook_val([]) : integer (deprecated)
This extracts the last occurrence of the cookie nameon 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 nameon 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 headerin 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 ifis
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 headerin 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 headerin an HTTP request,
converts it to an IPv4 or IPv6 address and returns this address. When used
with ACLs, all occurrences are checked, and ifis 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 headerin an HTTP request, and
converts it to an integer value. When used with ACLs, all occurrences are
checked, and ifis 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 nameon 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 ifis 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 nameon 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 headerin an HTTP response, or of
the last header if nois 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 ifis
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 headerin an HTTP response, or of
the last header if nois 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 ifis
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 headerin 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 headerin 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 nameon 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 parameterin 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 parameteras 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 parameterin 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_httpmatch 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_SLASHurl_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 CONNECTmatch 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 OPTIONSmatch HTTP OPTIONS method
METH_POST method POST match HTTP POST method
METH_TRACEmethod TRACE match HTTP TRACE method
RDP_COOKIEreq_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
Feb6 12:12:09 localhost \
haproxy: 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:
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
Feb6 12:12:56 localhost \
haproxy: 10.0.1.2:33313 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:
2 client_ip ‘:’ client_port 10.0.1.2:33313
3 ‘[’ accept_date ‘]’
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
Feb6 12:14:14 localhost \
haproxy: 10.0.1.2:33317 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:
2 client_ip ‘:’ client_port 10.0.1.2:33317
3 ‘[’ accept_date ‘]’
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 :
>>> Dec3 18:27:14 localhost \
haproxy: 127.0.0.1:56059 frt/f1: \
Connection error during SSL handshake
Field Format Extract from the example above
1 process_name ‘[’ pid ‘]:’ haproxy:
2 client_ip ‘:’ client_port 127.0.0.1:56059
3 ‘[’ accept_date ‘]’
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/+TtThe “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 requestheader Host len 20
# log the amount of data uploaded during a POST
capture requestheader Content-Length len 10
# log the beginning of the referrer
capture requestheader 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
Aug9 20:26:09 localhost \
haproxy: 127.0.0.1:34014 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/”
Aug9 20:30:46 localhost \
haproxy: 127.0.0.1:34020 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”
Aug9 20:30:46 localhost \
haproxy: 127.0.0.1:34028 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: 127.0.0.1:33318 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: 127.0.0.1:33319 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: 127.0.0.1:33320 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: 127.0.0.1:33320 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: 127.0.0.1:34548 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: 127.0.0.1:34549 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: 127.0.0.1:34550 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: 10.0.0.1:34552 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 thereturned by
“show acl”. This command does not verify if the entry already exists. This
command cannot be used if the referenceis 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 mapto associate the valueto 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 referenceis 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 referenceis 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 entryis 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
echo“cleartablehttpproxydata.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 aclcorresponding to the key .
is the # or thereturned by “show acl”. If theis used,
this command delete only the listed reference. The reference can be found with
listing the content of the acl. Note that if the referenceis 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 mapcorresponding to the key .
is the # or thereturned by “show map”. If theis used,
this command delete only the listed reference. The reference can be found with
listing the content of the map. Note that if the referenceis 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 valuein the mapor in the ACL .or
are the # or thereturned 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 serverin
backendor 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 keyin a map .is the
orreturned by “show map”. If theis used in place of
, only the entry pointed byis 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*
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. Ifis 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
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:
00000HTTP/1.0 200 OK\r\n
00017header/bizarre:blah\r\n
00038Location: blah\r\n
00054Long-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 ais 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 ais 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 towith 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 entryis 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; }’ )
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]