| ---------------------- |
| HAProxy |
| Configuration Manual |
| ---------------------- |
| version 2.4 |
| 2022/04/29 |
| |
| |
| This document covers the configuration language as implemented in the version |
| specified above. It does not provide any hints, examples, or advice. For such |
| documentation, please refer to the Reference Manual or the Architecture Manual. |
| The summary below is meant to help you find 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 outputs) with 3 |
| closing angle brackets ('>>>') in order to emphasize the difference between |
| inputs and outputs when they may be 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. Quoting and escaping |
| 2.3. Environment variables |
| 2.4. Conditional blocks |
| 2.5. Time format |
| 2.6. Examples |
| |
| 3. Global parameters |
| 3.1. Process management and security |
| 3.2. Performance tuning |
| 3.3. Debugging |
| 3.4. Userlists |
| 3.5. Peers |
| 3.6. Mailers |
| 3.7. Programs |
| 3.8. HTTP-errors |
| 3.9. Rings |
| 3.10. Log forwarding |
| |
| 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 |
| 5.3. Server DNS resolution |
| 5.3.1. Global overview |
| 5.3.2. The resolvers section |
| |
| 6. Cache |
| 6.1. Limitation |
| 6.2. Setup |
| 6.2.1. Cache section |
| 6.2.2. Proxy section |
| |
| 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.3.7. Fetching samples for developers |
| 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. Supported filters |
| 9.1. Trace |
| 9.2. HTTP compression |
| 9.3. Stream Processing Offload Engine (SPOE) |
| 9.4. Cache |
| 9.5. fcgi-app |
| 9.6. OpenTracing |
| |
| 10. FastCGI applications |
| 10.1. Setup |
| 10.1.1. Fcgi-app section |
| 10.1.2. Proxy section |
| 10.1.3. Example |
| 10.2. Default parameters |
| 10.3. Limitations |
| |
| 11. Address formats |
| 11.1. Address family prefixes |
| 11.2. Socket type prefixes |
| 11.3. Protocol prefixes |
| |
| 1. Quick reminder about 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. |
| |
| 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 |
| ------------------------------- |
| |
| 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 through the |
| connection, the server responds, and the connection is closed. A new request |
| will involve a new connection : |
| |
| [CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ... |
| |
| In this mode, called the "HTTP close" mode, there are as many connection |
| establishments as there are HTTP transactions. Since the connection is closed |
| by the server after the response, the client does not need to know the content |
| length. |
| |
| 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 : |
| |
| [CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ... |
| |
| Its advantages are a reduced latency between transactions, and less processing |
| power required on the server side. It is generally better than the close mode, |
| but not always because the clients often limit their concurrent connections to |
| a smaller value. |
| |
| Another 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 : |
| |
| [CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ... |
| |
| This can obviously have a tremendous benefit on performance because the network |
| latency is eliminated between subsequent requests. Many HTTP agents do not |
| correctly support pipelining since there is no way to associate a response with |
| the corresponding request in HTTP. For this reason, it is mandatory for the |
| server to reply in the exact same order as the requests were received. |
| |
| The next improvement is the multiplexed mode, as implemented in HTTP/2. This |
| time, each transaction is assigned a single stream identifier, and all streams |
| are multiplexed over an existing connection. Many requests can be sent in |
| parallel by the client, and responses can arrive in any order since they also |
| carry the stream identifier. |
| |
| 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. When it receives HTTP/2 connections from a client, it |
| processes all the requests in parallel and leaves the connection idling, |
| waiting for new requests, just as if it was a keep-alive HTTP connection. |
| |
| HAProxy supports 4 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 (deprecated). |
| - server close : the server-facing connection is closed after the response. |
| - close : the connection is actively closed after end of response. |
| |
| |
| |
| 1.2. HTTP request |
| ----------------- |
| |
| First, let's consider this HTTP request : |
| |
| 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. |
| |
| The URI itself can have several forms : |
| |
| - A "relative 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. |
| |
| - An "absolute URI", also called a "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. |
| |
| - 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. |
| |
| 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. |
| |
| HTTP/2 doesn't convey a version information with the request, so the version is |
| assumed to be the same as the one of the underlying protocol (i.e. "HTTP/2"). |
| |
| |
| 1.2.2. The request 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. |
| |
| Contrary to a common misconception, header names are not case-sensitive, and |
| their values are not either if they refer to other header names (such as the |
| "Connection:" header). In HTTP/2, header names are always sent in lower case, |
| as can be seen when running in debug mode. Internally, all header names are |
| normalized to lower case so that HTTP/1.x and HTTP/2 use the exact same |
| representation, and they are sent as-is on the other side. This explains why an |
| HTTP/1.x request typed with camel case is delivered in lower case. |
| |
| 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. |
| |
| 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. |
| |
| Important note: |
| As suggested by RFC7231, 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 |
| ------------------ |
| |
| An HTTP response looks very much like an HTTP request. Both are called HTTP |
| messages. Let's consider this HTTP response : |
| |
| 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. |
| |
| |
| 1.3.1. The response line |
| ------------------------ |
| |
| Line 1 is the "response line". It is always composed of 3 fields : |
| |
| - 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 (e.g. 100, 101) |
| - 2xx = OK, content is following (e.g. 200, 206) |
| - 3xx = OK, no content following (e.g. 302, 304) |
| - 4xx = error caused by the client (e.g. 401, 403, 404) |
| - 5xx = error caused by the server (e.g. 500, 502, 503) |
| |
| Please refer to RFC7231 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". |
| |
| HAProxy may emit the following status codes by itself : |
| |
| Code When / reason |
| 200 access to stats page, and when replying to monitoring requests |
| 301 when performing a redirection, depending on the configured code |
| 302 when performing a redirection, depending on the configured code |
| 303 when performing a redirection, depending on the configured code |
| 307 when performing a redirection, depending on the configured code |
| 308 when performing a redirection, depending on the configured code |
| 400 for an invalid or too large request |
| 401 when an authentication is required to perform the action (when |
| accessing the stats page) |
| 403 when a request is forbidden by a "http-request deny" rule |
| 404 when the requested resource could not be found |
| 408 when the request timeout strikes before the request is complete |
| 410 when the requested resource is no longer available and will not |
| be available again |
| 500 when HAProxy encounters an unrecoverable internal error, such as a |
| memory allocation failure, which should never happen |
| 501 when HAProxy is unable to satisfy a client request because of an |
| unsupported feature |
| 502 when the server returns an empty, invalid or incomplete response, or |
| when an "http-response deny" rule blocks the response. |
| 503 when no server was available to handle the request, or in response to |
| monitoring requests which match the "monitor fail" condition |
| 504 when the response timeout strikes before the server responds |
| |
| The error 4xx and 5xx codes above may be customized (see "errorloc" in section |
| 4.2). |
| |
| |
| 1.3.2. The response headers |
| --------------------------- |
| |
| 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. |
| |
| |
| 2. Configuring HAProxy |
| ---------------------- |
| |
| 2.1. Configuration file format |
| ------------------------------ |
| |
| HAProxy's configuration process involves 3 major sources of parameters : |
| |
| - the arguments from the command-line, which always take precedence |
| - the configuration file(s), whose format is described here |
| - the running process's environment, in case some environment variables are |
| explicitly referenced |
| |
| The configuration file follows a fairly simple hierarchical format which obey |
| a few basic rules: |
| |
| 1. a configuration file is an ordered sequence of statements |
| |
| 2. a statement is a single non-empty line before any unprotected "#" (hash) |
| |
| 3. a line is a series of tokens or "words" delimited by unprotected spaces or |
| tab characters |
| |
| 4. the first word or sequence of words of a line is one of the keywords or |
| keyword sequences listed in this document |
| |
| 5. all other words are all arguments of the first one, some being well-known |
| keywords listed in this document, others being values, references to other |
| parts of the configuration, or expressions |
| |
| 6. certain keywords delimit a section inside which only a subset of keywords |
| are supported |
| |
| 7. a section ends at the end of a file or on a special keyword starting a new |
| section |
| |
| This is all that is needed to know to write a simple but reliable configuration |
| generator, but this is not enough to reliably parse any configuration nor to |
| figure how to deal with certain corner cases. |
| |
| First, there are a few consequences of the rules above. Rule 6 and 7 imply that |
| the keywords used to define a new section are valid everywhere and cannot have |
| a different meaning in a specific section. These keywords are always a single |
| word (as opposed to a sequence of words), and traditionally the section that |
| follows them is designated using the same name. For example when speaking about |
| the "global section", it designates the section of configuration that follows |
| the "global" keyword. This usage is used a lot in error messages to help locate |
| the parts that need to be addressed. |
| |
| A number of sections create an internal object or configuration space, which |
| requires to be distinguished from other ones. In this case they will take an |
| extra word which will set the name of this particular section. For some of them |
| the section name is mandatory. For example "frontend foo" will create a new |
| section of type "frontend" named "foo". Usually a name is specific to its |
| section and two sections of different types may use the same name, but this is |
| not recommended as it tends to complexify configuration management. |
| |
| A direct consequence of rule 7 is that when multiple files are read at once, |
| each of them must start with a new section, and the end of each file will end |
| a section. A file cannot contain sub-sections nor end an existing section and |
| start a new one. |
| |
| Rule 1 mentioned that ordering matters. Indeed, some keywords create directives |
| that can be repeated multiple times to create ordered sequences of rules to be |
| applied in a certain order. For example "tcp-request" can be used to alternate |
| "accept" and "reject" rules on varying criteria. As such, a configuration file |
| processor must always preserve a section's ordering when editing a file. The |
| ordering of sections usually does not matter except for the global section |
| which must be placed before other sections, but it may be repeated if needed. |
| In addition, some automatic identifiers may automatically be assigned to some |
| of the created objects (e.g. proxies), and by reordering sections, their |
| identifiers will change. These ones appear in the statistics for example. As |
| such, the configuration below will assign "foo" ID number 1 and "bar" ID number |
| 2, which will be swapped if the two sections are reversed: |
| |
| listen foo |
| bind :80 |
| |
| listen bar |
| bind :81 |
| |
| Another important point is that according to rules 2 and 3 above, empty lines, |
| spaces, tabs, and comments following and unprotected "#" character are not part |
| of the configuration as they are just used as delimiters. This implies that the |
| following configurations are strictly equivalent: |
| |
| global#this is the global section |
| daemon#daemonize |
| frontend foo |
| mode http # or tcp |
| |
| and: |
| |
| global |
| daemon |
| |
| # this is the public web frontend |
| frontend foo |
| mode http |
| |
| The common practice is to align to the left only the keyword that initiates a |
| new section, and indent (i.e. prepend a tab character or a few spaces) all |
| other keywords so that it's instantly visible that they belong to the same |
| section (as done in the second example above). Placing comments before a new |
| section helps the reader decide if it's the desired one. Leaving a blank line |
| at the end of a section also visually helps spotting the end when editing it. |
| |
| Tabs are very convenient for indent but they do not copy-paste well. If spaces |
| are used instead, it is recommended to avoid placing too many (2 to 4) so that |
| editing in field doesn't become a burden with limited editors that do not |
| support automatic indent. |
| |
| In the early days it used to be common to see arguments split at fixed tab |
| positions because most keywords would not take more than two arguments. With |
| modern versions featuring complex expressions this practice does not stand |
| anymore, and is not recommended. |
| |
| |
| 2.2. Quoting and escaping |
| ------------------------- |
| |
| In modern configurations, some arguments require the use of some characters |
| that were previously considered as pure delimiters. In order to make this |
| possible, HAProxy supports character escaping by prepending a backslash ('\') |
| in front of the character to be escaped, weak quoting within double quotes |
| ('"') and strong quoting within single quotes ("'"). |
| |
| This is pretty similar to what is done in a number of programming languages and |
| very close to what is commonly encountered in Bourne shell. The principle is |
| the following: while the configuration parser cuts the lines into words, it |
| also takes care of quotes and backslashes to decide whether a character is a |
| delimiter or is the raw representation of this character within the current |
| word. The escape character is then removed, the quotes are removed, and the |
| remaining word is used as-is as a keyword or argument for example. |
| |
| If a backslash is needed in a word, it must either be escaped using itself |
| (i.e. double backslash) or be strongly quoted. |
| |
| Escaping outside quotes is achieved by preceding a special character by a |
| backslash ('\'): |
| |
| \ to mark a space and differentiate it from a delimiter |
| \# to mark a hash and differentiate it from a comment |
| \\ to use a backslash |
| \' to use a single quote and differentiate it from strong quoting |
| \" to use a double quote and differentiate it from weak quoting |
| |
| In addition, a few non-printable characters may be emitted using their usual |
| C-language representation: |
| |
| \n to insert a line feed (LF, character \x0a or ASCII 10 decimal) |
| \r to insert a carriage return (CR, character \x0d or ASCII 13 decimal) |
| \t to insert a tab (character \x09 or ASCII 9 decimal) |
| \xNN to insert character having ASCII code hex NN (e.g \x0a for LF). |
| |
| Weak quoting is achieved by surrounding double quotes ("") around the character |
| or sequence of characters to protect. Weak quoting prevents the interpretation |
| of: |
| |
| space or tab as a word separator |
| ' single quote as a strong quoting delimiter |
| # hash as a comment start |
| |
| Weak quoting permits the interpretation of environment variables (which are not |
| evaluated outside of quotes) by preceding them with a dollar sign ('$'). If a |
| dollar character is needed inside double quotes, it must be escaped using a |
| backslash. |
| |
| Strong quoting is achieved by surrounding single quotes ('') around the |
| character or sequence of characters to protect. Inside single quotes, nothing |
| is interpreted, it's the efficient way to quote regular expressions. |
| |
| As a result, here is the matrix indicating how special characters can be |
| entered in different contexts (unprintable characters are replaced with their |
| name within angle brackets). Note that some characters that may only be |
| represented escaped have no possible representation inside single quotes, |
| hence the '-' there: |
| |
| Character | Unquoted | Weakly quoted | Strongly quoted |
| -----------+---------------+-----------------------------+----------------- |
| <TAB> | \<TAB>, \x09 | "<TAB>", "\<TAB>", "\x09" | '<TAB>' |
| <LF> | \n, \x0a | "\n", "\x0a" | - |
| <CR> | \r, \x0d | "\r", "\x0d" | - |
| <SPC> | \<SPC>, \x20 | "<SPC>", "\<SPC>", "\x20" | '<SPC>' |
| " | \", \x22 | "\"", "\x22" | '"' |
| # | \#, \x23 | "#", "\#", "\x23" | '#' |
| $ | $, \$, \x24 | "\$", "\x24" | '$' |
| ' | \', \x27 | "'", "\'", "\x27" | - |
| \ | \\, \x5c | "\\", "\x5c" | '\' |
| |
| Example: |
| # those are all strictly equivalent: |
| log-format %{+Q}o\ %t\ %s\ %{-Q}r |
| log-format "%{+Q}o %t %s %{-Q}r" |
| log-format '%{+Q}o %t %s %{-Q}r' |
| log-format "%{+Q}o %t"' %s %{-Q}r' |
| log-format "%{+Q}o %t"' %s'\ %{-Q}r |
| |
| There is one particular case where a second level of quoting or escaping may be |
| necessary. Some keywords take arguments within parenthesis, sometimes delimited |
| by commas. These arguments are commonly integers or predefined words, but when |
| they are arbitrary strings, it may be required to perform a separate level of |
| escaping to disambiguate the characters that belong to the argument from the |
| characters that are used to delimit the arguments themselves. A pretty common |
| case is the "regsub" converter. It takes a regular expression in argument, and |
| if a closing parenthesis is needed inside, this one will require to have its |
| own quotes. |
| |
| The keyword argument parser is exactly the same as the top-level one regarding |
| quotes, except that the \#, \$, and \xNN escapes are not processed. But what is |
| not always obvious is that the delimiters used inside must first be escaped or |
| quoted so that they are not resolved at the top level. |
| |
| Let's take this example making use of the "regsub" converter which takes 3 |
| arguments, one regular expression, one replacement string and one set of flags: |
| |
| # replace all occurrences of "foo" with "blah" in the path: |
| http-request set-path %[path,regsub(foo,blah,g)] |
| |
| Here no special quoting was necessary. But if now we want to replace either |
| "foo" or "bar" with "blah", we'll need the regular expression "(foo|bar)". We |
| cannot write: |
| |
| http-request set-path %[path,regsub((foo|bar),blah,g)] |
| |
| because we would like the string to cut like this: |
| |
| http-request set-path %[path,regsub((foo|bar),blah,g)] |
| |---------|----|-| |
| arg1 _/ / / |
| arg2 __________/ / |
| arg3 ______________/ |
| |
| but actually what is passed is a string between the opening and closing |
| parenthesis then garbage: |
| |
| http-request set-path %[path,regsub((foo|bar),blah,g)] |
| |--------|--------| |
| arg1=(foo|bar _/ / |
| trailing garbage _________/ |
| |
| The obvious solution here seems to be that the closing parenthesis needs to be |
| quoted, but alone this will not work, because as mentioned above, quotes are |
| processed by the top-level parser which will resolve them before processing |
| this word: |
| |
| http-request set-path %[path,regsub("(foo|bar)",blah,g)] |
| ------------ -------- ---------------------------------- |
| word1 word2 word3=%[path,regsub((foo|bar),blah,g)] |
| |
| So we didn't change anything for the argument parser at the second level which |
| still sees a truncated regular expression as the only argument, and garbage at |
| the end of the string. By escaping the quotes they will be passed unmodified to |
| the second level: |
| |
| http-request set-path %[path,regsub(\"(foo|bar)\",blah,g)] |
| ------------ -------- ------------------------------------ |
| word1 word2 word3=%[path,regsub("(foo|bar)",blah,g)] |
| |---------||----|-| |
| arg1=(foo|bar) _/ / / |
| arg2=blah ___________/ / |
| arg3=g _______________/ |
| |
| Another approach consists in using single quotes outside the whole string and |
| double quotes inside (so that the double quotes are not stripped again): |
| |
| http-request set-path '%[path,regsub("(foo|bar)",blah,g)]' |
| ------------ -------- ---------------------------------- |
| word1 word2 word3=%[path,regsub("(foo|bar)",blah,g)] |
| |---------||----|-| |
| arg1=(foo|bar) _/ / / |
| arg2 ___________/ / |
| arg3 _______________/ |
| |
| When using regular expressions, it can happen that the dollar ('$') character |
| appears in the expression or that a backslash ('\') is used in the replacement |
| string. In this case these ones will also be processed inside the double quotes |
| thus single quotes are preferred (or double escaping). Example: |
| |
| http-request set-path '%[path,regsub("^/(here)(/|$)","my/\1",g)]' |
| ------------ -------- ----------------------------------------- |
| word1 word2 word3=%[path,regsub("^/(here)(/|$)","my/\1",g)] |
| |-------------| |-----||-| |
| arg1=(here)(/|$) _/ / / |
| arg2=my/\1 ________________/ / |
| arg3 ______________________/ |
| |
| Remember that backslashes are not escape characters within single quotes and |
| that the whole word above is already protected against them using the single |
| quotes. Conversely, if double quotes had been used around the whole expression, |
| single the dollar character and the backslashes would have been resolved at top |
| level, breaking the argument contents at the second level. |
| |
| Unfortunately, since single quotes can't be escaped inside of strong quoting, |
| if you need to include single quotes in your argument, you will need to escape |
| or quote them twice. There are a few ways to do this: |
| |
| http-request set-var(txn.foo) str("\\'foo\\'") |
| http-request set-var(txn.foo) str(\"\'foo\'\") |
| http-request set-var(txn.foo) str(\\\'foo\\\') |
| |
| When in doubt, simply do not use quotes anywhere, and start to place single or |
| double quotes around arguments that require a comma or a closing parenthesis, |
| and think about escaping these quotes using a backslash if the string contains |
| a dollar or a backslash. Again, this is pretty similar to what is used under |
| a Bourne shell when double-escaping a command passed to "eval". For API writers |
| the best is probably to place escaped quotes around each and every argument, |
| regardless of their contents. Users will probably find that using single quotes |
| around the whole expression and double quotes around each argument provides |
| more readable configurations. |
| |
| |
| 2.3. Environment variables |
| -------------------------- |
| |
| HAProxy's configuration supports environment variables. Those variables are |
| interpreted only within double quotes. Variables are expanded during the |
| configuration parsing. Variable names must be preceded by a dollar ("$") and |
| optionally enclosed with braces ("{}") similarly to what is done in Bourne |
| shell. Variable names can contain alphanumerical characters or the character |
| underscore ("_") but should not start with a digit. If the variable contains a |
| list of several values separated by spaces, it can be expanded as individual |
| arguments by enclosing the variable with braces and appending the suffix '[*]' |
| before the closing brace. |
| |
| Example: |
| |
| bind "fd@${FD_APP1}" |
| |
| log "${LOCAL_SYSLOG}:514" local0 notice # send to local server |
| |
| user "$HAPROXY_USER" |
| |
| Some variables are defined by HAProxy, they can be used in the configuration |
| file, or could be inherited by a program (See 3.7. Programs): |
| |
| * HAPROXY_LOCALPEER: defined at the startup of the process which contains the |
| name of the local peer. (See "-L" in the management guide.) |
| |
| * HAPROXY_CFGFILES: list of the configuration files loaded by HAProxy, |
| separated by semicolons. Can be useful in the case you specified a |
| directory. |
| |
| * HAPROXY_MWORKER: In master-worker mode, this variable is set to 1. |
| |
| * HAPROXY_CLI: configured listeners addresses of the stats socket for every |
| processes, separated by semicolons. |
| |
| * HAPROXY_MASTER_CLI: In master-worker mode, listeners addresses of the master |
| CLI, separated by semicolons. |
| |
| In addition, some pseudo-variables are internally resolved and may be used as |
| regular variables. Pseudo-variables always start with a dot ('.'), and are the |
| only ones where the dot is permitted. The current list of pseudo-variables is: |
| |
| * .FILE: the name of the configuration file currently being parsed. |
| |
| * .LINE: the line number of the configuration file currently being parsed, |
| starting at one. |
| |
| * .SECTION: the name of the section currently being parsed, or its type if the |
| section doesn't have a name (e.g. "global"), or an empty string before the |
| first section. |
| |
| These variables are resolved at the location where they are parsed. For example |
| if a ".LINE" variable is used in a "log-format" directive located in a defaults |
| section, its line number will be resolved before parsing and compiling the |
| "log-format" directive, so this same line number will be reused by subsequent |
| proxies. |
| |
| This way it is possible to emit information to help locate a rule in variables, |
| logs, error statuses, health checks, header values, or even to use line numbers |
| to name some config objects like servers for example. |
| |
| See also "external-check command" for other variables. |
| |
| |
| 2.4. Conditional blocks |
| ----------------------- |
| |
| It may sometimes be convenient to be able to conditionally enable or disable |
| some arbitrary parts of the configuration, for example to enable/disable SSL or |
| ciphers, enable or disable some pre-production listeners without modifying the |
| configuration, or adjust the configuration's syntax to support two distinct |
| versions of HAProxy during a migration.. HAProxy brings a set of nestable |
| preprocessor-like directives which allow to integrate or ignore some blocks of |
| text. These directives must be placed on their own line and they act on the |
| lines that follow them. Two of them support an expression, the other ones only |
| switch to an alternate block or end a current level. The 4 following directives |
| are defined to form conditional blocks: |
| |
| - .if <condition> |
| - .elif <condition> |
| - .else |
| - .endif |
| |
| The ".if" directive nests a new level, ".elif" stays at the same level, ".else" |
| as well, and ".endif" closes a level. Each ".if" must be terminated by a |
| matching ".endif". The ".elif" may only be placed after ".if" or ".elif", and |
| there is no limit to the number of ".elif" that may be chained. There may be |
| only one ".else" per ".if" and it must always be after the ".if" or the last |
| ".elif" of a block. |
| |
| Comments may be placed on the same line if needed after a '#', they will be |
| ignored. The directives are tokenized like other configuration directives, and |
| as such it is possible to use environment variables in conditions. |
| |
| The conditions are currently limited to: |
| |
| - an empty string, always returns "false" |
| - the integer zero ('0'), always returns "false" |
| - a non-nul integer (e.g. '1'), always returns "true". |
| - a predicate optionally followed by argument(s) in parenthesis. |
| |
| The list of currently supported predicates is the following: |
| |
| - defined(<name>) : returns true if an environment variable <name> |
| exists, regardless of its contents |
| |
| - feature(<name>) : returns true if feature <name> is listed as present |
| in the features list reported by "haproxy -vv" |
| (which means a <name> appears after a '+') |
| |
| - streq(<str1>,<str2>) : returns true only if the two strings are equal |
| - strneq(<str1>,<str2>) : returns true only if the two strings differ |
| |
| - version_atleast(<ver>): returns true if the current haproxy version is |
| at least as recent as <ver> otherwise false. The |
| version syntax is the same as shown by "haproxy -v" |
| and missing components are assumed as being zero. |
| |
| - version_before(<ver>) : returns true if the current haproxy version is |
| strictly older than <ver> otherwise false. The |
| version syntax is the same as shown by "haproxy -v" |
| and missing components are assumed as being zero. |
| |
| Example: |
| |
| .if defined(HAPROXY_MWORKER) |
| listen mwcli_px |
| bind :1111 |
| ... |
| .endif |
| |
| .if strneq("$SSL_ONLY",yes) |
| bind :80 |
| .endif |
| |
| .if streq("$WITH_SSL",yes) |
| .if feature(OPENSSL) |
| bind :443 ssl crt ... |
| .endif |
| .endif |
| |
| .if version_atleast(2.4-dev19) |
| profiling.memory on |
| .endif |
| |
| Four other directives are provided to report some status: |
| |
| - .diag "message" : emit this message only when in diagnostic mode (-dD) |
| - .notice "message" : emit this message at level NOTICE |
| - .warning "message" : emit this message at level WARNING |
| - .alert "message" : emit this message at level ALERT |
| |
| Messages emitted at level WARNING may cause the process to fail to start if the |
| "strict-mode" is enabled. Messages emitted at level ALERT will always cause a |
| fatal error. These can be used to detect some inappropriate conditions and |
| provide advice to the user. |
| |
| Example: |
| |
| .if "${A}" |
| .if "${B}" |
| .notice "A=1, B=1" |
| .elif "${C}" |
| .notice "A=1, B=0, C=1" |
| .elif "${D}" |
| .warning "A=1, B=0, C=0, D=1" |
| .else |
| .alert "A=1, B=0, C=0, D=0" |
| .endif |
| .else |
| .notice "A=0" |
| .endif |
| |
| .diag "WTA/2021-05-07: replace 'redirect' with 'return' after switch to 2.4" |
| http-request redirect location /goaway if ABUSE |
| |
| |
| 2.5. 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 : |
| |
| - 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.6. Examples |
| ------------- |
| |
| # Simple configuration for an HTTP proxy listening on port 80 on all |
| # interfaces and forwarding requests to a single backend "servers" with a |
| # 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. |
| 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: |
| |
| $ sudo haproxy -f configuration.conf -c |
| |
| |
| 3. 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. |
| |
| The following keywords are supported in the "global" section : |
| |
| * Process management and security |
| - ca-base |
| - chroot |
| - crt-base |
| - cpu-map |
| - daemon |
| - default-path |
| - description |
| - deviceatlas-json-file |
| - deviceatlas-log-level |
| - deviceatlas-separator |
| - deviceatlas-properties-cookie |
| - expose-experimental-directives |
| - external-check |
| - gid |
| - group |
| - hard-stop-after |
| - h1-case-adjust |
| - h1-case-adjust-file |
| - insecure-fork-wanted |
| - insecure-setuid-wanted |
| - issuers-chain-path |
| - h2-workaround-bogus-websocket-clients |
| - localpeer |
| - log |
| - log-tag |
| - log-send-hostname |
| - lua-load |
| - lua-load-per-thread |
| - lua-prepend-path |
| - mworker-max-reloads |
| - nbproc |
| - nbthread |
| - node |
| - numa-cpu-mapping |
| - pidfile |
| - pp2-never-send-local |
| - presetenv |
| - resetenv |
| - uid |
| - ulimit-n |
| - user |
| - set-dumpable |
| - set-var |
| - setenv |
| - stats |
| - ssl-default-bind-ciphers |
| - ssl-default-bind-ciphersuites |
| - ssl-default-bind-curves |
| - ssl-default-bind-options |
| - ssl-default-server-ciphers |
| - ssl-default-server-ciphersuites |
| - ssl-default-server-options |
| - ssl-dh-param-file |
| - ssl-server-verify |
| - ssl-skip-self-issued-ca |
| - unix-bind |
| - unsetenv |
| - 51degrees-data-file |
| - 51degrees-property-name-list |
| - 51degrees-property-separator |
| - 51degrees-cache-size |
| - wurfl-data-file |
| - wurfl-information-list |
| - wurfl-information-list-separator |
| - wurfl-cache-size |
| - strict-limits |
| |
| * Performance tuning |
| - busy-polling |
| - max-spread-checks |
| - maxconn |
| - maxconnrate |
| - maxcomprate |
| - maxcompcpuusage |
| - maxpipes |
| - maxsessrate |
| - maxsslconn |
| - maxsslrate |
| - maxzlibmem |
| - no-memory-trimming |
| - noepoll |
| - nokqueue |
| - noevports |
| - nopoll |
| - nosplice |
| - nogetaddrinfo |
| - noreuseport |
| - profiling.tasks |
| - spread-checks |
| - server-state-base |
| - server-state-file |
| - ssl-engine |
| - ssl-mode-async |
| - tune.buffers.limit |
| - tune.buffers.reserve |
| - tune.bufsize |
| - tune.chksize |
| - tune.comp.maxlevel |
| - tune.fd.edge-triggered |
| - tune.h2.header-table-size |
| - tune.h2.initial-window-size |
| - tune.h2.max-concurrent-streams |
| - tune.http.cookielen |
| - tune.http.logurilen |
| - tune.http.maxhdr |
| - tune.idle-pool.shared |
| - tune.idletimer |
| - tune.lua.forced-yield |
| - tune.lua.maxmem |
| - tune.lua.session-timeout |
| - tune.lua.task-timeout |
| - tune.lua.service-timeout |
| - tune.maxaccept |
| - tune.maxpollevents |
| - tune.maxrewrite |
| - tune.pattern.cache-size |
| - tune.pipesize |
| - tune.pool-high-fd-ratio |
| - tune.pool-low-fd-ratio |
| - tune.rcvbuf.client |
| - tune.rcvbuf.server |
| - tune.recv_enough |
| - tune.runqueue-depth |
| - tune.sched.low-latency |
| - tune.sndbuf.client |
| - tune.sndbuf.server |
| - tune.ssl.cachesize |
| - tune.ssl.keylog |
| - tune.ssl.lifetime |
| - tune.ssl.force-private-cache |
| - tune.ssl.maxrecord |
| - tune.ssl.default-dh-param |
| - tune.ssl.ssl-ctx-cache-size |
| - tune.ssl.capture-cipherlist-size |
| - tune.vars.global-max-size |
| - tune.vars.proc-max-size |
| - tune.vars.reqres-max-size |
| - tune.vars.sess-max-size |
| - tune.vars.txn-max-size |
| - tune.zlib.memlevel |
| - tune.zlib.windowsize |
| |
| * Debugging |
| - quiet |
| - zero-warning |
| |
| |
| 3.1. Process management and security |
| ------------------------------------ |
| |
| ca-base <dir> |
| Assigns a default directory to fetch SSL CA certificates and CRLs from when a |
| relative path is used with "ca-file", "ca-verify-file" or "crl-file" |
| directives. Absolute locations specified in "ca-file", "ca-verify-file" and |
| "crl-file" prevail and ignore "ca-base". |
| |
| chroot <jail dir> |
| Changes current directory to <jail dir> and performs a chroot() there before |
| dropping privileges. This increases the security level in case an unknown |
| vulnerability would be exploited, since it would make it very hard for the |
| attacker to exploit the system. This only works when the process is started |
| with superuser privileges. It is important to ensure that <jail_dir> is both |
| empty and non-writable to anyone. |
| |
| cpu-map [auto:]<process-set>[/<thread-set>] <cpu-set>... |
| On Linux 2.6 and above, it is possible to bind a process or a thread to a |
| specific CPU set. This means that the process or the thread will never run on |
| other CPUs. The "cpu-map" directive specifies CPU sets for process or thread |
| sets. The first argument is a process set, eventually followed by a thread |
| set. These sets have the format |
| |
| all | odd | even | number[-[number]] |
| |
| <number>> must be a number between 1 and 32 or 64, depending on the machine's |
| word size. Any process IDs above nbproc and any thread IDs above nbthread are |
| ignored. It is possible to specify a range with two such number delimited by |
| a dash ('-'). It also 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 starting at 0 for the first |
| CPU or a range with two such numbers delimited by a dash ('-'). Outside of |
| Linux and BSDs, there may be a limitation on the maximum CPU index to either |
| 31 or 63. Multiple CPU numbers or ranges may be specified, and the processes |
| or threads 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. A thread will be bound on the |
| intersection of its mapping and the one of the process on which it is |
| attached. If the intersection is null, no specific binding will be set for |
| the thread. |
| |
| Ranges can be partially defined. The higher bound can be omitted. In such |
| case, it is replaced by the corresponding maximum value, 32 or 64 depending |
| on the machine's word size. |
| |
| The prefix "auto:" can be added before the process set to let HAProxy |
| automatically bind a process or a thread to a CPU by incrementing |
| process/thread and CPU sets. To be valid, both sets must have the same |
| size. No matter the declaration order of the CPU sets, it will be bound from |
| the lowest to the highest bound. Having a process and a thread range with the |
| "auto:" prefix is not supported. Only one range is supported, the other one |
| must be a fixed number. |
| |
| Examples: |
| cpu-map 1-4 0-3 # bind processes 1 to 4 on the first 4 CPUs |
| |
| cpu-map 1/all 0-3 # bind all threads of the first process on the |
| # first 4 CPUs |
| |
| cpu-map 1- 0- # will be replaced by "cpu-map 1-64 0-63" |
| # or "cpu-map 1-32 0-31" depending on the machine's |
| # word size. |
| |
| # all these lines bind the process 1 to the cpu 0, the process 2 to cpu 1 |
| # and so on. |
| cpu-map auto:1-4 0-3 |
| cpu-map auto:1-4 0-1 2-3 |
| cpu-map auto:1-4 3 2 1 0 |
| |
| # all these lines bind the thread 1 to the cpu 0, the thread 2 to cpu 1 |
| # and so on. |
| cpu-map auto:1/1-4 0-3 |
| cpu-map auto:1/1-4 0-1 2-3 |
| cpu-map auto:1/1-4 3 2 1 0 |
| |
| # bind each process to exactly one CPU using all/odd/even keyword |
| cpu-map auto:all 0-63 |
| cpu-map auto:even 0-31 |
| cpu-map auto:odd 32-63 |
| |
| # invalid cpu-map because process and CPU sets have different sizes. |
| cpu-map auto:1-4 0 # invalid |
| cpu-map auto:1 0-3 # invalid |
| |
| # invalid cpu-map because automatic binding is used with a process range |
| # and a thread range. |
| cpu-map auto:all/all 0 # invalid |
| cpu-map auto:all/1-4 0 # invalid |
| cpu-map auto:1-4/all 0 # invalid |
| |
| crt-base <dir> |
| Assigns a default directory to fetch SSL certificates from when a relative |
| path is used with "crtfile" or "crt" directives. Absolute locations specified |
| prevail and ignore "crt-base". |
| |
| 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. This option is ignored in |
| systemd mode. |
| |
| default-path { current | config | parent | origin <path> } |
| By default HAProxy loads all files designated by a relative path from the |
| location the process is started in. In some circumstances it might be |
| desirable to force all relative paths to start from a different location |
| just as if the process was started from such locations. This is what this |
| directive is made for. Technically it will perform a temporary chdir() to |
| the designated location while processing each configuration file, and will |
| return to the original directory after processing each file. It takes an |
| argument indicating the policy to use when loading files whose path does |
| not start with a slash ('/'): |
| - "current" indicates that all relative files are to be loaded from the |
| directory the process is started in ; this is the default. |
| |
| - "config" indicates that all relative files should be loaded from the |
| directory containing the configuration file. More specifically, if the |
| configuration file contains a slash ('/'), the longest part up to the |
| last slash is used as the directory to change to, otherwise the current |
| directory is used. This mode is convenient to bundle maps, errorfiles, |
| certificates and Lua scripts together as relocatable packages. When |
| multiple configuration files are loaded, the directory is updated for |
| each of them. |
| |
| - "parent" indicates that all relative files should be loaded from the |
| parent of the directory containing the configuration file. More |
| specifically, if the configuration file contains a slash ('/'), ".." |
| is appended to the longest part up to the last slash is used as the |
| directory to change to, otherwise the directory is "..". This mode is |
| convenient to bundle maps, errorfiles, certificates and Lua scripts |
| together as relocatable packages, but where each part is located in a |
| different subdirectory (e.g. "config/", "certs/", "maps/", ...). |
| |
| - "origin" indicates that all relative files should be loaded from the |
| designated (mandatory) path. This may be used to ease management of |
| different HAProxy instances running in parallel on a system, where each |
| instance uses a different prefix but where the rest of the sections are |
| made easily relocatable. |
| |
| Each "default-path" directive instantly replaces any previous one and will |
| possibly result in switching to a different directory. While this should |
| always result in the desired behavior, it is really not a good practice to |
| use multiple default-path directives, and if used, the policy ought to remain |
| consistent across all configuration files. |
| |
| Warning: some configuration elements such as maps or certificates are |
| uniquely identified by their configured path. By using a relocatable layout, |
| it becomes possible for several of them to end up with the same unique name, |
| making it difficult to update them at run time, especially when multiple |
| configuration files are loaded from different directories. It is essential to |
| observe a strict collision-free file naming scheme before adopting relative |
| paths. A robust approach could consist in prefixing all files names with |
| their respective site name, or in doing so at the directory level. |
| |
| deviceatlas-json-file <path> |
| Sets the path of the DeviceAtlas JSON data file to be loaded by the API. |
| The path must be a valid JSON data file and accessible by HAProxy process. |
| |
| deviceatlas-log-level <value> |
| Sets the level of information returned by the API. This directive is |
| optional and set to 0 by default if not set. |
| |
| deviceatlas-separator <char> |
| Sets the character separator for the API properties results. This directive |
| is optional and set to | by default if not set. |
| |
| deviceatlas-properties-cookie <name> |
| Sets the client cookie's name used for the detection if the DeviceAtlas |
| Client-side component was used during the request. This directive is optional |
| and set to DAPROPS by default if not set. |
| |
| expose-experimental-directives |
| This statement must appear before using directives tagged as experimental or |
| the config file will be rejected. |
| |
| external-check |
| Allows the use of an external agent to perform health checks. This is |
| disabled by default as a security precaution, and even when enabled, checks |
| may still fail unless "insecure-fork-wanted" is enabled as well. If the |
| program launched makes use of a setuid executable (it should really not), |
| you may also need to set "insecure-setuid-wanted" in the global section. |
| See "option external-check", and "insecure-fork-wanted", and |
| "insecure-setuid-wanted". |
| |
| gid <number> |
| Changes the process's group ID to <number>. 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 <group name> |
| Similar to "gid" but uses the GID of group name <group name> from /etc/group. |
| See also "gid" and "user". |
| |
| hard-stop-after <time> |
| Defines the maximum time allowed to perform a clean soft-stop. |
| |
| Arguments : |
| <time> is the maximum time (by default in milliseconds) for which the |
| instance will remain alive when a soft-stop is received via the |
| SIGUSR1 signal. |
| |
| This may be used to ensure that the instance will quit even if connections |
| remain opened during a soft-stop (for example with long timeouts for a proxy |
| in tcp mode). It applies both in TCP and HTTP mode. |
| |
| Example: |
| global |
| hard-stop-after 30s |
| |
| h1-case-adjust <from> <to> |
| Defines the case adjustment to apply, when enabled, to the header name |
| <from>, to change it to <to> before sending it to HTTP/1 clients or |
| servers. <from> must be in lower case, and <from> and <to> must not differ |
| except for their case. It may be repeated if several header names need to be |
| adjusted. Duplicate entries are not allowed. If a lot of header names have to |
| be adjusted, it might be more convenient to use "h1-case-adjust-file". |
| Please note that no transformation will be applied unless "option |
| h1-case-adjust-bogus-client" or "option h1-case-adjust-bogus-server" is |
| specified in a proxy. |
| |
| There is no standard case for header names because, as stated in RFC7230, |
| they are case-insensitive. So applications must handle them in a case- |
| insensitive manner. But some bogus applications violate the standards and |
| erroneously rely on the cases most commonly used by browsers. This problem |
| becomes critical with HTTP/2 because all header names must be exchanged in |
| lower case, and HAProxy follows the same convention. All header names are |
| sent in lower case to clients and servers, regardless of the HTTP version. |
| |
| Applications which fail to properly process requests or responses may require |
| to temporarily use such workarounds to adjust header names sent to them for |
| the time it takes the application to be fixed. Please note that an |
| application which requires such workarounds might be vulnerable to content |
| smuggling attacks and must absolutely be fixed. |
| |
| Example: |
| global |
| h1-case-adjust content-length Content-Length |
| |
| See "h1-case-adjust-file", "option h1-case-adjust-bogus-client" and |
| "option h1-case-adjust-bogus-server". |
| |
| h1-case-adjust-file <hdrs-file> |
| Defines a file containing a list of key/value pairs used to adjust the case |
| of some header names before sending them to HTTP/1 clients or servers. The |
| file <hdrs-file> must contain 2 header names per line. The first one must be |
| in lower case and both must not differ except for their case. Lines which |
| start with '#' are ignored, just like empty lines. Leading and trailing tabs |
| and spaces are stripped. Duplicate entries are not allowed. Please note that |
| no transformation will be applied unless "option h1-case-adjust-bogus-client" |
| or "option h1-case-adjust-bogus-server" is specified in a proxy. |
| |
| If this directive is repeated, only the last one will be processed. It is an |
| alternative to the directive "h1-case-adjust" if a lot of header names need |
| to be adjusted. Please read the risks associated with using this. |
| |
| See "h1-case-adjust", "option h1-case-adjust-bogus-client" and |
| "option h1-case-adjust-bogus-server". |
| |
| insecure-fork-wanted |
| By default HAProxy tries hard to prevent any thread and process creation |
| after it starts. Doing so is particularly important when using Lua files of |
| uncertain origin, and when experimenting with development versions which may |
| still contain bugs whose exploitability is uncertain. And generally speaking |
| it's good hygiene to make sure that no unexpected background activity can be |
| triggered by traffic. But this prevents external checks from working, and may |
| break some very specific Lua scripts which actively rely on the ability to |
| fork. This option is there to disable this protection. Note that it is a bad |
| idea to disable it, as a vulnerability in a library or within HAProxy itself |
| will be easier to exploit once disabled. In addition, forking from Lua or |
| anywhere else is not reliable as the forked process may randomly embed a lock |
| set by another thread and never manage to finish an operation. As such it is |
| highly recommended that this option is never used and that any workload |
| requiring such a fork be reconsidered and moved to a safer solution (such as |
| agents instead of external checks). This option supports the "no" prefix to |
| disable it. |
| |
| insecure-setuid-wanted |
| HAProxy doesn't need to call executables at run time (except when using |
| external checks which are strongly recommended against), and is even expected |
| to isolate itself into an empty chroot. As such, there basically is no valid |
| reason to allow a setuid executable to be called without the user being fully |
| aware of the risks. In a situation where HAProxy would need to call external |
| checks and/or disable chroot, exploiting a vulnerability in a library or in |
| HAProxy itself could lead to the execution of an external program. On Linux |
| it is possible to lock the process so that any setuid bit present on such an |
| executable is ignored. This significantly reduces the risk of privilege |
| escalation in such a situation. This is what HAProxy does by default. In case |
| this causes a problem to an external check (for example one which would need |
| the "ping" command), then it is possible to disable this protection by |
| explicitly adding this directive in the global section. If enabled, it is |
| possible to turn it back off by prefixing it with the "no" keyword. |
| |
| issuers-chain-path <dir> |
| Assigns a directory to load certificate chain for issuer completion. All |
| files must be in PEM format. For certificates loaded with "crt" or "crt-list", |
| if certificate chain is not included in PEM (also commonly known as |
| intermediate certificate), HAProxy will complete chain if the issuer of the |
| certificate corresponds to the first certificate of the chain loaded with |
| "issuers-chain-path". |
| A "crt" file with PrivateKey+Certificate+IntermediateCA2+IntermediateCA1 |
| could be replaced with PrivateKey+Certificate. HAProxy will complete the |
| chain if a file with IntermediateCA2+IntermediateCA1 is present in |
| "issuers-chain-path" directory. All other certificates with the same issuer |
| will share the chain in memory. |
| |
| h2-workaround-bogus-websocket-clients |
| This disables the announcement of the support for h2 websockets to clients. |
| This can be use to overcome clients which have issues when implementing the |
| relatively fresh RFC8441, such as Firefox 88. To allow clients to |
| automatically downgrade to http/1.1 for the websocket tunnel, specify h2 |
| support on the bind line using "alpn" without an explicit "proto" keyword. If |
| this statement was previously activated, this can be disabled by prefixing |
| the keyword with "no'. |
| |
| localpeer <name> |
| Sets the local instance's peer name. It will be ignored if the "-L" |
| command line argument is specified or if used after "peers" section |
| definitions. In such cases, a warning message will be emitted during |
| the configuration parsing. |
| |
| This option will also set the HAPROXY_LOCALPEER environment variable. |
| See also "-L" in the management guide and "peers" section below. |
| |
| log <address> [len <length>] [format <format>] [sample <ranges>:<sample_size>] |
| <facility> [max level [min level]] |
| Adds a global syslog server. Several global servers can be defined. They |
| will receive logs for starts and exits, as well as all logs from proxies |
| configured with "log global". |
| |
| <address> 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 datagram 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 |
| writable). |
| |
| - A file descriptor number in the form "fd@<number>", which may point |
| to a pipe, terminal, or socket. In this case unbuffered logs are used |
| and one writev() call per log is performed. This is a bit expensive |
| but acceptable for most workloads. Messages sent this way will not be |
| truncated but may be dropped, in which case the DroppedLogs counter |
| will be incremented. The writev() call is atomic even on pipes for |
| messages up to PIPE_BUF size, which POSIX recommends to be at least |
| 512 and which is 4096 bytes on most modern operating systems. Any |
| larger message may be interleaved with messages from other processes. |
| Exceptionally for debugging purposes the file descriptor may also be |
| directed to a file, but doing so will significantly slow HAProxy down |
| as non-blocking calls will be ignored. Also there will be no way to |
| purge nor rotate this file without restarting the process. Note that |
| the configured syslog format is preserved, so the output is suitable |
| for use with a TCP syslog server. See also the "short" and "raw" |
| format below. |
| |
| - "stdout" / "stderr", which are respectively aliases for "fd@1" and |
| "fd@2", see above. |
| |
| - A ring buffer in the form "ring@<name>", which will correspond to an |
| in-memory ring buffer accessible over the CLI using the "show events" |
| command, which will also list existing rings and their sizes. Such |
| buffers are lost on reload or restart but when used as a complement |
| this can help troubleshooting by having the logs instantly available. |
| |
| You may want to reference some environment variables in the address |
| parameter, see section 2.3 about environment variables. |
| |
| <length> is an optional maximum line length. Log lines larger than this value |
| will be truncated before being sent. The reason is that syslog |
| servers act differently on log line length. All servers support the |
| default value of 1024, but some servers simply drop larger lines |
| while others do log them. If a server supports long lines, it may |
| make sense to set this value here in order to avoid truncating long |
| lines. Similarly, if a server drops long lines, it is preferable to |
| truncate them before sending them. Accepted values are 80 to 65535 |
| inclusive. The default value of 1024 is generally fine for all |
| standard usages. Some specific cases of long captures or |
| JSON-formatted logs may require larger values. You may also need to |
| increase "tune.http.logurilen" if your request URIs are truncated. |
| |
| <format> is the log format used when generating syslog messages. It may be |
| one of the following : |
| |
| local Analog to rfc3164 syslog message format except that hostname |
| field is stripped. This is the default. |
| Note: option "log-send-hostname" switches the default to |
| rfc3164. |
| |
| rfc3164 The RFC3164 syslog message format. |
| (https://tools.ietf.org/html/rfc3164) |
| |
| rfc5424 The RFC5424 syslog message format. |
| (https://tools.ietf.org/html/rfc5424) |
| |
| priority A message containing only a level plus syslog facility between |
| angle brackets such as '<63>', followed by the text. The PID, |
| date, time, process name and system name are omitted. This is |
| designed to be used with a local log server. |
| |
| short A message containing only a level between angle brackets such as |
| '<3>', followed by the text. The PID, date, time, process name |
| and system name are omitted. This is designed to be used with a |
| local log server. This format is compatible with what the systemd |
| logger consumes. |
| |
| timed A message containing only a level between angle brackets such as |
| '<3>', followed by ISO date and by the text. The PID, process |
| name and system name are omitted. This is designed to be |
| used with a local log server. |
| |
| iso A message containing only the ISO date, followed by the text. |
| The PID, process name and system name are omitted. This is |
| designed to be used with a local log server. |
| |
| raw A message containing only the text. The level, PID, date, time, |
| process name and system name are omitted. This is designed to be |
| used in containers or during development, where the severity only |
| depends on the file descriptor used (stdout/stderr). |
| |
| <ranges> A list of comma-separated ranges to identify the logs to sample. |
| This is used to balance the load of the logs to send to the log |
| server. The limits of the ranges cannot be null. They are numbered |
| from 1. The size or period (in number of logs) of the sample must be |
| set with <sample_size> parameter. |
| |
| <sample_size> |
| The size of the sample in number of logs to consider when balancing |
| their logging loads. It is used to balance the load of the logs to |
| send to the syslog server. This size must be greater or equal to the |
| maximum of the high limits of the ranges. |
| (see also <ranges> parameter). |
| |
| <facility> must be one of the 24 standard syslog facilities : |
| |
| kern user mail daemon auth syslog lpr news |
| uucp cron auth2 ftp ntp audit alert cron2 |
| local0 local1 local2 local3 local4 local5 local6 local7 |
| |
| Note that the facility is ignored for the "short" and "raw" |
| formats, but still required as a positional field. It is |
| recommended to use "daemon" in this case to make it clear that |
| it's only supposed to be used locally. |
| |
| 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 : |
| |
| emerg alert crit err warning notice info debug |
| |
| log-send-hostname [<string>] |
| 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. |
| |
| log-tag <string> |
| 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. See also the per-proxy "log-tag" directive. |
| |
| lua-load <file> |
| This global directive loads and executes a Lua file in the shared context |
| that is visible to all threads. Any variable set in such a context is visible |
| from any thread. This is the easiest and recommended way to load Lua programs |
| but it will not scale well if a lot of Lua calls are performed, as only one |
| thread may be running on the global state at a time. A program loaded this |
| way will always see 0 in the "core.thread" variable. This directive can be |
| used multiple times. |
| |
| lua-load-per-thread <file> |
| This global directive loads and executes a Lua file into each started thread. |
| Any global variable has a thread-local visibility so that each thread could |
| see a different value. As such it is strongly recommended not to use global |
| variables in programs loaded this way. An independent copy is loaded and |
| initialized for each thread, everything is done sequentially and in the |
| thread's numeric order from 1 to nbthread. If some operations need to be |
| performed only once, the program should check the "core.thread" variable to |
| figure what thread is being initialized. Programs loaded this way will run |
| concurrently on all threads and will be highly scalable. This is the |
| recommended way to load simple functions that register sample-fetches, |
| converters, actions or services once it is certain the program doesn't depend |
| on global variables. For the sake of simplicity, the directive is available |
| even if only one thread is used and even if threads are disabled (in which |
| case it will be equivalent to lua-load). This directive can be used multiple |
| times. |
| |
| lua-prepend-path <string> [<type>] |
| Prepends the given string followed by a semicolon to Lua's package.<type> |
| variable. |
| <type> must either be "path" or "cpath". If <type> is not given it defaults |
| to "path". |
| |
| Lua's paths are semicolon delimited lists of patterns that specify how the |
| `require` function attempts to find the source file of a library. Question |
| marks (?) within a pattern will be replaced by module name. The path is |
| evaluated left to right. This implies that paths that are prepended later |
| will be checked earlier. |
| |
| As an example by specifying the following path: |
| |
| lua-prepend-path /usr/share/haproxy-lua/?/init.lua |
| lua-prepend-path /usr/share/haproxy-lua/?.lua |
| |
| When `require "example"` is being called Lua will first attempt to load the |
| /usr/share/haproxy-lua/example.lua script, if that does not exist the |
| /usr/share/haproxy-lua/example/init.lua will be attempted and the default |
| paths if that does not exist either. |
| |
| See https://www.lua.org/pil/8.1.html for the details within the Lua |
| documentation. |
| |
| master-worker [no-exit-on-failure] |
| Master-worker mode. It is equivalent to the command line "-W" argument. |
| This mode will launch a "master" which will monitor the "workers". Using |
| this mode, you can reload HAProxy directly by sending a SIGUSR2 signal to |
| the master. The master-worker mode is compatible either with the foreground |
| or daemon mode. It is recommended to use this mode with multiprocess and |
| systemd. |
| By default, if a worker exits with a bad return code, in the case of a |
| segfault for example, all workers will be killed, and the master will leave. |
| It is convenient to combine this behavior with Restart=on-failure in a |
| systemd unit file in order to relaunch the whole process. If you don't want |
| this behavior, you must use the keyword "no-exit-on-failure". |
| |
| See also "-W" in the management guide. |
| |
| mworker-max-reloads <number> |
| In master-worker mode, this option limits the number of time a worker can |
| survive to a reload. If the worker did not leave after a reload, once its |
| number of reloads is greater than this number, the worker will receive a |
| SIGTERM. This option helps to keep under control the number of workers. |
| See also "show proc" in the Management Guide. |
| |
| nbproc <number> (deprecated) |
| Creates <number> processes when going daemon. This requires the "daemon" |
| mode. By default, only one process is created, which is the recommended mode |
| of operation. For systems limited to small sets of file descriptors per |
| process, it may be needed to fork multiple daemons. When set to a value |
| larger than 1, threads are automatically disabled. USING MULTIPLE PROCESSES |
| IS HARDER TO DEBUG AND IS REALLY DISCOURAGED. This directive is deprecated |
| and scheduled for removal in 2.5. Please use "nbthread" instead. See also |
| "daemon" and "nbthread". |
| |
| nbthread <number> |
| This setting is only available when support for threads was built in. It |
| makes HAProxy run on <number> threads. This is exclusive with "nbproc". While |
| "nbproc" historically used to be the only way to use multiple processors, it |
| also involved a number of shortcomings related to the lack of synchronization |
| between processes (health-checks, peers, stick-tables, stats, ...) which do |
| not affect threads. As such, any modern configuration is strongly encouraged |
| to migrate away from "nbproc" to "nbthread". "nbthread" also works when |
| HAProxy is started in foreground. On some platforms supporting CPU affinity, |
| when nbproc is not used, the default "nbthread" value is automatically set to |
| the number of CPUs the process is bound to upon startup. This means that the |
| thread count can easily be adjusted from the calling process using commands |
| like "taskset" or "cpuset". Otherwise, this value defaults to 1. The default |
| value is reported in the output of "haproxy -vv". See also "nbproc". |
| |
| numa-cpu-mapping |
| By default, if running on Linux, HAProxy inspects on startup the CPU topology |
| of the machine. If a multi-socket machine is detected, the affinity is |
| automatically calculated to run on the CPUs of a single node. This is done in |
| order to not suffer from the performance penalties caused by the inter-socket |
| bus latency. However, if the applied binding is non optimal on a particular |
| architecture, it can be disabled with the statement 'no numa-cpu-mapping'. |
| This automatic binding is also not applied if a nbthread statement is present |
| in the configuration, or the affinity of the process is already specified, |
| for example via the 'cpu-map' directive or the taskset utility. |
| |
| pidfile <pidfile> |
| Writes PIDs of all daemons into file <pidfile> when daemon mode or writes PID |
| of master process into file <pidfile> when master-worker mode. This option is |
| equivalent to the "-p" command line argument. The file must be accessible to |
| the user starting the process. See also "daemon" and "master-worker". |
| |
| pp2-never-send-local |
| A bug in the PROXY protocol v2 implementation was present in HAProxy up to |
| version 2.1, causing it to emit a PROXY command instead of a LOCAL command |
| for health checks. This is particularly minor but confuses some servers' |
| logs. Sadly, the bug was discovered very late and revealed that some servers |
| which possibly only tested their PROXY protocol implementation against |
| HAProxy fail to properly handle the LOCAL command, and permanently remain in |
| the "down" state when HAProxy checks them. When this happens, it is possible |
| to enable this global option to revert to the older (bogus) behavior for the |
| time it takes to contact the affected components' vendors and get them fixed. |
| This option is disabled by default and acts on all servers having the |
| "send-proxy-v2" statement. |
| |
| presetenv <name> <value> |
| Sets environment variable <name> to value <value>. If the variable exists, it |
| is NOT overwritten. The changes immediately take effect so that the next line |
| in the configuration file sees the new value. See also "setenv", "resetenv", |
| and "unsetenv". |
| |
| resetenv [<name> ...] |
| Removes all environment variables except the ones specified in argument. It |
| allows to use a clean controlled environment before setting new values with |
| setenv or unsetenv. Please note that some internal functions may make use of |
| some environment variables, such as time manipulation functions, but also |
| OpenSSL or even external checks. This must be used with extreme care and only |
| after complete validation. The changes immediately take effect so that the |
| next line in the configuration file sees the new environment. See also |
| "setenv", "presetenv", and "unsetenv". |
| |
| stats bind-process [ all | odd | even | <process_num>[-[process_num>]] ] ... |
| 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. The maximum process ID depends on the machine's |
| word size (32 or 64). Ranges can be partially defined. The higher bound can |
| be omitted. In such case, it is replaced by the corresponding maximum |
| value. A better option consists in using the "process" setting of the "stats |
| socket" line to force the process on each line. |
| |
| server-state-base <directory> |
| Specifies the directory prefix to be prepended in front of all servers state |
| file names which do not start with a '/'. See also "server-state-file", |
| "load-server-state-from-file" and "server-state-file-name". |
| |
| server-state-file <file> |
| Specifies the path to the file containing state of servers. If the path starts |
| with a slash ('/'), it is considered absolute, otherwise it is considered |
| relative to the directory specified using "server-state-base" (if set) or to |
| the current directory. Before reloading HAProxy, it is possible to save the |
| servers' current state using the stats command "show servers state". The |
| output of this command must be written in the file pointed by <file>. When |
| starting up, before handling traffic, HAProxy will read, load and apply state |
| for each server found in the file and available in its current running |
| configuration. See also "server-state-base" and "show servers state", |
| "load-server-state-from-file" and "server-state-file-name" |
| |
| set-var <var-name> <expr> |
| Sets the process-wide variable '<var-name>' to the result of the evaluation |
| of the sample expression <expr>. The variable '<var-name>' may only be a |
| process-wide variable (using the 'proc.' prefix). It works exactly like the |
| 'set-var' action in TCP or HTTP rules except that the expression is evaluated |
| at configuration parsing time and that the variable is instantly set. The |
| sample fetch functions and converters permitted in the expression are only |
| those using internal data, typically 'int(value)' or 'str(value)'. It's is |
| possible to reference previously allocated variables as well. These variables |
| will then be readable (and modifiable) from the regular rule sets. |
| |
| Example: |
| global |
| set-var proc.current_state str(primary) |
| set-var proc.prio int(100) |
| set-var proc.threshold int(200),sub(proc.prio) |
| |
| setenv <name> <value> |
| Sets environment variable <name> to value <value>. If the variable exists, it |
| is overwritten. The changes immediately take effect so that the next line in |
| the configuration file sees the new value. See also "presetenv", "resetenv", |
| and "unsetenv". |
| |
| set-dumpable |
| This option is better left disabled by default and enabled only upon a |
| developer's request. If it has been enabled, it may still be forcibly |
| disabled by prefixing it with the "no" keyword. It has no impact on |
| performance nor stability but will try hard to re-enable core dumps that were |
| possibly disabled by file size limitations (ulimit -f), core size limitations |
| (ulimit -c), or "dumpability" of a process after changing its UID/GID (such |
| as /proc/sys/fs/suid_dumpable on Linux). Core dumps might still be limited by |
| the current directory's permissions (check what directory the file is started |
| from), the chroot directory's permission (it may be needed to temporarily |
| disable the chroot directive or to move it to a dedicated writable location), |
| or any other system-specific constraint. For example, some Linux flavours are |
| notorious for replacing the default core file with a path to an executable |
| not even installed on the system (check /proc/sys/kernel/core_pattern). Often, |
| simply writing "core", "core.%p" or "/var/log/core/core.%p" addresses the |
| issue. When trying to enable this option waiting for a rare issue to |
| re-appear, it's often a good idea to first try to obtain such a dump by |
| issuing, for example, "kill -11" to the "haproxy" process and verify that it |
| leaves a core where expected when dying. |
| |
| ssl-default-bind-ciphers <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 up to TLSv1.2 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. For background |
| information and recommendations see e.g. |
| (https://wiki.mozilla.org/Security/Server_Side_TLS) and |
| (https://mozilla.github.io/server-side-tls/ssl-config-generator/). For TLSv1.3 |
| cipher configuration, please check the "ssl-default-bind-ciphersuites" keyword. |
| Please check the "bind" keyword for more information. |
| |
| ssl-default-bind-ciphersuites <ciphersuites> |
| This setting is only available when support for OpenSSL was built in and |
| OpenSSL 1.1.1 or later was used to build HAProxy. It sets the default string |
| describing the list of cipher algorithms ("cipher suite") that are negotiated |
| during the TLSv1.3 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 under the section "ciphersuites". For |
| cipher configuration for TLSv1.2 and earlier, please check the |
| "ssl-default-bind-ciphers" keyword. Please check the "bind" keyword for more |
| information. |
| |
| ssl-default-bind-curves <curves> |
| This setting is only available when support for OpenSSL was built in. It sets |
| the default string describing the list of elliptic curves algorithms ("curve |
| suite") that are negotiated during the SSL/TLS handshake with ECDHE. The format |
| of the string is a colon-delimited list of curve name. |
| Please check the "bind" keyword for more information. |
| |
| ssl-default-bind-options [<option>]... |
| This setting is only available when support for OpenSSL was built in. It sets |
| default ssl-options to force on all "bind" lines. Please check the "bind" |
| keyword to see available options. |
| |
| Example: |
| global |
| ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets |
| |
| ssl-default-server-ciphers <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 up to TLSv1.2 with the server, |
| for all "server" lines which do not explicitly define theirs. The format of |
| the string is defined in "man 1 ciphers" from OpenSSL man pages. For background |
| information and recommendations see e.g. |
| (https://wiki.mozilla.org/Security/Server_Side_TLS) and |
| (https://mozilla.github.io/server-side-tls/ssl-config-generator/). |
| For TLSv1.3 cipher configuration, please check the |
| "ssl-default-server-ciphersuites" keyword. Please check the "server" keyword |
| for more information. |
| |
| ssl-default-server-ciphersuites <ciphersuites> |
| This setting is only available when support for OpenSSL was built in and |
| OpenSSL 1.1.1 or later was used to build HAProxy. It sets the default |
| string describing the list of cipher algorithms that are negotiated during |
| the TLSv1.3 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" from OpenSSL man pages under the section "ciphersuites". For |
| cipher configuration for TLSv1.2 and earlier, please check the |
| "ssl-default-server-ciphers" keyword. Please check the "server" keyword for |
| more information. |
| |
| ssl-default-server-options [<option>]... |
| This setting is only available when support for OpenSSL was built in. It sets |
| default ssl-options to force on all "server" lines. Please check the "server" |
| keyword to see available options. |
| |
| ssl-dh-param-file <file> |
| This setting is only available when support for OpenSSL was built in. It sets |
| the default DH parameters that are used during the SSL/TLS handshake when |
| ephemeral Diffie-Hellman (DHE) key exchange is used, for all "bind" lines |
| which do not explicitly define theirs. It will be overridden by custom DH |
| parameters found in a bind certificate file if any. If custom DH parameters |
| are not specified either by using ssl-dh-param-file or by setting them |
| directly in the certificate file, pre-generated DH parameters of the size |
| specified by tune.ssl.default-dh-param will be used. Custom parameters are |
| known to be more secure and therefore their use is recommended. |
| Custom DH parameters may be generated by using the OpenSSL command |
| "openssl dhparam <size>", where size should be at least 2048, as 1024-bit DH |
| parameters should not be considered secure anymore. |
| |
| ssl-load-extra-del-ext |
| This setting allows to configure the way HAProxy does the lookup for the |
| extra SSL files. By default HAProxy adds a new extension to the filename. |
| (ex: with "foobar.crt" load "foobar.crt.key"). With this option enabled, |
| HAProxy removes the extension before adding the new one (ex: with |
| "foobar.crt" load "foobar.key"). |
| |
| Your crt file must have a ".crt" extension for this option to work. |
| |
| This option is not compatible with bundle extensions (.ecdsa, .rsa. .dsa) |
| and won't try to remove them. |
| |
| This option is disabled by default. See also "ssl-load-extra-files". |
| |
| ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>* |
| This setting alters the way HAProxy will look for unspecified files during |
| the loading of the SSL certificates. This option applies to certificates |
| associated to "bind" lines as well as "server" lines but some of the extra |
| files will not have any functional impact for "server" line certificates. |
| |
| By default, HAProxy discovers automatically a lot of files not specified in |
| the configuration, and you may want to disable this behavior if you want to |
| optimize the startup time. |
| |
| "none": Only load the files specified in the configuration. Don't try to load |
| a certificate bundle if the file does not exist. In the case of a directory, |
| it won't try to bundle the certificates if they have the same basename. |
| |
| "all": This is the default behavior, it will try to load everything, |
| bundles, sctl, ocsp, issuer, key. |
| |
| "bundle": When a file specified in the configuration does not exist, HAProxy |
| will try to load a "cert bundle". Certificate bundles are only managed on the |
| frontend side and will not work for backend certificates. |
| |
| Starting from HAProxy 2.3, the bundles are not loaded in the same OpenSSL |
| certificate store, instead it will loads each certificate in a separate |
| store which is equivalent to declaring multiple "crt". OpenSSL 1.1.1 is |
| required to achieve this. Which means that bundles are now used only for |
| backward compatibility and are not mandatory anymore to do an hybrid RSA/ECC |
| bind configuration. |
| |
| To associate these PEM files into a "cert bundle" that is recognized by |
| HAProxy, they must be named in the following way: All PEM files that are to |
| be bundled must have the same base name, with a suffix indicating the key |
| type. Currently, three suffixes are supported: rsa, dsa and ecdsa. For |
| example, if www.example.com has two PEM files, an RSA file and an ECDSA |
| file, they must be named: "example.pem.rsa" and "example.pem.ecdsa". The |
| first part of the filename is arbitrary; only the suffix matters. To load |
| this bundle into HAProxy, specify the base name only: |
| |
| Example : bind :8443 ssl crt example.pem |
| |
| Note that the suffix is not given to HAProxy; this tells HAProxy to look for |
| a cert bundle. |
| |
| HAProxy will load all PEM files in the bundle as if they were configured |
| separately in several "crt". |
| |
| The bundle loading does not have an impact anymore on the directory loading |
| since files are loading separately. |
| |
| On the CLI, bundles are seen as separate files, and the bundle extension is |
| required to commit them. |
| |
| OCSP files (.ocsp), issuer files (.issuer), Certificate Transparency (.sctl) |
| as well as private keys (.key) are supported with multi-cert bundling. |
| |
| "sctl": Try to load "<basename>.sctl" for each crt keyword. If provided for |
| a backend certificate, it will be loaded but will not have any functional |
| impact. |
| |
| "ocsp": Try to load "<basename>.ocsp" for each crt keyword. If provided for |
| a backend certificate, it will be loaded but will not have any functional |
| impact. |
| |
| "issuer": Try to load "<basename>.issuer" if the issuer of the OCSP file is |
| not provided in the PEM file. If provided for a backend certificate, it will |
| be loaded but will not have any functional impact. |
| |
| "key": If the private key was not provided by the PEM file, try to load a |
| file "<basename>.key" containing a private key. |
| |
| The default behavior is "all". |
| |
| Example: |
| ssl-load-extra-files bundle sctl |
| ssl-load-extra-files sctl ocsp issuer |
| ssl-load-extra-files none |
| |
| See also: "crt", section 5.1 about bind options and section 5.2 about server |
| options. |
| |
| ssl-server-verify [none|required] |
| The default behavior for SSL verify on servers side. If specified to 'none', |
| servers certificates are not verified. The default is 'required' except if |
| forced using cmdline option '-dV'. |
| |
| ssl-skip-self-issued-ca |
| Self issued CA, aka x509 root CA, is the anchor for chain validation: as a |
| server is useless to send it, client must have it. Standard configuration |
| need to not include such CA in PEM file. This option allows you to keep such |
| CA in PEM file without sending it to the client. Use case is to provide |
| issuer for ocsp without the need for '.issuer' file and be able to share it |
| with 'issuers-chain-path'. This concerns all certificates without intermediate |
| certificates. It's useless for BoringSSL, .issuer is ignored because ocsp |
| bits does not need it. Requires at least OpenSSL 1.0.2. |
| |
| stats socket [<address:port>|<path>] [param*] |
| Binds a UNIX socket to <path> or a TCPv4/v6 address to <address:port>. |
| 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.3 "Unix Socket commands" of Management Guide 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 <timeout, in milliseconds> |
| The default timeout on the stats socket is set to 10 seconds. It is possible |
| to change this value with "stats timeout". The value must be passed in |
| milliseconds, or be suffixed by a time unit among { us, ms, s, m, h, d }. |
| |
| stats maxconn <connections> |
| By default, the stats socket is limited to 10 concurrent connections. It is |
| possible to change this value with "stats maxconn". |
| |
| uid <number> |
| Changes the process's user ID to <number>. It is recommended that the user ID |
| is dedicated to HAProxy or to a small set of similar daemons. HAProxy must |
| be started with superuser privileges in order to be able to switch to another |
| one. See also "gid" and "user". |
| |
| ulimit-n <number> |
| Sets the maximum number of per-process file-descriptors to <number>. By |
| default, it is automatically computed, so it is recommended not to use this |
| option. |
| |
| unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ] |
| [ group <group> ] [ gid <gid> ] |
| |
| Fixes common settings to UNIX listening sockets declared in "bind" statements. |
| This is mainly used to simplify declaration of those UNIX sockets and reduce |
| the risk of errors, since those settings are most commonly required but are |
| also process-specific. The <prefix> setting can be used to force all socket |
| path to be relative to that directory. This might be needed to access another |
| component's chroot. Note that those paths are resolved before HAProxy chroots |
| itself, so they are absolute. The <mode>, <user>, <uid>, <group> and <gid> |
| all have the same meaning as their homonyms used by the "bind" statement. If |
| both are specified, the "bind" statement has priority, meaning that the |
| "unix-bind" settings may be seen as process-wide default settings. |
| |
| unsetenv [<name> ...] |
| Removes environment variables specified in arguments. This can be useful to |
| hide some sensitive information that are occasionally inherited from the |
| user's environment during some operations. Variables which did not exist are |
| silently ignored so that after the operation, it is certain that none of |
| these variables remain. The changes immediately take effect so that the next |
| line in the configuration file will not see these variables. See also |
| "setenv", "presetenv", and "resetenv". |
| |
| user <user name> |
| Similar to "uid" but uses the UID of user name <user name> from /etc/passwd. |
| See also "uid" and "group". |
| |
| node <name> |
| Only letters, digits, hyphen and underscore are allowed, like in DNS names. |
| |
| This statement is useful in HA configurations where two or more processes or |
| servers share the same IP address. By setting a different node-name on all |
| nodes, it becomes easy to immediately spot what server is handling the |
| traffic. |
| |
| description <text> |
| Add a text that describes the instance. |
| |
| Please note that it is required to escape certain characters (# for example) |
| and this text is inserted into a html page so you should avoid using |
| "<" and ">" characters. |
| |
| 51degrees-data-file <file path> |
| The path of the 51Degrees data file to provide device detection services. The |
| file should be unzipped and accessible by HAProxy with relevant permissions. |
| |
| Please note that this option is only available when HAProxy has been |
| compiled with USE_51DEGREES. |
| |
| 51degrees-property-name-list [<string> ...] |
| A list of 51Degrees property names to be load from the dataset. A full list |
| of names is available on the 51Degrees website: |
| https://51degrees.com/resources/property-dictionary |
| |
| Please note that this option is only available when HAProxy has been |
| compiled with USE_51DEGREES. |
| |
| 51degrees-property-separator <char> |
| A char that will be appended to every property value in a response header |
| containing 51Degrees results. If not set that will be set as ','. |
| |
| Please note that this option is only available when HAProxy has been |
| compiled with USE_51DEGREES. |
| |
| 51degrees-cache-size <number> |
| Sets the size of the 51Degrees converter cache to <number> entries. This |
| is an LRU cache which reminds previous device detections and their results. |
| By default, this cache is disabled. |
| |
| Please note that this option is only available when HAProxy has been |
| compiled with USE_51DEGREES. |
| |
| wurfl-data-file <file path> |
| The path of the WURFL data file to provide device detection services. The |
| file should be accessible by HAProxy with relevant permissions. |
| |
| Please note that this option is only available when HAProxy has been compiled |
| with USE_WURFL=1. |
| |
| wurfl-information-list [<capability>]* |
| A space-delimited list of WURFL capabilities, virtual capabilities, property |
| names we plan to use in injected headers. A full list of capability and |
| virtual capability names is available on the Scientiamobile website : |
| |
| https://www.scientiamobile.com/wurflCapability |
| |
| Valid WURFL properties are: |
| - wurfl_id Contains the device ID of the matched device. |
| |
| - wurfl_root_id Contains the device root ID of the matched |
| device. |
| |
| - wurfl_isdevroot Tells if the matched device is a root device. |
| Possible values are "TRUE" or "FALSE". |
| |
| - wurfl_useragent The original useragent coming with this |
| particular web request. |
| |
| - wurfl_api_version Contains a string representing the currently |
| used Libwurfl API version. |
| |
| - wurfl_info A string containing information on the parsed |
| wurfl.xml and its full path. |
| |
| - wurfl_last_load_time Contains the UNIX timestamp of the last time |
| WURFL has been loaded successfully. |
| |
| - wurfl_normalized_useragent The normalized useragent. |
| |
| Please note that this option is only available when HAProxy has been compiled |
| with USE_WURFL=1. |
| |
| wurfl-information-list-separator <char> |
| A char that will be used to separate values in a response header containing |
| WURFL results. If not set that a comma (',') will be used by default. |
| |
| Please note that this option is only available when HAProxy has been compiled |
| with USE_WURFL=1. |
| |
| wurfl-patch-file [<file path>] |
| A list of WURFL patch file paths. Note that patches are loaded during startup |
| thus before the chroot. |
| |
| Please note that this option is only available when HAProxy has been compiled |
| with USE_WURFL=1. |
| |
| wurfl-cache-size <size> |
| Sets the WURFL Useragent cache size. For faster lookups, already processed user |
| agents are kept in a LRU cache : |
| - "0" : no cache is used. |
| - <size> : size of lru cache in elements. |
| |
| Please note that this option is only available when HAProxy has been compiled |
| with USE_WURFL=1. |
| |
| strict-limits |
| Makes process fail at startup when a setrlimit fails. HAProxy tries to set the |
| best setrlimit according to what has been calculated. If it fails, it will |
| emit a warning. This option is here to guarantee an explicit failure of |
| HAProxy when those limits fail. It is enabled by default. It may still be |
| forcibly disabled by prefixing it with the "no" keyword. |
| |
| 3.2. Performance tuning |
| ----------------------- |
| |
| busy-polling |
| In some situations, especially when dealing with low latency on processors |
| supporting a variable frequency or when running inside virtual machines, each |
| time the process waits for an I/O using the poller, the processor goes back |
| to sleep or is offered to another VM for a long time, and it causes |
| excessively high latencies. This option provides a solution preventing the |
| processor from sleeping by always using a null timeout on the pollers. This |
| results in a significant latency reduction (30 to 100 microseconds observed) |
| at the expense of a risk to overheat the processor. It may even be used with |
| threads, in which case improperly bound threads may heavily conflict, |
| resulting in a worse performance and high values for the CPU stolen fields |
| in "show info" output, indicating which threads are misconfigured. It is |
| important not to let the process run on the same processor as the network |
| interrupts when this option is used. It is also better to avoid using it on |
| multiple CPU threads sharing the same core. This option is disabled by |
| default. If it has been enabled, it may still be forcibly disabled by |
| prefixing it with the "no" keyword. It is ignored by the "select" and |
| "poll" pollers. |
| |
| This option is automatically disabled on old processes in the context of |
| seamless reload; it avoids too much cpu conflicts when multiple processes |
| stay around for some time waiting for the end of their current connections. |
| |
| max-spread-checks <delay in milliseconds> |
| By default, HAProxy tries to spread the start of health checks across the |
| smallest health check interval of all the servers in a farm. The principle is |
| to avoid hammering services running on the same server. But when using large |
| check intervals (10 seconds or more), the last servers in the farm take some |
| time before starting to be tested, which can be a problem. This parameter is |
| used to enforce an upper bound on delay between the first and the last check, |
| even if the servers' check intervals are larger. When servers run with |
| shorter intervals, their intervals will be respected though. |
| |
| maxconn <number> |
| Sets the maximum per-process number of concurrent connections to <number>. It |
| is equivalent to the command-line argument "-n". Proxies will stop accepting |
| connections when this limit is reached. The "ulimit-n" parameter is |
| automatically adjusted according to this value. See also "ulimit-n". Note: |
| the "select" poller cannot reliably use more than 1024 file descriptors on |
| some platforms. If your platform only supports select and reports "select |
| FAILED" on startup, you need to reduce maxconn until it works (slightly |
| below 500 in general). If this value is not set, it will automatically be |
| calculated based on the current file descriptors limit reported by the |
| "ulimit -n" command, possibly reduced to a lower value if a memory limit |
| is enforced, based on the buffer size, memory allocated to compression, SSL |
| cache size, and use or not of SSL and the associated maxsslconn (which can |
| also be automatic). |
| |
| maxconnrate <number> |
| Sets the maximum per-process number of connections per second to <number>. |
| Proxies will stop accepting connections when this limit is reached. It can be |
| used to limit the global capacity regardless of each frontend capacity. It is |
| important to note that this can only be used as a service protection measure, |
| as there will not necessarily be a fair share between frontends when the |
| limit is reached, so it's a good idea to also limit each frontend to some |
| value close to its expected share. Also, lowering tune.maxaccept can improve |
| fairness. |
| |
| maxcomprate <number> |
| Sets the maximum per-process input compression rate to <number> kilobytes |
| per second. For each session, if the maximum is reached, the compression |
| level will be decreased during the session. If the maximum is reached at the |
| beginning of a session, the session will not compress at all. If the maximum |
| is not reached, the compression level will be increased up to |
| tune.comp.maxlevel. A value of zero means there is no limit, this is the |
| default value. |
| |
| maxcompcpuusage <number> |
| Sets the maximum CPU usage HAProxy can reach before stopping the compression |
| for new requests or decreasing the compression level of current requests. |
| It works like 'maxcomprate' but measures CPU usage instead of incoming data |
| bandwidth. The value is expressed in percent of the CPU used by HAProxy. In |
| case of multiple processes (nbproc > 1), each process manages its individual |
| usage. A value of 100 disable the limit. The default value is 100. Setting |
| a lower value will prevent the compression work from slowing the whole |
| process down and from introducing high latencies. |
| |
| maxpipes <number> |
| Sets the maximum per-process number of pipes to <number>. Currently, pipes |
| are only used by kernel-based tcp splicing. Since a pipe contains two file |
| descriptors, the "ulimit-n" value will be increased accordingly. The default |
| value is maxconn/4, which seems to be more than enough for most heavy usages. |
| The splice code dynamically allocates and releases pipes, and can fall back |
| to standard copy, so setting this value too low may only impact performance. |
| |
| maxsessrate <number> |
| Sets the maximum per-process number of sessions per second to <number>. |
| Proxies will stop accepting connections when this limit is reached. It can be |
| used to limit the global capacity regardless of each frontend capacity. It is |
| important to note that this can only be used as a service protection measure, |
| as there will not necessarily be a fair share between frontends when the |
| limit is reached, so it's a good idea to also limit each frontend to some |
| value close to its expected share. Also, lowering tune.maxaccept can improve |
| fairness. |
| |
| maxsslconn <number> |
| Sets the maximum per-process number of concurrent SSL connections to |
| <number>. By default there is no SSL-specific limit, which means that the |
| global maxconn setting will apply to all connections. Setting this limit |
| avoids having openssl use too much memory and crash when malloc returns NULL |
| (since it unfortunately does not reliably check for such conditions). Note |
| that the limit applies both to incoming and outgoing connections, so one |
| connection which is deciphered then ciphered accounts for 2 SSL connections. |
| If this value is not set, but a memory limit is enforced, this value will be |
| automatically computed based on the memory limit, maxconn, the buffer size, |
| memory allocated to compression, SSL cache size, and use of SSL in either |
| frontends, backends or both. If neither maxconn nor maxsslconn are specified |
| when there is a memory limit, HAProxy will automatically adjust these values |
| so that 100% of the connections can be made over SSL with no risk, and will |
| consider the sides where it is enabled (frontend, backend, both). |
| |
| maxsslrate <number> |
| Sets the maximum per-process number of SSL sessions per second to <number>. |
| SSL listeners will stop accepting connections when this limit is reached. It |
| can be used to limit the global SSL CPU usage regardless of each frontend |
| capacity. It is important to note that this can only be used as a service |
| protection measure, as there will not necessarily be a fair share between |
| frontends when the limit is reached, so it's a good idea to also limit each |
| frontend to some value close to its expected share. It is also important to |
| note that the sessions are accounted before they enter the SSL stack and not |
| after, which also protects the stack against bad handshakes. Also, lowering |
| tune.maxaccept can improve fairness. |
| |
| maxzlibmem <number> |
| Sets the maximum amount of RAM in megabytes per process usable by the zlib. |
| When the maximum amount is reached, future sessions will not compress as long |
| as RAM is unavailable. When sets to 0, there is no limit. |
| The default value is 0. The value is available in bytes on the UNIX socket |
| with "show info" on the line "MaxZlibMemUsage", the memory used by zlib is |
| "ZlibMemUsage" in bytes. |
| |
| no-memory-trimming |
| Disables memory trimming ("malloc_trim") at a few moments where attempts are |
| made to reclaim lots of memory (on memory shortage or on reload). Trimming |
| memory forces the system's allocator to scan all unused areas and to release |
| them. This is generally seen as nice action to leave more available memory to |
| a new process while the old one is unlikely to make significant use of it. |
| But some systems dealing with tens to hundreds of thousands of concurrent |
| connections may experience a lot of memory fragmentation, that may render |
| this release operation extremely long. During this time, no more traffic |
| passes through the process, new connections are not accepted anymore, some |
| health checks may even fail, and the watchdog may even trigger and kill the |
| unresponsive process, leaving a huge core dump. If this ever happens, then it |
| is suggested to use this option to disable trimming and stop trying to be |
| nice with the new process. Note that advanced memory allocators usually do |
| not suffer from such a problem. |
| |
| noepoll |
| Disables the use of the "epoll" event polling system on Linux. It is |
| equivalent to the command-line argument "-de". The next polling system |
| used will generally be "poll". See also "nopoll". |
| |
| nokqueue |
| Disables the use of the "kqueue" event polling system on BSD. It is |
| equivalent to the command-line argument "-dk". The next polling system |
| used will generally be "poll". See also "nopoll". |
| |
| noevports |
| Disables the use of the event ports event polling system on SunOS systems |
| derived from Solaris 10 and later. It is equivalent to the command-line |
| argument "-dv". The next polling system used will generally be "poll". See |
| also "nopoll". |
| |
| nopoll |
| Disables the use of the "poll" event polling system. It is equivalent to the |
| command-line argument "-dp". The next polling system used will be "select". |
| It should never be needed to disable "poll" since it's available on all |
| platforms supported by HAProxy. See also "nokqueue", "noepoll" and |
| "noevports". |
| |
| nosplice |
| Disables the use of kernel tcp splicing between sockets on Linux. It is |
| equivalent to the command line argument "-dS". Data will then be copied |
| using conventional and more portable recv/send calls. Kernel tcp splicing is |
| limited to some very recent instances of kernel 2.6. Most versions between |
| 2.6.25 and 2.6.28 are buggy and will forward corrupted data, so they must not |
| be used. This option makes it easier to globally disable kernel splicing in |
| case of doubt. See also "option splice-auto", "option splice-request" and |
| "option splice-response". |
| |
| nogetaddrinfo |
| Disables the use of getaddrinfo(3) for name resolving. It is equivalent to |
| the command line argument "-dG". Deprecated gethostbyname(3) will be used. |
| |
| noreuseport |
| Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the |
| command line argument "-dR". |
| |
| profiling.memory { on | off } |
| Enables ('on') or disables ('off') per-function memory profiling. This will |
| keep usage statistics of malloc/calloc/realloc/free calls anywhere in the |
| process (including libraries) which will be reported on the CLI using the |
| "show profiling" command. This is essentially meant to be used when an |
| abnormal memory usage is observed that cannot be explained by the pools and |
| other info are required. The performance hit will typically be around 1%, |
| maybe a bit more on highly threaded machines, so it is normally suitable for |
| use in production. The same may be achieved at run time on the CLI using the |
| "set profiling memory" command, please consult the management manual. |
| |
| profiling.tasks { auto | on | off } |
| Enables ('on') or disables ('off') per-task CPU profiling. When set to 'auto' |
| the profiling automatically turns on a thread when it starts to suffer from |
| an average latency of 1000 microseconds or higher as reported in the |
| "avg_loop_us" activity field, and automatically turns off when the latency |
| returns below 990 microseconds (this value is an average over the last 1024 |
| loops so it does not vary quickly and tends to significantly smooth short |
| spikes). It may also spontaneously trigger from time to time on overloaded |
| systems, containers, or virtual machines, or when the system swaps (which |
| must absolutely never happen on a load balancer). |
| |
| CPU profiling per task can be very convenient to report where the time is |
| spent and which requests have what effect on which other request. Enabling |
| it will typically affect the overall's performance by less than 1%, thus it |
| is recommended to leave it to the default 'auto' value so that it only |
| operates when a problem is identified. This feature requires a system |
| supporting the clock_gettime(2) syscall with clock identifiers |
| CLOCK_MONOTONIC and CLOCK_THREAD_CPUTIME_ID, otherwise the reported time will |
| be zero. This option may be changed at run time using "set profiling" on the |
| CLI. |
| |
| spread-checks <0..50, in percent> |
| Sometimes it is desirable to avoid sending agent and health checks to |
| servers at exact intervals, for instance when many logical servers are |
| located on the same physical server. With the help of this parameter, it |
| becomes possible to add some randomness in the check interval between 0 |
| and +/- 50%. A value between 2 and 5 seems to show good results. The |
| default value remains at 0. |
| |
| ssl-engine <name> [algo <comma-separated list of algorithms>] |
| Sets the OpenSSL engine to <name>. List of valid values for <name> may be |
| obtained using the command "openssl engine". This statement may be used |
| multiple times, it will simply enable multiple crypto engines. Referencing an |
| unsupported engine will prevent HAProxy from starting. Note that many engines |
| will lead to lower HTTPS performance than pure software with recent |
| processors. The optional command "algo" sets the default algorithms an ENGINE |
| will supply using the OPENSSL function ENGINE_set_default_string(). A value |
| of "ALL" uses the engine for all cryptographic operations. If no list of |
| algo is specified then the value of "ALL" is used. A comma-separated list |
| of different algorithms may be specified, including: RSA, DSA, DH, EC, RAND, |
| CIPHERS, DIGESTS, PKEY, PKEY_CRYPTO, PKEY_ASN1. This is the same format that |
| openssl configuration file uses: |
| https://www.openssl.org/docs/man1.0.2/apps/config.html |
| |
| ssl-mode-async |
| Adds SSL_MODE_ASYNC mode to the SSL context. This enables asynchronous TLS |
| I/O operations if asynchronous capable SSL engines are used. The current |
| implementation supports a maximum of 32 engines. The Openssl ASYNC API |
| doesn't support moving read/write buffers and is not compliant with |
| HAProxy's buffer management. So the asynchronous mode is disabled on |
| read/write operations (it is only enabled during initial and renegotiation |
| handshakes). |
| |
| tune.buffers.limit <number> |
| Sets a hard limit on the number of buffers which may be allocated per process. |
| The default value is zero which means unlimited. The minimum non-zero value |
| will always be greater than "tune.buffers.reserve" and should ideally always |
| be about twice as large. Forcing this value can be particularly useful to |
| limit the amount of memory a process may take, while retaining a sane |
| behavior. When this limit is reached, sessions which need a buffer wait for |
| another one to be released by another session. Since buffers are dynamically |
| allocated and released, the waiting time is very short and not perceptible |
| provided that limits remain reasonable. In fact sometimes reducing the limit |
| may even increase performance by increasing the CPU cache's efficiency. Tests |
| have shown good results on average HTTP traffic with a limit to 1/10 of the |
| expected global maxconn setting, which also significantly reduces memory |
| usage. The memory savings come from the fact that a number of connections |
| will not allocate 2*tune.bufsize. It is best not to touch this value unless |
| advised to do so by an HAProxy core developer. |
| |
| tune.buffers.reserve <number> |
| Sets the number of buffers which are pre-allocated and reserved for use only |
| during memory shortage conditions resulting in failed memory allocations. The |
| minimum value is 2 and is also the default. There is no reason a user would |
| want to change this value, it's mostly aimed at HAProxy core developers. |
| |
| tune.bufsize <number> |
| Sets the buffer size to this size (in bytes). Lower values allow more |
| sessions to coexist in the same amount of RAM, and higher values allow some |
| applications with very large cookies to work. The default value is 16384 and |
| can be changed at build time. It is strongly recommended not to change this |
| from the default value, as very low values will break some services such as |
| statistics, and values larger than default size will increase memory usage, |
| possibly causing the system to run out of memory. At least the global maxconn |
| parameter should be decreased by the same factor as this one is increased. In |
| addition, use of HTTP/2 mandates that this value must be 16384 or more. If an |
| HTTP request is larger than (tune.bufsize - tune.maxrewrite), HAProxy will |
| return HTTP 400 (Bad Request) error. Similarly if an HTTP response is larger |
| than this size, HAProxy will return HTTP 502 (Bad Gateway). Note that the |
| value set using this parameter will automatically be rounded up to the next |
| multiple of 8 on 32-bit machines and 16 on 64-bit machines. |
| |
| tune.chksize <number> (deprecated) |
| This option is deprecated and ignored. |
| |
| tune.comp.maxlevel <number> |
| Sets the maximum compression level. The compression level affects CPU |
| usage during compression. This value affects CPU usage during compression. |
| Each session using compression initializes the compression algorithm with |
| this value. The default value is 1. |
| |
| tune.fail-alloc |
| If compiled with DEBUG_FAIL_ALLOC, gives the percentage of chances an |
| allocation attempt fails. Must be between 0 (no failure) and 100 (no |
| success). This is useful to debug and make sure memory failures are handled |
| gracefully. |
| |
| tune.fd.edge-triggered { on | off } [ EXPERIMENTAL ] |
| Enables ('on') or disables ('off') the edge-triggered polling mode for FDs |
| that support it. This is currently only support with epoll. It may noticeably |
| reduce the number of epoll_ctl() calls and slightly improve performance in |
| certain scenarios. This is still experimental, it may result in frozen |
| connections if bugs are still present, and is disabled by default. |
| |
| tune.h2.header-table-size <number> |
| Sets the HTTP/2 dynamic header table size. It defaults to 4096 bytes and |
| cannot be larger than 65536 bytes. A larger value may help certain clients |
| send more compact requests, depending on their capabilities. This amount of |
| memory is consumed for each HTTP/2 connection. It is recommended not to |
| change it. |
| |
| tune.h2.initial-window-size <number> |
| Sets the HTTP/2 initial window size, which is the number of bytes the client |
| can upload before waiting for an acknowledgment from HAProxy. This setting |
| only affects payload contents (i.e. the body of POST requests), not headers. |
| The default value is 65535, which roughly allows up to 5 Mbps of upload |
| bandwidth per client over a network showing a 100 ms ping time, or 500 Mbps |
| over a 1-ms local network. It can make sense to increase this value to allow |
| faster uploads, or to reduce it to increase fairness when dealing with many |
| clients. It doesn't affect resource usage. |
| |
| tune.h2.max-concurrent-streams <number> |
| Sets the HTTP/2 maximum number of concurrent streams per connection (ie the |
| number of outstanding requests on a single connection). The default value is |
| 100. A larger one may slightly improve page load time for complex sites when |
| visited over high latency networks, but increases the amount of resources a |
| single client may allocate. A value of zero disables the limit so a single |
| client may create as many streams as allocatable by HAProxy. It is highly |
| recommended not to change this value. |
| |
| tune.h2.max-frame-size <number> |
| Sets the HTTP/2 maximum frame size that HAProxy announces it is willing to |
| receive to its peers. The default value is the largest between 16384 and the |
| buffer size (tune.bufsize). In any case, HAProxy will not announce support |
| for frame sizes larger than buffers. The main purpose of this setting is to |
| allow to limit the maximum frame size setting when using large buffers. Too |
| large frame sizes might have performance impact or cause some peers to |
| misbehave. It is highly recommended not to change this value. |
| |
| tune.http.cookielen <number> |
| Sets the maximum length of captured cookies. This is the maximum value that |
| the "capture cookie xxx len yyy" will be allowed to take, and any upper value |
| will automatically be truncated to this one. It is important not to set too |
| high a value because all cookie captures still allocate this size whatever |
| their configured value (they share a same pool). This value is per request |
| per response, so the memory allocated is twice this value per connection. |
| When not specified, the limit is set to 63 characters. It is recommended not |
| to change this value. |
| |
| tune.http.logurilen <number> |
| Sets the maximum length of request URI in logs. This prevents truncating long |
| request URIs with valuable query strings in log lines. This is not related |
| to syslog limits. If you increase this limit, you may also increase the |
| 'log ... len yyy' parameter. Your syslog daemon may also need specific |
| configuration directives too. |
| The default value is 1024. |
| |
| tune.http.maxhdr <number> |
| Sets the maximum number of headers in a request. When a request comes with a |
| number of headers greater than this value (including the first line), it is |
| rejected with a "400 Bad Request" status code. Similarly, too large responses |
| are blocked with "502 Bad Gateway". The default value is 101, which is enough |
| for all usages, considering that the widely deployed Apache server uses the |
| same limit. It can be useful to push this limit further to temporarily allow |
| a buggy application to work by the time it gets fixed. The accepted range is |
| 1..32767. Keep in mind that each new header consumes 32bits of memory for |
| each session, so don't push this limit too high. |
| |
| tune.idle-pool.shared { on | off } |
| Enables ('on') or disables ('off') sharing of idle connection pools between |
| threads for a same server. The default is to share them between threads in |
| order to minimize the number of persistent connections to a server, and to |
| optimize the connection reuse rate. But to help with debugging or when |
| suspecting a bug in HAProxy around connection reuse, it can be convenient to |
| forcefully disable this idle pool sharing between multiple threads, and force |
| this option to "off". The default is on. It is strongly recommended against |
| disabling this option without setting a conservative value on "pool-low-conn" |
| for all servers relying on connection reuse to achieve a high performance |
| level, otherwise connections might be closed very often as the thread count |
| increases. |
| |
| tune.idletimer <timeout> |
| Sets the duration after which HAProxy will consider that an empty buffer is |
| probably associated with an idle stream. This is used to optimally adjust |
| some packet sizes while forwarding large and small data alternatively. The |
| decision to use splice() or to send large buffers in SSL is modulated by this |
| parameter. The value is in milliseconds between 0 and 65535. A value of zero |
| means that HAProxy will not try to detect idle streams. The default is 1000, |
| which seems to correctly detect end user pauses (e.g. read a page before |
| clicking). There should be no reason for changing this value. Please check |
| tune.ssl.maxrecord below. |
| |
| tune.listener.multi-queue { on | off } |
| Enables ('on') or disables ('off') the listener's multi-queue accept which |
| spreads the incoming traffic to all threads a "bind" line is allowed to run |
| on instead of taking them for itself. This provides a smoother traffic |
| distribution and scales much better, especially in environments where threads |
| may be unevenly loaded due to external activity (network interrupts colliding |
| with one thread for example). This option is enabled by default, but it may |
| be forcefully disabled for troubleshooting or for situations where it is |
| estimated that the operating system already provides a good enough |
| distribution and connections are extremely short-lived. |
| |
| tune.lua.forced-yield <number> |
| This directive forces the Lua engine to execute a yield each <number> of |
| instructions executed. This permits interrupting a long script and allows the |
| HAProxy scheduler to process other tasks like accepting connections or |
| forwarding traffic. The default value is 10000 instructions. If HAProxy often |
| executes some Lua code but more responsiveness is required, this value can be |
| lowered. If the Lua code is quite long and its result is absolutely required |
| to process the data, the <number> can be increased. |
| |
| tune.lua.maxmem |
| Sets the maximum amount of RAM in megabytes per process usable by Lua. By |
| default it is zero which means unlimited. It is important to set a limit to |
| ensure that a bug in a script will not result in the system running out of |
| memory. |
| |
| tune.lua.session-timeout <timeout> |
| This is the execution timeout for the Lua sessions. This is useful for |
| preventing infinite loops or spending too much time in Lua. This timeout |
| counts only the pure Lua runtime. If the Lua does a sleep, the sleep is |
| not taken in account. The default timeout is 4s. |
| |
| tune.lua.task-timeout <timeout> |
| Purpose is the same as "tune.lua.session-timeout", but this timeout is |
| dedicated to the tasks. By default, this timeout isn't set because a task may |
| remain alive during of the lifetime of HAProxy. For example, a task used to |
| check servers. |
| |
| tune.lua.service-timeout <timeout> |
| This is the execution timeout for the Lua services. This is useful for |
| preventing infinite loops or spending too much time in Lua. This timeout |
| counts only the pure Lua runtime. If the Lua does a sleep, the sleep is |
| not taken in account. The default timeout is 4s. |
| |
| tune.maxaccept <number> |
| Sets the maximum number of consecutive connections a process may accept in a |
| row before switching to other work. In single process mode, higher numbers |
| used to give better performance at high connection rates, though this is not |
| the case anymore with the multi-queue. This value applies individually to |
| each listener, so that the number of processes a listener is bound to is |
| taken into account. This value defaults to 4 which showed best results. If a |
| significantly higher value was inherited from an ancient config, it might be |
| worth removing it as it will both increase performance and lower response |
| time. In multi-process mode, it is divided by twice the number of processes |
| the listener is bound to. Setting this value to -1 completely disables the |
| limitation. It should normally not be needed to tweak this value. |
| |
| tune.maxpollevents <number> |
| Sets the maximum amount of events that can be processed at once in a call to |
| the polling system. The default value is adapted to the operating system. It |
| has been noticed that reducing it below 200 tends to slightly decrease |
| latency at the expense of network bandwidth, and increasing it above 200 |
| tends to trade latency for slightly increased bandwidth. |
| |
| tune.maxrewrite <number> |
| Sets the reserved buffer space to this size in bytes. The reserved space is |
| used for header rewriting or appending. The first reads on sockets will never |
| fill more than bufsize-maxrewrite. Historically it has defaulted to half of |
| bufsize, though that does not make much sense since there are rarely large |
| numbers of headers to add. Setting it too high prevents processing of large |
| requests or responses. Setting it too low prevents addition of new headers |
| to already large requests or to POST requests. It is generally wise to set it |
| to about 1024. It is automatically readjusted to half of bufsize if it is |
| larger than that. This means you don't have to worry about it when changing |
| bufsize. |
| |
| tune.pattern.cache-size <number> |
| Sets the size of the pattern lookup cache to <number> entries. This is an LRU |
| cache which reminds previous lookups and their results. It is used by ACLs |
| and maps on slow pattern lookups, namely the ones using the "sub", "reg", |
| "dir", "dom", "end", "bin" match methods as well as the case-insensitive |
| strings. It applies to pattern expressions which means that it will be able |
| to memorize the result of a lookup among all the patterns specified on a |
| configuration line (including all those loaded from files). It automatically |
| invalidates entries which are updated using HTTP actions or on the CLI. The |
| default cache size is set to 10000 entries, which limits its footprint to |
| about 5 MB per process/thread on 32-bit systems and 8 MB per process/thread |
| on 64-bit systems, as caches are thread/process local. There is a very low |
| risk of collision in this cache, which is in the order of the size of the |
| cache divided by 2^64. Typically, at 10000 requests per second with the |
| default cache size of 10000 entries, there's 1% chance that a brute force |
| attack could cause a single collision after 60 years, or 0.1% after 6 years. |
| This is considered much lower than the risk of a memory corruption caused by |
| aging components. If this is not acceptable, the cache can be disabled by |
| setting this parameter to 0. |
| |
| tune.pipesize <number> |
| Sets the kernel pipe buffer size to this size (in bytes). By default, pipes |
| are the default size for the system. But sometimes when using TCP splicing, |
| it can improve performance to increase pipe sizes, especially if it is |
| suspected that pipes are not filled and that many calls to splice() are |
| performed. This has an impact on the kernel's memory footprint, so this must |
| not be changed if impacts are not understood. |
| |
| tune.pool-high-fd-ratio <number> |
| This setting sets the max number of file descriptors (in percentage) used by |
| HAProxy globally against the maximum number of file descriptors HAProxy can |
| use before we start killing idle connections when we can't reuse a connection |
| and we have to create a new one. The default is 25 (one quarter of the file |
| descriptor will mean that roughly half of the maximum front connections can |
| keep an idle connection behind, anything beyond this probably doesn't make |
| much sense in the general case when targeting connection reuse). |
| |
| tune.pool-low-fd-ratio <number> |
| This setting sets the max number of file descriptors (in percentage) used by |
| HAProxy globally against the maximum number of file descriptors HAProxy can |
| use before we stop putting connection into the idle pool for reuse. The |
| default is 20. |
| |
| tune.rcvbuf.client <number> |
| tune.rcvbuf.server <number> |
| Forces the kernel socket receive buffer size on the client or the server side |
| to the specified value in bytes. This value applies to all TCP/HTTP frontends |
| and backends. It should normally never be set, and the default size (0) lets |
| the kernel auto-tune this value depending on the amount of available memory. |
| However it can sometimes help to set it to very low values (e.g. 4096) in |
| order to save kernel memory by preventing it from buffering too large amounts |
| of received data. Lower values will significantly increase CPU usage though. |
| |
| tune.recv_enough <number> |
| HAProxy uses some hints to detect that a short read indicates the end of the |
| socket buffers. One of them is that a read returns more than <recv_enough> |
| bytes, which defaults to 10136 (7 segments of 1448 each). This default value |
| may be changed by this setting to better deal with workloads involving lots |
| of short messages such as telnet or SSH sessions. |
| |
| tune.runqueue-depth <number> |
| Sets the maximum amount of task that can be processed at once when running |
| tasks. The default value depends on the number of threads but sits between 35 |
| and 280, which tend to show the highest request rates and lowest latencies. |
| Increasing it may incur latency when dealing with I/Os, making it too small |
| can incur extra overhead. Higher thread counts benefit from lower values. |
| When experimenting with much larger values, it may be useful to also enable |
| tune.sched.low-latency and possibly tune.fd.edge-triggered to limit the |
| maximum latency to the lowest possible. |
| |
| tune.sched.low-latency { on | off } |
| Enables ('on') or disables ('off') the low-latency task scheduler. By default |
| HAProxy processes tasks from several classes one class at a time as this is |
| the most efficient. But when running with large values of tune.runqueue-depth |
| this can have a measurable effect on request or connection latency. When this |
| low-latency setting is enabled, tasks of lower priority classes will always |
| be executed before other ones if they exist. This will permit to lower the |
| maximum latency experienced by new requests or connections in the middle of |
| massive traffic, at the expense of a higher impact on this large traffic. |
| For regular usage it is better to leave this off. The default value is off. |
| |
| tune.sndbuf.client <number> |
| tune.sndbuf.server <number> |
| Forces the kernel socket send buffer size on the client or the server side to |
| the specified value in bytes. This value applies to all TCP/HTTP frontends |
| and backends. It should normally never be set, and the default size (0) lets |
| the kernel auto-tune this value depending on the amount of available memory. |
| However it can sometimes help to set it to very low values (e.g. 4096) in |
| order to save kernel memory by preventing it from buffering too large amounts |
| of received data. Lower values will significantly increase CPU usage though. |
| Another use case is to prevent write timeouts with extremely slow clients due |
| to the kernel waiting for a large part of the buffer to be read before |
| notifying HAProxy again. |
| |
| tune.ssl.cachesize <number> |
| Sets the size of the global SSL session cache, in a number of blocks. A block |
| is large enough to contain an encoded session without peer certificate. An |
| encoded session with peer certificate is stored in multiple blocks depending |
| on the size of the peer certificate. A block uses approximately 200 bytes of |
| memory (based on `sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE` |
| calculation used for `shctx_init` function). The default value may be forced |
| at build time, otherwise defaults to 20000. When the cache is full, the most |
| idle entries are purged and reassigned. Higher values reduce the occurrence |
| of such a purge, hence the number of CPU-intensive SSL handshakes by ensuring |
| that all users keep their session as long as possible. All entries are |
| pre-allocated upon startup and are shared between all processes if "nbproc" |
| is greater than 1. Setting this value to 0 disables the SSL session cache. |
| |
| tune.ssl.force-private-cache |
| This option disables SSL session cache sharing between all processes. It |
| should normally not be used since it will force many renegotiations due to |
| clients hitting a random process. But it may be required on some operating |
| systems where none of the SSL cache synchronization method may be used. In |
| this case, adding a first layer of hash-based load balancing before the SSL |
| layer might limit the impact of the lack of session sharing. |
| |
| tune.ssl.keylog { on | off } |
| This option activates the logging of the TLS keys. It should be used with |
| care as it will consume more memory per SSL session and could decrease |
| performances. This is disabled by default. |
| |
| These sample fetches should be used to generate the SSLKEYLOGFILE that is |
| required to decipher traffic with wireshark. |
| |
| https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format |
| |
| The SSLKEYLOG is a series of lines which are formatted this way: |
| |
| <Label> <space> <ClientRandom> <space> <Secret> |
| |
| The ClientRandom is provided by the %[ssl_fc_client_random,hex] sample |
| fetch, the secret and the Label could be find in the array below. You need |
| to generate a SSLKEYLOGFILE with all the labels in this array. |
| |
| The following sample fetches are hexadecimal strings and does not need to be |
| converted. |
| |
| SSLKEYLOGFILE Label | Sample fetches for the Secrets |
| --------------------------------|----------------------------------------- |
| CLIENT_EARLY_TRAFFIC_SECRET | %[ssl_fc_client_early_traffic_secret] |
| CLIENT_HANDSHAKE_TRAFFIC_SECRET | %[ssl_fc_client_handshake_traffic_secret] |
| SERVER_HANDSHAKE_TRAFFIC_SECRET | %[ssl_fc_server_handshake_traffic_secret] |
| CLIENT_TRAFFIC_SECRET_0 | %[ssl_fc_client_traffic_secret_0] |
| SERVER_TRAFFIC_SECRET_0 | %[ssl_fc_server_traffic_secret_0] |
| EXPORTER_SECRET | %[ssl_fc_exporter_secret] |
| EARLY_EXPORTER_SECRET | %[ssl_fc_early_exporter_secret] |
| |
| This is only available with OpenSSL 1.1.1, and useful with TLS1.3 session. |
| |
| If you want to generate the content of a SSLKEYLOGFILE with TLS < 1.3, you |
| only need this line: |
| |
| "CLIENT_RANDOM %[ssl_fc_client_random,hex] %[ssl_fc_session_key,hex]" |
| |
| tune.ssl.lifetime <timeout> |
| Sets how long a cached SSL session may remain valid. This time is expressed |
| in seconds and defaults to 300 (5 min). It is important to understand that it |
| does not guarantee that sessions will last that long, because if the cache is |
| full, the longest idle sessions will be purged despite their configured |
| lifetime. The real usefulness of this setting is to prevent sessions from |
| being used for too long. |
| |
| tune.ssl.maxrecord <number> |
| Sets the maximum amount of bytes passed to SSL_write() at a time. Default |
| value 0 means there is no limit. Over SSL/TLS, the client can decipher the |
| data only once it has received a full record. With large records, it means |
| that clients might have to download up to 16kB of data before starting to |
| process them. Limiting the value can improve page load times on browsers |
| located over high latency or low bandwidth networks. It is suggested to find |
| optimal values which fit into 1 or 2 TCP segments (generally 1448 bytes over |
| Ethernet with TCP timestamps enabled, or 1460 when timestamps are disabled), |
| keeping in mind that SSL/TLS add some overhead. Typical values of 1419 and |
| 2859 gave good results during tests. Use "strace -e trace=write" to find the |
| best value. HAProxy will automatically switch to this setting after an idle |
| stream has been detected (see tune.idletimer above). |
| |
| tune.ssl.default-dh-param <number> |
| Sets the maximum size of the Diffie-Hellman parameters used for generating |
| the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange. The |
| final size will try to match the size of the server's RSA (or DSA) key (e.g, |
| a 2048 bits temporary DH key for a 2048 bits RSA key), but will not exceed |
| this maximum value. Default value if 2048. Only 1024 or higher values are |
| allowed. Higher values will increase the CPU load, and values greater than |
| 1024 bits are not supported by Java 7 and earlier clients. This value is not |
| used if static Diffie-Hellman parameters are supplied either directly |
| in the certificate file or by using the ssl-dh-param-file parameter. |
| |
| tune.ssl.ssl-ctx-cache-size <number> |
| Sets the size of the cache used to store generated certificates to <number> |
| entries. This is a LRU cache. Because generating a SSL certificate |
| dynamically is expensive, they are cached. The default cache size is set to |
| 1000 entries. |
| |
| tune.ssl.capture-cipherlist-size <number> |
| Sets the maximum size of the buffer used for capturing client-hello cipher |
| list. If the value is 0 (default value) the capture is disabled, otherwise |
| a buffer is allocated for each SSL/TLS connection. |
| |
| tune.vars.global-max-size <size> |
| tune.vars.proc-max-size <size> |
| tune.vars.reqres-max-size <size> |
| tune.vars.sess-max-size <size> |
| tune.vars.txn-max-size <size> |
| These five tunes help to manage the maximum amount of memory used by the |
| variables system. "global" limits the overall amount of memory available for |
| all scopes. "proc" limits the memory for the process scope, "sess" limits the |
| memory for the session scope, "txn" for the transaction scope, and "reqres" |
| limits the memory for each request or response processing. |
| Memory accounting is hierarchical, meaning more coarse grained limits include |
| the finer grained ones: "proc" includes "sess", "sess" includes "txn", and |
| "txn" includes "reqres". |
| |
| For example, when "tune.vars.sess-max-size" is limited to 100, |
| "tune.vars.txn-max-size" and "tune.vars.reqres-max-size" cannot exceed |
| 100 either. If we create a variable "txn.var" that contains 100 bytes, |
| all available space is consumed. |
| Notice that exceeding the limits at runtime will not result in an error |
| message, but values might be cut off or corrupted. So make sure to accurately |
| plan for the amount of space needed to store all your variables. |
| |
| tune.zlib.memlevel <number> |
| Sets the memLevel parameter in zlib initialization for each session. It |
| defines how much memory should be allocated for the internal compression |
| state. A value of 1 uses minimum memory but is slow and reduces compression |
| ratio, a value of 9 uses maximum memory for optimal speed. Can be a value |
| between 1 and 9. The default value is 8. |
| |
| tune.zlib.windowsize <number> |
| Sets the window size (the size of the history buffer) as a parameter of the |
| zlib initialization for each session. Larger values of this parameter result |
| in better compression at the expense of memory usage. Can be a value between |
| 8 and 15. The default value is 15. |
| |
| 3.3. Debugging |
| -------------- |
| |
| quiet |
| Do not display any message during startup. It is equivalent to the command- |
| line argument "-q". |
| |
| zero-warning |
| When this option is set, HAProxy will refuse to start if any warning was |
| emitted while processing the configuration. It is highly recommended to set |
| this option on configurations that are not changed often, as it helps detect |
| subtle mistakes and keep the configuration clean and forward-compatible. Note |
| that "haproxy -c" will also report errors in such a case. This option is |
| equivalent to command line argument "-dW". |
| |
| |
| 3.4. Userlists |
| -------------- |
| It is possible to control access to frontend/backend/listen sections or to |
| http stats by allowing only authenticated and authorized users. To do this, |
| it is required to create at least one userlist and to define users. |
| |
| userlist <listname> |
| Creates new userlist with name <listname>. Many independent userlists can be |
| used to store authentication & authorization data for independent customers. |
| |
| group <groupname> [users <user>,<user>,(...)] |
| Adds group <groupname> to the current userlist. It is also possible to |
| attach users to this group by using a comma separated list of names |
| proceeded by "users" keyword. |
| |
| user <username> [password|insecure-password <password>] |
| [groups <group>,<group>,(...)] |
| Adds user <username> to the current userlist. Both secure (encrypted) and |
| insecure (unencrypted) passwords can be used. Encrypted passwords are |
| evaluated using the crypt(3) function, so depending on the system's |
| capabilities, different algorithms are supported. For example, modern Glibc |
| based Linux systems support MD5, SHA-256, SHA-512, and, of course, the |
| classic DES-based method of encrypting passwords. |
| |
| Attention: Be aware that using encrypted passwords might cause significantly |
| increased CPU usage, depending on the number of requests, and the algorithm |
| used. For any of the hashed variants, the password for each request must |
| be processed through the chosen algorithm, before it can be compared to the |
| value specified in the config file. Most current algorithms are deliberately |
| designed to be expensive to compute to achieve resistance against brute |
| force attacks. They do not simply salt/hash the clear text password once, |
| but thousands of times. This can quickly become a major factor in HAProxy's |
| overall CPU consumption! |
| |
| Example: |
| userlist L1 |
| group G1 users tiger,scott |
| group G2 users xdb,scott |
| |
| user tiger password $6$k6y3o.eP$JlKBx9za9667qe4(...)xHSwRv6J.C0/D7cV91 |
| user scott insecure-password elgato |
| user xdb insecure-password hello |
| |
| userlist L2 |
| group G1 |
| group G2 |
| |
| user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1 |
| user scott insecure-password elgato groups G1,G2 |
| user xdb insecure-password hello groups G2 |
| |
| Please note that both lists are functionally identical. |
| |
| |
| 3.5. Peers |
| ---------- |
| It is possible to propagate entries of any data-types in stick-tables between |
| several HAProxy instances over TCP connections in a multi-master fashion. Each |
| instance pushes its local updates and insertions to remote peers. The pushed |
| values overwrite remote ones without aggregation. Interrupted exchanges are |
| automatically detected and recovered from the last known point. |
| In addition, during a soft restart, the old process connects to the new one |
| using such a TCP connection to push all its entries before the new process |
| tries to connect to other peers. That ensures very fast replication during a |
| reload, it typically takes a fraction of a second even for large tables. |
| Note that Server IDs are used to identify servers remotely, so it is important |
| that configurations look similar or at least that the same IDs are forced on |
| each server on all participants. |
| |
| peers <peersect> |
| Creates a new peer list with name <peersect>. It is an independent section, |
| which is referenced by one or more stick-tables. |
| |
| bind [<address>]:<port_range> [, ...] [param*] |
| Defines the binding parameters of the local peer of this "peers" section. |
| Such lines are not supported with "peer" line in the same "peers" section. |
| |
| disabled |
| Disables a peers section. It disables both listening and any synchronization |
| related to this section. This is provided to disable synchronization of stick |
| tables without having to comment out all "peers" references. |
| |
| default-bind [param*] |
| Defines the binding parameters for the local peer, excepted its address. |
| |
| default-server [param*] |
| Change default options for a server in a "peers" section. |
| |
| Arguments: |
| <param*> is a list of parameters for this server. The "default-server" |
| keyword accepts an important number of options and has a complete |
| section dedicated to it. Please refer to section 5 for more |
| details. |
| |
| |
| See also: "server" and section 5 about server options |
| |
| enabled |
| This re-enables a peers section which was previously disabled via the |
| "disabled" keyword. |
| |
| log <address> [len <length>] [format <format>] [sample <ranges>:<sample_size>] |
| <facility> [<level> [<minlevel>]] |
| "peers" sections support the same "log" keyword as for the proxies to |
| log information about the "peers" listener. See "log" option for proxies for |
| more details. |
| |
| peer <peername> <ip>:<port> [param*] |
| Defines a peer inside a peers section. |
| If <peername> is set to the local peer name (by default hostname, or forced |
| using "-L" command line option or "localpeer" global configuration setting), |
| HAProxy will listen for incoming remote peer connection on <ip>:<port>. |
| Otherwise, <ip>:<port> defines where to connect to in order to join the |
| remote peer, and <peername> is used at the protocol level to identify and |
| validate the remote peer on the server side. |
| |
| During a soft restart, local peer <ip>:<port> is used by the old instance to |
| connect the new one and initiate a complete replication (teaching process). |
| |
| It is strongly recommended to have the exact same peers declaration on all |
| peers and to only rely on the "-L" command line argument or the "localpeer" |
| global configuration setting to change the local peer name. This makes it |
| easier to maintain coherent configuration files across all peers. |
| |
| You may want to reference some environment variables in the address |
| parameter, see section 2.3 about environment variables. |
| |
| Note: "peer" keyword may transparently be replaced by "server" keyword (see |
| "server" keyword explanation below). |
| |
| server <peername> [<ip>:<port>] [param*] |
| As previously mentioned, "peer" keyword may be replaced by "server" keyword |
| with a support for all "server" parameters found in 5.2 paragraph. |
| If the underlying peer is local, <ip>:<port> parameters must not be present. |
| These parameters must be provided on a "bind" line (see "bind" keyword |
| of this "peers" section). |
| Some of these parameters are irrelevant for "peers" sections. |
| |
| |
| Example: |
| # The old way. |
| peers mypeers |
| peer haproxy1 192.168.0.1:1024 |
| peer haproxy2 192.168.0.2:1024 |
| peer haproxy3 10.2.0.1:1024 |
| |
| backend mybackend |
| mode tcp |
| balance roundrobin |
| stick-table type ip size 20k peers mypeers |
| stick on src |
| |
| server srv1 192.168.0.30:80 |
| server srv2 192.168.0.31:80 |
| |
| Example: |
| peers mypeers |
| bind 127.0.0.11:10001 ssl crt mycerts/pem |
| default-server ssl verify none |
| server hostA 127.0.0.10:10000 |
| server hostB #local peer |
| |
| |
| table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]} |
| size <size> [expire <expire>] [nopurge] [store <data_type>]* |
| |
| Configure a stickiness table for the current section. This line is parsed |
| exactly the same way as the "stick-table" keyword in others section, except |
| for the "peers" argument which is not required here and with an additional |
| mandatory first parameter to designate the stick-table. Contrary to others |
| sections, there may be several "table" lines in "peers" sections (see also |
| "stick-table" keyword). |
| |
| Also be aware of the fact that "peers" sections have their own stick-table |
| namespaces to avoid collisions between stick-table names identical in |
| different "peers" section. This is internally handled prepending the "peers" |
| sections names to the name of the stick-tables followed by a '/' character. |
| If somewhere else in the configuration file you have to refer to such |
| stick-tables declared in "peers" sections you must use the prefixed version |
| of the stick-table name as follows: |
| |
| peers mypeers |
| peer A ... |
| peer B ... |
| table t1 ... |
| |
| frontend fe1 |
| tcp-request content track-sc0 src table mypeers/t1 |
| |
| This is also this prefixed version of the stick-table names which must be |
| used to refer to stick-tables through the CLI. |
| |
| About "peers" protocol, as only "peers" belonging to the same section may |
| communicate with each others, there is no need to do such a distinction. |
| Several "peers" sections may declare stick-tables with the same name. |
| This is shorter version of the stick-table name which is sent over the network. |
| There is only a '/' character as prefix to avoid stick-table name collisions between |
| stick-tables declared as backends and stick-table declared in "peers" sections |
| as follows in this weird but supported configuration: |
| |
| peers mypeers |
| peer A ... |
| peer B ... |
| table t1 type string size 10m store gpc0 |
| |
| backend t1 |
| stick-table type string size 10m store gpc0 peers mypeers |
| |
| Here "t1" table declared in "mypeers" section has "mypeers/t1" as global name. |
| "t1" table declared as a backend as "t1" as global name. But at peer protocol |
| level the former table is named "/t1", the latter is again named "t1". |
| |
| 3.6. Mailers |
| ------------ |
| It is possible to send email alerts when the state of servers changes. |
| If configured email alerts are sent to each mailer that is configured |
| in a mailers section. Email is sent to mailers using SMTP. |
| |
| mailers <mailersect> |
| Creates a new mailer list with the name <mailersect>. It is an |
| independent section which is referenced by one or more proxies. |
| |
| mailer <mailername> <ip>:<port> |
| Defines a mailer inside a mailers section. |
| |
| Example: |
| mailers mymailers |
| mailer smtp1 192.168.0.1:587 |
| mailer smtp2 192.168.0.2:587 |
| |
| backend mybackend |
| mode tcp |
| balance roundrobin |
| |
| email-alert mailers mymailers |
| email-alert from test1@horms.org |
| email-alert to test2@horms.org |
| |
| server srv1 192.168.0.30:80 |
| server srv2 192.168.0.31:80 |
| |
| timeout mail <time> |
| Defines the time available for a mail/connection to be made and send to |
| the mail-server. If not defined the default value is 10 seconds. To allow |
| for at least two SYN-ACK packets to be send during initial TCP handshake it |
| is advised to keep this value above 4 seconds. |
| |
| Example: |
| mailers mymailers |
| timeout mail 20s |
| mailer smtp1 192.168.0.1:587 |
| |
| 3.7. Programs |
| ------------- |
| In master-worker mode, it is possible to launch external binaries with the |
| master, these processes are called programs. These programs are launched and |
| managed the same way as the workers. |
| |
| During a reload of HAProxy, those processes are dealing with the same |
| sequence as a worker: |
| |
| - the master is re-executed |
| - the master sends a SIGUSR1 signal to the program |
| - if "option start-on-reload" is not disabled, the master launches a new |
| instance of the program |
| |
| During a stop, or restart, a SIGTERM is sent to the programs. |
| |
| program <name> |
| This is a new program section, this section will create an instance <name> |
| which is visible in "show proc" on the master CLI. (See "9.4. Master CLI" in |
| the management guide). |
| |
| command <command> [arguments*] |
| Define the command to start with optional arguments. The command is looked |
| up in the current PATH if it does not include an absolute path. This is a |
| mandatory option of the program section. Arguments containing spaces must |
| be enclosed in quotes or double quotes or be prefixed by a backslash. |
| |
| user <user name> |
| Changes the executed command user ID to the <user name> from /etc/passwd. |
| See also "group". |
| |
| group <group name> |
| Changes the executed command group ID to the <group name> from /etc/group. |
| See also "user". |
| |
| option start-on-reload |
| no option start-on-reload |
| Start (or not) a new instance of the program upon a reload of the master. |
| The default is to start a new instance. This option may only be used in a |
| program section. |
| |
| |
| 3.8. HTTP-errors |
| ---------------- |
| |
| It is possible to globally declare several groups of HTTP errors, to be |
| imported afterwards in any proxy section. Same group may be referenced at |
| several places and can be fully or partially imported. |
| |
| http-errors <name> |
| Create a new http-errors group with the name <name>. It is an independent |
| section that may be referenced by one or more proxies using its name. |
| |
| errorfile <code> <file> |
| Associate a file contents to an HTTP error code |
| |
| Arguments : |
| <code> is the HTTP status code. Currently, HAProxy is capable of |
| generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410, |
| 425, 429, 500, 501, 502, 503, and 504. |
| |
| <file> designates a file containing the full HTTP response. It is |
| recommended to follow the common practice of appending ".http" to |
| the filename so that people do not confuse the response with HTML |
| error pages, and to use absolute paths, since files are read |
| before any chroot is performed. |
| |
| Please referrers to "errorfile" keyword in section 4 for details. |
| |
| Example: |
| http-errors website-1 |
| errorfile 400 /etc/haproxy/errorfiles/site1/400.http |
| errorfile 404 /etc/haproxy/errorfiles/site1/404.http |
| errorfile 408 /dev/null # work around Chrome pre-connect bug |
| |
| http-errors website-2 |
| errorfile 400 /etc/haproxy/errorfiles/site2/400.http |
| errorfile 404 /etc/haproxy/errorfiles/site2/404.http |
| errorfile 408 /dev/null # work around Chrome pre-connect bug |
| |
| 3.9. Rings |
| ---------- |
| |
| It is possible to globally declare ring-buffers, to be used as target for log |
| servers or traces. |
| |
| ring <ringname> |
| Creates a new ring-buffer with name <ringname>. |
| |
| description <text> |
| The description is an optional description string of the ring. It will |
| appear on CLI. By default, <name> is reused to fill this field. |
| |
| format <format> |
| Format used to store events into the ring buffer. |
| |
| Arguments: |
| <format> is the log format used when generating syslog messages. It may be |
| one of the following : |
| |
| iso A message containing only the ISO date, followed by the text. |
| The PID, process name and system name are omitted. This is |
| designed to be used with a local log server. |
| |
| local Analog to rfc3164 syslog message format except that hostname |
| field is stripped. This is the default. |
| Note: option "log-send-hostname" switches the default to |
| rfc3164. |
| |
| raw A message containing only the text. The level, PID, date, time, |
| process name and system name are omitted. This is designed to be |
| used in containers or during development, where the severity |
| only depends on the file descriptor used (stdout/stderr). This |
| is the default. |
| |
| rfc3164 The RFC3164 syslog message format. |
| (https://tools.ietf.org/html/rfc3164) |
| |
| rfc5424 The RFC5424 syslog message format. |
| (https://tools.ietf.org/html/rfc5424) |
| |
| short A message containing only a level between angle brackets such as |
| '<3>', followed by the text. The PID, date, time, process name |
| and system name are omitted. This is designed to be used with a |
| local log server. This format is compatible with what the systemd |
| logger consumes. |
| |
| priority A message containing only a level plus syslog facility between angle |
| brackets such as '<63>', followed by the text. The PID, date, time, |
| process name and system name are omitted. This is designed to be used |
| with a local log server. |
| |
| timed A message containing only a level between angle brackets such as |
| '<3>', followed by ISO date and by the text. The PID, process |
| name and system name are omitted. This is designed to be |
| used with a local log server. |
| |
| maxlen <length> |
| The maximum length of an event message stored into the ring, |
| including formatted header. If an event message is longer than |
| <length>, it will be truncated to this length. |
| |
| server <name> <address> [param*] |
| Used to configure a syslog tcp server to forward messages from ring buffer. |
| This supports for all "server" parameters found in 5.2 paragraph. Some of |
| these parameters are irrelevant for "ring" sections. Important point: there |
| is little reason to add more than one server to a ring, because all servers |
| will receive the exact same copy of the ring contents, and as such the ring |
| will progress at the speed of the slowest server. If one server does not |
| respond, it will prevent old messages from being purged and may block new |
| messages from being inserted into the ring. The proper way to send messages |
| to multiple servers is to use one distinct ring per log server, not to |
| attach multiple servers to the same ring. Note that specific server directive |
| "log-proto" is used to set the protocol used to send messages. |
| |
| size <size> |
| This is the optional size in bytes for the ring-buffer. Default value is |
| set to BUFSIZE. |
| |
| timeout connect <timeout> |
| Set the maximum time to wait for a connection attempt to a server to succeed. |
| |
| Arguments : |
| <timeout> 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. |
| |
| timeout server <timeout> |
| Set the maximum time for pending data staying into output buffer. |
| |
| Arguments : |
| <timeout> 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. |
| |
| Example: |
| global |
| log ring@myring local7 |
| |
| ring myring |
| description "My local buffer" |
| format rfc3164 |
| maxlen 1200 |
| size 32764 |
| timeout connect 5s |
| timeout server 10s |
| server mysyslogsrv 127.0.0.1:6514 log-proto octet-count |
| |
| 3.10. Log forwarding |
| ------------------- |
| |
| It is possible to declare one or multiple log forwarding section, |
| HAProxy will forward all received log messages to a log servers list. |
| |
| log-forward <name> |
| Creates a new log forwarder proxy identified as <name>. |
| |
| backlog <conns> |
| Give hints to the system about the approximate listen backlog desired size |
| on connections accept. |
| |
| bind <addr> [param*] |
| Used to configure a stream log listener to receive messages to forward. |
| This supports the "bind" parameters found in 5.1 paragraph including |
| those about ssl but some statements such as "alpn" may be irrelevant for |
| syslog protocol over TCP. |
| Those listeners support both "Octet Counting" and "Non-Transparent-Framing" |
| modes as defined in rfc-6587. |
| |
| dgram-bind <addr> [param*] |
| Used to configure a datagram log listener to receive messages to forward. |
| Addresses must be in IPv4 or IPv6 form,followed by a port. This supports |
| for some of the "bind" parameters found in 5.1 paragraph among which |
| "interface", "namespace" or "transparent", the other ones being |
| silently ignored as irrelevant for UDP/syslog case. |
| |
| log global |
| log <address> [len <length>] [format <format>] [sample <ranges>:<sample_size>] |
| <facility> [<level> [<minlevel>]] |
| Used to configure target log servers. See more details on proxies |
| documentation. |
| If no format specified, HAProxy tries to keep the incoming log format. |
| Configured facility is ignored, except if incoming message does not |
| present a facility but one is mandatory on the outgoing format. |
| If there is no timestamp available in the input format, but the field |
| exists in output format, HAProxy will use the local date. |
| |
| Example: |
| global |
| log stderr format iso local7 |
| |
| ring myring |
| description "My local buffer" |
| format rfc5424 |
| maxlen 1200 |
| size 32764 |
| timeout connect 5s |
| timeout server 10s |
| # syslog tcp server |
| server mysyslogsrv 127.0.0.1:514 log-proto octet-count |
| |
| log-forward sylog-loadb |
| dgram-bind 127.0.0.1:1514 |
| bind 127.0.0.1:1514 |
| # all messages on stderr |
| log global |
| # all messages on local tcp syslog server |
| log ring@myring local0 |
| # load balance messages on 4 udp syslog servers |
| log 127.0.0.1:10001 sample 1:4 local0 |
| log 127.0.0.1:10002 sample 2:4 local0 |
| log 127.0.0.1:10003 sample 3:4 local0 |
| log 127.0.0.1:10004 sample 4:4 local0 |
| |
| maxconn <conns> |
| Fix the maximum number of concurrent connections on a log forwarder. |
| 10 is the default. |
| |
| timeout client <timeout> |
| Set the maximum inactivity time on the client side. |
| |
| 4. Proxies |
| ---------- |
| |
| Proxy configuration can be located in a set of sections : |
| - defaults [<name>] [ from <defaults_name> ] |
| - frontend <name> [ from <defaults_name> ] |
| - backend <name> [ from <defaults_name> ] |
| - listen <name> [ from <defaults_name> ] |
| |
| A "frontend" section describes a set of listening sockets accepting client |
| connections. |
| |
| A "backend" section describes a set of servers to which the proxy will connect |
| to forward incoming connections. |
| |
| A "listen" section defines a complete proxy with its frontend and backend |
| parts combined in one section. It is generally useful for TCP-only traffic. |
| |
| A "defaults" section resets all settings to the documented ones and presets new |
| ones for use by subsequent sections. All of "frontend", "backend" and "listen" |
| sections always take their initial settings from a defaults section, by default |
| the latest one that appears before the newly created section. It is possible to |
| explicitly designate a specific "defaults" section to load the initial settings |
| from by indicating its name on the section line after the optional keyword |
| "from". While "defaults" section do not impose a name, this use is encouraged |
| for better readability. It is also the only way to designate a specific section |
| to use instead of the default previous one. Since "defaults" section names are |
| optional, by default a very permissive check is applied on their name and these |
| are even permitted to overlap. However if a "defaults" section is referenced by |
| any other section, its name must comply with the syntax imposed on all proxy |
| names, and this name must be unique among the defaults sections. Please note |
| that regardless of what is currently permitted, it is recommended to avoid |
| duplicate section names in general and to respect the same syntax as for proxy |
| names. This rule might be enforced in a future version. |
| |
| Note that it is even possible for a defaults section to take its initial |
| settings from another one, and as such, inherit settings across multiple levels |
| of defaults sections. This can be convenient to establish certain configuration |
| profiles to carry groups of default settings (e.g. TCP vs HTTP or short vs long |
| timeouts) but can quickly become confusing to follow. |
| |
| All proxy names must be formed from upper and lower case letters, digits, |
| '-' (dash), '_' (underscore) , '.' (dot) and ':' (colon). ACL names are |
| case-sensitive, which means that "www" and "WWW" are two different proxies. |
| |
| Historically, all proxy names could overlap, it just caused troubles in the |
| logs. Since the introduction of content switching, it is mandatory that two |
| proxies with overlapping capabilities (frontend/backend) have different names. |
| However, it is still permitted that a frontend and a backend share the same |
| name, as this configuration seems to be commonly encountered. |
| |
| Right now, two major proxy modes are supported : "tcp", also known as layer 4, |
| and "http", also known as layer 7. In layer 4 mode, HAProxy simply forwards |
| bidirectional traffic between two sides. In layer 7 mode, HAProxy analyzes the |
| protocol, and can interact with it by allowing, blocking, switching, adding, |
| modifying, or removing arbitrary contents in requests or responses, based on |
| arbitrary criteria. |
| |
| In HTTP mode, the processing applied to requests and responses flowing over |
| a connection depends in the combination of the frontend's HTTP options and |
| the backend's. HAProxy supports 3 connection modes : |
| |
| - KAL : keep alive ("option http-keep-alive") which is the default mode : all |
| requests and responses are processed, and connections remain open but idle |
| between responses and new requests. |
| |
| - SCL: server close ("option http-server-close") : the server-facing |
| connection is closed after the end of the response is received, but the |
| client-facing connection remains open. |
| |
| - CLO: close ("option httpclose"): the connection is closed after the end of |
| the response and "Connection: close" appended in both directions. |
| |
| The effective mode that will be applied to a connection passing through a |
| frontend and a backend can be determined by both proxy modes according to the |
| following matrix, but in short, the modes are symmetric, keep-alive is the |
| weakest option and close is the strongest. |
| |
| Backend mode |
| |
| | KAL | SCL | CLO |
| ----+-----+-----+---- |
| KAL | KAL | SCL | CLO |
| ----+-----+-----+---- |
| mode SCL | SCL | SCL | CLO |
| ----+-----+-----+---- |
| CLO | CLO | CLO | CLO |
| |
| It is possible to chain a TCP frontend to an HTTP backend. It is pointless if |
| only HTTP traffic is handled. But it may be used to handle several protocols |
| within the same frontend. In this case, the client's connection is first handled |
| as a raw tcp connection before being upgraded to HTTP. Before the upgrade, the |
| content processings are performend on raw data. Once upgraded, data is parsed |
| and stored using an internal representation called HTX and it is no longer |
| possible to rely on raw representation. There is no way to go back. |
| |
| There are two kind of upgrades, in-place upgrades and destructive upgrades. The |
| first ones involves a TCP to HTTP/1 upgrade. In HTTP/1, the request |
| processings are serialized, thus the applicative stream can be preserved. The |
| second one involves a TCP to HTTP/2 upgrade. Because it is a multiplexed |
| protocol, the applicative stream cannot be associated to any HTTP/2 stream and |
| is destroyed. New applicative streams are then created when HAProxy receives |
| new HTTP/2 streams at the lower level, in the H2 multiplexer. It is important |
| to understand this difference because that drastically changes the way to |
| process data. When an HTTP/1 upgrade is performed, the content processings |
| already performed on raw data are neither lost nor reexecuted while for an |
| HTTP/2 upgrade, applicative streams are distinct and all frontend rules are |
| evaluated systematically on each one. And as said, the first stream, the TCP |
| one, is destroyed, but only after the frontend rules were evaluated. |
| |
| There is another importnat point to understand when HTTP processings are |
| performed from a TCP proxy. While HAProxy is able to parse HTTP/1 in-fly from |
| tcp-request content rules, it is not possible for HTTP/2. Only the HTTP/2 |
| preface can be parsed. This is a huge limitation regarding the HTTP content |
| analysis in TCP. Concretely it is only possible to know if received data are |
| HTTP. For instance, it is not possible to choose a backend based on the Host |
| header value while it is trivial in HTTP/1. Hopefully, there is a solution to |
| mitigate this drawback. |
| |
| There are two ways to perform an HTTP upgrade. The first one, the historical |
| method, is to select an HTTP backend. The upgrade happens when the backend is |
| set. Thus, for in-place upgrades, only the backend configuration is considered |
| in the HTTP data processing. For destructive upgrades, the applicative stream |
| is destroyed, thus its processing is stopped. With this method, possibilities |
| to choose a backend with an HTTP/2 connection are really limited, as mentioned |
| above, and a bit useless because the stream is destroyed. The second method is |
| to upgrade during the tcp-request content rules evaluation, thanks to the |
| "switch-mode http" action. In this case, the upgrade is performed in the |
| frontend context and it is possible to define HTTP directives in this |
| frontend. For in-place upgrades, it offers all the power of the HTTP analysis |
| as soon as possible. It is not that far from an HTTP frontend. For destructive |
| upgrades, it does not change anything except it is useless to choose a backend |
| on limited information. It is of course the recommended method. Thus, testing |
| the request protocol from the tcp-request content rules to perform an HTTP |
| upgrade is enough. All the remaining HTTP manipulation may be moved to the |
| frontend http-request ruleset. But keep in mind that tcp-request content rules |
| remains evaluated on each streams, that can't be changed. |
| |
| 4.1. Proxy keywords matrix |
| -------------------------- |
| |
| The following list of keywords is supported. Most of them may only be used in a |
| limited set of section types. Some of them are marked as "deprecated" because |
| they are inherited from an old syntax which may be confusing or functionally |
| limited, and there are new recommended keywords to replace them. Keywords |
| marked with "(*)" can be optionally inverted using the "no" prefix, e.g. "no |
| option contstats". This makes sense when the option has been enabled by default |
| and must be disabled for a specific instance. Such options may also be prefixed |
| with "default" in order to restore default settings regardless of what has been |
| specified in a previous "defaults" section. |
| |
| |
| keyword defaults frontend listen backend |
| ------------------------------------+----------+----------+---------+--------- |
| acl - X X X |
| backlog X X X - |
| balance X - X X |
| bind - X X - |
| bind-process X X X X |
| capture cookie - X X - |
| capture request header - X X - |
| capture response header - X X - |
| clitcpka-cnt X X X - |
| clitcpka-idle X X X - |
| clitcpka-intvl X X X - |
| compression X X X X |
| cookie X - X X |
| declare capture - X X - |
| default-server X - X X |
| default_backend X X X - |
| description - X X X |
| disabled X X X X |
| dispatch - - X X |
| email-alert from X X X X |
| email-alert level X X X X |
| email-alert mailers X X X X |
| email-alert myhostname X X X X |
| email-alert to X X X X |
| enabled X X X X |
| errorfile X X X X |
| errorfiles X X X X |
| errorloc X X X X |
| errorloc302 X X X X |
| -- keyword -------------------------- defaults - frontend - listen -- backend - |
| errorloc303 X X X X |
| force-persist - - X X |
| filter - X X X |
| fullconn X - X X |
| grace X X X X |
| hash-type X - X X |
| http-after-response - X X X |
| http-check comment X - X X |
| http-check connect X - X X |
| http-check disable-on-404 X - X X |
| http-check expect X - X X |
| http-check send X - X X |
| http-check send-state X - X X |
| http-check set-var X - X X |
| http-check unset-var X - X X |
| http-error X X X X |
| http-request - X X X |
| http-response - X X X |
| http-reuse X - X X |
| http-send-name-header - - X X |
| id - X X X |
| ignore-persist - - X X |
| load-server-state-from-file X - X X |
| log (*) X X X X |
| log-format X X X - |
| log-format-sd X X X - |
| log-tag X X X X |
| max-keep-alive-queue X - X X |
| maxconn X X X - |
| mode X X X X |
| monitor fail - X X - |
| monitor-uri X X X - |
| option abortonclose (*) X - X X |
| option accept-invalid-http-request (*) X X X - |
| option accept-invalid-http-response (*) X - X X |
| option allbackups (*) X - X X |
| option checkcache (*) X - X X |
| option clitcpka (*) X X X - |
| option contstats (*) X X X - |
| option disable-h2-upgrade (*) X X X - |
| option dontlog-normal (*) X X X - |
| option dontlognull (*) X X X - |
| -- keyword -------------------------- defaults - frontend - listen -- backend - |
| option forwardfor X X X X |
| option h1-case-adjust-bogus-client (*) X X X - |
| option h1-case-adjust-bogus-server (*) X - X X |
| option http-buffer-request (*) X X X X |
| option http-ignore-probes (*) X X X - |
| option http-keep-alive (*) X X X X |
| option http-no-delay (*) X X X X |
| option http-pretend-keepalive (*) X - X X |
| option http-server-close (*) X X X X |
| option http-use-proxy-header (*) X X X - |
| option httpchk X - X X |
| option httpclose (*) X X X X |
| option httplog X X X - |
| option http_proxy (*) X X X X |
| option independent-streams (*) X X X X |
| option ldap-check X - X X |
| option external-check X - X X |
| option log-health-checks (*) X - X X |
| option log-separate-errors (*) X X X - |
| option logasap (*) X X X - |
| option mysql-check X - X X |
| option nolinger (*) X X X X |
| option originalto X X X X |
| option persist (*) X - X X |
| option pgsql-check X - X X |
| option prefer-last-server (*) X - X X |
| option redispatch (*) X - X X |
| option redis-check X - X X |
| option smtpchk X - X X |
| option socket-stats (*) X X X - |
| option splice-auto (*) X X X X |
| option splice-request (*) X X X X |
| option splice-response (*) X X X X |
| option spop-check - - - X |
| option srvtcpka (*) X - X X |
| option ssl-hello-chk X - X X |
| -- keyword -------------------------- defaults - frontend - listen -- backend - |
| option tcp-check X - X X |
| option tcp-smart-accept (*) X X X - |
| option tcp-smart-connect (*) X - X X |
| option tcpka X X X X |
| option tcplog X X X X |
| option transparent (*) X - X X |
| option idle-close-on-response (*) X X X - |
| external-check command X - X X |
| external-check path X - X X |
| persist rdp-cookie X - X X |
| rate-limit sessions X X X - |
| redirect - X X X |
| -- keyword -------------------------- defaults - frontend - listen -- backend - |
| retries X - X X |
| retry-on X - X X |
| server - - X X |
| server-state-file-name X - X X |
| server-template - - X X |
| source X - X X |
| srvtcpka-cnt X - X X |
| srvtcpka-idle X - X X |
| srvtcpka-intvl X - X X |
| stats admin - X X X |
| stats auth X X X X |
| stats enable X X X X |
| stats hide-version X X X X |
| stats http-request - X X X |
| stats realm X X X X |
| stats refresh X X X X |
| stats scope X X X X |
| stats show-desc X X X X |
| stats show-legends X X X X |
| stats show-node X X X X |
| stats uri X X X X |
| -- keyword -------------------------- defaults - frontend - listen -- backend - |
| stick match - - X X |
| stick on - - X X |
| stick store-request - - X X |
| stick store-response - - X X |
| stick-table - X X X |
| tcp-check comment X - X X |
| tcp-check connect X - X X |
| tcp-check expect X - X X |
| tcp-check send X - X X |
| tcp-check send-lf X - X X |
| tcp-check send-binary X - X X |
| tcp-check send-binary-lf X - X X |
| tcp-check set-var X - X X |
| tcp-check unset-var X - X X |
| tcp-request connection - X X - |
| tcp-request content - X X X |
| tcp-request inspect-delay - X X X |
| tcp-request session - X X - |
| tcp-response content - - X X |
| tcp-response inspect-delay - - X X |
| timeout check X - X X |
| timeout client X X X - |
| timeout client-fin X X X - |
| timeout connect X - X X |
| timeout http-keep-alive X X X X |
| timeout http-request X X X X |
| timeout queue X - X X |
| timeout server X - X X |
| timeout server-fin X - X X |
| timeout tarpit X X X X |
| timeout tunnel X - X X |
| transparent (deprecated) X - X X |
| unique-id-format X X X - |
| unique-id-header X X X - |
| use_backend - X X - |
| use-fcgi-app - - X X |
| use-server - - X X |
| ------------------------------------+----------+----------+---------+--------- |
| keyword defaults frontend listen backend |
| |
| |
| 4.2. Alphabetically sorted keywords reference |
| --------------------------------------------- |
| |
| This section provides a description of each keyword and its usage. |
| |
| |
| acl <aclname> <criterion> [flags] [operator] <value> ... |
| Declare or complete an access list. |
| May be used in sections : defaults | frontend | listen | backend |
| no | yes | yes | yes |
| Example: |
| acl invalid_src src 0.0.0.0/7 224.0.0.0/3 |
| acl invalid_src src_port 0:1023 |
| acl local_dst hdr(host) -i localhost |
| |
| See section 7 about ACL usage. |
| |
| |
| backlog <conns> |
| Give hints to the system about the approximate listen backlog desired size |
| May be used in sections : defaults | frontend | listen | backend |
| yes | yes | yes | no |
| Arguments : |
| <conns> is the number of pending connections. Depending on the operating |
| system, it may represent the number of already acknowledged |
| connections, of non-acknowledged ones, or both. |
| |
| In order to protect against SYN flood attacks, one solution is to increase |
| the system's SYN backlog size. Depending on the system, sometimes it is just |
| tunable via a system parameter, sometimes it is not adjustable at all, and |
| sometimes the system relies on hints given by the application at the time of |
| the listen() syscall. By default, HAProxy passes the frontend's maxconn value |
| to the listen() syscall. On systems which can make use of this value, it can |
| sometimes be useful to be able to specify a different value, hence this |
| backlog parameter. |
| |
| On Linux 2.4, the parameter is ignored by the system. On Linux 2.6, it is |
| used as a hint and the system accepts up to the smallest greater power of |
| two, and never more than some limits (usually 32768). |
| |
| See also : "maxconn" and the target operating system's tuning guide. |
| |
| |
| balance <algorithm> [ <arguments> ] |
| balance url_param <param> [check_post] |
| Define the load balancing algorithm to be used in a backend. |
| May be used in sections : defaults | frontend | listen | backend |
| yes | no | yes | yes |
| Arguments : |
| <algorithm> is the algorithm used to select a server when doing load |
| balancing. This only applies when no persistence information |
| is available, or when a connection is redispatched to another |
| server. <algorithm> may be one of the following : |
| |
| roundrobin Each server is used in turns, according to their weights. |
| This is the smoothest and fairest algorithm when the server's |
| processing time remains equally distributed. This algorithm |
| is dynamic, which means that server weights may be adjusted |
| on the fly for slow starts for instance. It is limited by |
| design to 4095 active servers per backend. Note that in some |
| large farms, when a server becomes up after having been down |
| for a very short time, it may sometimes take a few hundreds |
| requests for it to be re-integrated into the farm and start |
| receiving traffic. This is normal, though very rare. It is |
| indicated here in case you would have the chance to observe |
| it, so that you don't worry. |
| |
| static-rr Each server is used in turns, according to their weights. |
| This algorithm is as similar to roundrobin except that it is |
| static, which means that changing a server's weight on the |
| fly will have no effect. On the other hand, it has no design |
| limitation on the number of servers, and when a server goes |
| up, it is always immediately reintroduced into the farm, once |
| the full map is recomputed. It also uses slightly less CPU to |
| run (around -1%). |
| |
| leastconn The server with the lowest number of connections receives the |
| connection. Round-robin is performed within groups of servers |
| of the same load to ensure that all servers will be used. Use |
| of this algorithm is recommended where very long sessions are |
| expected, such as LDAP, SQL, TSE, etc... but is not very well |
| suited for protocols using short sessions such as HTTP. This |
| algorithm is dynamic, which means that server weights may be |
| adjusted on the fly for slow starts for instance. It will |
| also consider the number of queued connections in addition to |
| the established ones in order to minimize queuing. |
| |
| first The first server with available connection slots receives the |
| connection. The servers are chosen from the lowest numeric |
| identifier to the highest (see server parameter "id"), which |
| defaults to the server's position in the farm. Once a server |
| reaches its maxconn value, the next server is used. It does |
| not make sense to use this algorithm without setting maxconn. |
| The purpose of this algorithm is to always use the smallest |
| number of servers so that extra servers can be powered off |
| during non-intensive hours. This algorithm ignores the server |
| weight, and brings more benefit to long session such as RDP |
| or IMAP than HTTP, though it can be useful there too. In |
| order to use this algorithm efficiently, it is recommended |
| that a cloud controller regularly checks server usage to turn |
| them off when unused, and regularly checks backend queue to |
| turn new servers on when the queue inflates. Alternatively, |
| using "http-check send-state" may inform servers on the load. |
| |
| source The source IP address is hashed and divided by the total |
| weight of the running servers to designate which server will |
| receive the request. This ensures that the same client IP |
| address will always reach the same server as long as no |
| server goes down or up. If the hash result changes due to the |
| number of running servers changing, many clients will be |
| directed to a different server. This algorithm is generally |
| used in TCP mode where no cookie may be inserted. It may also |
| be used on the Internet to provide a best-effort stickiness |
| to clients which refuse session cookies. This algorithm is |
| static by default, which means that changing a server's |
| weight on the fly will have no effect, but this can be |
| changed using "hash-type". |
| |
| uri This algorithm hashes either the left part of the URI (before |
| the question mark) or the whole URI (if the "whole" parameter |
| is present) and divides the hash value by the total weight of |
| the running servers. The result designates which server will |
| receive the request. This ensures that the same URI will |
| always be directed to the same server as long as no server |
| goes up or down. This is used with proxy caches and |
| anti-virus proxies in order to maximize the cache hit rate. |
| Note that this algorithm may only be used in an HTTP backend. |
| This algorithm is static by default, which means that |
| changing a server's weight on the fly will have no effect, |
| but this can be changed using "hash-type". |
| |
| This algorithm supports two optional parameters "len" and |
| "depth", both followed by a positive integer number. These |
| options may be helpful when it is needed to balance servers |
| based on the beginning of the URI only. The "len" parameter |
| indicates that the algorithm should only consider that many |
| characters at the beginning of the URI to compute the hash. |
| Note that having "len" set to 1 rarely makes sense since most |
| URIs start with a leading "/". |
| |
| The "depth" parameter indicates the maximum directory depth |
| to be used to compute the hash. One level is counted for each |
| slash in the request. If both parameters are specified, the |
| evaluation stops when either is reached. |
| |
| A "path-only" parameter indicates that the hashing key starts |
| at the first '/' of the path. This can be used to ignore the |
| authority part of absolute URIs, and to make sure that HTTP/1 |
| and HTTP/2 URIs will provide the same hash. |
| |
| url_param The URL parameter specified in argument will be looked up in |
| the query string of each HTTP GET request. |
| |
| If the modifier "check_post" is used, then an HTTP POST |
| request entity will be searched for the parameter argument, |
| when it is not found in a query string after a question mark |
| ('?') in the URL. The message body will only start to be |
| analyzed once either the advertised amount of data has been |
| received or the request buffer is full. In the unlikely event |
| that chunked encoding is used, only the first chunk is |
| scanned. Parameter values separated by a chunk boundary, may |
| be randomly balanced if at all. This keyword used to support |
| an optional <max_wait> parameter which is now ignored. |
| |
| If the parameter is found followed by an equal sign ('=') and |
| a value, then the value is hashed and divided by the total |
| weight of the running servers. The result designates which |
| server will receive the request. |
| |
| This is used to track user identifiers in requests and ensure |
| that a same user ID will always be sent to the same server as |
| long as no server goes up or down. If no value is found or if |
| the parameter is not found, then a round robin algorithm is |
| applied. Note that this algorithm may only be used in an HTTP |
| backend. This algorithm is static by default, which means |
| that changing a server's weight on the fly will have no |
| effect, but this can be changed using "hash-type". |
| |
| hdr(<name>) The HTTP header <name> will be looked up in each HTTP |
| request. Just as with the equivalent ACL 'hdr()' function, |
| the header name in parenthesis is not case sensitive. If the |
| header is absent or if it does not contain any value, the |
| roundrobin algorithm is applied instead. |
| |
| An optional 'use_domain_only' parameter is available, for |
| reducing the hash algorithm to the main domain part with some |
| specific headers such as 'Host'. For instance, in the Host |
| value "haproxy.1wt.eu", only "1wt" will be considered. |
| |
| This algorithm is static by default, which means that |
| changing a server's weight on the fly will have no effect, |
| but this can be changed using "hash-type". |
| |
| random |
| random(<draws>) |
| A random number will be used as the key for the consistent |
| hashing function. This means that the servers' weights are |
| respected, dynamic weight changes immediately take effect, as |
| well as new server additions. Random load balancing can be |
| useful with large farms or when servers are frequently added |
| or removed as it may avoid the hammering effect that could |
| result from roundrobin or leastconn in this situation. The |
| hash-balance-factor directive can be used to further improve |
| fairness of the load balancing, especially in situations |
| where servers show highly variable response times. When an |
| argument <draws> is present, it must be an integer value one |
| or greater, indicating the number of draws before selecting |
| the least loaded of these servers. It was indeed demonstrated |
| that picking the least loaded of two servers is enough to |
| significantly improve the fairness of the algorithm, by |
| always avoiding to pick the most loaded server within a farm |
| and getting rid of any bias that could be induced by the |
| unfair distribution of the consistent list. Higher values N |
| will take away N-1 of the highest loaded servers at the |
| expense of performance. With very high values, the algorithm |
| will converge towards the leastconn's result but much slower. |
| The default value is 2, which generally shows very good |
| distribution and performance. This algorithm is also known as |
| the Power of Two Random Choices and is described here : |
| http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf |
| |
| rdp-cookie |
| rdp-cookie(<name>) |
| The RDP cookie <name> (or "mstshash" if omitted) will be |
| looked up and hashed for each incoming TCP request. Just as |
| with the equivalent ACL 'req.rdp_cookie()' function, the name |
| is not case-sensitive. This mechanism is useful as a degraded |
| persistence mode, as it makes it possible to always send the |
| same user (or the same session ID) to the same server. If the |
| cookie is not found, the normal roundrobin algorithm is |
| used instead. |
| |
| Note that for this to work, the frontend must ensure that an |
| RDP cookie is already present in the request buffer. For this |
| you must use 'tcp-request content accept' rule combined with |
| a 'req.rdp_cookie_cnt' ACL. |
| |
| This algorithm is static by default, which means that |
| changing a server's weight on the fly will have no effect, |
| but this can be changed using "hash-type". |
| |
| <arguments> is an optional list of arguments which may be needed by some |
| algorithms. Right now, only "url_param" and "uri" support an |
| optional argument. |
| |
| The load balancing algorithm of a backend is set to roundrobin when no other |
| algorithm, mode nor option have been set. The algorithm may only be set once |
| for each backend. |
| |
| With authentication schemes that require the same connection like NTLM, URI |
| based algorithms must not be used, as they would cause subsequent requests |
| to be routed to different backend servers, breaking the invalid assumptions |
| NTLM relies on. |
| |
| Examples : |
| balance roundrobin |
| balance url_param userid |
| balance url_param session_id check_post 64 |
| balance hdr(User-Agent) |
|