配置手册

版本 2.9.15

2025/03/21

本文档涵盖了上述版本中实现的配置语言。它不提供任何提示、示例或建议。有关此类文档,请参阅参考手册或架构手册。以下摘要旨在帮助您按名称查找章节并在文档中导航。文档贡献者须知:本文档每行格式化为80列,使用偶数个空格进行缩进,不使用制表符。请严格遵守这些规则,以便在任何地方都能轻松打印。如果某行需要逐字打印且不适合,请在每行末尾加上反斜杠('\'),并在下一行继续,缩进两个字符。有时,为了强调输入和输出之间的差异,当它们可能模糊不清时,用三个闭合尖括号('>>>')作为所有输出行(日志、控制台输出)的前缀也很有用。如果添加新章节,请更新下面的摘要以便于搜索。
1. 关于 HTTP 的快速提醒
1.1.
1.2.
1.3.
1.3.1.
1.3.2.
1.4.
1.4.1.
1.4.2.

2.

配置 HAProxy
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.

3.

全局参数
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
3.7.
3.8.
3.9.
3.10.
3.11.

4.

代理
4.1.
4.2.
4.3.
4.4.

5.

绑定和服务​​器选项
5.1.
5.2.
5.3.
5.3.1.
5.3.2.

6.

缓存
6.1.
6.2.
6.2.1.
6.2.2.

7.

使用 ACL 和获取样本
7.1.
7.1.1.
7.1.2.
7.1.3.
7.1.4.
7.1.5.
7.1.6.
7.2.
7.3.
7.3.1.
7.3.2.
7.3.3.
7.3.4.
7.3.5.
7.3.6.
7.3.7.
7.4.

8.

日志
8.1.
8.2.
8.2.1.
8.2.2.
8.2.3.
8.2.4.
8.2.5.
8.2.6.
8.3.
8.3.1.
8.3.2.
8.3.3.
8.3.4.
8.4.
8.5.
8.6.
8.7.
8.8.
8.9.

9.

支持的过滤器
9.1.
9.2.
9.3.
9.4.
9.5.
9.6.
9.7.

10.

FastCGI 应用程序
10.1.
10.1.1.
10.1.2.
10.1.3.
10.2.
10.3.

11.

地址格式
11.1.
11.2.
11.3.
当 HAProxy 在 HTTP 模式下运行时,请求和响应都会被完全分析和索引,因此可以根据内容中找到的几乎任何信息构建匹配标准。然而,了解 HTTP 请求和响应的构成方式以及 HAProxy 如何分解它们是很重要的。这样一来,编写正确的规则和调试现有配置就会变得更加容易。首先,HTTP 由一系列 RFC 标准化,HAProxy 尽可能地遵循这些标准: - RFC 9110: HTTP 语义 (解释协议元素的含义) - RFC 9111: HTTP 缓存 (解释 HTTP 缓存应遵循的规则) - RFC 9112: HTTP/1.1 (表示、互操作性规则、安全) - RFC 9113: HTTP/2 (表示、互操作性规则、安全) - RFC 9114: HTTP/3 (表示、互操作性规则、安全) 除此之外,RFC 8999 到 9002 规定了 HTTP/3 协议使用的 QUIC 传输层。

1.1. HTTP 事务模型

HTTP 协议是事务驱动的。这意味着每个请求都只会产生一个响应。最初,在协议的 1.0 版本中,每个连接只有一个请求:客户端与服务器建立 TCP 连接,客户端通过该连接发送请求,服务器响应,然后连接关闭。新的请求需要新的连接:[CON1] [REQ1] ... [RESP1] [CLO1] [CON2] [REQ2] ... [RESP2] [CLO2] ... 在这种模式下,通常称为“HTTP close”模式,有多少 HTTP 事务就有多少连接建立。由于服务器在响应后关闭连接,客户端不需要知道内容长度,它认为当连接关闭时响应就完成了。这也意味着如果某些响应由于网络错误而被截断,客户端可能会错误地认为响应已完成,这有时会导致屏幕上呈现截断的图像。由于协议的事务性质,可以对其进行改进,以避免在两个后续事务之间关闭连接。然而,在这种模式下,服务器必须为每个响应指示内容长度,以便客户端不会无限期地等待。为此,使用了一个特殊的标头:“Content-length”。这种模式被称为“keep-alive”模式,随 HTTP/1.1 一起出现(一些 HTTP/1.0 代理支持它),在请求之间重用的连接被称为“持久连接”:[CON] [REQ1] ... [RESP1] [REQ2] ... [RESP2] [CLO] ... 它的优点是事务之间的延迟减少,服务器端所需的处理能力减少,以及能够检测截断的响应。它通常比关闭模式更快,但并非总是如此,因为一些客户端通常将其并发连接限制在较小的值,这减少了对不良网络连接的补偿。此外,一些服务器必须长时间保持连接活动,等待可能的新请求,并且由于连接数量过多可能会遇到高内存使用率,而关闭过快可能会破坏在连接关闭时到达的一些请求。在这种模式下,响应大小需要事先知道,因此对于动态生成或压缩的内容来说并不总是可行。出于这个原因,实现了另一种模式,即“分块模式”(chunked mode),发送方不是一次性宣布整个大小,而是只宣布它在缓冲区中已有的下一个“块”的响应大小,并且可以随时以零大小的块终止。在这种模式下,不使用 Content-Length 标头。通信中的另一个改进是管道模式。它仍然使用 keep-alive,但客户端在发送第二个请求时不会等待第一个响应。这对于获取构成页面的大量图像很有用:[CON] [REQ1] [REQ2] ... [RESP1] [RESP2] [CLO] ... 这显然对性能有巨大的好处,因为后续请求之间的网络延迟被消除了。许多 HTTP 代理不支持管道,因为在 HTTP 中无法将响应与相应的请求相关联。出于这个原因,服务器必须按照接收请求的完全相同的顺序回复。在实践中,在各种客户端尝试部署后,由于其在某些服务器上的可靠性不足,它已被完全放弃。但服务器必须支持它。下一个改进是多路复用模式,如 HTTP/2 和 HTTP/3 中所实现。在这种模式下,多个事务(即请求-响应对)通过单个连接并行传输,并且它们都以自己的速度进展,彼此独立。对于多路复用协议,引入了“流”(stream)的新概念,用于表示通过同一连接发生的这些并行通信。每个流通常被分配一个给定连接的唯一标识符,两端都使用该标识符来知道将数据传送到何处。客户端在同一连接上并行启动多个流(多达 100 个,有时更多)是很常见的,并让服务器对它们进行排序,并根据哪个响应可用以任何顺序响应。多路复用模式的主要好处是它显着减少了往返次数,并加快了高延迟网络上的页面加载时间。在使用许多图像的网站上,所有图像似乎都在并行加载时,这是有时可见的。这些协议还通过采用一些机制来压缩标头字段以减少线路上的字节数来提高效率,因此如果没有适当的工具,它们不像 HTTP/1 那样可以手动操作或肉眼可读。出于这个原因,在文献中(包括本文档)继续使用 HTTP/1 语法表示各种 HTTP 消息示例,即使对于较新版本的协议也是如此。HTTP/2 存在一些设计限制,例如数据包丢失会同时影响所有流,如果客户端花费太多时间来检索对象(例如需要将其存储在磁盘上),它可能会减慢检索速度,并使得在此期间无法访问其后面待处理的数据。这被称为“队头阻塞”("head of line blocking"或"HoL blocking")或有时简称为“HoL”。HTTP/3 是在 QUIC 上实现的,QUIC 本身是在 UDP 上实现的。QUIC 通过独立处理的流在传输层解决了队头阻塞问题。实际上,当遇到丢失时,受影响的流不会影响其他流,所有流都可以并行访问。QUIC 还提供连接迁移支持,但目前 haproxy 不支持它。默认情况下,HAProxy 在处理持久连接时以 keep-alive 模式运行:对于它处理的每个连接,它处理每个请求和响应,并在响应结束和新请求开始之间使连接在两端空闲。当它从客户端接收到 HTTP/2 连接时,它会并行处理所有请求并使连接空闲,等待新请求,就像它是一个 keep-alive HTTP 连接一样。HAProxy 主要支持 3 种连接模式:- keep alive:处理所有请求和响应,并且面向客户端和面向服务器的连接保持活动以用于新请求。这是默认设置,适用于现代 Web 和现代协议(HTTP/2 和 HTTP/3)。- server close:在响应后关闭面向服务器的连接。- close:在两端响应结束后主动关闭连接。除此之外,默认情况下,面向服务器的连接可以被来自任何客户端的任何请求重用,正如 HTTP 协议规范所要求的那样,因此如果需要(例如客户端的源地址等),任何与特定客户端相关的信息都必须随每个请求一起传递。当 HTTP/2 与服务器一起使用时,默认情况下 HAProxy 会将此连接专用于同一客户端,以避免客户端之间队头阻塞的风险。

1.2. 术语

在 HAProxy 内部,术语随着时间的推移而发展,以适应 HTTP 协议及其用途的演变。虽然最初连接、会话、流或事务之间没有显着差异,但随着时间的推移,这些术语变得清晰,以与现代 HTTP 协议版本中存在的术语紧密匹配,尽管某些术语为了历史兼容性仍然可以在配置或命令行界面中看到。以下是适用于当前 HAProxy 版本的定义:- connection(连接):连接是远程代理(客户端或服务器)与 haproxy 之间在最低级别上的单个双向通信通道。它通常对应于在一对 IP 和端口之间建立的 TCP 套接字。在面向客户端的一侧,连接是客户端连接到 haproxy 时实例化的第一个实体,并且在连接级别应用的规则是最早应用的规则。- session(会话):会话添加了一些与连接关联的上下文信息。这包括特定于传输层的信息(例如 TLS 密钥等)或变量。这个术语长期以来在 HAProxy 内部用于表示两端之间的端到端 HTTP/1.0 通信,因此尽管现在它代表流,但它仍然在某些 CLI 命令或统计信息的名称中可见,但帮助消息和描述试图使其明确。它在网络级别术语(例如操作系统内部的 TCP 会话或跨防火墙的 TCP 会话)或非 HTTP 用户级应用程序(例如 telnet 会话或 SSH 会话)方面仍然有效。它不得与用于在 cookie 中存储完整用户上下文并要求发送到同一服务器的“应用程序会话”混淆。- stream(流):流精确地对应于应用程序级别的端到端双向通信,可以在其中应用分析和转换。在 HTTP 中,它包含单个请求及其关联的响应,并由请求的到达实例化,并随着响应交付的结束而完成。在这种情况下,这种流与多路复用协议的流之间存在 1:1 关系。在 TCP 通信中,每个连接只有一个流。- transaction(事务):事务仅是一对请求和关联的响应。该术语在流之前与会话结合使用,但现在事务与流之间存在 1:1 关系。它主要在变量的范围“txn”中可见,该范围在整个事务期间有效,因此在流中有效。- request(请求):它指定从客户端流向服务器的流量。它主要用于 HTTP 以指示执行操作的位置。该术语也存在于 TCP 操作中以指示处理数据的位置。请求通常作为流量或活动的单位出现在计数器中。它们并不总是意味着响应(例如,由于错误),但由于没有自发的响应而没有请求,请求仍然是总体活动的相关指标。在 TCP 中,请求数量与连接数量相同。- response(响应):它指定从服务器流向客户端的流量,或者有时是 HAProxy 流向客户端的流量,当 HAProxy 自己生成响应时(例如 HTTP 重定向)。- service(服务):这通常表示 HAProxy 中的某些内部处理,不需要服务器,例如 stats 页面、缓存或一些 Lua 代码来实现小型应用程序。服务通常读取请求,执行某些操作并生成响应。

1.3. HTTP 请求

首先,让我们考虑这个 HTTP 请求: 行号 内容 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.3.1. 请求行

第 1 行是“请求行”。它始终由 3 个字段组成:- METHOD:GET- URI:/serv/login.php?lang=en&profile=2- 版本标签:HTTP/1.1所有这些都由标准称为 LWS(线性空白字符,linear white spaces)的东西分隔,通常是空格,但也可能是制表符或换行符/回车符后跟空格/制表符。方法本身不能包含任何冒号(':'),并且仅限于字母。所有这些各种组合使得 HAProxy 最好自己执行拆分,而不是让用户编写复杂或不准确的正则表达式。URI 本身可以有几种形式:- “相对 URI”:/serv/login.php?lang=en&profile=2它是没有主机部分的完整 URL。这通常是服务器、反向代理和透明代理接收到的内容。- “绝对 URI”,也称为“URL”:http://192.168.0.12:8080/serv/login.php?lang=en&profile=2它由“方案”(协议名称后跟 '://')、主机名或地址、可选的冒号(':')后跟端口号,然后是从地址部分后面的第一个斜杠('/')开始的相对 URI 组成。这通常是代理接收到的内容,但支持 HTTP/1.1 的服务器也必须接受这种形式。- 星号('*'):这种形式仅在与 OPTIONS 方法关联时接受,且不可转发。它用于查询下一跳的功能。- address:port 组合:192.168.0.12:80这与 CONNECT 方法一起使用,CONNECT 方法用于通过 HTTP 代理建立 TCP 隧道,通常用于 HTTPS,但有时也用于其他协议。在相对 URI 中,识别出两个子部分。问号之前的部分称为 "path"(路径)。它通常是服务器上静态对象的相对路径。问号之后的部分称为“query string”(查询字符串)。它主要用于发送给动态脚本的 GET 请求,并且非常特定于所使用的语言、框架或应用程序。HTTP/2 和 HTTP/3 不会随请求传递版本信息,因此版本被假定与底层协议的版本相同(即“HTTP/2”)。此外,这些协议不会将请求行作为一个部分发送,而是将其拆分为称为“伪标头”(pseudo-headers)的单独字段,其名称以冒号开头,并且 HAProxy 会方便地将它们重新组合成等效的请求行。因此,日志中找到的请求行在 HTTP/1.x 和 HTTP/2 或 HTTP/3 之间可能略有不同。

1.3.2. 请求头

标头从第二行开始。它们由行开头的名称组成,紧跟一个冒号(':')。传统上,在冒号后添加 LWS,但这并非必需。然后是值。多个相同的标头可以折叠成一行,用逗号分隔值,前提是它们的顺序得到尊重。这在“Cookie:”字段中很常见。如果后续行以 LWS 开头,则标头可以跨多行。在 1.3 中的示例中,第 4 行和第 5 行共定义了“Accept:”标头的 3 个值。最后,根据规范,忽略标头开头或结尾处的所有 LWS,它们不属于值的一部分。与常见的误解相反,标头名称不区分大小写,如果它们引用其他标头名称(例如“Connection:”标头),则它们的值也不区分大小写。在 HTTP/2 和 HTTP/3 中,标头名称始终以小写形式发送,在调试模式下运行时可以看到。在内部,所有标头名称都规范化为小写,以便 HTTP/1.x 和 HTTP/2 或 HTTP/3 使用完全相同的表示形式,并且它们在另一侧按原样发送。这解释了为什么使用驼峰式大小写的 HTTP/1.x 请求会以小写形式交付。标头结束由第一个空行指示。人们常说它是双换行符,这不准确,即使双换行符是空行的一种有效形式。幸运的是,HAProxy 在索引标头、检查值和计数它们时会处理所有这些复杂的组合,因此无需担心它们的写入方式,但重要的是不要指责应用程序如果它做了不寻常但有效的事情就是有错误的。重要提示:正如 RFC7231 所建议的那样,HAProxy 通过用 LWS 替换标头中间的换行符来规范化标头,以便连接多行标头。这对于正确的分析是必要的,并有助于功能较弱的 HTTP 解析器正常工作,而不会被这种复杂的结构所愚弄。

1.4. HTTP 响应

HTTP 响应看起来非常像 HTTP 请求。两者都称为 HTTP 消息。让我们考虑这个 HTTP 响应:行内容编号 1 HTTP/1.1 200 OK 2 Content-length: 350 3 Content-Type: text/html作为一个特例,HTTP 支持所谓的“信息性响应”(Informational responses),状态码为 1xx。这些消息很特别,因为它们不传达响应的任何部分,它们只用作一种信号消息,例如要求客户端继续发送请求。在状态码为 100 的响应的情况下,请求的信息将由紧随信息性消息之后的下一个非 100 响应消息携带。这意味着可以向单个请求发送多个响应,并且这仅在启用 keep-alive 时有效(1xx 消息出现在 HTTP/1.1 中)。HAProxy 处理这些消息,并能够正确转发和跳过它们,并且只处理下一个非 100 响应。因此,除非另有明确说明,否则这些消息既不会被记录也不会被转换。状态码为 101 的消息表示协议正在同一连接上更改,并且 HAProxy 必须切换到隧道模式,就像发生了 CONNECT 一样。然后 Upgrade 标头将包含有关连接正在切换到的协议类型的附加信息。

1.4.1. 响应行

第 1 行是“响应行”。它始终由 3 个字段组成:- 版本标签:HTTP/1.1- 状态码:200- 原因:OK状态码始终是 3 位数字。第一位数字表示一般状态:- 1xx = 要跳过的信息性消息(例如 100, 101)- 2xx = OK,内容正在跟随(例如 200, 206)- 3xx = OK,没有内容跟随(例如 302, 304)- 4xx = 客户端引起的错误(例如 401, 403, 404)- 5xx = 服务器引起的错误(例如 500, 502, 503)状态码大于 599 的不应在通信中发出,尽管某些代理可能会在日志中生成它们以报告其内部状态。有关所有此类代码的详细含义,请参阅 RFC9110。HTTP/2 及更高版本没有版本标签,而是使用“:status”伪标头来报告状态码。“原因”字段只是一个提示,但客户端不会解析它。那里可以找到任何东西,但尊重既定的消息是一种常见的做法。它可以由一个或多个单词组成,例如“OK”、“Found”或“Authentication Required”。它在 HTTP/2 及更高版本中不存在,也不会在那里发出。当 HTTP/2 或更高版本的响应传输到 HTTP/1 客户端时,HAProxy 将生成与状态码匹配的常见原因字段。HAProxy 可能会自行发出以下状态码:代码时间/原因200 访问统计信息页面,以及回复监控请求时301 执行重定向时,取决于配置的代码302 执行重定向时,取决于配置的代码303 执行重定向时,取决于配置的代码307 执行重定向时,取决于配置的代码308 执行重定向时,取决于配置的代码400 对于无效或过大的请求401 需要身份验证才能执行操作时(访问统计信息页面时)403 当“http-request deny”规则禁止请求时404 当找不到请求的资源时408 在请求完成之前请求超时时410 当请求的资源不再可用且以后也不会再可用时500 当 HAProxy 遇到无法恢复的内部错误时,例如内存分配失败,这不应该发生501 当 HAProxy 因不支持的功能而无法满足客户端请求时502 当服务器返回空、无效或不完整的响应时,或者当“http-response deny”规则阻止响应时。503 当没有可用的服务器来处理请求时,或者响应与“monitor fail”条件匹配的监控请求时504 在服务器响应之前响应超时时上面的错误 4xx 和 5xx 代码可以自定义(请参阅 section 4.2 中的“errorloc”)。其他状态码可以通过特定操作有意发出(例如,请参阅 section 4.3 中的“deny”、“return”和“redirect”操作)。

1.4.2. 响应头

响应头的工作方式与请求头完全相同,因此,HAProxy 对两者使用相同的解析函数。有关更多详细信息,请参阅第 1.3.2 段。

2.1. 配置文件格式

HAProxy 的配置过程涉及 3 个主要的参数来源:- 命令行参数,始终优先- 配置文件,此处描述其格式- 运行进程的环境,以防某些环境变量被明确引用配置文件遵循一个相当简单的分层格式,它服从一些基本规则:1. 配置文件是语句的有序序列2. 语句是任何不受保护的 "#"(哈希)之前的一行非空行3. 一行是一系列由不受保护的空格或制表符分隔的标记或“单词”4. 一行的第一个单词或单词序列是本文档中列出的关键字或关键字序列之一5. 所有其他单词都是第一个单词的所有参数,其中一些是本文档中列出的众所周知的关键字,其他是值、对配置其他部分的引用或表达式6. 某些关键字划分了一个部分,在该部分内只支持关键字的一个子集7. 一个部分在文件末尾或在开始新部分的特殊关键字处结束这就是编写简单但可靠的配置生成器所需要知道的一切,但这不足以可靠地解析任何配置,也无法弄清楚如何处理某些边缘情况。首先,上述规则有一些后果。规则 6 和 7 意味着用于定义新部分的关键字在任何地方都有效,并且不能在特定部分中具有不同的含义。这些关键字始终是单个单词(而不是单词序列),并且传统上,紧随其后的部分使用相同的名称来指定。例如,当谈论“global section”(全局部分)时,它指定了跟在“global”关键字后面的配置部分。这种用法在错误消息中经常使用,以帮助定位需要解决的部分。许多部分创建了一个内部对象或配置空间,需要将其与其他对象区分开来。在这种情况下,它们将采用一个额外的单词来设置此特定部分的名称。对于其中一些,部分名称是强制性的。例如,“frontend foo”将创建一个名为“foo”的类型为“frontend”的新部分。通常,名称特定于其部分,不同类型的两个部分可以使用相同的名称,但不建议这样做,因为它往往会使配置管理复杂化。规则 7 的直接后果是,当同时读取多个文件时,每个文件都必须以一个新部分开头,并且每个文件的末尾都将结束一个部分。文件不能包含子部分,也不能结束现有部分并开始新部分。规则 1 提到顺序很重要。实际上,一些关键字创建了可以重复多次的指令,以创建要按特定顺序应用的有序列规则。例如,"tcp-request" 可用于根据不同的条件交替使用 "accept" 和 "reject" 规则。因此,配置文件处理器在编辑文件时必须始终保留部分的顺序。部分的顺序通常无关紧要,但全局部分必须放置在其他部分之前,但如果需要可以重复。此外,一些自动标识符可能会自动分配给某些创建的对象(例如代理),并且通过重新排序部分,它们的标识符将发生变化。这些出现在统计信息中。因此,下面的配置将为“foo”分配 ID 1,为“bar”分配 ID 2,如果颠倒这两个部分,ID 将互换:listen foo bind :80 listen bar bind :81另一个重要点是,根据上面的规则 2 和 3,空行、空格、制表符以及紧跟不受保护的 "#" 字符的注释不是配置的一部分,因为它们仅用作分隔符。这意味着以下配置是完全等效的:global#这是全局部分 daemon#守护进程 frontend foo mode http # 或者 tcp and: global daemon # 这是公共 Web frontend frontend foo mode http常见的做法是只将启动新部分的关键字左对齐,并缩进(即在前面加上制表符或几个空格)所有其他关键字,以便立即看出它们属于同一部分(如上例中的第二个示例所示)。在新部分之前放置注释有助于读者判断它是否是所需的部分。在部分末尾留一个空行也有助于在编辑时直观地发现末尾。制表符非常方便用于缩进,但它们复制粘贴效果不佳。如果使用空格代替,建议不要放置太多(2 到 4 个),这样在有限的编辑器中编辑时不会成为负担,因为这些编辑器不支持自动缩进。早期,由于大多数关键字不超过两个参数,因此将参数在固定制表符位置拆分是很常见的。随着现代版本具有复杂的表达式,这种做法不再适用,也不推荐。

2.2. 引号和转义

在现代配置中,一些参数需要使用以前被认为是纯分隔符的字符。为了使这成为可能,HAProxy 支持通过在要转义的字符前面加上反斜杠 ('\')、在双引号 ('"') 内进行弱引用以及在单引号 ("'") 内进行强引用来实现字符转义。这与许多编程语言中所做的工作非常相似,并且非常接近 Bourne shell 中常见的操作。其原理如下:当配置解析器将行切割成单词时,它还会处理引号和反斜杠,以确定字符是分隔符还是当前单词中的该字符的原始表示形式。然后删除转义字符,删除引号,剩余的单词按原样用作关键字或参数。如果单词中需要反斜杠,则必须使用它本身进行转义(即双反斜杠)或进行强引用。在引号外部进行转义是通过在特殊字符前加上反斜杠 ('\') 来实现的:\ 标记空格并将其与分隔符区分开来\# 标记哈希并将其与注释区分开来\\ 使用反斜杠\' 使用单引号并将其与强引用区分开来\" 使用双引号并将其与弱引用区分开来此外,可以使用其通常的 C 语言表示形式发出一些不可打印字符:\n 插入换行符 (LF, character \x0a or ASCII 10 decimal)\r 插入回车符 (CR, character \x0d or ASCII 13 decimal)\t 插入制表符 (character \x09 or ASCII 9 decimal)\xNN 插入 ASCII 码为十六进制 NN 的字符(例如 \x0a 用于 LF)。弱引用是通过在要保护的字符或字符序列周围加上双引号 ("") 来实现的。弱引用会阻止对以下内容的解释:空格或制表符作为单词分隔符' 单引号作为强引用分隔符# 哈希作为注释开始弱引用允许通过在前面加上美元符号 ('$') 来解释环境变量(在引号外部不进行评估)。如果双引号内需要美元字符,则必须使用反斜杠进行转义。强引用是通过在要保护的字符或字符序列周围加上单引号 ('') 来实现的。在单引号内部,不解释任何内容,这是引用正则表达式的有效方式。因此,下表显示了特殊字符如何在不同的上下文(不可打印字符替换为其名称,并用尖括号括起来)中输入。请注意,某些只能以转义形式表示的字符在单引号内没有可能的表示形式,因此此处没有。
字符无引号弱引用强引用
<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"'\'
示例
# 以下这些都是完全等效的: 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
在某些情况下,可能需要第二级引用或转义。一些关键字在括号内接受参数,有时用逗号分隔。这些参数通常是整数或预定义单词,但当它们是任意字符串时,可能需要执行单独的转义级别,以消除属于参数的字符与用于分隔参数本身的字符之间的歧义。一个非常常见的情况是 "regsub" 转换器。它接受一个正则表达式作为参数,如果需要在其中包含一个右括号,则需要对其进行自己的引用。关键字参数解析器与顶层解析器在引用方面完全相同,只是不处理 \#、$ 和 \xNN 转义。但并不总是显而易见的是,内部使用的分隔符必须首先进行转义或引用,以便它们不会在顶层解析。让我们看一个使用 "regsub" 转换器的示例,它接受 3 个参数,一个正则表达式、一个替换字符串和一组标志:# replace all occurrences of "foo" with "blah" in the path: http-request set-path %[path,regsub(foo,blah,g)]这里不需要特殊的引用。但是如果现在我们想用“blah”替换“foo”或“bar”,我们需要正则表达式“(foo|bar)”。我们不能写成:http-request set-path %[path,regsub((foo|bar),blah,g)]因为我们希望字符串像这样切割:http-request set-path %[path,regsub((foo|bar),blah,g)] |---------|----|-| arg1 _/ / / arg2 __________/ / arg3 ______________/但实际上,传递的是开括号和闭括号之间的字符串,然后是垃圾:http-request set-path %[path,regsub((foo|bar),blah,g)] |--------|--------| arg1=(foo|bar _/ / trailing garbage _________/这里的明显解决方案似乎是闭括号需要被引用,但仅凭这一点行不通,因为如上所述,引用由顶层解析器处理,该解析器将在处理此单词之前解析它们:http-request set-path %[path,regsub("(foo|bar)",blah,g)] ------------ -------- ---------------------------------- word1 word2 word3=%[path,regsub((foo|bar),blah,g)]因此,我们没有为第二层的参数解析器更改任何内容,它仍然将截断的正则表达式视为唯一的参数,而字符串末尾有垃圾。通过转义引号,它们将未经修改地传递到第二层: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 _______________/另一种方法是使用单引号将整个字符串括起来,并使用双引号将内部括起来(这样双引号就不会再次被剥离):http-request set-path '%[path,regsub("(foo|bar)",blah,g)]' ------------ -------- ---------------------------------- word1 word2 word3=%[path,regsub("(foo|bar)",blah,g)] |---------||----|-| arg1=(foo|bar) _/ / / arg2 ___________/ / arg3 _______________/使用正则表达式时,美元字符 ('$') 可能出现在表达式中,或者反斜杠 ('\') 用于替换字符串中。在这种情况下,这些字符也将在双引号内处理,因此首选单引号(或双重转义)。示例: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 ______________________/请记住,反斜杠在单引号内不是转义字符,并且上面的整个单词已经通过单引号保护了它们。相反,如果使用双引号将整个表达式括起来,则美元字符和反斜杠将在顶层解析,从而在第二层破坏参数内容。不幸的是,由于单引号不能在强引用内部转义,如果需要在参数中包含单引号,则需要对它们进行两次转义或引用。有几种方法可以做到这一点:http-request set-var(txn.foo) str("\\'foo\\'") http-request set-var(txn.foo) str(\"\'foo\'\") http-request set-var(txn.foo) str(\\\'foo\\\')有疑问时,只需不要在任何地方使用引号,然后开始在需要逗号或闭括号的参数周围放置单引号或双引号,并考虑如果字符串包含美元或反斜杠,则使用反斜杠转义这些引号。同样,这与在 Bourne shell 下将命令双重转义传递给 "eval" 时所使用的非常相似。对于 API 编写者来说,最好的方法可能是无论内容如何,都在每个参数周围放置转义引号。用户可能会发现,在整个表达式周围使用单引号并在每个参数周围使用双引号提供了更具可读性的配置。

2.3. 环境变量

HAProxy 的配置支持环境变量。这些变量仅在双引号内被解释。变量在配置解析期间被展开。变量名前必须有美元符号 ("$"),并且可以选择性地用大括号 ("{}") 括起来,类似于 Bourne shell 中的做法。变量名可以包含字母数字字符或下划线 ("_"),但不应以数字开头。如果变量包含由空格分隔的多个值列表,可以通过用大括号将变量括起来并在右大括号前附加后缀 '[*]' 来将其展开为单个参数。当变量未设置时,也可以通过在变量名旁边的破折号 '-' 后面附加该值来指定一个默认值。请注意,默认值只替换不存在的变量,而不是空变量。
示例
bind "fd@${FD_APP1}" log "${LOCAL_SYLOG-127.0.0.1}:514" local0 notice # 发送到本地服务器 user "$HAPROXY_USER"
有一些变量是由 HAProxy 定义的,它们可以在配置文件中使用,或者可以被程序继承(参见 3.7. 程序): * HAPROXY_LOCALPEER:在进程启动时定义,包含本地对等点的名称。(参见管理指南中的 "-L"。) * HAPROXY_CFGFILES:HAProxy 加载的配置文件的列表,用分号分隔。在您指定了一个目录的情况下可能很有用。 * HAPROXY_HTTP_LOG_FMT:包含在 第 8.2.3 节“HTTP 日志格式”中定义的默认 HTTP 日志格式的值。它可以用来覆盖默认的日志格式,而无需复制整个原始定义。
示例
# 将给出最终判决的规则添加到日志中 log-format "${HAPROXY_TCP_LOG_FMT} lr=last_rule_file:last_rule_line"
* HAPROXY_HTTPS_LOG_FMT:类似于 HAPROXY_HTTP_LOG_FMT,但用于 section 8.2.4 “HTTPS log format”(HTTPS 日志格式)中定义的 HTTPS 日志格式。* HAPROXY_TCP_LOG_FMT:类似于 HAPROXY_HTTP_LOG_FMT,但用于 section 8.2.2 “TCP log format”(TCP 日志格式)中定义的 TCP 日志格式。* HAPROXY_MWORKER:在主工作模式下,此变量设置为 1。* HAPROXY_CLI:为每个进程配置的统计套接字侦听器地址,用分号分隔。* HAPROXY_MASTER_CLI:在主工作模式下,主 CLI 的侦听器地址,用分号分隔。* HAPROXY_STARTUP_VERSION:包含用于启动的版本,在主工作模式下,这是用于启动主版本(即使在更新二进制文件和重新加载之后)。* HAPROXY_BRANCH:包含 HAProxy 分支版本(例如“2.8”)。它不包含完整的版本号。如果资源(例如地图或证书)位于包含分支号的路径中,这在迁移的情况下很有用。此外,一些伪变量会在内部解析,并可用作常规变量。伪变量总是以点 ('.') 开头,并且是唯一允许使用点的变量。当前的伪变量列表是:* .FILE:当前正在解析的配置文件的名称。* .LINE:当前正在解析的配置文件的行号,从一开始。* .SECTION:当前正在解析的部分的名称,如果部分没有名称(例如“global”),则为其类型,或者在第一个部分之前为空字符串。这些变量在解析它们的位置解析。例如,如果 ".LINE" 变量用于位于 defaults 部分的 "log-format" 指令中,则在解析和编译 "log-format" 指令之前会解析其行号,因此后续代理将重用相同的行号。通过这种方式,可以发出信息以帮助定位变量、日志、错误状态、健康检查、标头值中的规则,甚至可以使用行号来命名一些配置对象,例如服务器。另请参阅 "external-check command" 以了解其他变量。

2.4. 条件块

有时,能够有条件地启用或禁用配置的某些任意部分是很方便的,例如启用/禁用 SSL 或密码套件,启用或禁用某些预生产侦听器而无需修改配置,或者调整配置的语法以在迁移期间支持两个不同的 HAProxy 版本。HAProxy 带来了一组可嵌套的类似预处理器的指令,允许集成或忽略某些文本块。这些指令必须放在自己的行上,并且它们作用于紧随其后的行。其中两个支持表达式,其他的只切换到备用块或结束当前级别。定义了以下 4 个指令来形成条件块:- .if <condition>- .elif <condition>- .else- .endif“.if”指令嵌套一个新级别,“.elif”保持在同一级别,“.else”也是如此,“.endif”关闭一个级别。每个“.if”必须由匹配的“.endif”终止。“.elif”只能放在“.if”或“.elif”之后,并且可以链接的“.elif”数量没有限制。每个“.if”只能有一个“.else”,并且它必须始终位于“.if”或块中最后一个“.elif”之后。如果需要在 '#' 之后放置注释,它们将被忽略。指令像其他配置指令一样被标记化,因此可以在条件中使用环境变量。条件也可以在启动时使用 -cc 参数进行评估。请参阅管理文档中的“3. Starting HAProxy”。条件要么是空字符串(返回 false),要么是由以下任意组合组成的表达式:- 整数零 ('0'),始终返回“false”- 非零整数(例如 '1'),始终返回“true”。- 一个谓词,可选后跟括号中的参数。- 放置在一对括号 '(' 和 ')' 之间的条件- 一个感叹号 ('!') 在上述任何非空元素之前,它将否定其状态。- 使用逻辑 AND ('&&') 组合的表达式,将从左到右评估,直到一个返回 false- 使用逻辑 OR ('||') 组合的表达式,将从右到左评估,直到一个返回 true使用与配置语言其余部分相同的行标记器和参数解析器。单词围绕连续的一个或多个非引用空格或制表符系列拆分,并使用单个空格重新组合在一起以分隔它们,然后再进行评估,以使用户不必引用整行。但这R也意味着围绕逗号或括号的空格肯定是值的一部分,这并不总是预期的。例如,下面的表达式:.if defined( HAPROXY_MWORKER )将测试变量 " HAPROXY_MWORKER "(带空格)是否存在,而这个:.if streq("$ENABLE_SSL", 1)会将环境变量 "ENABLE_SSL" 与值 " 1"(带有一个前导空格)进行比较。原因是该行首先被拆分成单词,如下所示:.if streq("$ENABLE_SSL", 1) |---|--------------------| |--| 1 2 3然后应用弱引用并解析环境变量 "$ENABLE_SSL"(假设 ENABLE_SSL=0),最后通过在单词之间放置单个空格将单词重新组合成一个字符串:.if streq(0, 1) |---|-------|--| 1 2 3然后才将其解析为单个表达式。在逗号和 "1" 之间插入的空格仍然是参数值的一部分,使此参数为 " 1":.if streq(0, 1) |---|-----|-|--| \ \ \ \_ argument2: " 1" \ \ \___ argument1: "0" \ \_______ function: "streq" \___________ directive: ".if"这里很明显,即使 ENABLE_SSL 等于 "1",它也不会匹配 " 1",因为字符串会相差一个空格。注意:如“2.2. Quoting and escaping”(引用和转义)部分所述,一个好的经验法则是永远不要在表达式中插入不必要的空格。请注意,与其他语言一样,AND 运算符优先于 OR 运算符,因此 "A && B || C && D" 的评估结果为 "(A && B) || (C && D)"。当前支持的谓词列表如下:- defined(<name>):如果环境变量 <name> 存在,则返回 true,无论其内容如何- feature(<name>):如果功能 <name> 被列为存在于 "haproxy -vv" 报告的功能列表中(这意味着 <name> 出现在 '+' 之后),则返回 true- streq(<str1>,<str2>):仅当两个字符串相等时才返回 true- strneq(<str1>,<str2>):仅当两个字符串不同时才返回 true- strstr(<str1>,<str2>):仅当在第一个字符串中找到第二个字符串时才返回 true。- version_atleast(<ver>):如果当前 haproxy 版本至少与 <ver> 一样新,则返回 true,否则返回 false。版本语法与 "haproxy -v" 所示相同,缺少组件被假定为零。- version_before(<ver>):如果当前 haproxy 版本严格早于 <ver>,则返回 true,否则返回 false。版本语法与 "haproxy -v" 所示相同,缺少组件被假定为零。- enabled(<opt>):如果选项 <opt> 在运行时启用,则返回 true。仅支持部分选项:POLL, EPOLL, KQUEUE, EVPORTS, SPLICE, GETADDRINFO, REUSEPORT, FAST-FORWARD, SERVER-SSL-VERIFY-NONE
示例
.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 feature(OPENSSL) && (streq("$WITH_SSL",yes) || streq("$SSL_ONLY",yes)) bind :443 ssl crt ... .endif .if version_atleast(2.4-dev19) profiling.memory on .endif .if !feature(OPENSSL) .alert "必须支持 SSL" .endif
提供了另外四个指令来报告一些状态:- .diag "message":仅在诊断模式下 (-dD) 发出此消息- .notice "message":以 NOTICE 级别发出此消息- .warning "message":以 WARNING 级别发出此消息- .alert "message":以 ALERT 级别发出此消息如果在 "strict-mode" 启用时,以 WARNING 级别发出的消息可能会导致进程启动失败。以 ALERT 级别发出的消息将始终导致致命错误。这些可用于检测一些不适当的条件并向用户提供建议。
示例
.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: 切换到 2.4 后将 'redirect' 替换为 'return'" http-request redirect location /goaway if ABUSE

2.5. 时间格式

一些参数涉及表示时间的值,例如超时。这些值通常以毫秒表示(除非另有明确说明),但也可以通过在数值后附加单位来以任何其他单位表示。考虑这一点很重要,因为每个关键字都不会重复说明。支持的单位有:- us:微秒。1 微秒 = 1/1000000 秒 - ms:毫秒。1 毫秒 = 1/1000 秒。这是默认单位。 - s:秒。1s = 1000ms - m:分钟。1m = 60s = 60000ms - h:小时。1h = 60m = 3600s = 3600000ms - d:天。1d = 24h = 1440m = 86400s = 86400000ms

2.6. 大小格式

一些参数涉及表示大小的值,例如带宽限制。这些值通常以字节表示(除非另有明确说明),但也可以通过在数值后附加单位来以任何其他单位表示。考虑这一点很重要,因为每个关键字都不会重复说明。支持的单位不区分大小写:- k:千字节。1 千字节 = 1024 字节 - m:兆字节。1 兆字节 = 1048576 字节 - g:吉字节。1 吉字节 = 1073741824 字节 时间和大小格式都需要整数,不允许使用小数表示法。

2.7. 示例

# 一个简单的 HTTP 代理配置,在所有接口的 80 端口上监听,# 并将请求转发到名为 "servers" 的单个后端,该后端有一个名为 "server1" 的服务器,# 监听于 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 # 使用单个 listen 块定义的相同配置。更短但表达力较差,尤其是在 HTTP 模式下。 global daemon maxconn 256 defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen http-in bind *:80 server server1 127.0.0.1:8000 maxconn 32 假设 haproxy 在 $PATH 中,请在 shell 中使用以下命令测试这些配置:$ sudo haproxy -f configuration.conf -c
“global” 部分中的参数是针对整个进程的,并且通常与操作系统相关。它们通常只需设置一次即可供所有人使用,并且一旦正确就不需要更改。其中一些有命令行等效项。 “global” 部分支持以下关键字: * 进程管理和安全性 - 51degrees-allow-unmatched - 51degrees-cache-size - 51degrees-data-file - 51degrees-difference - 51degrees-drift - 51degrees-property-name-list - 51degrees-property-separator - 51degrees-use-performance-graph - 51degrees-use-predictive-graph - ca-base - chroot - cluster-secret - cpu-map - crt-base - daemon - default-path - description - deviceatlas-json-file - deviceatlas-log-level - deviceatlas-properties-cookie - deviceatlas-separator - expose-experimental-directives - external-check - fd-hard-limit - gid - grace - group - h1-accept-payload-with-any-method - h1-case-adjust - h1-case-adjust-file - h2-workaround-bogus-websocket-clients - hard-stop-after - harden.reject-privileged-ports.tcp - harden.reject-privileged-ports.quic - insecure-fork-wanted - insecure-setuid-wanted - issuers-chain-path - localpeer - log - log-send-hostname - log-tag - lua-load - lua-load-per-thread - lua-prepend-path - mworker-max-reloads - nbthread - node - numa-cpu-mapping - pidfile - pp2-never-send-local - presetenv - prealloc-fd - resetenv - set-dumpable - set-var - setenv - ssl-default-bind-ciphers - ssl-default-bind-ciphersuites - ssl-default-bind-client-sigalgs - ssl-default-bind-curves - ssl-default-bind-options - ssl-default-bind-sigalgs - ssl-default-server-ciphers - ssl-default-server-ciphersuites - ssl-default-server-client-sigalgs - ssl-default-server-curves - ssl-default-server-options - ssl-default-server-sigalgs - ssl-dh-param-file - ssl-propquery - ssl-provider - ssl-provider-path - ssl-server-verify - ssl-skip-self-issued-ca - stats - strict-limits - uid - ulimit-n - unix-bind - unsetenv - user - wurfl-cache-size - wurfl-data-file - wurfl-information-list - wurfl-information-list-separator * 性能调优 - busy-polling - max-spread-checks - maxcompcpuusage - maxcomprate - maxconn - maxconnrate - maxpipes - maxsessrate - maxsslconn - maxsslrate - maxzlibmem - no-memory-trimming - noepoll - noevports - nogetaddrinfo - nokqueue - nopoll - noreuseport - nosplice - profiling.tasks - server-state-base - server-state-file - spread-checks - ssl-engine - ssl-mode-async - tune.buffers.limit - tune.buffers.reserve - tune.bufsize - tune.comp.maxlevel - tune.disable-fast-forward - tune.disable-zero-copy-forwarding - tune.events.max-events-at-once - tune.fail-alloc - tune.fd.edge-triggered - tune.h1.zero-copy-fwd-recv - tune.h1.zero-copy-fwd-send - tune.h2.be.glitches-threshold - tune.h2.be.initial-window-size - tune.h2.be.max-concurrent-streams - tune.h2.fe.glitches-threshold - tune.h2.fe.initial-window-size - tune.h2.fe.max-concurrent-streams - tune.h2.fe.max-total-streams - tune.h2.header-table-size - tune.h2.initial-window-size - tune.h2.max-concurrent-streams - tune.h2.max-frame-size - tune.h2.zero-copy-fwd-send - tune.http.cookielen - tune.http.logurilen - tune.http.maxhdr - tune.idle-pool.shared - tune.idletimer - tune.lua.burst-timeout - tune.lua.forced-yield - tune.lua.log.loggers - tune.lua.log.stderr - tune.lua.maxmem - tune.lua.service-timeout - tune.lua.session-timeout - tune.lua.task-timeout - tune.max-checks-per-thread - tune.maxaccept - tune.maxpollevents - tune.maxrewrite - tune.memory.hot-size - tune.pattern.cache-size - tune.peers.max-updates-at-once - tune.pipesize - tune.pool-high-fd-ratio - tune.pool-low-fd-ratio - tune.pt.zero-copy-forwarding - tune.quic.frontend.conn-tx-buffers.limit - tune.quic.frontend.max-idle-timeout - tune.quic.frontend.max-streams-bidi - tune.quic.max-frame-loss - tune.quic.reorder-ratio - tune.quic.retry-threshold - tune.quic.socket-owner - tune.quic.zero-copy-fwd-send - tune.rcvbuf.backend - tune.rcvbuf.client - tune.rcvbuf.frontend - tune.rcvbuf.server - tune.recv_enough - tune.runqueue-depth - tune.sched.low-latency - tune.sndbuf.backend - tune.sndbuf.client - tune.sndbuf.frontend - tune.sndbuf.server - tune.stick-counters - tune.ssl.cachesize - tune.ssl.capture-buffer-size - tune.ssl.capture-cipherlist-size (deprecated) - tune.ssl.default-dh-param - tune.ssl.force-private-cache - tune.ssl.hard-maxrecord - tune.ssl.keylog - tune.ssl.lifetime - tune.ssl.maxrecord - tune.ssl.ssl-ctx-cache-size - tune.ssl.ocsp-update.maxdelay - tune.ssl.ocsp-update.mindelay - 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 * 调试 - anonkey - quiet - warn-blocked-traffic-after - zero-warning * HTTP客户端 - httpclient.resolvers.disabled - httpclient.resolvers.id - httpclient.resolvers.prefer - httpclient.retries - httpclient.ssl.ca-file - httpclient.ssl.verify - httpclient.timeout.connect

3.1. 进程管理与安全

用于提供设备检测服务的 51Degrees 数据文件的路径。该文件应该是解压缩的,并且 HAProxy 具有相关权限可以访问。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 的情况下可用。
要从数据集中加载的 51Degrees 属性名称列表。完整的名称列表可在 51Degrees 网站上找到:https://51degrees.com/resources/property-dictionary 请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 的情况下可用。
一个字符,将附加到包含 51Degrees 结果的响应头中每个属性值的末尾。如果未设置,则默认为 ','。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 的情况下可用。
将 51Degrees 转换器缓存的大小设置为 <数字> 个条目。这是一个 LRU 缓存,用于记录以前的设备检测及其结果。默认情况下,此缓存是禁用的。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 的情况下可用。
启用('on')或禁用('off')在检测过程中使用性能图。默认值取决于 51Degrees 库。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 和 51DEGREES_VER=4 的情况下可用。
启用('on')或禁用('off')在检测过程中使用预测图。默认值取决于 51Degrees 库。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 和 51DEGREES_VER=4 的情况下可用。
设置检测可以允许的漂移值。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 和 51DEGREES_VER=4 的情况下可用。
设置检测可以允许的差异值。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 和 51DEGREES_VER=4 的情况下可用。
启用('on')或禁用('off')在检测过程中使用不匹配的节点。默认值取决于 51Degrees 库。请注意,此选项仅在 HAProxy 编译时启用了 USE_51DEGREES 和 51DEGREES_VER=4 的情况下可用。
ca-base <dir>
使用相对路径指定 "ca-file"、"ca-verify-file" 或 "crl-file" 指令时,分配一个默认目录来获取 SSL CA 证书和 CRL。在 "ca-file"、"ca-verify-file" 和 "crl-file" 中指定的绝对路径优先,并忽略 "ca-base"。
chroot <jail dir>
在降低权限之前,将当前目录更改为 <jail dir> 并在那里执行 chroot()。这提高了安全级别,以防未知漏洞被利用,因为它会使攻击者很难利用系统。这仅在进程以超级用户权限启动时有效。确保 <jail_dir> 既为空又对任何人不可写非常重要。
定义一个时间窗口,在此期间,在软停止的情况下,空闲连接和活动连接的关闭将被分散进行。收到 SIGUSR1 并且宽限期结束后(如果有的话),如果没有设置此选项,空闲连接将立即全部关闭,而活动的 HTTP 或 HTTP2 连接将在收到下一个请求后结束,方法是在 HTTP 响应中附加“Connection: close”行,或者在 HTTP2 的情况下发送 GOAWAY 帧。当设置此选项时,连接关闭将在此设定的 <time> 内分散进行。如果 close-spread-time 设置为“infinite”,则在软停止期间将禁用活动连接的关闭。“Connection: close”头将不再添加到 HTTP 响应中(或 HTTP2 的 GOAWAY),空闲连接只有在其超时到达时(基于配置中设置的各种超时)才会被关闭。
参数
<time> 是一个时间窗口(默认为毫秒),在此期间,连接关闭将在软停止操作期间分散进行,或者如果应禁用活动连接关闭,则为“infinite”。
如果使用了“hard-stop-after”选项,建议将此设置的值设置为低于该选项中使用的值,以便所有连接都有机会在进程停止前正常关闭。
定义一个由属于同一集群的多个节点共享的 ASCII 字符串密钥。它可以用于不同的用途。它至少用于为该进程实例化的所有 QUIC 连接派生无状态重置令牌。这也用于派生用于加密重试令牌的密钥。如果未设置此参数,则在进程启动时将选择一个随机值。这允许使用依赖于它的功能,尽管有一些限制。
cpu-map [auto:]<线程组>[/<线程集>] <cpu集>[,...] [...]
在某些操作系统上,可以将线程组或线程绑定到特定的 CPU 集。这意味着指定的线程永远不会在其他 CPU 上运行。 "cpu-map" 指令为单个线程或线程组指定 CPU 集。第一个参数是线程组范围,后面可选地跟着一个线程集。这些范围具有以下格式:all | odd | even | number[-[number]] <number> 必须是 1 到 32 或 64 之间的数字,具体取决于机器的字大小。任何超出 'thread-groups' 的组 ID 和任何超出机器字大小的线程 ID 都将被忽略。所有线程号都相对于它们所属的组。可以使用由短划线 ('-') 分隔的两个此类数字来指定范围。也可以使用 "all" 来指定所有线程,使用 "odd" 来指定奇数线程,或使用 "even" 来指定偶数线程,就像使用 "thread" bind 指令一样。第二个及后续参数是 CPU 集。每个 CPU 集要么是一个唯一的数字(从第一个 CPU 的 0 开始),要么是一个由短划线 ('-') 分隔的两个此类数字的范围。这些 CPU 编号和范围可以通过逗号分隔重复,或者通过在同一行上传递更多范围作为新参数来重复。在 Linux 和 BSD 操作系统之外,最大 CPU 索引可能限制为 31 或 63。可以指定多个 "cpu-map" 指令,但当它们重叠时,每个 "cpu-map" 指令都会替换前面的指令。范围可以部分定义。可以省略上限。在这种情况下,它会被替换为相应的最大值,具体取决于机器的字大小,可能是 32 或 64。可以在线程集之前添加前缀 "auto:",让 HAProxy 通过递增线程和 CPU 集自动将一组线程绑定到一个 CPU。为了有效,两组必须具有相同的大小。无论 CPU 集的声明顺序如何,它都将从最低到最高绑定。不支持同时具有组和线程范围且带有 "auto:" 前缀。只支持一个范围,另一个必须是固定数字。请注意,支持组范围是出于历史原因。如今,一个单独的数字表示一个线程组,如果不使用线程组,则必须为 1,并且指定线程范围或数字需要在其前面加上 "1/"(如果不使用线程组)。最后,"1" 与 "1/all" 完全等价,表示组中的所有线程。
示例
cpu-map 1/all 0-3 # 将第一个组的所有线程绑定到 # 前 4 个 CPU cpu-map 1/1- 0- # 将被替换为 "cpu-map 1/1-64 0-63" # 或 "cpu-map 1/1-32 0-31" 取决于机器的 # 字大小。 # 所有这些行都将线程 1 绑定到 cpu 0,线程 2 绑定到 cpu 1 # 等等。 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 cpu-map auto:1/1-4 3,2,1,0 # 使用 all/odd/even 关键字将每个线程精确绑定到一个 CPU cpu-map auto:1/all 0-63 cpu-map auto:1/even 0-31 cpu-map auto:1/odd 32-63 # 无效的 cpu-map,因为线程集和 CPU 集的大小不同。 cpu-map auto:1/1-4 0 # 无效 cpu-map auto:1/1 0-3 # 无效 # 将这 4 个组的 40 个线程映射到单个 CPU cpu-map auto:1/1-10 0-9 cpu-map auto:2/1-10 10-19 cpu-map auto:3/1-10 20-29 cpu-map auto:4/1-10 30-39 # 将 80 个线程映射到一个物理插槽,另外 80 个映射到另一个插槽 # 而不强制分配。这些被分成 4 个组,因为没有 # 组可以超过 64 个线程。 cpu-map 1/1-40 0-39,80-119 # node0, siblings 0 & 1 cpu-map 2/1-40 0-39,80-119 cpu-map 3/1-40 40-79,120-159 # node1, siblings 0 & 1 cpu-map 4/1-40 40-79,120-159
crt-base <dir>
当使用 "crtfile" 或 "crt" 指令并提供相对路径时,指定一个用于获取 SSL 证书的默认目录。指定的绝对位置优先,并忽略 "crt-base"。
使进程 fork 到后台运行。这是推荐的操作模式。它等同于命令行参数 "-D"。它可以通过命令行参数 "-db" 禁用。此选项在 systemd 模式下被忽略。
default-path { current | config | parent | origin <path> }
默认情况下,HAProxy 会从进程启动位置加载所有相对路径指定的文件。在某些情况下,可能需要强制所有相对路径从不同的位置开始,就像进程是从这些位置启动的一样。这就是此指令的目的。从技术上讲,它将在处理每个配置文件时对指定位置执行临时 chdir(),并在处理完每个文件后返回原始目录。它接受一个参数来指示加载不以斜杠 ('/') 开头的文件时使用的策略:- "current" 表示所有相对文件都将从进程启动的目录加载;这是默认设置。 - "config" 表示所有相对文件都应从包含配置文件的目录加载。更具体地说,如果配置文件包含斜杠 ('/'),则使用直到最后一个斜杠的最长部分作为要更改的目录,否则使用当前目录。此模式便于将映射、错误文件、证书和 Lua 脚本捆绑在一起作为可重定位包。当加载多个配置文件时,目录会针对每个文件进行更新。 - "parent" 表示所有相对文件都应从包含配置文件的目录的父目录加载。更具体地说,如果配置文件包含斜杠 ('/'),则将 ".." 附加到直到最后一个斜杠的最长部分作为要更改的目录,否则目录为 ".."。此模式便于将映射、错误文件、证书和 Lua 脚本捆绑在一起作为可重定位包,但每个部分位于不同的子目录中(例如 "config/"、"certs/"、"maps/" 等)。 - "origin" 表示所有相对文件都应从指定的(强制)路径加载。这可用于简化管理在系统上并行运行的不同 HAProxy 实例,其中每个实例使用不同的前缀,但其余部分易于重定位。每个 "default-path" 指令会立即替换任何以前的指令,并可能导致切换到不同的目录。虽然这应该总是能产生所需的行为,但使用多个 default-path 指令确实不是一个好的做法,如果使用,策略应在所有配置文件中保持一致。警告:某些配置元素(例如映射或证书)通过其配置路径唯一标识。通过使用可重定位布局,它们中的几个可能最终具有相同的唯一名称,从而难以在运行时更新它们,尤其是当从不同目录加载多个配置文件时。在采用相对路径之前,必须遵守严格的无冲突文件命名方案。一种可靠的方法可能是为所有文件名添加相应站点名称的前缀,或者在目录级别执行此操作。
添加描述实例的文本。请注意,需要转义某些字符(例如 #),并且此文本将插入 HTML 页面中,因此您应避免使用“<”和“>”字符。
设置要由 API 加载的 DeviceAtlas JSON 数据文件的路径。该路径必须是一个有效的 JSON 数据文件,并且 HAProxy 进程可以访问。
设置 API 返回的信息级别。此指令是可选的,如果未设置,则默认为 0。
设置用于检测请求期间是否使用了 DeviceAtlas 客户端组件的客户端 cookie 名称。此指令是可选的,如果未设置,则默认为 DAPROPS。
设置 API 属性结果的字符分隔符。此指令是可选的,如果未设置,则默认为 |。
在使用标记为实验性的指令之前,必须出现此语句,否则配置文件将被拒绝。
external-check [preserve-env]
允许使用外部代理执行健康检查。默认情况下禁用此功能作为安全预防措施,即使启用,检查仍可能失败,除非也启用了 "insecure-fork-wanted"。如果启动的程序使用了 setuid 可执行文件(它真的不应该),您可能还需要在 global 部分设置 "insecure-setuid-wanted"。默认情况下,检查以干净的环境开始,其中只包含后端部分中 "external-check" 命令中定义的变量。但是,有时需要保留环境,例如当复杂的脚本从那里检索额外的路径或信息时。这可以通过附加 "preserve-env" 关键字来完成。在这种情况下,强烈建议不要运行 setuid 或作为特权用户运行,因为这会将检查程序暴露给潜在的攻击。有关详细信息,请参阅 "option external-check" 和 "insecure-fork-wanted" 以及 "insecure-setuid-wanted"。
fd-hard-limit <number>
设置进程将使用的最大文件描述符数量的上限,无论系统限制如何。虽然 "ulimit-n" 和 "maxconn" 可用于强制执行某个值,但当它们未设置时,进程将受限于 RLIMIT_NOFILE 设置的硬限制,如 "ulimit -n -H" 所报告。但是一些现代操作系统现在允许在这里设置极大的值(大约 10 亿),这对于常规使用会消耗过多的 RAM。fd-hard-limit 设置用于强制执行此限制的可能较低上限。这意味着当系统施加的限制低于 <number> 时,它将始终尊重系统施加的限制,但如果系统施加的限制更高,则将使用指定的值。默认情况下,fd-hard-limit 设置为 1048576。可以通过 DEFAULT_MAXFD 编译时变量更改此默认值,该变量可以用作最大(内核)系统限制,如果 RLIMIT_NOFILE 硬限制非常大。在 global 部分设置 fd-hard-limit 允许在运行时暂时覆盖通过 DEFAULT_MAXFD 在构建时提供的值。在下面的示例中,未指定其他设置,maxconn 值将自动适应 "fd-hard-limit" 和 RLIMIT_NOFILE 限制中的较低者:global # 尽可能使用多的 FD,但不超过 50000 fd-hard-limit 50000
gid <number>
将进程的组 ID 更改为 <number>。建议将组 ID 专用于 HAProxy 或一小组类似的守护程序。HAProxy 必须以属于此组的用户或具有超级用户权限启动。请注意,如果 HAProxy 是从具有补充组的用户启动的,则只有在以超级用户权限启动时才能删除这些组。另请参阅 "group" 和 "uid"。
grace <time>
定义 SIGUSR1 和实际软停止之间的延迟。
参数
<time> 是在接收到 SIGUSR1 信号后,在继续执行软停止操作之前将等待的额外延迟(默认为毫秒)。
这用于与需要停止 haproxy 进程但某些外部组件需要在解绑监听器之前检测状态的旧环境兼容。其原理是内部的 "stopping" 变量(由 "stopping" 样本获取函数报告)将被设置为 true,但监听器将继续无干扰地接受连接,直到延迟到期,之后将进行常规的软停止。这不能与重新加载的进程一起使用,否则会阻止旧进程解绑,并可能阻止新进程启动,或者只是引起麻烦。
示例
global grace 10s # 在通过 SIGUSR1 设置 stopping 之前,返回 200 OK frontend ext-check bind :9999 monitor-uri /ext-check monitor fail if { stopping }
请注意,一个更灵活、更持久的方法是让编排系统从 CLI 设置一个全局变量,使用该变量来响应外部检查,然后在延迟后发送 SIGUSR1 信号。
示例
# 在 proc.stopping 设置为非零之前返回 200 OK。可以通过 # HTTP 使用 set-var(proc.stopping) 或从 CLI 使用: # > set var proc.stopping int(1) frontend ext-check bind :9999 monitor-uri /ext-check monitor fail if { var(proc.stopping) -m int gt 0 }
group <group name>
类似于 "gid",但使用 /etc/group 中组名 <group name> 的 GID。另请参阅 "gid" 和 "user"。
不拒绝带有负载(payload)的 HTTP/1.0 GET/HEAD/DELETE 请求。虽然这在 HTTP/1.1 中是明确允许的,但 HTTP/1.0 在这一点上并不明确,一些旧服务器不期望任何负载,也从不查找正文长度(通过 Content-Length 或 Transfer-Encoding 头)。这意味着一些中间件可能正确处理 HTTP/1.0 GET/HEAD/DELETE 请求的负载,而另一些则可能完全忽略它。这可能导致安全问题,因为可能存在请求走私攻击。因此,默认情况下,HAProxy 会拒绝带有负载的 HTTP/1.0 GET/HEAD/DELETE 请求。然而,对于一些旧客户端来说,这可能是一个问题。在这种情况下,可以设置此全局选项。
h1-case-adjust <from> <to>
定义在发送给 HTTP/1 客户端或服务器之前,对标头名称 <from> 应用的调整大小写,将其更改为 <to>。<from> 必须是小写,<from> 和 <to> 除了大小写外不能有区别。如果需要调整多个标头名称,可以重复。不允许重复条目。如果需要调整大量标头名称,使用 "h1-case-adjust-file" 可能更方便。请注意,除非在代理中指定了 "option h1-case-adjust-bogus-client" 或 "option h1-case-adjust-bogus-server",否则不会应用任何转换。标头名称没有标准大小写,因为正如 RFC7230 所述,它们是不区分大小写的。因此,应用程序必须以不区分大小写的方式处理它们。但一些有问题的应用程序违反了标准,错误地依赖于浏览器最常用的大小写。当使用 HTTP/2 时,这个问题变得至关重要,因为所有标头名称都必须以小写形式交换,HAProxy 也遵循相同的约定。无论 HTTP 版本如何,所有标头名称都以小写形式发送给客户端和服务器。无法正确处理请求或响应的应用程序可能需要暂时使用此类变通方法来调整发送给它们的标头名称,直到应用程序得到修复。请注意,需要此类变通方法的应用程序可能容易受到内容走私攻击,必须绝对修复。
示例
global h1-case-adjust content-length Content-Length
请参阅 "h1-case-adjust-file"、"option h1-case-adjust-bogus-client" 和 "option h1-case-adjust-bogus-server"。
定义一个文件,其中包含用于在将标头名称发送给 HTTP/1 客户端或服务器之前调整其大小写的键/值对列表。文件 <hdrs-file> 必须包含每行 2 个标头名称。第一个必须是小写,并且两者除了大小写外不能有区别。以 '#' 开头的行将被忽略,空行也是如此。前导和尾随的制表符和空格将被删除。不允许重复条目。请注意,除非在代理中指定了 "option h1-case-adjust-bogus-client" 或 "option h1-case-adjust-bogus-server",否则不会应用任何转换。如果重复此指令,则只处理最后一个。如果需要调整大量标头名称,它是指令 "h1-case-adjust" 的替代方案。请阅读使用此功能相关的风险。请参阅 "h1-case-adjust"、"option h1-case-adjust-bogus-client" 和 "option h1-case-adjust-bogus-server"。
这会禁用向客户端宣布支持 h2 websockets。这可用于克服在实施相对较新的 RFC8441 时遇到问题的客户端,例如 Firefox 88。要允许客户端自动降级到 http/1.1 以进行 websocket 隧道,请在绑定行上指定 h2 支持,使用 "alpn",但不带显式 "proto" 关键字。如果此语句先前已激活,则可以通过在其前面加上 "no" 禁用它。
定义执行干净的软停止所允许的最长时间。
参数
<time> 是实例在通过 SIGUSR1 信号接收到软停止时将保持活动的最长时间(默认为毫秒)。
这可用于确保即使在软停止期间连接保持打开(例如,在 tcp 模式下为代理设置了长超时),实例也会退出。它适用于 TCP 和 HTTP 模式。
示例
global hard-stop-after 30s
切换每个协议的保护,禁止与使用特权端口作为其源端口的客户端进行通信。此端口范围根据 RFC 6335 定义。默认情况下,两种协议的保护都处于非活动状态。
默认情况下,HAProxy 会努力防止在启动后创建任何线程和进程。在使用来源不确定的 Lua 文件以及试验仍可能包含可利用性不确定的错误的开发版本时,这样做尤为重要。一般来说,确保不会因流量触发任何意外的后台活动是很好的卫生习惯。但这会阻止外部检查工作,并可能破坏一些严重依赖于 fork 能力的特定 Lua 脚本。此选项用于禁用此保护。请注意,禁用它是一个坏主意,因为一旦禁用,库中或 HAProxy 本身中的漏洞将更容易被利用。此外,从 Lua 或其他任何地方进行分叉并不可靠,因为分叉的进程可能会随机嵌入另一个线程设置的锁,并且永远无法完成操作。因此,强烈建议永远不要使用此选项,并且任何需要此类分叉的工作负载都应重新考虑并转移到更安全的解决方案(例如,使用代理而不是外部检查)。此选项支持使用 "no" 前缀禁用它。
HAProxy 不需要(除非使用强烈不推荐的外部检查)在运行时调用可执行文件,甚至期望将自己隔离到空的 chroot 中。因此,基本上没有有效理由允许在用户完全了解风险的情况下调用 setuid 可执行文件。在 HAProxy 需要调用外部检查和/或禁用 chroot 的情况下,利用库中或 HAProxy 本身中的漏洞可能导致执行外部程序。在 Linux 上,可以锁定进程,以便忽略此类可执行文件上存在的任何 setuid 位。这显着降低了在此类情况下特权升级的风险。这是 HAProxy 默认执行的操作。如果这导致外部检查出现问题(例如,需要 "ping" 命令的检查),则可以通过在 global 部分显式添加此指令来禁用此保护。如果启用,可以通过在其前面加上 "no" 关键字将其重新关闭。
分配一个目录以加载证书颁发者链以完成颁发者链。所有文件必须采用 PEM 格式。对于使用 "crt" 或 "crt-list" 加载的证书,如果证书链未包含在 PEM 中(也通常称为中间证书),如果证书的颁发者与使用 "issuers-chain-path" 加载的链中的第一个证书对应,HAProxy 将完成链。一个包含 PrivateKey+Certificate+IntermediateCA2+IntermediateCA1 的 "crt" 文件可以用 PrivateKey+Certificate 替换。如果 "issuers-chain-path" 目录中存在包含 IntermediateCA2+IntermediateCA1 的文件,HAProxy 将完成链。所有具有相同颁发者的其他证书将在内存中共享该链。OCSP 功能无法使用来自 'issuers-chain-path' 的完整链,如果您想实现 OCSP Stapling,请使用额外的 .issuer 文件。
当 haproxy 编译时所依赖的 TLS/SSL 库不支持 QUIC(通常是 OpenSSL)时,必须使用此设置来显式启用 QUIC 监听器绑定。当 haproxy 编译时所依赖的 TLS/SSL 库支持 QUIC(例如 quictls)时,此设置无效。请注意,设置此项后不支持 QUIC 0-RTT。
localpeer <name>
设置本地实例的对等名称。如果指定了 "-L" 命令行参数或在 "peers" 部分定义之后使用,它将被忽略。在这种情况下,在配置解析期间将发出警告消息。此选项还将设置 HAPROXY_LOCALPEER 环境变量。另请参阅管理指南中的 "-L" 和下面的 "peers" 部分。
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [max level [min level]]
添加一个全局 syslog 服务器。可以定义多个全局服务器。它们将接收启动和退出的日志,以及配置了 "log global" 的代理的所有日志。有关代理的更多详细信息,请参阅 "log" 选项。
设置 syslog 报头中的 hostname 字段。如果设置了可选的 "string" 参数,则报头将设置为该字符串内容,否则使用系统的主机名。通常在不通过中间 syslog 服务器中继日志或仅为自定义日志中打印的主机名时使用。
log-tag <string>
将 syslog 报头中的 tag 字段设置为此字符串。它默认为从命令行启动的程序名,通常是 "haproxy"。有时,区分同一主机上运行的多个进程会很有用。另请参阅每个代理的 "log-tag" 指令。
lua-load <file> [ <arg1> [ <arg2> [ ... ] ] ]
此全局指令在对所有线程可见的共享上下文中加载并执行一个 Lua 文件。在此类上下文中设置的任何变量对任何线程都可见。这是加载 Lua 程序的最简单和推荐的方法,但如果执行大量 Lua 调用,它将无法很好地扩展,因为一次只有一个线程可以在全局状态上运行。以这种方式加载的程序在 "core.thread" 变量中将始终看到 0。此指令可以多次使用。在 Lua 文件的主体中使用以下代码可以使用参数。不要忘记 Lua 数组的索引从 1 开始。在文件中声明的 "local" 变量在整个文件中可用,但在其他文件中不可用。 local args = table.pack(...)
lua-load-per-thread <file> [ <arg1> [ <arg2> [ ... ] ] ]
此全局指令将 Lua 文件加载并执行到每个启动的线程中。任何全局变量都具有线程本地可见性,因此每个线程可以看到不同的值。因此,强烈建议不要在以这种方式加载的程序中使用全局变量。将为每个线程加载并初始化一个独立的副本,所有操作按线程的数字顺序从 1 到 nbthread 顺序完成。如果某些操作只需要执行一次,程序应该检查 "core.thread" 变量以找出正在初始化的线程。以这种方式加载的程序将在所有线程上并发运行,并且具有高度可扩展性。这是加载简单函数的推荐方式,这些函数注册样本获取、转换器、操作或服务,一旦确定程序不依赖于全局变量。为了简单起见,即使只使用一个线程,甚至禁用线程(在这种情况下,它将等同于 lua-load),此指令也可用。此指令可以使用多次。有关 args 的用法,请参阅 lua-load。
lua-prepend-path <string> [<type>]
在 Lua 的 package.<type> 变量前面加上给定的字符串,后面跟着一个分号。<type> 必须是 "path" 或 "cpath"。如果未给出 <type>,则默认为 "path"。Lua 的路径是以分号分隔的模式列表,用于指定 `require` 函数如何尝试查找库的源文件。模式中的问号 (?) 将替换为模块名称。路径从左到右评估。这意味着稍后添加的前缀路径将首先被检查。例如,通过指定以下路径:lua-prepend-path /usr/share/haproxy-lua/?/init.lua lua-prepend-path /usr/share/haproxy-lua/?.lua 当调用 `require "example"` 时,Lua 将首先尝试加载 /usr/share/haproxy-lua/example.lua 脚本,如果不存在,则尝试 /usr/share/haproxy-lua/example/init.lua,如果仍不存在,则尝试默认路径。有关 Lua 文档中的详细信息,请参阅 https://lua.ac.cn/pil/8.1.html。
master-worker [no-exit-on-failure]
主-从模式(Master-worker mode)。它等同于命令行参数“-W”。此模式将启动一个“主进程”,该进程在读取配置后会 fork 一个“工作进程”来处理流量。主进程用作进程管理器,将监控“工作进程”。使用此模式,您可以通过向主进程发送 SIGUSR2 信号直接重新加载 HAProxy。重新加载将要求主进程再次读取配置并 fork 一个新的工作进程。先前的工作进程将保留直到其作业结束。主-从模式与前台或守护进程模式兼容。默认情况下,如果工作进程因错误返回码退出,例如发生段错误,所有工作进程都将被杀死,主进程将退出。将此行为与 systemd 单元文件中的 Restart=on-failure 结合使用,以重新启动整个进程,是很方便的。如果您不希望此行为,必须使用关键字“no-exit-on-failure”。另请参阅管理指南中的“-W”。
在主-从模式下,此选项限制了工作进程可以承受的重载次数。如果工作进程在重载后没有退出,一旦其重载次数大于此数字,该工作进程将收到一个 SIGTERM 信号。此选项有助于控制工作进程的数量。另请参阅管理指南中的“show proc”。
nbthread <number>
此设置仅在内置线程支持时可用。它使 HAProxy 在 <number> 个线程上运行。当 HAProxy 在前台启动时,“nbthread” 也有效。在一些支持 CPU 亲和性的平台上,默认的 “nbthread” 值会自动设置为进程启动时绑定的 CPU 数量。这意味着可以轻松地使用 "taskset" 或 "cpuset" 等命令从调用进程中调整线程数。否则,此值默认为 1。默认值在 "haproxy -vv" 的输出中报告。
禁用 QUIC 传输协议。所有 QUIC 监听器仍将被创建,但它们不会绑定其地址。因此,haproxy 将不会处理任何 QUIC 流量。另请参阅“quic_enabled”样本获取。
如果在 NUMA 感知平台上运行,HAProxy 会在启动时检查机器的 CPU 拓扑。如果检测到多插槽机器,则会自动计算亲和性以在单个节点的 CPU 上运行。这样做是为了避免因插槽间总线延迟而导致的性能损失。但是,如果在特定架构上应用的绑定不是最优的,可以使用 'no numa-cpu-mapping' 语句禁用它。如果配置中存在 nbthread 语句,或者已指定进程的亲和性(例如通过 'cpu-map' 指令或 taskset 实用程序),则此自动绑定也不会应用。
pidfile <pidfile>
在守护进程模式下,将所有守护进程的 PID 写入文件 <pidfile>;在主-工作者模式下,将主进程的 PID 写入文件 <pidfile>。此选项等同于 "-p" 命令行参数。该文件必须对启动进程的用户可访问。另请参阅 "daemon" 和 "master-worker"。
PROXY 协议 v2 实现中的一个错误存在于 HAProxy 2.1 之前的版本中,导致它为健康检查发出 PROXY 命令而不是 LOCAL 命令。这问题特别微小,但会混淆一些服务器的日志。遗憾的是,这个错误发现得很晚,并揭示出一些可能只针对 HAProxy 测试其 PROXY 协议实现的服务器无法正确处理 LOCAL 命令,并在 HAProxy 检查它们时永久保持在 "down" 状态。当这种情况发生时,可以启用此全局选项以恢复到旧的(错误的)行为,直到联系受影响组件的供应商并修复它们。此选项默认禁用,并作用于所有具有 "send-proxy-v2" 语句的服务器。
presetenv <name> <value>
将环境变量 <name> 设置为值 <value>。如果该变量已存在,则不会被覆盖。更改会立即生效,以便配置文件中的下一行可以看到新值。另请参阅 "setenv"、"resetenv" 和 "unsetenv"。
执行一次性打开最大文件描述符的操作,从而预分配内核的数据结构。这可以防止当 nbthread>1 且 HAProxy 打开一个需要内核扩展其数据结构的文件描述符时出现的短暂暂停。
resetenv [<name> ...]
删除除参数中指定的环境变量之外的所有环境变量。它允许在使用 setenv 或 unsetenv 设置新值之前,使用一个干净受控的环境。请注意,一些内部函数可能会使用某些环境变量,例如时间操作函数,以及 OpenSSL 甚至外部检查。此命令必须极其小心使用,并且只能在完全验证后使用。更改会立即生效,因此配置文件中的下一行将看到新的环境。另请参阅 “setenv”、“presetenv” 和 “unsetenv”。
server-state-base <directory>
指定目录前缀,该前缀将附加在所有不以“/”开头的服务器状态文件名前面。另请参阅 "server-state-file"、"load-server-state-from-file" 和 "server-state-file-name"。
指定包含服务器状态的文件路径。如果路径以斜杠('/')开头,则视为绝对路径,否则视为相对于使用 "server-state-base" 指定的目录(如果已设置)或当前目录。在重新加载 HAProxy 之前,可以使用统计命令 "show servers state" 保存服务器的当前状态。该命令的输出必须写入 <file> 指向的文件中。启动时,在处理流量之前,HAProxy 将读取、加载并应用文件中找到且在其当前运行配置中可用的每个服务器的状态。另请参阅 "server-state-base" 和 "show servers state"、"load-server-state-from-file" 和 "server-state-file-name"。
此选项最好默认禁用,仅应开发人员要求启用。如果已启用,仍可以通过在其前面加上 "no" 关键字来强制禁用。它不影响性能或稳定性,但会努力重新启用可能因文件大小限制 (ulimit -f)、核心大小限制 (ulimit -c) 或进程更改 UID/GID 后的“可转储性”(例如 Linux 上的 /proc/sys/fs/suid_dumpable)而禁用的核心转储。核心转储可能仍然受当前目录权限(检查文件从哪个目录启动)、chroot 目录权限(可能需要临时禁用 chroot 指令或将其移动到专用的可写位置)或任何其他系统特定约束的限制。例如,一些 Linux 版本以将默认核心文件替换为系统上甚至未安装的可执行文件路径而闻名(检查 /proc/sys/kernel/core_pattern)。通常,只需写入 "core"、"core.%p" 或 "/var/log/core/core.%p" 即可解决问题。当尝试启用此选项等待罕见问题重新出现时,通常最好先尝试通过向 "haproxy" 进程发出 "kill -11" 等命令来获取此类转储,并验证它在死亡时是否在预期位置留下了核心。
set-var <var-name> <expr>
将进程范围变量“<var-name>”设置为样本表达式 <expr> 的求值结果。变量“<var-name>”只能是进程范围变量(使用“proc.”前缀)。它的工作方式与 TCP 或 HTTP 规则中的“set-var”操作完全相同,不同之处在于表达式在配置解析时进行求值,并且变量会立即设置。表达式中允许的样本获取函数和转换器仅限于那些使用内部数据的函数,通常是“int(value)”或“str(value)”。也可以引用先前分配的变量。然后,这些变量将可以从常规规则集中读取(和修改)。
示例
global set-var proc.current_state str(primary) set-var proc.prio int(100) set-var proc.threshold int(200),sub(proc.prio)
set-var-fmt <var-name> <fmt>
将进程范围的变量 '<var-name>' 设置为对日志格式 <fmt> 求值所得到的字符串。变量 '<var-name>' 只能是进程范围的变量(使用 'proc.' 前缀)。它的工作方式与 TCP 或 HTTP 规则中的 'set-var-fmt' 操作完全相同,只是表达式在配置解析时求值,并且变量会立即设置。表达式中允许的样本获取函数和转换器仅限于那些使用内部数据的函数,通常是 'int(value)' 或 'str(value)'。也可以引用先前分配的变量。然后,这些变量将可以从常规规则集中读取(和修改)。有关自定义日志格式语法的详细信息,请参阅第 8.2.6 节
示例
global set-var-fmt proc.current_state "primary" set-var-fmt proc.bootid "%pid|%t"
setcap <name>[,<name>...]
设置启动时使用 uid 0 并切换到非零 uid 时必须保留的功能列表。默认情况下,uid 切换会丢失所有权限,但在透明代理期间尝试从外部地址连接到服务器时,或者绑定到低于 1024 的端口时,通常需要保留一些功能,例如使用 "tune.quic.socket-owner connection",导致设置完全在 uid 0 下运行。设置功能通常是一种更安全的选择,因为只保留所需的功能。此功能特定于操作系统,仅在构建时设置 USE_LINUX_CAP=1 时在 Linux 上启用。支持的功能列表也取决于操作系统,并由传递无效功能名称或空名称时显示的错误消息枚举。可以传递多个功能,用逗号分隔。在常用功能中,"cap_net_raw" 允许透明地绑定到外部地址,"cap_net_bind_service" 允许绑定到特权端口,可用于 QUIC。
setenv <name> <value>
将环境变量 <name> 设置为值 <value>。如果该变量存在,则会被覆盖。更改会立即生效,因此配置文件中的下一行将看到新的值。另请参阅 “presetenv”、“resetenv” 和 “unsetenv”。
此设置仅在内置 OpenSSL 支持时可用。它设置描述 SSL/TLS 握手期间协商的密码算法("cipher suite")列表的默认字符串,直到 TLSv1.2,适用于所有未明确定义其密码算法的 "bind" 行。字符串的格式在 OpenSSL 手册页中的 "man 1 ciphers" 中定义。有关背景信息和建议,请参阅例如 (https://wiki.mozilla.org/Security/Server_Side_TLS) 和 (https://mozilla.github.io/server-side-tls/ssl-config-generator/)。对于 TLSv1.3 密码配置,请检查 "ssl-default-bind-ciphersuites" 关键字。请检查 "bind" 关键字以获取更多信息。
此设置仅在内置 OpenSSL 支持且用于构建 HAProxy 的 OpenSSL 版本为 1.1.1 或更高版本时可用。它设置描述 TLSv1.3 握手期间协商的密码算法("cipher suite")列表的默认字符串,适用于所有未明确定义其密码算法的 "bind" 行。字符串的格式在 OpenSSL 手册页中 "ciphersuites" 部分定义。对于 TLSv1.2 及更早版本的密码配置,请检查 "ssl-default-bind-ciphers" 关键字。此设置可能接受 TLSv1.2 密码套件,但这是一种未记录的行为,不建议使用,因为它可能不一致或有错误。OpenSSL 的默认 TLSv1.3 密码套件是:"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" TLSv1.3 仅支持 5 个密码套件: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - TLS_AES_128_CCM_SHA256 - TLS_AES_128_CCM_8_SHA256 请检查 "bind" 关键字以获取更多信息。
示例
global ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256 ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
此设置仅在内置 OpenSSL 支持时可用。它设置描述与客户端身份验证相关的签名算法列表的默认字符串,适用于所有未明确定义其签名算法的 "bind" 行。字符串的格式是以冒号分隔的签名算法列表。每个签名算法可以使用两种形式之一:TLS1.3 签名方案名称 ("rsa_pss_rsae_sha256") 或公钥算法 + 摘要形式 ("ECDSA+SHA256")。列表可以包含两种形式。有关格式的更多信息,请参阅 SSL_CTX_set1_client_sigalgs(3)。签名算法列表也可在 RFC8446 section 4.2.3 和 OpenSSL 的 ssl/t1_lib.c 文件中找到。此设置不适用于 TLSv1.1 及更早版本的协议,因为这些版本中没有单独协商签名算法。除非需要与中间盒兼容,否则不建议更改此设置。
此设置仅在编译时内置 OpenSSL 支持时可用。它设置了在 SSL/TLS 握手期间使用 ECDHE 协商的椭圆曲线算法列表(“曲线套件”)的默认字符串。字符串的格式是以冒号分隔的曲线名称列表。有关更多信息,请检查 "bind" 关键字。
此设置仅在内置 OpenSSL 支持时可用。它设置默认 ssl-options,以强制应用于所有 "bind" 行。请检查 "bind" 关键字以查看可用选项。
示例
global ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets
此设置仅在内置 OpenSSL 支持时可用。它设置描述 TLSv1.2 和 TLSv1.3 握手期间协商的签名算法列表的默认字符串,适用于所有未明确定义其签名算法的 "bind" 行。字符串的格式是以冒号分隔的签名算法列表。每个签名算法可以使用两种形式之一:TLS1.3 签名方案名称 ("rsa_pss_rsae_sha256") 或公钥算法 + 摘要形式 ("ECDSA+SHA256")。列表可以包含两种形式。有关格式的更多信息,请参阅 SSL_CTX_set1_sigalgs(3)。签名算法列表也可在 RFC8446 section 4.2.3 和 OpenSSL 的 ssl/t1_lib.c 文件中找到。此设置不适用于 TLSv1.1 及更早版本的协议,因为这些版本中没有单独协商签名算法。除非需要与中间盒兼容,否则不建议更改此设置。
此设置仅在内置 OpenSSL 支持时可用。它设置描述与服务器协商的 SSL/TLS 握手期间协商的密码算法列表的默认字符串,直到 TLSv1.2,适用于所有未明确定义其密码算法的 "server" 行。字符串的格式在 OpenSSL 手册页中的 "man 1 ciphers" 中定义。有关背景信息和建议,请参阅例如 (https://wiki.mozilla.org/Security/Server_Side_TLS) 和 (https://mozilla.github.io/server-side-tls/ssl-config-generator/)。对于 TLSv1.3 密码配置,请检查 "ssl-default-server-ciphersuites" 关键字。请检查 "server" 关键字以获取更多信息。
此设置仅在内置 OpenSSL 支持且用于构建 HAProxy 的 OpenSSL 版本为 1.1.1 或更高版本时可用。它设置描述与服务器协商的 TLSv1.3 握手期间协商的密码算法列表的默认字符串,适用于所有未明确定义其密码算法的 "server" 行。字符串的格式在 OpenSSL 手册页中 "ciphersuites" 部分定义。对于 TLSv1.2 及更早版本的密码配置,请检查 "ssl-default-server-ciphers" 关键字。请检查 "server" 关键字以获取更多信息。
此设置仅在内置 OpenSSL 支持时可用。它设置描述与客户端身份验证相关的签名算法列表的默认字符串,适用于所有未明确定义其签名算法的 "server" 行。字符串的格式是以冒号分隔的签名算法列表。每个签名算法可以使用两种形式之一:TLS1.3 签名方案名称 ("rsa_pss_rsae_sha256") 或公钥算法 + 摘要形式 ("ECDSA+SHA256")。列表可以包含两种形式。有关格式的更多信息,请参阅 SSL_CTX_set1_client_sigalgs(3)。签名算法列表也可在 RFC8446 section 4.2.3 和 OpenSSL 的 ssl/t1_lib.c 文件中找到。此设置不适用于 TLSv1.1 及更早版本的协议,因为这些版本中没有单独协商签名算法。除非需要与中间盒兼容,否则不建议更改此设置。
此设置仅在编译时内置 OpenSSL 支持时可用。它设置了在 SSL/TLS 握手期间使用 ECDHE 协商的椭圆曲线算法列表(“曲线套件”)的默认字符串。字符串的格式是以冒号分隔的曲线名称列表。有关更多信息,请检查 "server" 关键字。
此设置仅在内置 OpenSSL 支持时可用。它设置默认 ssl-options,以强制应用于所有 "server" 行。请检查 "server" 关键字以查看可用选项。
此设置仅在内置 OpenSSL 支持时可用。它设置描述 TLSv1.2 和 TLSv1.3 握手期间协商的签名算法列表的默认字符串,适用于所有未明确定义其签名算法的 "server" 行。字符串的格式是以冒号分隔的签名算法列表。每个签名算法可以使用两种形式之一:TLS1.3 签名方案名称 ("rsa_pss_rsae_sha256") 或公钥算法 + 摘要形式 ("ECDSA+SHA256")。列表可以包含两种形式。有关格式的更多信息,请参阅 SSL_CTX_set1_sigalgs(3)。签名算法列表也可在 RFC8446 section 4.2.3 和 OpenSSL 的 ssl/t1_lib.c 文件中找到。此设置不适用于 TLSv1.1 及更早版本的协议,因为这些版本中没有单独协商签名算法。除非需要与中间盒兼容,否则不建议更改此设置。
此设置仅在内置 OpenSSL 支持时可用。它设置在 SSL/TLS 握手期间使用短暂 Diffie-Hellman (DHE) 密钥交换时使用的默认 DH 参数,适用于所有未明确定义其参数的 "bind" 行。如果绑定证书文件中包含自定义 DH 参数,则它将被覆盖。如果未使用 ssl-dh-param-file 或未直接在证书文件中设置自定义 DH 参数,则不会使用 DHE 密码,除非设置了 tune.ssl.default-dh-param。在后一种情况下,将使用指定大小的预定义 DH 参数。自定义参数已知更安全,因此建议使用它们。可以使用 OpenSSL 命令 "openssl dhparam <size>" 生成自定义 DH 参数,其中 size 应至少为 2048,因为 1024 位 DH 参数不应再被视为安全。
此设置仅在内置 OpenSSL 支持且 OpenSSL 版本至少为 3.0 时可用。它允许定义在提供程序中获取算法时使用的默认属性字符串。它的行为方式与 openssl propquery 选项相同,并遵循相同的语法(在 https://www.openssl.org/docs/man3.0/man7/property.html 中描述)。例如,如果您加载了两个提供程序,foo 和默认提供程序,则 propquery “?provider=foo” 允许默认选择由 foo 提供程序提供的算法实现,如果找不到,则回退到默认提供程序的实现。
此设置仅在内置 OpenSSL 支持且 OpenSSL 版本至少为 3.0 时可用。它允许在初始化期间加载提供程序。如果加载成功,HAProxy 可能会使用加载的提供程序提供的任何功能。可以在配置文件中指定多个 'ssl-provider' 选项。提供程序将按其出现的顺序加载。请注意,显式加载提供程序会阻止 OpenSSL 自动加载“默认”提供程序。OpenSSL 还允许直接在其配置文件(例如 openssl.cnf)中定义应加载的提供程序,因此不一定需要使用此 'ssl-provider' 选项来加载提供程序。可以使用 "show ssl providers" CLI 命令显示所有已成功加载的提供程序。OpenSSL 提供程序的默认搜索路径可以在 "openssl version -a" 命令的输出中找到。如果提供程序位于另一个目录中,则可以设置 OPENSSL_MODULES 环境变量,该变量接受可以找到提供程序的目录。另请参阅 "ssl-propquery" 和 "ssl-provider-path"。
此设置仅在内置 OpenSSL 支持且 OpenSSL 版本至少为 3.0 时可用。它允许指定 OpenSSL 用于查找提供程序的搜索路径。它的行为方式与 OPENSSL_MODULES 环境变量相同。它将用于任何后续的 “ssl-provider” 选项,直到定义新的 “ssl-provider-path”。另请参阅 “ssl-provider”。
此设置允许配置 HAProxy 查找额外 SSL 文件的方式。默认情况下,HAProxy 会在文件名后添加一个新的扩展名。(例如:对于 “foobar.crt”,加载 “foobar.crt.key”)。启用此选项后,HAProxy 会在添加新扩展名之前删除原扩展名(例如:对于 “foobar.crt”,加载 “foobar.key”)。您的 crt 文件必须具有 “.crt” 扩展名才能使此选项生效。此选项与捆绑扩展名(.ecdsa、.rsa、.dsa)不兼容,并且不会尝试删除它们。此选项默认禁用。另请参阅 “ssl-load-extra-files”。
ssl-load-extra-files <none|all|bundle|sctl|ocsp|issuer|key>*
此设置更改了 HAProxy 在加载 SSL 证书期间查找未指定文件的方式。此选项适用于与 "bind" 行关联的证书以及 "server" 行关联的证书,但某些额外文件对 "server" 行证书没有任何功能影响。默认情况下,HAProxy 会自动发现配置中未指定的许多文件,如果您想优化启动时间,可能需要禁用此行为。"none":仅加载配置中指定的文件。如果文件不存在,请勿尝试加载证书包。在目录的情况下,如果证书具有相同的基本名称,它不会尝试捆绑证书。"all":这是默认行为,它将尝试加载所有内容,包括包、sctl、ocsp、issuer、key。"bundle":当配置中指定的文件不存在时,HAProxy 将尝试加载“证书包”。证书包仅在前端管理,不适用于后端证书。从 HAProxy 2.3 开始,包不会加载到相同的 OpenSSL 证书存储中,而是会将每个证书加载到单独的存储中,这等同于声明多个 "crt"。需要 OpenSSL 1.1.1 才能实现此目的。这意味着包现在仅用于向后兼容性,并且不再是实现混合 RSA/ECC 绑定配置的强制要求。要将这些 PEM 文件关联到 HAProxy 识别的“证书包”中,必须按以下方式命名:所有要捆绑的 PEM 文件必须具有相同的基本名称,并带有指示密钥类型的后缀。目前支持三个后缀:rsa、dsa 和 ecdsa。例如,如果 www.example.com 有两个 PEM 文件,一个 RSA 文件和一个 ECDSA 文件,则它们必须命名为:"example.pem.rsa" 和 "example.pem.ecdsa"。文件名的第一部分是任意的;只有后缀才重要。要将此包加载到 HAProxy 中,只需指定基本名称
示例
bind :8443 ssl crt example.pem
请注意,后缀未提供给 HAProxy;这告诉 HAProxy 查找证书包。HAProxy 将加载包中的所有 PEM 文件,就像它们在多个 "crt" 中单独配置一样。包加载对目录加载不再有影响,因为文件是单独加载的。在 CLI 上,包被视为单独的文件,并且需要包扩展名才能提交它们。OCSP 文件 (.ocsp)、颁发者文件 (.issuer)、证书透明度 (.sctl) 以及私钥 (.key) 支持多证书捆绑。 "sctl":尝试为每个 crt 关键字加载 "<basename>.sctl"。如果为后端证书提供,它将被加载但不会有任何功能影响。"ocsp":尝试为每个 crt 关键字加载 "<basename>.ocsp"。如果为后端证书提供,它将被加载但不会有任何功能影响。"issuer":如果 PEM 文件中未提供 OCSP 文件的颁发者,则尝试加载 "<basename>.issuer" 文件。如果为后端证书提供,它将被加载但不会有任何功能影响。"key":如果 PEM 文件未提供私钥,则尝试加载包含私钥的 "<basename>.key" 文件。默认行为是 "all"。
示例
ssl-load-extra-files bundle sctl ssl-load-extra-files sctl ocsp issuer ssl-load-extra-files none
ssl-server-verify [none|required]
服务器端 SSL 验证的默认行为。如果指定为 'none',则不验证服务器证书。默认值为 'required',除非使用命令行选项 '-dV' 强制指定。
自签发 CA,即 x509 根 CA,是证书链验证的锚点:作为服务器发送它是无用的,客户端必须拥有它。标准配置需要不在 PEM 文件中包含此类 CA。此选项允许您在 PEM 文件中保留此类 CA 而不将其发送给客户端。用例是为 ocsp 提供颁发者,而无需“.issuer”文件,并能够与“issuers-chain-path”共享它。这涉及所有没有中间证书的证书。对于 BoringSSL 来说是无用的,.issuer 被忽略,因为 ocsp 位不需要它。至少需要 OpenSSL 1.0.2。
stats maxconn <connections>
默认情况下,统计套接字限制为 10 个并发连接。可以使用 "stats maxconn" 更改此值。
stats socket [<address:port>|<path>] [param*]
将 UNIX 套接字绑定到 <path> 或将 TCPv4/v6 地址绑定到 <address:port>。对此套接字的连接将返回各种统计信息输出,甚至允许发出一些命令来更改某些运行时设置。有关更多详细信息,请参阅管理指南的 第 9.3 节 “Unix 套接字命令”。支持 "bind" 行支持的所有参数,例如限制某些用户或其访问权限。有关更多信息,请参阅 第 5.1 节
stats timeout <timeout, in milliseconds>
统计套接字的默认超时时间设置为 10 秒。可以使用 "stats timeout" 更改此值。该值必须以毫秒为单位传递,或者带有时间单位后缀,如 { us, ms, s, m, h, d }。
当 setrlimit 失败时,使进程在启动时失败。HAProxy 会根据计算结果尝试设置最佳的 setrlimit。如果失败,它将发出警告。此选项旨在保证当这些限制失败时 HAProxy 明确失败。它默认启用。仍可通过在其前添加“no”关键字来强制禁用它。
thread-group <group> [<thread-range>...]
此设置仅在内置线程支持时可用。它枚举了将组成线程组 <group> 的线程列表。线程号和组号从 1 开始。线程范围可以一次使用单个线程号定义,也可以通过指定由破折号“-”分隔的下限和上限来定义(例如 “1-16”)。未分配的线程将自动分配给未分配的线程组,而使用此指令定义的线程组将永远不会接收超过定义的线程数。多次定义同一组会用新的定义覆盖以前的定义。另请参阅 “nbthread” 和 “thread-groups”。
thread-groups <number>
此设置仅在内置线程支持时可用。它使 HAProxy 将其线程分成 <number> 个独立的组。目前,默认值为 1。线程组可以减少线程之间的共享以限制争用,但需要一些额外的配置工作。这也是使用超过 64 个线程的唯一方法,因为每个组最多可以配置 64 个线程。最大组数在编译时配置,默认为 16。另请参阅 “nbthread”。
trace <args...>
此命令配置一个 "trace" 子系统语句。每个都可以在管理手册中找到,并遵循完全相同的语法。每行只允许一个语句(即,如果导入使用分号的某些长跟踪配置,则必须将它们放在每行一个)。"trace" 命令将产生的任何输出将在该部分的解析步骤中发出。大多数情况下,这些将是错误和警告,但某些不完整的命令可能会列出允许的选择。此命令不用于常规使用,通常只在复杂的调试会话中由开发人员建议。因此,它在内部被标记为实验性,这意味着 "expose-experimental-directives" 必须出现在任何 "trace" 语句之前的行上。请注意,这些指令是动态解析的,因此引用稍后才声明的环形缓冲区将不起作用。对于此类用例,建议在该环形缓冲区声明之后放置另一个只有 "trace" 语句的 "global" 部分。重要的是要记住,根据跟踪级别和详细信息,启用跟踪可能会严重降低整体性能。请参阅管理手册了解语句语法。
uid <number>
将进程的用户 ID 更改为 <number>。建议将用户 ID 专用于 HAProxy 或一小组类似的守护程序。HAProxy 必须以超级用户权限启动才能切换到另一个用户。另请参阅 "gid" 和 "user"。
ulimit-n <number>
将每个进程的文件描述符最大数量设置为 <number>。默认情况下,它是自动计算的,因此建议不要使用此选项。如果目的只是限制文件描述符的数量,最好改用 “fd-hard-limit”。请注意,在此自动资源计算中未考虑动态服务器。如果使用大量动态服务器,可能需要手动指定此值。
unix-bind [ prefix <prefix> ] [ mode <mode> ] [ user <user> ] [ uid <uid> ] [ group <group> ] [ gid <gid> ]
配置在 "bind" 语句中声明的 UNIX 侦听套接字的通用设置。这主要用于简化 UNIX 套接字的声明并减少错误风险,因为这些设置通常是必需的,但也是特定于进程的。<prefix> 设置可用于强制所有套接字路径都相对于该目录。这可能需要访问另一个组件的 chroot。请注意,这些路径是在 HAProxy chroot 自身之前解析的,因此它们是绝对路径。<mode>、<user>、<uid>、<group> 和 <gid> 都具有与 "bind" 语句使用的同名参数相同的含义。如果两者都指定,则 "bind" 语句具有优先级,这意味着 "unix-bind" 设置可以被视为进程范围的默认设置。
unsetenv [<name> ...]
删除参数中指定的环境变量。这对于隐藏某些操作期间偶尔从用户环境中继承的一些敏感信息很有用。不存在的变量会被静默忽略,因此操作后可以确定这些变量都不再存在。更改会立即生效,因此配置文件中的下一行将看不到这些变量。另请参阅 “setenv”、“presetenv” 和 “resetenv”。
user <user name>
类似于 "uid",但使用 /etc/passwd 中用户名 <user name> 的 UID。另请参阅 "uid" 和 "group"。
node <name>
只允许字母、数字、连字符和下划线,与 DNS 名称类似。此语句在 HA 配置中很有用,其中两个或多个进程或服务器共享相同的 IP 地址。通过在所有节点上设置不同的节点名称,可以轻松地立即发现哪个服务器正在处理流量。
设置 WURFL User-Agent 缓存大小。为了更快地查找,已处理的用户代理会保存在 LRU 缓存中:- “0”:不使用缓存。- <size>:lru 缓存的大小(以元素为单位)。请注意,此选项仅在 HAProxy 编译时带有 USE_WURFL=1 时可用。
wurfl-data-file <file path>
WURFL 数据文件的路径,用于提供设备检测服务。HAProxy 应具有相关权限才能访问该文件。请注意,此选项仅在 HAProxy 编译时带有 USE_WURFL=1 时可用。
wurfl-information-list [<capability>]*
WURFL 功能、虚拟功能、我们计划在注入标头中使用的属性名称的空格分隔列表。Scientiamobile 网站上提供了功能和虚拟功能名称的完整列表:https://www.scientiamobile.com/wurflCapability 有效的 WURFL 属性有: - wurfl_id 包含匹配设备的设备 ID。 - wurfl_root_id 包含匹配设备的设备根 ID。 - wurfl_isdevroot 指示匹配设备是否为根设备。可能的值为 "TRUE" 或 "FALSE"。 - wurfl_useragent 随此特定 Web 请求而来的原始 useragent。 - wurfl_api_version 包含表示当前使用的 Libwurfl API 版本的字符串。 - wurfl_info 包含已解析的 wurfl.xml 及其完整路径信息的字符串。 - wurfl_last_load_time 包含上次成功加载 WURFL 的 UNIX 时间戳。 - wurfl_normalized_useragent 规范化的 useragent。请注意,此选项仅在 HAProxy 使用 USE_WURFL=1 编译时才可用。
一个将用于在包含 WURFL 结果的响应头中分隔值的字符。如果未设置,则默认使用逗号(‘,’)。请注意,此选项仅在 HAProxy 编译时带有 USE_WURFL=1 时可用。
wurfl-patch-file [<file path>]
WURFL 补丁文件路径列表。请注意,补丁在启动期间加载,因此在 chroot 之前。请注意,此选项仅在 HAProxy 编译时带有 USE_WURFL=1 时可用。

3.2. 性能调优

在某些情况下,尤其是在处理器支持可变频率的低延迟或在虚拟机内部运行时,每当进程使用轮询器等待 I/O 时,处理器就会休眠或长时间提供给另一个 VM,从而导致延迟过高。此选项提供了一种解决方案,通过始终在轮询器上使用 null 超时来防止处理器休眠。这会导致延迟显着降低(观察到 30 到 100 微秒),但代价是处理器过热的风险。它甚至可以与线程一起使用,在这种情况下,绑定不当的线程可能会发生严重冲突,导致性能下降,并且 "show info" 输出中的 CPU stolen 字段值很高,表明线程配置错误。使用此选项时,重要的是不要让进程在与网络中断相同的处理器上运行。最好避免在共享同一核心的多个 CPU 线程上使用它。此选项默认禁用。如果已启用,仍可以通过在其前面加上 "no" 关键字来强制禁用。它被 "select" 和 "poll" 轮询器忽略。在无缝重新加载的上下文中,此选项会自动在旧进程上禁用;当多个进程停留一段时间等待当前连接结束时,它避免了过多的 CPU 冲突。
max-spread-checks <delay in milliseconds>
默认情况下,HAProxy 会尝试将健康检查的开始时间分散在服务器场中所有服务器的最小健康检查间隔内。其原则是避免对在同一台服务器上运行的服务进行密集冲击。但是当使用大的检查间隔(10 秒或更长)时,服务器场中的最后一个服务器需要一些时间才能开始被测试,这可能是一个问题。此参数用于强制规定第一次和最后一次检查之间的延迟上限,即使服务器的检查间隔较大。当服务器以较短的间隔运行时,它们的间隔仍将得到尊重。
设置 HAProxy 在停止新请求的压缩或降低当前请求的压缩级别之前可以达到的最大 CPU 使用率。它的工作方式类似于“maxcomprate”,但测量的是 CPU 使用率而不是传入数据带宽。该值以 HAProxy 使用的 CPU 百分比表示。值 100 表示禁用限制。默认值为 100。设置较低的值将防止压缩工作减慢整个进程的速度并引入高延迟。
maxcomprate <number>
将每个进程的最大输入压缩速率设置为 <number> 千字节/秒。对于每个流,如果达到最大值,压缩级别将在流期间降低。如果在流开始时达到最大值,则该流将完全不压缩。如果未达到最大值,压缩级别将增加到 tune.comp.maxlevel。值为零表示没有限制,这是默认值。
maxconn <number>
设置每个进程的最大并发连接数上限为 <number>。它等同于命令行参数 "-n"。通过 "-n" 命令行参数提供的值优先于在 global 部分设置的 maxconn 值。Haproxy 进程也可以使用 SYSTEM_MAXCONN 编译时变量进行编译,在这种情况下,它用作系统 maxconn 最大值。同样,如果设置了 SYSTEM_MAXCONN 限制,命令行 "-n" 参数允许在运行时绕过它。当达到 maxconn 时,进程将停止接受连接。进程软文件描述符限制(可以使用 "ulimit -n" 命令获取)会根据提供的 maxconn 自动调整。另请参阅 "ulimit-n"。注意:"select" 轮询器在某些平台上无法可靠地使用超过 1024 个文件描述符。如果您的平台仅支持 select 并在启动时报告 "select FAILED",则需要减少 maxconn 直到它起作用(通常略低于 500)。如果未设置 maxconn 值,它将根据当前文件描述符限制自动计算,如 "ulimit -nH" 命令所报告(我们取硬限制和软限制之间的最大值),然后自动值可能会被 "fd-hard-limit" 和内存限制(如果后者通过 "-m" 命令行选项强制执行)减少。自动值还取决于缓冲区大小、分配给压缩的内存、SSL 缓存大小以及是否使用 SSL 以及相关的 maxsslconn(也可以是自动的)。
maxconnrate <number>
将每个进程每秒的最大连接数设置为 <number>。当达到此限制时,代理将停止接受连接。它可以用来限制全局容量,而不考虑每个前端的容量。需要注意的是,这只能用作服务保护措施,因为当达到限制时,前端之间不一定会公平分配,所以最好也为每个前端限制一个接近其预期份额的值。此外,降低 tune.maxaccept 可以提高公平性。
maxpipes <number>
将每个进程的最大管道数设置为 <number>。目前,管道仅由基于内核的 tcp 拼接使用。由于一个管道包含两个文件描述符,"ulimit-n" 值将相应增加。默认值为 maxconn/4,这对于大多数重度使用情况来说似乎已经足够了。拼接代码动态分配和释放管道,并且可以回退到标准复制,因此将此值设置得太低可能只会影响性能。
maxsessrate <number>
将每个进程每秒的最大会话数设置为 <number>。当达到此限制时,代理将停止接受连接。它可以用来限制全局容量,而不考虑每个前端的容量。需要注意的是,这只能用作服务保护措施,因为当达到限制时,前端之间不一定会公平分配,所以最好也为每个前端限制一个接近其预期份额的值。此外,降低 tune.maxaccept 可以提高公平性。
maxsslconn <number>
设置每个进程的最大并发 SSL 连接数上限为 <number>。默认情况下没有 SSL 特定限制,这意味着全局 maxconn 设置将适用于所有连接。设置此限制可避免 openssl 使用过多内存并在 malloc 返回 NULL 时崩溃(因为它不幸地无法可靠地检查此类情况)。请注意,此限制适用于传入和传出连接,因此一个经过解密然后加密的连接计为 2 个 SSL 连接。如果未设置此值,但强制执行了内存限制,则将根据内存限制、maxconn、缓冲区大小、分配给压缩的内存、SSL 缓存大小以及在前端、后端或两者中是否使用 SSL 自动计算此值。如果在有内存限制时既未指定 maxconn 也未指定 maxsslconn,HAProxy 将自动调整这些值,以便 100% 的连接可以在 SSL 上进行,并且没有风险,并且会考虑启用 SSL 的侧面(前端、后端、两者)。
maxsslrate <number>
将每个进程每秒的最大 SSL 会话数设置为 <number>。当达到此限制时,SSL 侦听器将停止接受连接。它可以用来限制全局 SSL CPU 使用率,而不考虑每个前端的容量。需要注意的是,这只能用作服务保护措施,因为当达到限制时,前端之间不一定会公平分配,所以最好也为每个前端限制一个接近其预期份额的值。同样重要的是要注意,会话是在进入 SSL 堆栈之前而不是之后计算的,这也保护了堆栈免受不良握手的影响。此外,降低 tune.maxaccept 可以提高公平性。
maxzlibmem <number>
设置 zlib 每个进程可用的最大 RAM 量(以兆字节为单位)。当达到最大量时,只要 RAM 不可用,未来的数据流将不会被压缩。当设置为 0 时,没有限制。默认值为 0。该值可以通过 UNIX 套接字上的“show info”命令在“MaxZlibMemUsage”行中以字节为单位获取,zlib 使用的内存是“ZlibMemUsage”(以字节为单位)。
在某些尝试回收大量内存的时刻(内存不足或重载时)禁用内存修剪(“malloc_trim”)。修剪内存会强制系统的分配器扫描所有未使用的区域并释放它们。这通常被视为一种好的做法,可以为新进程留出更多可用内存,而旧进程不太可能大量使用它。但某些处理成千上万并发连接的系统可能会经历大量的内存碎片,这可能导致此释放操作极其漫长。在此期间,没有更多的流量通过该进程,不再接受新的连接,一些健康检查甚至可能失败,看门狗(watchdog)甚至可能触发并杀死无响应的进程,留下一个巨大的核心转储文件。如果发生这种情况,建议使用此选项来禁用修剪,停止尝试对新进程友好。请注意,先进的内存分配器通常不会遇到此类问题。
禁用在 Linux 上使用 "epoll" 事件轮询系统。它等同于命令行参数 "-de"。下一个使用的轮询系统通常是 "poll"。另请参阅 "nopoll"。
在源自 Solaris 10 及更高版本的 SunOS 系统上禁用事件端口(event ports)事件轮询系统的使用。它等同于命令行参数“-dv”。下一个使用的轮询系统通常是“poll”。另请参阅“nopoll”。
禁用使用 getaddrinfo(3) 进行名称解析。它等同于命令行参数 "-dG"。将使用已弃用的 gethostbyname(3)。
禁用在 BSD 上使用 "kqueue" 事件轮询系统。它等同于命令行参数 "-dk"。下一个使用的轮询系统通常是 "poll"。另请参阅 "nopoll"。
禁用“poll”事件轮询系统的使用。它等同于命令行参数“-dp”。下一个使用的轮询系统将是“select”。通常不需要禁用“poll”,因为它在 HAProxy 支持的所有平台上都可用。另请参阅“nokqueue”、“noepoll”和“noevports”。
禁用 SO_REUSEPORT 的使用 - 请参阅 socket(7)。它等同于命令行参数 "-dR"。
禁用在 Linux 上使用内核在套接字之间进行 tcp 拼接。它等同于命令行参数 "-dS"。数据将使用传统的、更具可移植性的 recv/send 调用进行复制。内核 tcp 拼接仅限于一些非常近期的内核 2.6 实例。大多数 2.6.25 到 2.6.28 之间的版本都有错误,会转发损坏的数据,因此不得使用。此选项使得在有疑问时可以轻松地全局禁用内核拼接。另请参阅 "option splice-auto"、"option splice-request" 和 "option splice-response"。
profiling.memory { on | off }
启用('on')或禁用('off')按函数的内存分析。这将保留进程中任何地方(包括库)的 malloc/calloc/realloc/free 调用的使用统计信息,这些信息将通过 CLI 上的“show profiling”命令报告。这主要用于当观察到无法通过池信息解释的异常内存使用,并且需要其他信息时。性能损失通常在 1% 左右,在高度线程化的机器上可能会更高一些,因此通常适合在生产环境中使用。同样的功能也可以在运行时通过 CLI 上的“set profiling memory”命令实现,请查阅管理手册。
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>
有时,希望避免以精确的间隔向服务器发送代理和健康检查,例如当许多逻辑服务器位于同一物理服务器上时。借助此参数,可以在检查间隔中添加 0 到 +/- 50% 之间的随机性。2 到 5 之间的值似乎效果很好。默认值仍为 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 HAProxy Version 2.6 disabled the support for engines in the default build. This option is only available when HAProxy has been built with support for it. In case the ssl-engine is required HAProxy can be rebuild with the USE_ENGINE=1 flag.
向 SSL 上下文添加 SSL_MODE_ASYNC 模式。如果使用支持异步的 SSL 引擎,这将启用异步 TLS I/O 操作。当前实现最多支持 32 个引擎。Openssl ASYNC API 不支持移动读/写缓冲区,并且与 HAProxy 的缓冲区管理不兼容。因此,在读/写操作上禁用了异步模式(它仅在初始和重新协商握手期间启用)。
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 "<a href="#tune.buffers.reserve">tune.buffers.reserve</a>" 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, streams which need a buffer wait for another one to be released by another stream. 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.
设置预分配并保留的缓冲区数量,仅在因内存分配失败而导致内存短缺的情况下使用。最小值为 2,也是默认值。用户没有理由更改此值,它主要面向 HAProxy 核心开发人员。
tune.bufsize <number>
Sets the buffer size to this size (in bytes). Lower values allow more streams 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.
设置最大压缩级别。压缩级别影响压缩过程中的 CPU 使用率。此值影响压缩过程中的 CPU 使用率。每个使用压缩的数据流都使用此值初始化压缩算法。默认值为 1。
tune.disable-fast-forward [ EXPERIMENTAL ]
禁用数据快速转发。这是一种通过将数据直接从一侧传递到另一侧而不唤醒流来优化数据转发的机制。通过此指令,可以禁用此优化。请注意,它还禁用了任何内核 TCP 拼接以及零拷贝转发。此命令不适用于常规使用,通常只会在复杂的调试会话中由开发人员建议使用。因此,它在内部被标记为实验性的,这意味着 "expose-experimental-directives" 必须在此指令之前的行上出现。
全局禁用数据的零拷贝转发。这是一种通过避免使用通道缓冲区来优化数据快速转发的机制。通过此指令,可以禁用此优化。注意,它还禁用了任何内核 TCP 拼接。
设置异步任务处理程序(来自 event_hdl API)一次可以处理的事件数量。<number> 应在 1 到 10000 之间。较大的数字可能导致线程争用,因为任务在不中断的情况下进行繁重的工作;另一方面,较小的数字可能导致任务不断被重新调度,因为它每次运行无法消耗足够多的事件,也无法跟上事件生成者的速度。默认值可以在构建时强制设置,否则默认为 100。
如果使用 DEBUG_FAIL_ALLOC 编译或使用 "-dMfail" 启动,则给出分配尝试失败的百分比机会。必须在 0(无失败)和 100(无成功)之间。这对于调试并确保内存故障得到妥善处理非常有用。未设置时,比率为 0。但是,命令行 "-dMfail" 选项会自动将其设置为 1% 的失败率,因此无需更改配置进行测试。
tune.fd.edge-triggered { on | off } [ 实验性 ]
为支持它的文件描述符(FD)启用('on')或禁用('off')边缘触发轮询模式。目前仅在 epoll 下支持。在某些情况下,它可能会显著减少 epoll_ctl() 调用的数量并略微提高性能。这仍然是实验性的,如果仍然存在错误,可能会导致连接冻结,并且默认禁用。
启用('on')或禁用('off')H1 多路复用器的数据零拷贝接收。默认启用。
启用('on')或禁用('off')H1 多路复用器的数据零拷贝发送。默认启用。
设置后端连接上故障数量的阈值,超过该阈值连接将自动被终止。这允许自动终止行为不当的连接,而无需为其编写明确的规则。默认值为零,表示未设置阈值,因此任何事件都不会导致连接关闭。请注意,一些 H2 服务器可能会在长时间持续的连接上偶尔引起一些故障,因此这里的任何非零值可能应该在几百或几千的范围内才能有效,而不会影响轻微有问题的服务器。
设置传出连接的 HTTP/2 初始窗口大小,即服务器在等待 HAProxy 确认之前可以响应的字节数。此设置仅影响有效负载内容,不影响标头。未设置时,将应用 tune.h2.initial-window-size 设置的通用默认值。适当增加此值可以加快下载速度或减少服务器上的 CPU 使用,但代价是在客户端之间造成不公平。它不影响资源使用。
设置每个传出连接的 HTTP/2 最大并发流数(即单个到服务器连接上的未完成请求数)。如果未设置,则应用由 tune.h2.max-concurrent-streams 设置的默认值。小于默认值 100 的值可能会提高站点的响应能力,但代价是需要维护更多到服务器的已建立连接。当“http-reuse”设置为“always”时,建议减小此值,以免在同一连接上混合过多不同的客户端,因为如果一个客户端比其他客户端慢,一种称为“队头阻塞”的机制往往会对共享连接的所有客户端的下载速度产生级联效应(在这种情况下,保持 tune.h2.be.initial-window-size 较低)。强烈建议不要增加此值;有些人可能会发现在较低的值(通常为 1..5)下运行是最佳的。
设置前端连接上故障数量的阈值,超过该阈值连接将自动被终止。这允许自动终止行为不当的连接,而无需为其编写明确的规则。默认值为零,表示未设置阈值,因此任何事件都不会导致连接关闭。请注意,一些 H2 客户端可能会在长时间持续的连接上偶尔引起一些故障,因此这里的任何非零值可能应该在几百或几千的范围内才能有效,而不会影响轻微有问题的客户端。
设置传入连接的 HTTP/2 初始窗口大小,即客户端在等待 HAProxy 确认之前可以上传的字节数。此设置仅影响有效负载内容(即 POST 请求的主体),不影响标头。未设置时,将应用由 tune.h2.initial-window-size 设置的通用默认值。增加此值可以加快上传速度。默认值 65536 允许每个客户端在 100 毫秒 ping 时间内达到最高 5 Mbps 的带宽,在 1 毫秒 ping 时间内达到 500 Mbps。它不影响资源使用。使用过大的值可能会导致客户端在并行访问页面和进行大文件上传时体验到响应性不足。
设置每个传入连接的 HTTP/2 最大并发流数(即单个客户端连接上的未完成请求数)。如果未设置,则应用由 tune.h2.max-concurrent-streams 设置的默认值。对于具有大量小对象的复杂站点,在高延迟网络上,大于默认值 100 的值有时可能会略微改善页面加载时间,但也可能因允许客户端一次性分配更多资源而导致使用更多内存。默认值 100 通常很好,建议不要更改此值。
Sets the HTTP/2 maximum number of total streams processed per incoming connection. Once this limit is reached, HAProxy will send a graceful GOAWAY frame informing the client that it will close the connection after all pending streams have been closed. In practice, clients tend to close as fast as possible when receiving this, and to establish a new connection for next requests. Doing this is sometimes useful and desired in situations where clients stay connected for a very long time and cause some imbalance inside a farm. For example, in some highly dynamic environments, it is possible that new load balancers are instantiated on the fly to adapt to a load increase, and that once the load goes down they should be stopped without breaking established connections. By setting a limit here, the connections will have a limited lifetime and will be frequently renewed, with some possibly being established to other nodes, so that existing resources are quickly released. It's important to understand that there is an implicit relation between this limit and "<a href="#tune.h2.fe.max-concurrent-streams">tune.h2.fe.max-concurrent-streams</a>" above. Indeed, HAProxy will always accept to process any possibly pending streams that might be in flight between the client and the frontend, so the advertised limit will always automatically be raised by the value configured in max-concurrent-streams, and this value will serve as a hard limit above which a violation by a non- compliant client will result in the connection being closed. Thus when counting the number of requests per connection from the logs, any number between max-total-streams and (max-total-streams + max-concurrent-streams) may be observed depending on how fast streams are created by the client. The default value is zero, which enforces no limit beyond those implied by the protocol (2^30 ~= 1.07 billion). Values around 1000 may already cause frequent connection renewal without causing any perceptible latency to most clients. Setting it too low may result in an increase of CPU usage due to frequent TLS reconnections, in addition to increased page load time. Please note that some load testing tools do not support reconnections and may report errors with this setting; as such it may be needed to disable it when running performance benchmarks. See also "<a href="#tune.h2.fe.max-concurrent-streams">tune.h2.fe.max-concurrent-streams</a>".
设置 HTTP/2 动态头表大小。默认为 4096 字节,不能大于 65536 字节。较大的值可能有助于某些客户端发送更紧凑的请求,具体取决于它们的能力。每个 HTTP/2 连接都会消耗此数量的内存。建议不要更改它。
设置 HTTP/2 初始窗口大小的默认值,适用于传入和传出连接。当未设置 tune.h2.fe.initial-window-size 时,此值用于传入连接;当未设置 tune.h2.be.initial-window-size 时,此值用于传出连接。默认值为 65536,对于上传,这大约允许在 100 毫秒 ping 时间的网络上每个客户端最高 5 Mbps 的带宽,或在 1 毫秒的本地网络上 500 Mbps。鉴于更改默认值会同时增加上传速度并导致客户端下载时更多的不公平,建议改用特定于侧的设置 tune.h2.fe.initial-window-size 和 tune.h2.be.initial-window-size。
设置每个连接的默认 HTTP/2 最大并发流数(即单个连接上的未完成请求数)。当未设置 tune.h2.fe.max-concurrent-streams 时,此值用于传入连接;当未设置 tune.h2.be.max-concurrent-streams 时,此值用于传出连接。默认值为 100。影响因方向而异,因此请参阅上述两个设置以获取更多详细信息。建议不要使用此设置,而是切换到按方向的设置。值为零将禁用限制,因此单个客户端可以创建 HAProxy 可分配的任意数量的流。强烈建议不要更改此值。
设置 HAProxy 向其对等方宣告愿意接收的 HTTP/2 最大帧大小。默认值是 16384 和缓冲区大小 (tune.bufsize) 之间的较大者。在任何情况下,HAProxy 都不会宣告支持大于缓冲区的帧大小。此设置的主要目的是允许在使用大缓冲区时限制最大帧大小设置。过大的帧大小可能会影响性能或导致某些对等方行为不当。强烈建议不要更改此值。
启用('on')或禁用('off')H2 多路复用器的数据零拷贝发送。默认启用。
设置捕获的 cookie 的最大长度。"capture cookie xxx len yyy" 允许的最大值将是此值,任何更高的值都将自动截断为此值。重要的是不要设置太高的值,因为所有 cookie 捕获无论其配置值如何都会分配此大小(它们共享一个池)。此值是每个请求每个响应的,因此每个连接分配的内存是此值的两倍。如果未指定,限制设置为 63 个字符。建议不要更改此值。
设置日志中请求 URI 的最大长度。这可以防止在日志行中截断带有有价值查询字符串的长请求 URI。这与 syslog 的限制无关。如果增加此限制,您可能还需要增加 'log ... len yyy' 参数。您的 syslog 守护进程可能也需要特定的配置指令。默认值为 1024。
Sets the maximum number of headers allowed in received HTTP messages. When a message comes with a number of headers greater than this value (including the first line), it is rejected with a "400 Bad Request" status code for a request, or "502 Bad Gateway" for a response. 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 stream, so don't push this limit too high. Note that HTTP/1.1 is a text protocol, so there is no special limit when the message is sent. The limit during the message parsing is sufficient. HTTP/2 and HTTP/3 are binary protocols and require an encoding step. A limit is set too when headers are encoded to comply to limitation imposed by the protocols. This limit is large enough but not documented on purpose. The same limit is applied on the first steps of the decoding for the same reason.
启用('on')或禁用('off')同一服务器的空闲连接池在线程间的共享。默认是共享它们,以最小化到服务器的持久连接数,并优化连接重用率。但为了帮助调试或当怀疑 HAProxy 在连接重用方面存在错误时,强制禁用多线程间的空闲池共享,并将此选项设置为 "off" 可能很方便。默认是 on。强烈建议在禁用此选项时,不要为所有依赖连接重用以实现高性能的服务器设置一个保守的“pool-low-conn”值,否则随着线程数的增加,连接可能会被频繁关闭。
tune.idletimer <timeout>
设置一个持续时间,在此之后 HAProxy 将认为一个空缓冲区可能与一个空闲流相关联。这用于在交替转发大数据和小数据时优化调整某些数据包的大小。使用 splice() 或在 SSL 中发送大缓冲区的决定受此参数调节。该值以毫秒为单位,介于 0 和 65535 之间。值为零表示 HAProxy 不会尝试检测空闲流。默认值为 1000,这似乎能正确检测最终用户的暂停(例如,在点击前阅读页面)。应该没有理由更改此值。请检查下面的 tune.ssl.maxrecord。
tune.listener.default-shards { by-process | by-thread | by-group }
Normally, all "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%20reference%29">Alphabetically sorted keywords reference</a></li></ul></span>" lines will create a single shard, that is, a single socket that all threads of the process will listen to. With many threads, this is not very efficient, and may even induce some important overhead in the kernel for updating the polling state or even distributing events to the various threads. Modern operating systems support balancing of incoming connections, a mechanism that will consist in permitting multiple sockets to be bound to the same address and port, and to evenly distribute all incoming connections to these sockets so that each thread only sees the connections that are waiting in the socket it is bound to. This significantly reduces kernel-side overhead and increases performance in the incoming connection path. This is usually enabled in HAProxy using the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">shards<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#shards%20%28Peers%29">Peers</a></li><li><a href="#shards%20%28Bind%20options%29">Bind options</a></li></ul></span>" setting on "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" lines, which defaults to 1, meaning that each listener will be unique in the process. On systems with many processors, it may be more convenient to change the default setting to "by-thread" in order to always create one listening socket per thread, or "by-group" in order to always create one listening socket per thread group. Be careful about the file descriptor usage with "by-thread" as each listener will need as many sockets as there are threads. Also some operating systems (e.g. FreeBSD) are limited to no more than 256 sockets on a same address. Note that "by-group" will remain equivalent to "by-process" for default configurations involving a single thread group, and will fall back to sharing the same socket on systems that do not support this mechanism. The default is "by-group" with a fallback to "by-process" for systems or socket families that do not support multiple bindings.
tune.listener.multi-queue { on | fair | off }
Enables ('on' / 'fair') or disables ('off') the listener's multi-queue accept which spreads the incoming traffic to all threads a "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" 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). The default mode, "on", optimizes the choice of a thread by picking in a sample the one with the less connections. It is often the best choice when connections are long-lived as it manages to keep all threads busy. A second mode, "fair", instead cycles through all threads regardless of their instant load level. It can be better suited for short- lived connections, or on machines with very large numbers of threads where the probability to find the least loaded thread with the first mode is low. Finally it is possible to forcefully disable the redistribution mechanism using "off" for troubleshooting, or for situations where connections are short-lived and it is estimated that the operating system already provides a good enough distribution. The default is "on".
The "burst" execution timeout applies to any Lua handler. If the handler fails to finish or yield before timeout is reached, it will be aborted to prevent thread contention, to prevent traffic from not being served for too long, and ultimately to prevent the process from crashing because of the watchdog kicking in. Unlike other lua timeouts which are yield-cumulative, burst-timeout will ensure that the time spent in a single lua execution window does not exceed the configured timeout. Yielding here means that the lua execution is effectively interrupted either through an explicit call to lua-yielding function such as core.(m)sleep() or core.yield(), or following an automatic forced-yield (see tune.lua.forced-yield) and that it will be resumed later when the related task is set for rescheduling. Not all lua handlers may yield: we have to make a distinction between yieldable handlers and unyieldable handlers. For yieldable handlers (tasks, actions..), reaching the timeout means "<a href="#tune.lua.forced-yield">tune.lua.forced-yield</a>" might be too high for the system, reducing it could improve the situation, but it could also be a good idea to check if adding manual yields at some key points within the lua function helps or not. It may also indicate that the handler is spending too much time in a specific lua library function that cannot be interrupted. For unyieldable handlers (lua converters, sample fetches), it could simply indicate that the handler is doing too much computation, which could result from an improper design given that such handlers, which often block the request execution flow, are expected to terminate quickly to allow the request processing to go through. A common resolution approach here would be to try to better optimize the lua function for speed since decreasing "<a href="#tune.lua.forced-yield">tune.lua.forced-yield</a>" won't help. This timeout only counts the pure Lua runtime. If the Lua does a core.sleep, the sleeping time is not taken in account. The default timeout is 1000ms. Note: if a lua GC cycle is initiated from the handler (either explicitly requested or automatically triggered by lua after some time), the GC cycle time will also be accounted for. Indeed, there is no way to deduce the GC cycle time, so this could lead to some false positives on saturated systems (where GC is having hard time to catch up and consumes most of the available execution runtime). If it were to be the case, here are some resolution leads: - checking if the script could be optimized to reduce lua memory footprint - fine-tuning lua GC parameters and / or requesting manual GC cycles (see: https://lua.ac.cn/manual/5.4/manual.html#pdf-collectgarbage) - increasing tune.lua.burst-timeout Setting value to 0 completely disables this protection.
该指令强制 Lua 引擎每执行 <number> 条指令就执行一次让出(yield)。这允许中断一个长时间运行的脚本,并让 HAProxy 调度器处理其他任务,如接受连接或转发流量。默认值为 10000 条指令。如果 HAProxy 经常执行一些 Lua 代码但需要更高的响应性,可以降低这个值。如果 Lua 代码相当长,并且其结果对于处理数据是绝对必需的,可以增加这个 <number>。
启用('on')或禁用('off')通过适用于当前代理的日志记录器(如果有)记录 LUA 脚本的输出。默认为 'on'。
tune.lua.log.stderr { on | auto | off }
启用('on')或禁用('off')通过 stderr 记录 LUA 脚本的输出。当设置为 'auto' 时,如果满足以下任一条件,则通过 stderr 进行日志记录为 'on': - tune.lua.log.loggers 设置为 'off' - 脚本在没有全局日志记录器的非代理上下文中执行 - 脚本在没有附加日志记录器的代理上下文中执行。请注意,启用时,此日志记录是 tune.lua.log.loggers 配置的日志记录之外的补充。默认为 'auto'。
设置 Lua 每个进程可用的最大 RAM 量(以兆字节为单位)。默认情况下为零,表示无限制。设置限制很重要,以确保脚本中的错误不会导致系统内存耗尽。
这是 Lua 服务的执行超时。这对于防止无限循环或在 Lua 中花费太多时间很有用。此超时仅计算纯 Lua 运行时。如果 Lua 执行了休眠,休眠时间不计入。默认超时为 4 秒。
这是 Lua 会话的执行超时。这对于防止无限循环或在 Lua 中花费太多时间很有用。此超时仅计算纯 Lua 运行时。如果 Lua 执行了休眠,休眠时间不计入。默认超时为 4 秒。
目的与 "tune.lua.session-timeout" 相同,但此超时专用于任务。默认情况下,此超时未设置,因为任务可能在 HAProxy 的整个生命周期内保持活动状态。例如,用于检查服务器的任务。
设置每个线程的活动检查数,超过此数,线程将主动尝试寻找负载较轻的线程来运行健康检查,或者将其排队,直到其上运行的活动检查数量减少。默认值为零,表示没有设置此类限制。在某些运行大量昂贵检查且线程数众多的环境中,当负载出现不均并可能导致健康检查在启动时随机超时时,可能需要此设置,尤其是在使用 OpenSSL 3.0 时,其在健康检查上的 CPU 密集度比旧版本高约 20 倍。这将导致尝试在所有线程之间平均分配健康检查工作。绝大多数配置不需要调整此参数。请注意,如果检查执行缓慢,过低的值可能会显著减慢健康检查的速度。
设置一个进程在切换到其他工作之前可以连续接受的最大连接数。在单进程模式下,较高的数字曾经在高连接率下提供更好的性能,但现在有了多队列后,情况已非如此。此值单独应用于每个监听器,因此会考虑监听器绑定的进程数。此值默认为 4,表现出最佳结果。如果从旧配置中继承了一个明显更高的值,可能值得将其移除,因为这既能提高性能又能降低响应时间。在多进程模式下,它会被监听器绑定的进程数的两倍所除。将此值设置为 -1 会完全禁用该限制。通常不需要调整此值。
设置一次调用轮询系统可以处理的最大事件量。默认值根据操作系统进行调整。已经注意到,将其降低到 200 以下会略微降低延迟,但会牺牲网络带宽,而将其增加到 200 以上则会以延迟换取略微增加的带宽。
将保留的缓冲区空间设置为此大小(以字节为单位)。保留空间用于报头重写或追加。套接字上的第一次读取永远不会超过 bufsize-maxrewrite。历史上,它默认为 bufsize 的一半,但这没有太大意义,因为很少有大量的报头需要添加。设置得太高会妨碍处理大的请求或响应。设置得太低会妨碍向已有的较大请求或 POST 请求添加新报头。通常明智的做法是将其设置为大约 1024。如果大于 bufsize 的一半,它会自动调整为 bufsize 的一半。这意味着您在更改 bufsize 时不必担心它。
Sets the per-thread amount of memory that will be kept hot in the local cache and will never be recoverable by other threads. Access to this memory is very fast (lockless), and having enough is critical to maintain a good performance level under extreme thread contention. The value is expressed in bytes, and the default value is configured at build time via CONFIG_HAP_POOL_CACHE_SIZE which defaults to 524288 (512 kB). A larger value may increase performance in some usage scenarios, especially when performance profiles show that memory allocation is stressed a lot. Experience shows that a good value sits between once to twice the per CPU core L2 cache size. Too large values will have a negative impact on performance by making inefficient use of the L3 caches in the CPUs, and will consume larger amounts of memory. It is recommended not to change this value, or to proceed in small increments. In order to completely disable the per-thread CPU caches, using a very small value could work, but it is better to use "-dMno-cache" on the command-line.
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 "<a href="#sub">sub</a>", "reg", "dir", "dom", "end", "<a href="#bin">bin</a>" 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.
设置 haproxy 在发送消息时一次将尝试处理的粘性表更新的最大数量。检索这些更新的数据需要一些锁定操作,这在高度线程化的机器上如果无限制可能会消耗大量 CPU,并且在旧进程和新进程之间的初始批量传输期间也可能增加流量延迟。相反,低值也可能导致更高的 CPU 开销,并需要更长的时间来完成。默认值为 200,建议不要更改它。
tune.pipesize <number>
将内核管道缓冲区大小设置为此大小(以字节为单位)。默认情况下,管道是系统的默认大小。但有时在使用 TCP 拼接时,增加管道大小可以提高性能,特别是在怀疑管道未被填满且执行了许多 splice() 调用时。这对内核的内存占用有影响,因此如果影响不明确,则不应更改此值。
此设置设置 HAProxy 全局使用的文件描述符最大数量(百分比),相对于 HAProxy 在我们无法重用连接并且必须创建新连接时开始终止空闲连接之前可以使用的最大文件描述符数量。默认值为 25(四分之一的文件描述符将意味着大约一半的最大前端连接可以保留一个空闲的后端连接,任何超出此范围的在针对连接重用的通用情况下可能没有多大意义)。
此设置设置 HAProxy 全局使用的文件描述符最大数量(百分比),相对于 HAProxy 在我们停止将连接放入空闲池以供重用之前可以使用的最大文件描述符数量。默认值为 20。
启用('on')或禁用('off')直通(pass-through)多路复用器的数据零拷贝转发。要使用此功能,还必须配置内核拼接。默认启用。
此设置定义了在数据发射时为 QUIC 连接分配的最大缓冲区数。默认情况下,设置为 30。QUIC 缓冲区在收到 ACK 后被清空。此设置直接影响吞吐量和内存消耗,并可根据估计的往返时间进行调整。每个缓冲区的大小为 tune.bufsize。
设置前端的 QUIC max_idle_timeout 传输参数(以毫秒为单位),该参数确定了连接在由两个端点宣告的两个 max_idle_timeout 值推导出的有效时间段内保持不活动后,静默关闭的时间段:- 如果两个值都不为空,则为两个值中的最小值,- 如果只有一个不为空,则为最大值,- 如果两个值都为空,则禁用此功能。默认值为 30000。
为前端设置 QUIC initial_max_streams_bidi 传输参数。这是远程对等方将被授权打开的初始最大双向流数。这决定了并发客户端请求的数量。默认值为 100。
设置单个 QUIC 帧可以被标记为丢失的限制。如果超过此限制,连接将被视为失败并立即关闭。默认值为 10。
tune.quic.reorder-ratio <0..100, in percent>
应用于计算出的数据包重排阈值的比率。如果太小,可能会触发高丢包检测。默认值为 50。
一旦半开连接数达到此数值,将为所有已配置的 QUIC 侦听器动态启用重试(Retry)功能。半开连接是指其握手尚未成功完成或失败的连接。要使此设置生效,需要设置集群密钥(cluster secret),否则它将被静默忽略(参见“cluster-secret”设置)。如果强制使用了 QUIC 重试(参见“quic-force-retry”),此设置也将被静默忽略。默认值为 100。有关 QUIC 重试的更多信息,请参阅 https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2。
tune.quic.socket-owner { connection | listener }
Specifies globally how QUIC connections will use socket for receive/send operations. Connections can share listener socket or each connection can allocate its own socket. When default "connection" value is set, a dedicated socket will be allocated by every QUIC connections. This option is the preferred one to achieve the best performance with a large QUIC traffic. This is also the only way to ensure soft-stop is conducted properly without data loss for QUIC connections and cases of transient errors during sendto() operation are handled efficiently. However, this relies on some advanced features from the UDP network stack. If your platform is deemed not compatible, haproxy will automatically switch to "listener" mode on startup. Please note that QUIC listeners running on privileged ports may require to run as uid 0, or some OS-specific tuning to permit the target uid to bind such ports, such as system capabilities. See also the "<a href="#setcap">setcap</a>" global directive. The "listener" value indicates that QUIC transfers will occur on the shared listener socket. This option can be a good compromise for small traffic as it allows to reduce FD consumption. However, performance won't be optimal due to a higher CPU usage if listeners are shared across a lot of threads or a large number of QUIC connections can be used simultaneously. This setting is applied in conjunction with each "<a href="#quic-socket">quic-socket</a>" bind options. If "connection" mode is used on global tuning, it will be activated for each listener, unless its bind option is set to "listener". However, if "listener" is used globally, it will be forced on every listener instance, regardless of their individual configuration.
Enables ('on') of disabled ('off') the zero-copy sends of data for the QUIC multiplexer. It is disabled by default.
<a class="anchor" name="tune.rcvbuf.backend"></a><a href="#3.2-tune.rcvbuf.backend">tune.rcvbuf.backend</a> <span style="color: #080"><number></span>
<a class="anchor" name="tune.rcvbuf.frontend"></a><a href="#3.2-tune.rcvbuf.frontend">tune.rcvbuf.frontend</a> <span style="color: #080"><number></span>
For the kernel socket receive buffer size on non-connected sockets to this size. This can be used QUIC in listener mode and log-forward on the frontend. The default system buffers might sometimes be too small for sockets receiving lots of aggregated traffic, causing some losses and possibly retransmits (in case of QUIC), possibly slowing down connection establishment under heavy traffic. The value is expressed in bytes, applied to each socket. In listener mode, sockets are shared between all connections, and the total number of sockets depends on the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">shards<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#shards%20%28Peers%29">Peers</a></li><li><a href="#shards%20%28Bind%20options%29">Bind options</a></li></ul></span>" value of the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" line. There's no good value, a good one corresponds to an expected size per connection multiplied by the expected number of connections. The kernel may trim large values. See also "<a href="#tune.rcvbuf.client">tune.rcvbuf.client</a>" and "<a href="#tune.rcvbuf.server">tune.rcvbuf.server</a>" for their connected socket counter parts, as well as "<a href="#tune.sndbuf.backend">tune.sndbuf.backend</a>" and "<a href="#tune.sndbuf.frontend">tune.sndbuf.frontend</a>" for the send setting.
强制将客户端或服务器端的内核套接字接收缓冲区大小设置为指定的字节值。此值适用于所有 TCP/HTTP 前端和后端。通常不应设置此值,默认大小(0)让内核根据可用内存量自动调整此值。但是,有时将其设置为非常低的值(例如 4096)有助于节省内核内存,因为它阻止内核缓冲过多的接收数据。不过,较低的值会显著增加 CPU 使用率。
HAProxy 使用一些提示来检测短读是否表示套接字缓冲区的末尾。其中之一是读取返回的字节数超过 <recv_enough>,默认为 10136(7 个 1448 字节的段)。此默认值可以通过此设置更改,以更好地处理涉及大量短消息的工作负载,例如 telnet 或 SSH 会话。
设置运行任务时一次可以处理的最大任务量。默认值取决于线程数,但在 35 到 280 之间,这往往显示出最高的请求率和最低的延迟。增加它可能会在处理 I/O 时产生延迟,使其太小可能会产生额外的开销。较高的线程数受益于较低的值。当尝试使用更大的值时,启用 tune.sched.low-latency 和可能启用 tune.fd.edge-triggered 以将最大延迟限制在最低可能值可能会很有用。
启用('on')或禁用('off')低延迟任务调度器。默认情况下,HAProxy 一次处理一个类别的多个类别的任务,因为这是最有效的。但是当使用较大的 tune.runqueue-depth 值运行时,这可能对请求或连接延迟产生可测量的影响。启用此低延迟设置后,如果存在较低优先级类别的任务,它们将始终在其他任务之前执行。这将允许在大量流量中降低新请求或连接所经历的最大延迟,但代价是对这种大流量产生更大的影响。对于常规使用,最好保持关闭。默认值为 off。
<a class="anchor" name="tune.sndbuf.backend"></a><a href="#3.2-tune.sndbuf.backend">tune.sndbuf.backend</a> <span style="color: #080"><number></span>
<a class="anchor" name="tune.sndbuf.frontend"></a><a href="#3.2-tune.sndbuf.frontend">tune.sndbuf.frontend</a> <span style="color: #080"><number></span>
For the kernel socket send buffer size on non-connected sockets to this size. This can be used for UNIX socket and UDP logging on the backend side, and for QUIC in listener mode on the frontend. The default system buffers might sometimes be too small for sockets shared between many connections (or log senders), causing some losses and possibly retransmits, slowing down new connection establishment under high traffic. The value is expressed in bytes, applied to each socket. In listener mode, sockets are shared between all connections, and the total number of sockets depends on the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">shards<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#shards%20%28Peers%29">Peers</a></li><li><a href="#shards%20%28Bind%20options%29">Bind options</a></li></ul></span>" value of the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" line. There's no good value, a good one corresponds to an expected size per connection multiplied by the expected number of connections. The kernel may trim large values. See also "<a href="#tune.sndbuf.client">tune.sndbuf.client</a>" and "<a href="#tune.sndbuf.server">tune.sndbuf.server</a>" for their connected socket counter parts, as well as "<a href="#tune.rcvbuf.backend">tune.rcvbuf.backend</a>" and "<a href="#tune.rcvbuf.frontend">tune.rcvbuf.frontend</a>" for the receive setting.
强制将客户端或服务器端的内核套接字发送缓冲区大小设置为指定的字节值。此值适用于所有 TCP/HTTP 前端和后端。通常不应设置此值,默认大小(0)让内核根据可用内存量自动调整此值。然而,有时将其设置为非常低的值(例如 4096)有助于节省内核内存,防止其缓冲过多的接收数据。但较低的值会显著增加 CPU 使用率。另一个用例是,对于极慢的客户端,防止因内核等待大部分缓冲区被读取后才再次通知 HAProxy 而导致的写入超时。
设置全局 SSL 会话缓存的大小,以块为单位。一个块足够大,可以包含一个不带对等证书的编码会话。一个带对等证书的编码会话根据对等证书的大小存储在多个块中。一个块大约使用 200 字节的内存(基于用于 `shctx_init` 函数的 `sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE` 计算)。默认值可在构建时强制指定,否则默认为 20000。当缓存满时,最空闲的条目将被清除并重新分配。较高的值会减少这种清除的发生,从而通过确保所有用户尽可能长时间地保留其会话来减少 CPU 密集型的 SSL 握手次数。所有条目在启动时预先分配。将此值设置为 0 会禁用 SSL 会话缓存。
设置用于捕获客户端 hello 密码列表、扩展列表、椭圆曲线列表和椭圆曲线点格式的缓冲区的最大大小。如果值为 0(默认值),则禁用捕获,否则将为每个 SSL/TLS 连接分配一个缓冲区。
在 DHE 密钥交换的情况下,设置用于生成临时/临时 Diffie-Hellman 密钥的 Diffie-Hellman 参数的最大大小。最终大小将尝试匹配服务器的 RSA(或 DSA)密钥的大小(例如,对于 2048 位 RSA 密钥,使用 2048 位临时 DH 密钥),但不会超过此最大值。只允许 1024 或更高的值。较高的值会增加 CPU 负载,而大于 1024 位的值不受 Java 7 及更早版本的客户端支持。如果直接在证书文件中或通过使用 ssl-dh-param-file 参数提供了静态 Diffie-Hellman 参数,则不使用此值。如果既没有定义 default-dh-param 也没有定义 ssl-dh-param-file,并且给定前端的服务器 PEM 文件没有指定其自己的 DH 参数,则 DHE 密码将对此前端不可用。
此选项禁用所有进程之间的 SSL 会话缓存共享。通常不应使用它,因为它会由于客户端命中随机进程而强制进行许多重新协商。但在某些操作系统上可能需要它,因为这些操作系统上可能无法使用任何 SSL 缓存同步方法。在这种情况下,在 SSL 层之前添加第一层基于哈希的负载均衡可能会限制缺少会话共享的影响。
设置在任何时候传递给 SSL_write() 的最大字节数。默认值 0 表示没有限制。与 tune.ssl.maxrecord 相反,此设置不会动态调整。较小的记录可能会降低吞吐量,但在处理低占用客户端时可能是必需的。
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://mdn.org.cn/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]"
设置缓存的 SSL 会话可以保持有效的时长。此时间以秒为单位表示,默认为 300(5 分钟)。重要的是要理解,这并不保证会话会持续那么长时间,因为如果缓存已满,最长时间空闲的会话将被清除,尽管它们配置了生命周期。此设置的真正用处是防止会话被使用太长时间。
设置在数据传输开始时传递给 SSL_write() 的最大字节数。默认值 0 表示没有限制。在 SSL/TLS 上,客户端只有在收到完整的记录后才能解密数据。对于大记录,这意味着客户端可能需要下载多达 16kB 的数据才能开始处理它们。限制该值可以改善位于高延迟或低带宽网络上的浏览器的页面加载时间。建议找到适合 1 或 2 个 TCP 段的最佳值(在启用 TCP 时间戳的以太网上通常为 1448 字节,或禁用时间戳时为 1460 字节),同时记住 SSL/TLS 会增加一些开销。测试期间,典型值 1419 和 2859 取得了良好效果。使用 "strace -e trace=write" 找到最佳值。HAProxy 将在检测到空闲流后自动切换到此设置(请参见上面的 tune.idletimer)。另请参见 tune.ssl.hard-maxrecord。
将用于存储生成证书的缓存大小设置为 <number> 个条目。这是一个 LRU 缓存。因为动态生成 SSL 证书的开销很大,所以它们被缓存起来。默认缓存大小设置为 1000 个条目。
<a class="anchor" name="tune.ssl.ocsp-update.maxdelay"></a><a href="#3.2-tune.ssl.ocsp-update.maxdelay">tune.ssl.ocsp-update.maxdelay</a> <span style="color: #080"><number></span>
Sets the maximum interval between two automatic updates of the same OCSP response. This time is expressed in seconds and defaults to 3600 (1 hour). It must be set to a higher value than "<a href="#tune.ssl.ocsp-update.mindelay">tune.ssl.ocsp-update.mindelay</a>". See option "<a href="#ocsp-update">ocsp-update</a>" for more information about the auto update mechanism.
<a class="anchor" name="tune.ssl.ocsp-update.mindelay"></a><a href="#3.2-tune.ssl.ocsp-update.mindelay">tune.ssl.ocsp-update.mindelay</a> <span style="color: #080"><number></span>
Sets the minimum interval between two automatic updates of the same OCSP response. This time is expressed in seconds and defaults to 300 (5 minutes). It is particularly useful for OCSP response that do not have explicit expiration times. It must be set to a lower value than "<a href="#tune.ssl.ocsp-update.maxdelay">tune.ssl.ocsp-update.maxdelay</a>". See option "<a href="#ocsp-update">ocsp-update</a>" for more information about the auto update mechanism.
设置连接或请求可以通过 "tcp-request" 或 "http-request" 规则中的 "track-sc*" 操作同时跟踪的粘性计数器(stick-counters)的数量。默认值在构建时由宏 MAX_SESS_STK_CTR 设置,默认为 3。使用此设置可以更改该值并忽略构建时传递的值。在将复杂配置移植到 HAProxy 时可能需要增加此值,但请用户注意其成本:每个条目每个连接占用 16 字节,每个请求占用 16 字节,所有这些都需要为所有请求分配和清零,即使未使用。因此,值为 10 将使每个请求的内存消耗增加 320 字节,并导致该内存在每个请求时都被擦除,这确实会对 CPU 产生可测量的影响。相反,当不使用 "track-sc" 规则时,可以降低该值(0 是有效的,可以完全禁用粘性计数器)。
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. "<a href="#proc">proc</a>" 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: "<a href="#proc">proc</a>" includes "sess", "sess" includes "txn", and "txn" includes "reqres". For example, when "<a href="#tune.vars.sess-max-size">tune.vars.sess-max-size</a>" is limited to 100, "<a href="#tune.vars.txn-max-size">tune.vars.txn-max-size</a>" and "<a href="#tune.vars.reqres-max-size">tune.vars.reqres-max-size</a>" 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.
为每个流设置 zlib 初始化中的 memLevel 参数。它定义了应为内部压缩状态分配多少内存。值为 1 使用最少的内存,但速度慢并降低压缩率;值为 9 使用最大的内存以获得最佳速度。可以是 1 到 9 之间的值。默认值为 8。
为每个流设置窗口大小(历史缓冲区的大小)作为 zlib 初始化的参数。此参数的较大值会导致更好的压缩,但代价是内存使用量增加。可以是 8 到 15 之间的值。默认值为 15。

3.3. 调试

anonkey <密钥>
这将全局匿名化密钥设置为 <密钥>,它必须是一个介于 0 和 4294967295 之间的 32 位数字。这是启用匿名模式时 CLI 命令默认使用的密钥。此密钥也可以在运行时通过 CLI 命令“set anon global-key”设置。另请参阅管理手册中的命令行参数“-dC”。
这通过跳过释放内存对象和侦听器来加快重载时旧进程的退出,因为所有这些都将在进程死亡时由操作系统回收。收益只是微不足道的(对于巨大的配置,最多也就几百毫秒)。实际上,主要目标用途是当在 deinit() 代码中发现错误时,因为它允许绕过它。除非开发人员指示,否则最好不要使用此选项。
启动期间不显示任何消息。它等同于命令行参数 "-q"。
This allows to adjust the delay after which a stuck task blocking the traffic will trigger the emission of a warning on the standard error output. The delay is expressed in milliseconds and defaults to 1000 ms. Permitted values must be comprised between 1 ms and 1000 ms included. Lower values will trigger warnings frequently and higher ones will rarely. The watchdog will kill a runaway task that fails to respond twice for one second anyway, so a 1000 ms warning delay will normally not trigger any warning. It is recommended to stay with values between 10 and 100ms to detect configuration anomalies that may degrade the user's experience, causing long response times or jerkiness on interactive sessions. For example, a poorly designed Lua sample-fetch function doing heavy computations, or a very large map_reg or map_regm map file with a very high evaluation cost may cause such trouble. For comparison a TLS handshake can eat between one and two milliseconds, and compressing a 16kB HTTP response buffer is around one millisecond. The output contains a thread dump of the offending task with a backtrace and some context that helps figure where the time is being spent.
设置此选项后,如果在处理配置时发出了任何警告,HAProxy 将拒绝启动。强烈建议在不经常更改的配置上设置此选项,因为它有助于检测细微的错误,并保持配置的清洁和向前兼容。请注意,在这种情况下,“haproxy -c”也会报告错误。此选项等同于命令行参数“-dW”。

3.4. 用户列表

可以通过仅允许经过身份验证和授权的用户来控制对前端/后端/侦听部分或 http 统计信息的访问。为此,需要创建至少一个用户列表并定义用户。
userlist <listname>
创建名为 <listname> 的新用户列表。可以使用许多独立的用户列表来存储独立客户的身份验证和授权数据。
group <groupname> [users <user>,<user>,(...)]
将组 <groupname> 添加到当前用户列表。也可以通过使用逗号分隔的名称列表(前面有 "users" 关键字)将用户附加到此组。
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!
示例
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
请注意,这两个列表在功能上是相同的。

3.5. 对等节点

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. As an exception, the data type "conn_cur" is never learned from peers, as it is supposed to reflect local values. Earlier versions used to synchronize it and to cause negative values in active-active setups, and always-growing values upon reloads or active-passive switches because the local value would reflect more connections than locally present. This information, however, is pushed so that monitoring systems can watch it. 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>
创建名为 <peersect> 的新对等节点列表。它是一个独立的部分,由一个或多个粘性表引用。
bind [<地址>]:端口 [参数*]
bind /<路径> [参数*]
定义此“peers”部分中本地对等节点的绑定参数。在同一个“peers”部分中,此类行不支持与“peer”行同时使用。
禁用一个对等节点部分。它会禁用与此部分相关的侦听和任何同步。这用于禁用粘性表的同步,而无需注释掉所有 "peers" 引用。
default-bind [参数*]
定义本地对等节点的绑定参数,但不包括其地址。
default-server [参数*]
更改“peers”部分中服务器的默认选项。
参数
<param*> is a list of parameters for this server. The "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">default-server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#default-server%20%28Peers%29">Peers</a></li><li><a href="#default-server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword accepts an important number of options and has a complete section dedicated to it. In a peers section, the transport parameters of a "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">default-server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#default-server%20%28Peers%29">Peers</a></li><li><a href="#default-server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" line are supported. Please refer to <a href="#5">section 5</a> for more details, and the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword below in this section for some of the restrictions.
此选项重新启用一个先前通过“disabled”关键字禁用的 peers 部分。
log <目标> [len <长度>] [format <格式>] [sample <范围>:<样本大小>] <facility> [<级别> [<最低级别>]]
"<a href="#peers">peers</a>" sections support the same "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">log<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#log%20%28Process%20management%20and%20security%29">Process management and security</a></li><li><a href="#log%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#log%20%28Peers%29">Peers</a></li><li><a href="#log%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword as for the proxies to log information about the "<a href="#peers">peers</a>" listener. See "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">log<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#log%20%28Process%20management%20and%20security%29">Process management and security</a></li><li><a href="#log%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#log%20%28Peers%29">Peers</a></li><li><a href="#log%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" option for proxies for more details.
peer <peername> [<address>]:port [param*]
peer <peername> /<path> [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 "<a href="#localpeer">localpeer</a>" global configuration setting), HAProxy will listen for incoming remote peer connection on the provided address. Otherwise, the address 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 address 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 "<a href="#localpeer">localpeer</a>" 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 <a href="#2.3">section 2.3</a> about environment variables. Note: "<a href="#peer">peer</a>" keyword may transparently be replaced by "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword (see "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword explanation below).
server <peername> [<address>:<port>] [param*]
server <peername> [/<path>] [param*]
As previously mentioned, "<a href="#peer">peer</a>" keyword may be replaced by "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword with a support for all "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" parameters found in 5.2 paragraph that are related to transport settings. If the underlying peer is local, the address parameter must not be present; it must be provided on a "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" line (see "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" keyword of this "<a href="#peers">peers</a>" section). A number of "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" parameters are irrelevant for "<a href="#peers">peers</a>" sections. Peers by nature do not support dynamic host name resolution nor health checks, hence parameters like "init_addr", "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">resolvers<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#resolvers%20%28Server%20and%20default-server%20options%29">Server and default-server options</a></li><li><a href="#resolvers%20%28The%20resolvers%20section%29">The resolvers section</a></li></ul></span>", "<a href="#check">check</a>", "<a href="#agent-check">agent-check</a>", or "<a href="#track">track</a>" are not supported. Similarly, there is no load balancing nor stickiness, thus parameters such as "<a href="#weight">weight</a>" or "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">cookie<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#cookie%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li><li><a href="#cookie%20%28Server%20and%20default-server%20options%29">Server and default-server options</a></li><li><a href="#cookie%20%28Fetching%20HTTP%20samples%20%28Layer%207%29%29">Fetching HTTP samples (Layer 7)</a></li></ul></span>" have no effect.
示例
 # 旧方法。 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 示例: peers mypeers bind 192.168.0.1:1024 ssl crt mycerts/pem default-server ssl verify none server haproxy1 #本地对等节点 server haproxy2 192.168.0.2:1024 server haproxy3 10.2.0.1:1024
shards <shards>
在某些配置中,人们可能希望将粘滞表(stick-table)的内容分发给某些对等节点,而不是将所有粘滞表内容发送给在“peers”部分中声明的每个对等节点。在这种情况下,“shards”指定了参与此粘滞表内容分发的对等节点的数量。另请参阅“shard”服务器参数。
table <tablename> type {ip | integer | string [len <length>] | binary [len <length>]} size <size> [expire <expire>] [write-to <wtable>] [nopurge] [store <data_type>]*
Configure a stickiness table for the current section. This line is parsed exactly the same way as the "<a href="#stick-table">stick-table</a>" keyword in others section, except for the "<a href="#peers">peers</a>" 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 "<a href="#table">table</a>" lines in "<a href="#peers">peers</a>" sections (see also "<a href="#stick-table">stick-table</a>" keyword). Also be aware of the fact that "<a href="#peers">peers</a>" sections have their own stick-table namespaces to avoid collisions between stick-table names identical in different "<a href="#peers">peers</a>" section. This is internally handled prepending the "<a href="#peers">peers</a>" 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 "<a href="#peers">peers</a>" 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 "<a href="#peers">peers</a>" protocol, as only "<a href="#peers">peers</a>" belonging to the same section may communicate with each others, there is no need to do such a distinction. Several "<a href="#peers">peers</a>" 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 "<a href="#peers">peers</a>" 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. 邮件发送器

当服务器状态发生变化时,可以发送电子邮件警报。如果配置了电子邮件警报,则会发送到邮件发送器部分中配置的每个邮件发送器。电子邮件使用 SMTP 发送给邮件发送器。
mailers <mailersect>
创建名为 <mailersect> 的新邮件发送器列表。它是一个独立的部分,由一个或多个代引用。
mailer <mailername> <ip>:<port>
在邮件发送器部分内定义一个邮件发送器。
示例
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 <时间>
定义可用于建立邮件/连接并发送到邮件服务器的时间。如果未定义,默认值为 10 秒。为了允许在初始 TCP 握手期间至少发送两个 SYN-ACK 数据包,建议将此值保持在 4 秒以上。
示例
mailers mymailers timeout mail 20s mailer smtp1 192.168.0.1:587

3.7. 程序

在 master-worker 模式下,可以与 master 一起启动外部二进制文件,这些进程称为程序。这些程序的启动和管理方式与 worker 相同。在 HAProxy 重载期间,这些进程将经历与 worker 相同的序列: - master 被重新执行 - master 向程序发送一个 SIGUSR1 信号 - 如果没有禁用“option start-on-reload”,master 将启动一个新的程序实例 在停止或重启期间,会向程序发送一个 SIGTERM 信号。
program <名称>
这是一个新的程序部分,此部分将创建一个名为 <name> 的实例,该实例在 master CLI 的 "show proc" 中可见。(请参阅管理指南中的 "9.4. Master CLI")。
command <命令> [参数*]
定义要启动的命令及可选参数。如果命令不包含绝对路径,则会在当前 PATH 中查找。这是 program 部分的一个强制选项。包含空格的参数必须用单引号或双引号括起来,或者以反斜杠为前缀。
user <用户名>
将执行的命令用户 ID 更改为 /etc/passwd 中的 <用户名>。另请参阅“group”。
group <组名>
将执行的命令组 ID 更改为 /etc/group 中的 <组名>。另请参阅“user”。
在 master 重载时启动(或不启动)程序的新实例。默认是启动新实例。此选项只能在 program 部分使用。

3.8. HTTP 错误

可以全局声明多个 HTTP 错误组,以便之后在任何代理部分中导入。同一个组可以在多个地方被引用,并且可以全部或部分导入。
http-errors <名称>
创建一个名为 <name> 的新 http-errors 组。它是一个独立的部分,可以由一个或多个代理通过其名称引用。
errorfile <代码> <文件>
将文件内容与一个 HTTP 错误码关联起来。
参数
<code> 是 HTTP 状态码。目前,HAProxy 能够生成 200、400、401、403、404、405、407、408、410、425、429、500、501、502、503 和 504 状态码。<file> 指定一个包含完整 HTTP 响应的文件。建议遵循通用做法,在文件名后附加 ".http",这样人们就不会将响应与 HTML 错误页面混淆,并建议使用绝对路径,因为文件在执行任何 chroot 之前被读取。
请参考第 4 节中的“errorfile”关键字以获取详细信息。
示例
http-errors website-1 errorfile 400 /etc/haproxy/errorfiles/site1/400.http errorfile 404 /etc/haproxy/errorfiles/site1/404.http errorfile 408 /dev/null # 解决 Chrome 预连接错误 http-errors website-2 errorfile 400 /etc/haproxy/errorfiles/site2/400.http errorfile 404 /etc/haproxy/errorfiles/site2/404.http errorfile 408 /dev/null # 解决 Chrome 预连接错误

3.9. 环形缓冲区

可以全局声明环形缓冲区,用作日志服务器或跟踪的目标。
ring <ringname>
创建一个名为 <ringname> 的新环形缓冲区。
This replaces the regular memory allocation by a RAM-mapped file to store the ring. This can be useful for collecting traces or logs for post-mortem analysis, without having to attach a slow client to the CLI. Newer contents will automatically replace older ones so that the latest contents are always available. The contents written to the ring will be visible in that file once the process stops (most often they will even be seen very soon after but there is no such guarantee since writes are not synchronous). When this option is used, the total storage area is reduced by the size of the "struct ring" that starts at the beginning of the area, and that is required to recover the area's contents. The file will be created with the starting user's ownership, with mode 0600 and will be of the size configured by the "<a href="#size">size</a>" directive. When the directive is parsed (thus even during config checks), any existing non-empty file will first be renamed with the extra suffix ".bak", and any previously existing file with suffix ".bak" will be removed. This ensures that instant reload or restart of the process will not wipe precious debugging information, and will leave time for an admin to spot this new ".bak" file and to archive it if needed. As such, after a crash the file designated by <path> will contain the freshest information, and if the service is restarted, the "<path>.bak" file will have it instead. This means that the total storage capacity required will be double of the ring size. Failures to rotate the file are silently ignored, so placing the file into a directory without write permissions will be sufficient to avoid the backup file if not desired. WARNING: there are stability and security implications in using this feature. First, backing the ring to a slow device (e.g. physical hard drive) may cause perceptible slowdowns during accesses, and possibly even panics if too many threads compete for accesses. Second, an external process modifying the area could cause the haproxy process to crash or to overwrite some of its own memory with traces. Third, if the file system fills up before the ring, writes to the ring may cause the process to crash. The information present in this ring are structured and are NOT directly readable using a text editor (even though most of it looks barely readable). The output of this file is only intended for developers.
description <文本>
描述是环形缓冲区的可选描述字符串。它将出现在 CLI 中。默认情况下,<name> 会被重用以填充此字段。
format <格式>
用于将事件存储到环形缓冲区的格式。
参数
<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 "<a href="#log-send-hostname">log-send-hostname</a>" 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>,它将被截断为此长度。
server <名称> <地址> [参数*]
Used to configure a syslog tcp server to forward messages from ring buffer. This supports for all "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">server<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#server%20%28Peers%29">Peers</a></li><li><a href="#server%20%28Rings%29">Rings</a></li><li><a href="#server%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" parameters found in 5.2 paragraph. Some of these parameters are irrelevant for "<a href="#ring">ring</a>" 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 "<a href="#log-proto">log-proto</a>" is used to set the protocol used to send messages.
size <大小>
这是环形缓冲区的可选大小,以字节为单位。默认值设置为 BUFSIZE。
设置等待服务器连接尝试成功的最大时间。
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
设置待处理数据在输出缓冲区中停留的最长时间。
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
示例
global log ring@myring local7 ring myring description "我的本地缓冲区" 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. 日志转发

可以声明一个或多个日志转发部分,HAProxy 会将所有接收到的日志消息转发到一个日志服务器列表。
log-forward <名称>
创建一个新的日志转发代理,标识为 <name>。
backlog <连接数>
向系统提供关于连接接受时期望的监听队列(backlog)大致大小的提示。
bind <地址> [参数*]
Used to configure a stream log listener to receive messages to forward. This supports the "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" parameters found in 5.1 paragraph including those about ssl but some statements such as "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">alpn<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#alpn%20%28Bind%20options%29">Bind options</a></li><li><a href="#alpn%20%28Server%20and%20default-server%20options%29">Server and default-server options</a></li></ul></span>" 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 <地址> [参数*]
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 "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">bind<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#bind%20%28Log%20forwarding%29">Log forwarding</a></li><li><a href="#bind%20%28Peers%29">Peers</a></li><li><a href="#bind%20%28Alphabetically%20sorted%20keywords%29">Alphabetically sorted keywords reference</a></li></ul></span>" parameters found in 5.1 paragraph among which "<a href="#interface">interface</a>", "<span class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">namespace<span class="caret"></span></a><ul class="dropdown-menu"><li class="dropdown-header">This keyword is available in sections :</li><li><a href="#namespace%20%28Bind%20options%29">Bind options</a></li><li><a href="#namespace%20%28Server%20and%20default-server%20options%29">Server and default-server options</a></li></ul></span>" or "<a href="#option%20transparent">transparent</a>", the other ones being silently ignored as irrelevant for UDP/syslog case.
log <目标> [len <长度>] [format <格式>] [sample <范围>:<样本大小>] <facility> [<级别> [<最低级别>]]
用于配置目标日志服务器。请参阅代理文档了解更多详情。如果未指定格式,HAProxy 会尝试保留传入的日志格式。配置的 facility 会被忽略,除非传入消息没有 facility 但在传出格式中是必需的。如果输入格式中没有时间戳,但输出格式中存在该字段,HAProxy 将使用本地日期。
示例
global log stderr format iso local7 ring myring description "我的本地缓冲区" format rfc5424 maxlen 1200 size 32764 timeout connect 5s timeout server 10s # syslog tcp 服务器 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 # 所有消息输出到 stderr log global # 所有消息输出到本地 tcp syslog 服务器 log ring@myring local0 # 在 4 个 udp syslog 服务器上负载均衡消息 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 <连接数>
固定日志转发器上的最大并发连接数。默认值为 10。
设置客户端侧的最大不活动时间。

3.11. HTTP 客户端调优

HTTPClient 是一个内部 HTTP 库,可供各种子系统使用,例如在 LUA 脚本中。HTTPClient 不用于数据路径,换句话说,它与通过 HAProxy 的 HTTP 流量无关。
禁用 httpclient 的 DNS 解析。阻止创建“default”解析器部分。默认值为 off。
此选项定义了 httpclient 将尝试解析时使用的解析器部分。默认选项是“default”解析器 ID。默认情况下,如果不使用此选项,如果找不到该部分,它将简单地禁用解析。但是,当明确启用此选项时,如果加载失败,它将触发配置错误。
此选项允许您在解析时选择您想要的 IP 族,当您的网络上 IPv6 不可用时,这很方便。默认选项是“ipv6”。
此选项允许配置 httpclient 在请求失败时的重试次数。这与后端中的“retries”关键字的作用相同。默认值为 3。
此选项定义了应用于验证服务器证书的 ca-file。它接受与服务器行上的“ca-file”选项相同的参数。默认情况下以及不使用此选项时,值为“@system-ca”,它会尝试加载系统的 CA。如果失败,httpclient 的 SSL 将被禁用。但是,当明确启用此选项时,如果失败,它将触发配置错误。
httpclient.ssl.verify [none|required]
其工作方式与服务器行上的 verify 选项相同。如果指定为 'none',则不验证服务器证书。默认选项是“required”。默认情况下以及不使用此选项时,值为“required”。如果失败,httpclient 的 SSL 将被禁用。但是,当明确启用此选项时,如果失败,它将触发配置错误。
为 httpclient 默认设置连接尝试的最大等待时间。
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
默认值为 5000ms。
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. In addition, a warning is emitted if a defaults section is explicitly used by a proxy while it is also implicitly used by another one because it is the last one defined. It is highly encouraged to not mix both usages by always using explicit references or by adding a last common defaults section reserved for all implicit uses. 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 ("<a href="#option%20http-keep-alive">option http-keep-alive</a>") 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 ("<a href="#option%20http-server-close">option http-server-close</a>") : the server-facing connection is closed after the end of the response is received, but the client-facing connection remains open. - CLO: close ("<a href="#option%20httpclose">option httpclose</a>"): 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 "<a href="#switch-mode%20http">switch-mode http</a>" 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. 代理关键字矩阵

支持以下关键字列表。它们中的大多数只能在有限的段落类型中使用。其中一些被标记为“已弃用”,因为它们继承自一个可能令人困惑或功能有限的旧语法,并且有新的推荐关键字来替代它们。标有“(*)”的关键字可以选择性地使用“no”前缀进行反转,例如“no option contstats”。当选项默认启用但必须为特定实例禁用时,这样做是有意义的。这些选项也可以使用“default”前缀,以便恢复默认设置,无论之前的“defaults”段落中指定了什么。在 defaults 段落中标有“(!)”的关键字仅在命名的 defaults 段落中支持,而不是匿名的。
关键字defaultsfrontendlistenbackend
aclX (!)XXX
backlogXXX 
balanceX XX
bind XX 
capture cookie XX 
capture request header XX 
capture response header XX 
clitcpka-cntXXX 
clitcpka-idleXXX 
clitcpka-intvlXXX 
compressionXXXX
cookieX XX
declare capture XX 
default-serverX XX
default_backendXXX 
description XXX
disabledXXXX
dispatch  XX
email-alert fromXXXX
email-alert levelXXXX
关键字defaultsfrontendlistenbackend
email-alert mailersXXXX
email-alert myhostnameXXXX
email-alert toXXXX
enabledXXXX
errorfileXXXX
errorfilesXXXX
errorlocXXXX
errorloc302XXXX
errorloc303XXXX
error-log-formatXXX 
force-persist  XX
filter XXX
fullconnX XX
hash-typeX XX
http-after-responseX (!)XXX
http-check commentX XX
http-check connectX XX
http-check disable-on-404X XX
http-check expectX XX
http-check sendX XX
关键字defaultsfrontendlistenbackend
http-check send-stateX XX
http-check set-varX XX
http-check unset-varX XX
http-errorXXXX
http-requestX (!)XXX
http-responseX (!)XXX
http-reuseX XX
http-send-name-headerX XX
id XXX
ignore-persist  XX
load-server-state-from-fileX XX
(*)logXXXX
log-formatXXX 
log-format-sdXXX 
log-tagXXXX
max-keep-alive-queueX XX
max-session-srv-connsXXX 
maxconnXXX 
modeXXXX
monitor fail XX 
关键字defaultsfrontendlistenbackend
monitor-uriXXX 
(*)option abortoncloseX XX
(*)option accept-invalid-http-requestXXX 
(*)option accept-invalid-http-responseX XX
(*)option allbackupsX XX
(*)option checkcacheX XX
(*)option clitcpkaXXX 
(*)option contstatsXXX 
(*)option disable-h2-upgradeXXX 
(*)option dontlog-normalXXX 
(*)option dontlognullXXX 
option forwardforXXXX
(*)option forwardedX XX
(*)option h1-case-adjust-bogus-clientXXX 
(*)option h1-case-adjust-bogus-serverX XX
(*)option http-buffer-requestXXXX
(*)option http-ignore-probesXXX 
(*)option http-keep-aliveXXXX
(*)option http-no-delayXXXX
(*)option http-pretend-keepaliveX XX
关键字defaultsfrontendlistenbackend
option http-restrict-req-hdr-namesXXXX
(*)option http-server-closeXXXX
(*)option http-use-proxy-headerXXX 
option httpchkX XX
(*)option httpcloseXXXX
option httplogXXX 
option httpslogXXX 
(*)option independent-streamsXXXX
option ldap-checkX XX
option external-checkX XX
(*)option log-health-checksX XX
(*)option log-separate-errorsXXX 
(*)option logasapXXX 
option mysql-checkX XX
(*)option nolingerXXXX
option originaltoXXXX
(*)option persistX XX
option pgsql-checkX XX
(*)option prefer-last-serverX XX
(*)option redispatchX XX
关键字defaultsfrontendlistenbackend
option redis-checkX XX
option smtpchkX XX
(*)option socket-statsXXX 
(*)option splice-autoXXXX
(*)option splice-requestXXXX
(*)option splice-responseXXXX
option spop-checkX XX
(*)option srvtcpkaX XX
option ssl-hello-chkX XX
option tcp-checkX XX
(*)option tcp-smart-acceptXXX 
(*)option tcp-smart-connectX XX
option tcpkaXXXX
option tcplogXXX 
(*)option transparentX XX
(*)option idle-close-on-responseXXX 
external-check commandX XX
external-check pathX XX
persist rdp-cookieX XX
rate-limit sessionsXXX 
关键字defaultsfrontendlistenbackend
redirect XXX
retriesX XX
retry-onX XX
server  XX
server-state-file-nameX XX
server-template  XX
sourceX XX
srvtcpka-cntX XX
srvtcpka-idleX XX
srvtcpka-intvlX XX
stats admin XXX
stats authXXXX
stats enableXXXX
stats hide-versionXXXX
stats http-request XXX
stats realmXXXX
stats refreshXXXX
stats scopeXXXX
stats show-descXXXX
stats show-legendsXXXX
关键字defaultsfrontendlistenbackend
stats show-nodeXXXX
stats uriXXXX
stick match  XX
stick on  XX
stick store-request  XX
stick store-response  XX
stick-table XXX
tcp-check commentX XX
tcp-check connectX XX
tcp-check expectX XX
tcp-check sendX XX
tcp-check send-lfX XX
tcp-check send-binaryX XX
tcp-check send-binary-lfX XX
tcp-check set-varX XX
tcp-check unset-varX XX
tcp-request connectionX (!)XX 
tcp-request contentX (!)XXX
tcp-request inspect-delayX (!)XXX
tcp-request sessionX (!)XX 
关键字defaultsfrontendlistenbackend
tcp-response contentX (!) XX
tcp-response inspect-delayX (!) XX
timeout checkX XX
timeout clientXXX 
timeout client-finXXX 
timeout client-hsXXX 
timeout connectX XX
timeout http-keep-aliveXXXX
timeout http-requestXXXX
timeout queueX XX
timeout serverX XX
timeout server-finX XX
timeout tarpitXXXX
timeout tunnelX XX
(已弃用)transparentX XX
unique-id-formatXXX 
unique-id-headerXXX 
use_backend XX 
use-fcgi-app  XX
use-server  XX

4.2. 按字母排序的关键字参考

本节提供了每个关键字及其用法的描述。
acl <aclname> <criterion> [flags] [operator] <value> ...
声明或完成一个访问列表。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
此指令仅在命名的 defaults 部分可用,而不能在匿名的 defaults 部分使用。在 defaults 部分中定义的 ACL 对使用它的其他部分不可见。
示例
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
有关 ACL 的用法,请参见第 7 节
backlog <conns>
向系统提供关于期望的侦听积压队列大致大小的提示。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<conns> 是待处理连接的数量。根据操作系统的不同,它可能表示已确认的连接数、未确认的连接数或两者之和。
This option is only meaningful for stream listeners, including QUIC ones. Its behavior however is not identical with QUIC instances. For all listeners but QUIC, 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). For QUIC listeners, backlog sets a shared limits for both the maximum count of active handshakes and connections waiting to be accepted. The handshake phase relies primarily of the network latency with the remote peer, whereas the second phase depends solely on haproxy load. When either one of this limit is reached, haproxy starts to drop reception of INITIAL packets, preventing any new connection allocation, until the connection excess starts to decrease. This situation may cause browsers to silently downgrade the HTTP versions and switching to TCP.
balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]
定义在后端中使用的负载均衡算法。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<algorithm> 是用于在进行负载均衡时选择服务器的算法。这仅适用于没有可用持久性信息的情况,或者当连接被重新分派到另一台服务器时。<algorithm> 可以是以下之一: roundrobin 每个服务器根据其权重轮流使用。当服务器的处理时间保持均匀分布时,这是最平滑和最公平的算法。此算法是动态的,这意味着可以即时调整服务器权重,例如用于慢启动。它在设计上每个后端限制为 4095 个活动服务器。请注意,在某些大型集群中,当服务器在非常短的时间内停机后重新启动时,可能需要数百个请求才能重新集成到集群中并开始接收流量。这是正常的,尽管非常罕见。在此指出,以防您有机会观察到它,这样您就不会担心。注意:对于处于 LOG 模式的后端,权重将被忽略。 static-rr 每个服务器根据其权重轮流使用。此算法与 roundrobin 类似,只是它是静态的,这意味着即时更改服务器的权重将无效。另一方面,它对服务器数量没有设计限制,并且当服务器启动时,一旦重新计算完整映射,它总是立即重新引入集群。它运行所需的 CPU 也略少(大约 -1%)。此算法不能在 LOG 模式下使用。 leastconn 具有最低连接数的服务器接收连接。在具有相同负载的服务器组内执行轮询,以确保所有服务器都将被使用。建议在预期有非常长会话(例如 LDAP、SQL、TSE 等)的情况下使用此算法,但不太适合使用短会话的协议(例如 HTTP)。此算法是动态的,这意味着可以即时调整服务器权重,例如用于慢启动。它还将考虑排队连接的数量以及已建立的连接,以最大限度地减少排队。此算法不能在 LOG 模式下使用。 first 具有可用连接槽的第一个服务器接收连接。服务器从最低数字标识符到最高数字标识符进行选择(请参阅服务器参数 "id"),默认值为服务器在集群中的位置。一旦服务器达到其 maxconn 值,将使用下一个服务器。如果不设置 maxconn,使用此算法没有意义。此算法的目的是始终使用最少数量的服务器,以便在非高峰时段可以关闭多余的服务器电源。此算法忽略服务器权重,对 RDP 或 IMAP 等长会话比 HTTP 带来更多好处,尽管它在那里也有用。为了有效地使用此算法,建议云控制器定期检查服务器使用情况,以便在未使用时将其关闭,并定期检查后端队列,以便在队列膨胀时打开新服务器。或者,使用 "http-check send-state" 可以通知服务器负载情况。此算法不能在 LOG 模式下使用。 hash 在参数中采用常规样本表达式。针对每个请求评估表达式,并根据配置的 hash-type 进行哈希处理。哈希结果除以正在运行的服务器的总权重,以指定哪个服务器将接收请求。这可以用于代替 "source"、"uri"、"hdr()"、"url_param()"、"rdp-cookie",以便使用转换器、完善评估,或者例如用于从本地变量中提取数据。当数据不可用时,将应用 round robin。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。此算法不能用于 LOG 模式的后端,请改用 "log-hash"。 source 源 IP 地址被哈希并除以正在运行的服务器的总权重,以指定哪个服务器将接收请求。这确保了只要没有服务器停机或启动,同一客户端 IP 地址将始终到达同一服务器。如果由于正在运行的服务器数量变化而导致哈希结果发生变化,许多客户端将被定向到不同的服务器。此算法通常用于无法插入 cookie 的 TCP 模式。它也可以在 Internet 上使用,为拒绝会话 cookie 的客户端提供尽力而为的粘性。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。另请参阅上面的 "hash" 选项。此算法不能用于 LOG 模式的后端。 uri 此算法对 URI 的左侧部分(问号之前)或整个 URI(如果存在 "whole" 参数)进行哈希处理,并将哈希值除以正在运行的服务器的总权重。结果指定哪个服务器将接收请求。这确保了只要没有服务器启动或停机,同一 URI 将始终被定向到同一服务器。这与代理缓存和防病毒代理一起使用,以最大限度地提高缓存命中率。请注意,此算法只能在 HTTP 后端使用。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。此算法支持两个可选参数 "len" 和 "depth",两者后跟一个正整数。当需要仅基于 URI 的开头来平衡服务器时,这些选项可能会有所帮助。"len" 参数指示算法应仅考虑 URI 开头的那么多字符来计算哈希。请注意,将 "len" 设置为 1 很少有意义,因为大多数 URI 都以开头的 "/" 开头。"depth" 参数指示用于计算哈希的最大目录深度。请求中的每个斜杠算作一个级别。如果同时指定了这两个参数,则当达到任一参数时,评估停止。一个 "path-only" 参数指示哈希键从路径的第一个 '/' 开始。这可用于忽略绝对 URI 的 authority 部分,并确保 HTTP/1 和 HTTP/2 URI 将提供相同的哈希。另请参阅上面的 "hash" 选项。 url_param 将在每个 HTTP GET 请求的查询字符串中查找参数中指定的 URL 参数。如果使用修饰符 "check_post",则在 URL 中的问号 ('?') 之后的查询字符串中未找到参数时,将在 HTTP POST 请求实体中搜索参数参数。仅当已接收到通告的数据量或请求缓冲区已满时,才会开始分析消息正文。在极少数情况下使用分块编码时,仅扫描第一个分块。如果参数值被分块边界分隔,则可能会被随机平衡(如果根本没有)。此关键字过去支持一个可选的 <max_wait> 参数,该参数现在已被忽略。如果找到该参数,后跟等号 ('=') 和一个值,则该值被哈希并除以正在运行的服务器的总权重。结果指定哪个服务器将接收请求。这用于跟踪请求中的用户标识符,并确保只要没有服务器启动或停机,同一用户 ID 将始终发送到同一服务器。如果未找到值或未找到参数,则应用轮询算法。请注意,此算法只能在 HTTP 后端使用。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。另请参阅上面的 "hash" 选项。 hdr(<name>) 将在每个 HTTP 请求中查找 HTTP 标头 <name>。与等效的 ACL 'hdr()' 函数一样,括号中的标头名称不区分大小写。如果标头不存在或者它不包含任何值,则应用 roundrobin 算法。一个可选的 'use_domain_only' 参数可用,用于将哈希算法缩减为主要域部分,并带有一些特定的标头,例如 'Host'。例如,在 Host 值 "haproxy.1wt.eu" 中,只会考虑 "1wt"。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。另请参阅上面的 "hash" 选项。 random random(<draws>) 一个随机数将用作一致性哈希函数的键。这意味着服务器的权重受到尊重,动态权重更改会立即生效,新服务器的添加也会立即生效。随机负载均衡对于大型集群或服务器频繁添加或移除的情况很有用,因为它可以避免在这种情况下 roundrobin 或 leastconn 可能导致的锤击效应。 hash-balance-factor 指令可用于进一步提高负载均衡的公平性,尤其是在服务器响应时间变化很大的情况下。当存在参数 <draws> 时,它必须是一个大于或等于一的整数值,表示在选择这些服务器中负载最低的服务器之前抽取的次数。事实上,已经证明,选择两个服务器中负载最低的一个足以显着提高算法的公平性,方法是始终避免选择集群中负载最高的服务器,并消除一致性列表的不公平分布可能导致的任何偏差。较高的值 N 将以牺牲性能为代价,移除 N-1 个负载最高的服务器。对于非常高的值,算法将收敛到 leastconn 的结果,但速度慢得多。默认值为 2,通常显示出非常好的分布和性能。此算法也称为“两个随机选择的力量”(Power of Two Random Choices),在此描述:http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf 对于处于 LOG 模式的后端,将忽略抽取的次数,并选择单个随机数,因为没有服务器负载的概念。随机日志平衡对于大型集群或服务器频繁从可用服务器池中添加或移除的情况很有用,因为它可以避免在这种情况下 roundrobin 可能导致的锤击效应。 rdp-cookie rdp-cookie(<name>) 将为每个传入的 TCP 请求查找 RDP cookie <name>(如果省略则为 "mstshash")并对其进行哈希处理。与等效的 ACL 'req.rdp_cookie()' 函数一样,名称不区分大小写。此机制可用作降级的持久性模式,因为它使得始终将同一用户(或同一会话 ID)发送到同一服务器成为可能。如果未找到 cookie,则改用正常的 roundrobin 算法。请注意,为了使其工作,前端必须确保请求缓冲区中已存在 RDP cookie。为此,您必须使用 'tcp-request content accept' 规则结合 'req.rdp_cookie_cnt' ACL。此算法默认是静态的,这意味着即时更改服务器的权重将无效,但这可以使用 "hash-type" 进行更改。另请参阅上面的 "hash" 选项。 log-hash 在参数中采用逗号分隔的转换器列表。这些转换器按顺序应用于输入日志消息,结果将转换为字符串,然后根据配置的 hash-type 进行哈希处理。生成的哈希将用于在日志后端中声明的服务器中选择目标服务器。此算法的目标是能够使用字符串转换器在最终日志消息中提取键,然后 благодаря哈希能够粘附到同一服务器。目前仅支持“基于映射”的哈希。此算法只能用于处于 LOG 模式的后端,对于其他后端,请改用 "hash"。 sticky 尽量粘附到同一服务器。可用服务器列表中的第一个服务器接收所有日志消息。当服务器停机时,列表中的下一个服务器取代其位置。当先前停机的服务器恢复正常运行时,它会添加到列表末尾,以便粘性服务器在停机之前不会更改。此算法只能用于处于 LOG 模式的后端。 <arguments> 是一个可选参数列表,某些算法可能需要这些参数。目前,只有 "url_param"、"uri" 和 "log-hash" 支持可选参数。
当没有设置其他算法、模式或选项时,后端的负载均衡算法设置为 roundrobin。每个后端只能设置一次算法。在处于 LOG 模式的后端中,服务器 "weight" 始终被忽略。对于需要相同连接的身份验证方案(如 NTLM),不得使用基于 URI 的算法,因为它们会导致后续请求路由到不同的后端服务器,从而破坏 NTLM 所依赖的无效假设。 TCP/HTTP 示例: balance roundrobin balance url_param userid balance url_param session_id check_post 64 balance hdr(User-Agent) balance hdr(host) balance hdr(Host) use_domain_only balance hash req.cookie(clientid) balance hash var(req.client_id) balance hash req.hdr_ip(x-forwarded-for,-1),ipmask(24) LOG 后端示例: global log backend@mylog-rrb local0 # send all logs to mylog-rrb backend log backend@mylog-hash local0 # send all logs to mylog-hash backend backend mylog-rrb mode log balance roundrobin server s1 udp@127.0.0.1:514 # will receive 50% of log messages server s2 udp@127.0.0.1:514 backend mylog-hash mode log # extract "METHOD URL PROTO" at the end of the log message, # and let haproxy hash it so that log messages generated from # similar requests get sent to the same syslog server: balance log-hash 'field(-2,\")' # server list here server s1 127.0.0.1:514 #... 注意:必须考虑使用带有 "url_param" 的 "check_post" 扩展的以下警告和限制: - 所有 POST 请求都有资格进行考虑,因为无法确定参数是否会在可能包含二进制数据的正文或实体中找到。因此,可能需要另一种方法来限制考虑正文中没有 URL 参数的 POST 请求。(请参阅 acl http_end) - 使用大于请求缓冲区大小的 <max_wait> 值没有意义且无用。缓冲区大小在构建时设置,默认为 16 kB。 - 不支持 Content-Encoding,参数搜索可能会失败;负载均衡将回退到 Round Robin。 - 不支持 Expect: 100-continue,负载均衡将回退到 Round Robin。 - Transfer-Encoding (RFC7230 3.3.1) 仅在第一个分块中受支持。如果整个参数值不存在于第一个分块中,则服务器的选择是不确定的(实际上,由第一个分块中实际出现的内容量决定)。 - 此功能不支持生成 100、411 或 501 响应。 - 在某些情况下,请求 "check_post" 可能会尝试扫描消息正文的全部内容。扫描通常在找到线性空白或控制字符时终止,这表示可能是 URL 参数列表的末尾。对于 SGML 类型消息正文,这可能不是问题。
bind [<address>]:<port_range> [, ...] [param*]
bind /<path> [, ...] [param*]
在前端中定义一个或多个监听地址和/或端口。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<address> 是可选的,可以是主机名、IPv4 地址、IPv6 地址或 '*'。它指定前端将侦听的地址。如果未设置,将侦听系统的所有 IPv4 地址。'*' 或系统的特殊地址 "0.0.0.0" 也会应用相同的情况。IPv6 等效项是 '::'。请注意,对于 UDP,当绑定到多个地址时,需要特定的 OS 功能以确保在响应时使用正确的网络接口和源地址。换句话说,对于 QUIC 侦听器,仅在运行足够现代的系统时才绑定到多个地址。或者,可以在地址前使用地址族前缀来强制指定族,而不管地址格式如何,这对于指定没有斜杠 ('/') 的 unix 套接字路径很有用。目前支持的前缀有: - 'ipv4@' -> 地址始终为 IPv4 - 'ipv6@' -> 地址始终为 IPv6 - 'udp@' -> 地址解析为 IPv4 或 IPv6,并使用协议 UDP。目前这些侦听器仅在 log-forward 部分支持。 - 'udp4@' -> 地址始终为 IPv4,并使用协议 UDP。目前这些侦听器仅在 log-forward 部分支持。 - 'udp6@' -> 地址始终为 IPv6,并使用协议 UDP。目前这些侦听器仅在 log-forward 部分支持。 - 'unix@' -> 地址是本地 unix 套接字的路径 - 'abns@' -> 地址位于抽象命名空间中(仅限 Linux)。 - 'fd@<n>' -> 使用从父级继承的文件描述符 <n>。fd 必须已绑定,并且可能已在侦听或未在侦听。 - 'sockpair@<n>'-> 类似于 fd@,但您必须使用已连接的 unix 套接字或 socketpair 的 fd。绑定等待通过 unix 套接字接收 FD,并将其用作 accept() 的 FD。应谨慎使用。 - 'quic4@' -> 地址解析为 IPv4,并使用协议 UDP。请注意,为了在大流量下实现最佳性能,您应该保持 "tune.quic.socket-owner" 处于连接状态。否则,QUIC 连接将通过侦听器套接字进行多路复用。另一种替代方法是跨多个线程复制 QUIC 侦听器实例,例如使用 "shards" 关键字来至少减少线程争用。 - 'quic6@' -> 地址解析为 IPv6,并使用协议 UDP。IPv4 上的 QUIC 性能说明也适用。 - 'rhttp@' [ EXPERIMENTAL ] -> 用于反向 HTTP。地址必须是具有格式 '<backend>/<server>' 的服务器。服务器将用于实例化与远程地址的连接。侦听器将尝试维护 "nbconn" 连接。这是一个实验性功能,需要在绑定之前的一行上使用 "expose-experimental-directives"。您可能想在 address 参数中引用一些环境变量,请参阅关于环境变量的第 2.3 节。 <port_range> 是一个唯一的 TCP 端口,或者是代理将接受连接的端口范围,用于上面指定的 IP 地址。对于 TCP 侦听器,端口是强制性的。请注意,对于 IPv6 地址,端口始终是最后一个冒号 (':') 之后的数字。范围可以是: - 一个数字端口(例如:'80') - 一个带短划线分隔的端口范围,明确说明下限和上限(例如:'2000-2100'),包含在范围内。必须特别注意端口范围,因为每个 <address:port> 对都会消耗一个套接字(= 一个文件描述符),因此很容易通过简单的范围消耗大量描述符,并耗尽套接字。此外,每个 <address:port> 对必须在同一系统上运行的所有实例中仅使用一次。请注意,绑定到低于 1024 的端口通常需要特定的权限才能启动程序,这与 'uid' 参数无关。 <path> 是一个以斜杠 ('/') 开头的 UNIX 套接字路径。这是 TCP 侦听端口的替代方案。HAProxy 将在位于此处的套接字上接收 UNIX 连接。路径必须以斜杠开头,并且默认是绝对路径。它可以是相对于全局部分中由 "unix-bind" 定义的前缀的相对路径。请注意,前缀后跟套接字路径的总长度不能超过 UNIX 套接字的一些系统限制,这些限制通常设置为 107 个字符。 <param*> 是同一行上声明的所有套接字共有的参数列表。这些众多参数取决于 OS 和构建选项,并有专门的部分介绍。请参阅第 5 节以获取更多详细信息。
可以指定一个由逗号分隔的地址:端口组合列表。然后,前端将监听所有这些地址。一个前端可以监听的地址和端口数量没有固定限制,同样,一个前端中的“bind”语句数量也没有限制。
示例
listen http_proxy bind :80,:443 bind 10.0.0.1:10080,10.0.0.1:10443 bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy listen http_https_proxy bind :80 bind :443 ssl crt /etc/haproxy/site.pem listen http_https_proxy_explicit bind ipv6@:80 bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem bind unix@ssl-frontend.sock user root mode 600 accept-proxy listen external_bind_app1 bind "fd@${FD_APP1}" listen h3_quic_proxy bind quic4@10.0.0.1:8888 ssl crt /etc/mycrt
注意:关于 Linux 的抽象命名空间套接字,HAProxy 使用整个 sun_path 长度作为地址长度。其他一些程序,如 socat,默认只使用字符串长度。在 socat 中对任何抽象套接字定义传递选项 ",unix-tightsocklen=0",以使其与 HAProxy 兼容。
capture cookie <name> len <length>
捕获并记录请求和响应中的 cookie。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<name> 是要捕获的 cookie 名称的开头。为了精确匹配名称,只需在名称后加上一个等号('=')。完整的名称将出现在日志中,这对于会同时调整 cookie 名称和值的应用服务器(例如 ASPSESSIONXXX)很有用。<length> 是日志中报告的最大字符数,包括 cookie 名称、等号和值,全部采用标准的 "name=value" 格式。如果字符串超过 <length>,它将被从右侧截断。
仅捕获第一个 cookie。监视 "cookie" 请求标头和 "set-cookie" 响应标头。这对于检查导致会话在用户之间交叉或窃取的应用程序错误特别有用,因为通常用户的 cookie 只能在登录页面上更改。当客户端未提供 cookie 时,关联的日志列将报告 "-"。当请求未导致服务器分配 cookie 时,响应列中会报告 "-"。捕获仅在前端执行,因为对于给定的前端,日志格式必须不因后端而异。将来可能会改变。请注意,一个前端中只能有一个 "capture cookie" 语句。最大捕获长度由全局 "tune.http.cookielen" 设置,默认为 63 个字符。无法在 "defaults" 部分中指定捕获。
示例
capture cookie ASPSESSION len 32
capture request header <name> len <length>
捕获并记录指定请求头的最后一次出现。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<name> 是要捕获的头的名称。头名称不区分大小写,但通常的做法是按照它们在请求中出现的样子来写,每个单词的首字母大写。头名称不会出现在日志中,只报告其值,但其在日志中的位置会得到尊重。<length> 是从值中提取并报告在日志中的最大字符数。如果字符串超过 <length>,它将被从右侧截断。
捕获标头最后一次出现的完整值。该值将添加到大括号 ('{}') 之间的日志中。如果捕获了多个标头,它们将由竖线 ('|') 分隔,并按照它们在配置中声明的顺序出现。不存在的标头将记录为空字符串。请求标头捕获的常见用途包括虚拟主机环境中的 "Host" 字段、支持上传时的 "Content-length"、用于快速区分真实用户和机器人的 "User-agent",以及代理环境中的 "X-Forwarded-For" 以查找请求来自何处。请注意,在捕获诸如 "User-agent" 之类的标头时,可能会记录一些空格,这使得日志分析更加困难。因此,如果您知道日志解析器不够智能而无法依赖大括号,请谨慎记录内容。捕获的请求标头数量及其长度没有限制,但明智的做法是保持较低以限制每个流的内存使用量。为了使同一前端的日志格式保持一致,标头捕获只能在前端中声明。无法在 "defaults" 部分中指定捕获。
示例
capture request header Host len 15 capture request header X-Forwarded-For len 15 capture request header Referer len 15
capture response header <name> len <length>
捕获并记录指定响应头的最后一次出现。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<name> 是要捕获的头的名称。头名称不区分大小写,但通常的做法是按照它们在响应中出现的样子来写,每个单词的首字母大写。头名称不会出现在日志中,只报告其值,但其在日志中的位置会得到尊重。<length> 是从值中提取并报告在日志中的最大字符数。如果字符串超过 <length>,它将被从右侧截断。
捕获该头最后一次出现的完整值。结果将添加到日志中,位于捕获的请求头之后,并用大括号('{}')括起来。如果捕获了多个头,它们将用竖线('|')分隔,并按照在配置中声明的相同顺序出现。不存在的头将被记录为空字符串。响应头捕获的常见用途包括指示预期返回字节数的 "Content-length" 头,以及跟踪重定向的 "Location" 头。捕获的响应头数量及其长度没有限制,但明智的做法是保持较低的值以限制每个流的内存使用。为了保持同一前端的日志格式一致,头捕获只能在前端中声明。不能在 "defaults" 部分中指定捕获。
示例
capture response header Content-length len 9 capture response header Location len 15
clitcpka-cnt <计数>
设置 TCP 在客户端侧断开连接之前应发送的最大 keepalive 探测次数。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<count> 是 keepalive 探测的最大次数。
此关键字对应于套接字选项 TCP_KEEPCNT。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_probes)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
clitcpka-idle <超时>
设置连接需要保持空闲多长时间后,TCP 开始发送 keepalive 探测,如果启用了在客户端侧发送 TCP keepalive 数据包。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<timeout> 是连接需要保持空闲的时间,之后 TCP 开始发送 keepalive 探测。默认以秒为单位指定,但如果数字后跟单位后缀,也可以是任何其他单位,如本文档开头所述。
此关键字对应于套接字选项 TCP_KEEPIDLE。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_time)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
设置客户端侧各个 keepalive 探测之间的时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<timeout> 是各个 keepalive 探测之间的时间。默认以秒为单位指定,但如果数字后跟单位后缀,也可以是任何其他单位,如本文档开头所述。
此关键字对应于套接字选项 TCP_KEEPINTVL。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_intvl)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
compression algo <algorithm> ...
compression type <mime type> ...
启用 HTTP 压缩。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
algo 后面是响应支持的压缩算法列表(旧关键字)。algo-req 后面是请求的压缩算法(只提供一种)。algo-res 后面是响应支持的压缩算法列表。type 后面是将为响应压缩的 MIME 类型列表(旧关键字)。type-req 后面是将为请求压缩的 MIME 类型列表。type-res 后面是将为响应压缩的 MIME 类型列表。
目前支持的算法有: identity 这主要用于调试,对于开发压缩功能很有用。Identity 不对数据应用任何更改。 gzip 应用 gzip 压缩。此设置仅在内置 zlib 或 libslz 支持时可用。 deflate 与 "gzip" 相同,但使用 deflate 算法和 zlib 格式。请注意,此算法在许多浏览器上的支持不明确,并且最近的浏览器根本不支持。强烈建议不要将其用于实验以外的任何目的。此设置仅在内置 zlib 或 libslz 支持时可用。 raw-deflate 与 "deflate" 相同,没有 zlib 包装器,并用作浏览器需要 "deflate" 时的替代方案。所有主要浏览器都理解它,尽管违反了标准,但已知它比 "deflate" 效果更好,至少在 MSIE 和某些版本的 Safari 上。不要将其与 "deflate" 结合使用,因为两者都对相同的 Accept-Encoding 令牌作出反应,因此请使用其中一个。此设置仅在内置 zlib 或 libslz 支持时可用。压缩将根据 Accept-Encoding 请求标头激活。对于 identity,它不关心该标头。如果后端服务器支持 HTTP 压缩,这些指令将是无操作的:HAProxy 将看到压缩的响应,并且不会再次压缩。如果后端服务器不支持 HTTP 压缩且请求中存在 Accept-Encoding 标头,HAProxy 将压缩匹配的响应。在以下情况下禁用压缩: * 请求未在 "Accept-Encoding" 标头中通告支持的压缩算法 * 响应消息不是 HTTP/1.1 或更高版本 * HTTP 状态代码不是 200、201、202 或 203 之一 * 响应既不包含 "Content-Length" 标头,也不包含最后一个值为 "chunked" 的 "Transfer-Encoding" * 响应包含 "Content-Type" 标头,其第一个值以 "multipart" 开头 * 响应在 "Cache-control" 标头中包含 "no-transform" 值 * User-Agent 匹配 "Mozilla/4",除非它是带有 XP SP2 的 MSIE 6,或者是 MSIE 7 及更高版本 * 响应包含 "Content-Encoding" 标头,表明响应已压缩(请参阅 compression offload) * 响应包含无效的 "ETag" 标头或多个 ETag 标头 注意:压缩不会发出 Warning 标头。
示例
compression algo gzip compression type text/html text/plain
使 HAProxy 仅作为压缩卸载器工作。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
"offload" 设置使 HAProxy 删除 Accept-Encoding 头,以防止后端服务器压缩响应。强烈建议不要这样做,因为这意味着所有的压缩工作都将在 HAProxy 所在的单点上完成。然而,在某些部署场景中,HAProxy 可能安装在一个有缺陷的网关前面,该网关的 HTTP 压缩实现有问题且无法关闭。在这种情况下,可以使用 HAProxy 来防止该网关发出无效的负载。在这种情况下,仅仅在配置中删除该头是行不通的,因为它在头被解析之前应用,这会阻止 HAProxy 进行压缩。因此,"offload" 设置应用于此类场景。如果在 defaults 部分中使用此设置,则会发出警告并忽略该选项。
使 haproxy 能够同时压缩请求和响应。有效值为 "request",仅压缩请求;"response",仅压缩响应;或 "both",当您想同时压缩两者时。默认值为 "response"。可在以下上下文中使用:http
cookie <名称> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <域名> ]* [ maxidle <空闲时间> ] [ maxlife <生命周期> ] [ dynamic ] [ attr <值> ]*
在后端启用基于 cookie 的持久性。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<name> 是将要监控、修改或插入以实现持久性的 cookie 的名称。此 cookie 通过响应中的 "Set-Cookie" 标头发送给客户端,并在所有请求中由客户端通过 "Cookie" 标头带回。应特别注意选择一个名称,该名称不会与任何可能的应用程序 cookie 冲突。此外,如果同一后端可能被同一客户端使用(例如 HTTP/HTTPS),如果不需要它们之间的持久性,则应注意在所有后端之间使用不同的 cookie 名称。 rewrite 此关键字指示 cookie 将由服务器提供,HAProxy 必须修改其值以在其中设置服务器的标识符。当将 "Set-cookie" 和 "Cache-control" 标头的复杂组合的管理留给应用程序时,此模式很方便。然后,应用程序可以决定是否适合发出持久性 cookie。由于必须监控所有响应,此模式在 HTTP 隧道模式下不起作用。除非应用程序行为非常复杂和/或损坏,否则建议不要在新部署中从这种模式开始。此关键字与 "insert" 和 "prefix" 不兼容。 insert 此关键字指示如果客户端尚未拥有允许其访问此服务器的有效 cookie,则 HAProxy 必须在服务器响应中插入持久性 cookie。当在没有 "preserve" 选项的情况下使用时,如果服务器发出具有相同名称的 cookie,它将在处理之前被删除。因此,此模式可用于升级在 "rewrite" 模式下运行的现有配置。cookie 将只是一个会话 cookie,不会存储在客户端的磁盘上。默认情况下,除非添加 "indirect" 选项,否则服务器将看到客户端发出的 cookie。由于缓存效应,通常明智的做法是添加 "nocache" 或 "postonly" 关键字(见下文)。"insert" 关键字与 "rewrite" 和 "prefix" 不兼容。 prefix 此关键字指示不是依赖于专用的持久性 cookie,而是将完成现有的 cookie。在某些特定环境中可能需要这样做,其中客户端不支持多个 cookie,并且应用程序已经需要它。在这种情况下,每当服务器设置名为 <name> 的 cookie 时,它将以服务器的标识符和分隔符作为前缀。前缀将从所有客户端请求中删除,以便服务器仍然找到它发出的 cookie。由于所有请求和响应都可能被修改,因此此模式不适用于隧道模式。"prefix" 关键字与 "rewrite" 和 "insert" 不兼容。注意:强烈建议不要将 "indirect" 与 "prefix" 一起使用,否则服务器 cookie 更新将不会发送给客户端。 indirect 指定此选项时,不会向已拥有用于处理请求的服务器的有效 cookie 的客户端发出 cookie。如果服务器本身设置了此类 cookie,则除非同时设置了 "preserve" 选项,否则将删除该 cookie。在 "insert" 模式下,这还将从传输到服务器的请求中删除 cookie,从而使持久性机制从应用程序的角度来看完全透明。注意:强烈建议不要将 "indirect" 与 "prefix" 一起使用,否则服务器 cookie 更新将不会发送给客户端。 nocache 在与 insert 模式结合使用时,如果客户端和 HAProxy 之间存在缓存,则建议使用此选项,因为它确保如果需要插入 cookie,可缓存的响应将被标记为不可缓存。这很重要,因为如果所有持久性 cookie 都添加在可缓存的主页上,例如,所有客户都将从外部缓存中获取该页面,并且都将共享相同的持久性 cookie,导致一个服务器接收的流量比其他服务器多得多。另请参阅 "insert" 和 "postonly" 选项。 postonly 此选项确保仅对 POST 请求的响应执行 cookie 插入。它是 "nocache" 选项的替代方案,因为 POST 响应不可缓存,因此这确保了持久性 cookie 永远不会被缓存。由于大多数站点在第一次 POST(通常是登录请求)之前不需要任何形式的持久性,因此这是一种优化缓存而不会冒在缓存中找到持久性 cookie 风险的非常有效的方法。另请参阅 "insert" 和 "nocache" 选项。 preserve 此选项只能与 "insert" 和/或 "indirect" 一起使用。它允许服务器本身发出持久性 cookie。在这种情况下,如果在响应中找到 cookie,HAProxy 将保留它不变。这对于例如在注销请求后结束持久性很有用。为此,服务器只需发出一个具有无效值(例如空)或过去日期的 cookie。通过将此机制与 "disable-on-404" 检查选项结合使用,可以执行完全优雅的关闭,因为用户在注销后肯定会离开服务器。 httponly 此选项告诉 HAProxy 在插入 cookie 时添加 "HttpOnly" cookie 属性。此属性用于使用户代理不与非 HTTP 组件共享 cookie。请查看 RFC6265 以获取有关此属性的更多信息。 secure 此选项告诉 HAProxy 在插入 cookie 时添加 "Secure" cookie 属性。此属性用于使用户代理永远不会通过非安全通道发出此 cookie,这意味着使用此标志学习的 cookie 将仅通过 SSL/TLS 连接呈现。请查看 RFC6265 以获取有关此属性的更多信息。 domain 此选项允许指定插入 cookie 的域。它需要恰好一个参数:一个有效的域名。如果域以点开头,则允许浏览器将其用于以该名称结尾的任何主机。也可以通过多次调用此选项来指定多个域名。某些浏览器可能对域的数量有小的限制,因此在这样做时要小心。记录显示,向 MSIE 6 或 Firefox 2 发送 10 个域可以按预期工作。 maxidle 此选项允许在一些空闲时间后忽略插入的 cookie。它仅适用于 insert-mode cookie。当 cookie 发送给客户端时,也会发送发出此 cookie 的日期。在后续呈现此 cookie 时,如果日期早于参数指示的延迟(以秒为单位),则将忽略它。否则,如果需要在将响应发送给客户端时,它将被刷新。这对于防止从不关闭浏览器的用户在同一服务器上停留太长时间(例如,在集群大小更改后)特别有用。当设置此选项且 cookie 没有日期时,它始终被接受,但在响应中会刷新。这保持了管理员访问其站点的能力。将来超过 24 小时日期的 cookie 将被忽略。这样做可以让管理员修复时区问题,而不会冒将用户踢出站点的风险。 maxlife 此选项允许在一些生命周期后忽略插入的 cookie,无论它们是否在使用中。它仅适用于 insert mode cookie。当 cookie 第一次发送给客户端时,也会发送发出此 cookie 的日期。在后续呈现此 cookie 时,如果日期早于参数指示的延迟(以秒为单位),则将忽略它。如果请求中的 cookie 没有日期,它将被接受并设置日期。将来超过 24 小时日期的 cookie 将被忽略。这样做可以让管理员修复时区问题,而不会冒将用户踢出站点的风险。与 maxidle 相反,此值不会刷新,只有第一次访问日期才算数。maxidle 和 maxlife 可能同时使用。这对于防止从不关闭浏览器的用户在同一服务器上停留太长时间(例如,在集群大小更改后)特别有用。这比 maxidle 方法更强,因为它在某些绝对延迟后强制重新分派。 dynamic 激活动态 cookie。使用时,将为每个服务器动态创建一个会话 cookie,基于服务器的 IP 和端口,以及在 "dynamic-cookie-key" 后端指令中指定的密钥。每次 IP 地址更改时,cookie 都会重新生成,并且仅针对 IPv4/IPv6 生成。 attr 此选项告诉 HAProxy 在插入 cookie 时添加额外的属性。属性值可以包含除控制字符或 ";" 以外的任何字符。此选项可以重复。
每个 HTTP 后端只能有一个持久性 cookie,并且可以在 defaults 部分中声明。cookie 的值将是 "server" 语句中 "cookie" 关键字后面指示的值。如果未为给定服务器声明 cookie,则不会设置 cookie。
示例
cookie JSESSIONID prefix cookie SRV insert indirect nocache cookie SRV insert postonly indirect cookie SRV insert indirect nocache maxidle 30m maxlife 8h
declare capture [ request | response ] len <length>
声明一个捕获槽。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<length> 是允许捕获的长度。
此声明仅在 frontend 或 listen 配置段中可用,但保留的槽可以在 backend 中使用。“request”关键字分配一个用于请求中的捕获槽,“response”分配一个用于响应中的捕获槽。
更改后端中服务器的默认选项。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<param*> 是此服务器的参数列表。“default-server”关键字接受大量选项,并有专门的完整章节介绍。更多详情请参阅 第 5 节
示例
default-server inter 1000 weight 13
default_backend <backend>
指定当没有匹配的 “use_backend” 规则时使用的后端。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<backend> 是要使用的后端的名称。
在使用“use_backend”关键字在前端和后端之间进行内容切换时,指明在没有规则匹配时将使用哪个后端通常很有用。这通常是动态后端,它将捕获所有未确定的请求。
示例
use_backend dynamic if url_dyn use_backend static if url_css url_img extension_img default_backend dynamic
description <string>
描述一个 listen、frontend 或 backend。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
参数: string
允许添加一句话来在 HAProxy HTML 统计页面中描述相关对象。该描述将打印在其所描述对象名称的右侧。<string> 参数中的空格无需使用反斜杠转义。
禁用一个代理、前端或后端。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
"disabled" 关键字用于禁用实例,主要目的是释放侦听端口或暂时禁用服务。实例仍将创建并检查其配置,但它将以 "stopped" 状态创建,并在统计信息中显示为如此。它不会接收任何流量,也不会发送任何健康检查或日志。可以通过在 "defaults" 部分中添加 "disabled" 关键字来一次禁用多个实例。
dispatch <address>:<port>
设置一个默认服务器地址。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<address> 是默认服务器的 IPv4 地址。或者,也支持可解析的主机名,但此名称将在启动期间解析。<ports> 是一个强制性的端口规范。所有连接都将发送到此端口,并且不允许像普通服务器那样使用端口偏移量。
dispatch”关键字指定一个默认服务器,用于在没有其他服务器可以接收连接时使用。过去,它被用来将非持久性连接转发到一个辅助负载均衡器。由于其语法简单,它也被用于简单的 TCP 中继。为了更清晰,建议不要使用它,而是使用“server”指令。
dynamic-cookie-key <字符串>
为后端设置动态 cookie 的密钥。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数: 要使用的密钥。
当启用动态 cookie 时(参见 cookie 的 "dynamic" 指令),会为每个服务器创建一个动态 cookie(除非在“server”行上明确指定了一个),使用服务器的 IP 地址、TCP 端口和密钥的哈希值。这样,我们可以确保跨多个负载均衡器的会话持久性,即使服务器是动态添加或删除的。
启用一个代理、前端或后端。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
"enabled" 关键字用于显式启用实例,当 defaults 已设置为 "disabled" 时。这很少使用。
errorfile <code> <file>
返回文件内容,而不是由 HAProxy 生成的错误。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<code> 是 HTTP 状态码。目前,HAProxy 能够生成的状态码有 200, 400, 401, 403, 404, 405, 407, 408, 410, 413, 425, 429, 500, 501, 502, 503, 和 504。 <file> 指定一个包含完整 HTTP 响应的文件。建议遵循惯例,在文件名后附加 ".http",这样人们就不会将响应与 HTML 错误页面混淆,并使用绝对路径,因为文件在执行任何 chroot 之前被读取。
重要的是要理解此关键字并非旨在重写服务器返回的错误,而是 HAProxy 检测到并返回的错误。这就是支持的错误列表仅限于一小部分的原因。代码 200 是为了响应与 "monitor-uri" 规则匹配的请求而发出的。文件在 HAProxy 启动时解析,并且必须根据 HTTP 规范有效。它们不应超过配置的缓冲区大小(BUFSIZE),通常为 16 kB,否则将返回内部错误。明智的做法是不要在其中放入任何对本地内容(例如图像)的引用,以避免当所有服务器都停机时,客户端和 HAProxy 之间发生循环,导致返回错误而不是图像。最后,响应不能超过 (tune.bufsize - tune.maxrewrite),以便 "http-after-response" 规则仍有操作空间(请参阅 "tune.maxrewrite")。文件在配置的同时读取并保存在内存中。因此,即使进程被 chrooted,错误也会继续返回,并且在进程运行时不会考虑任何文件更改。开发这些文件的一个简单方法是将它们与 403 状态代码相关联,并查询被阻止的 URL。
示例
errorfile 400 /etc/haproxy/errorfiles/400badreq.http errorfile 408 /dev/null # 解决 Chrome 预连接的 bug errorfile 403 /etc/haproxy/errorfiles/403forbid.http errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorfiles <名称> [<状态码> ...]
全部或部分地导入在 <name> http-errors 部分中定义的错误文件。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<name> 是一个已存在的 http-errors 段落的名称。<code> 是一个 HTTP 状态码。可以列出多个状态码。目前,HAProxy 能够生成的状态码有 200, 400, 401, 403, 404, 405, 407, 408, 410, 413, 425, 429, 500, 501, 502, 503, 和 504。
在 http-errors 部分中以名称 <name> 定义的错误将被导入到当前代理中。如果未指定状态码,则 http-errors 部分的所有错误文件都将被导入。否则,只有与所列状态码关联的错误文件才会被导入。这些错误文件会覆盖代理已定义的自定义错误。并且它们可能会被后续的错误文件覆盖。从功能上讲,这与使用 “errorfile” 指令手动声明所有错误文件完全相同。
示例
errorfiles generic errorfiles site-1 403 404
errorloc <code> <url>
errorloc302 <code> <url>
返回一个到 URL 的 HTTP 重定向,而不是由 HAProxy 生成的错误。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<code> 是 HTTP 状态码。目前,HAProxy 能够生成的状态码有 200, 400, 401, 403, 404, 405, 407, 408, 410, 413, 425, 429, 500, 501, 502, 503, 和 504。 <url> 是 "Location" 头的确切内容。它可以包含指向同一站点上错误页面的相对 URI,或者指向另一站点上错误页面的绝对 URI。应特别注意相对 URI,以避免在 URI 本身可能生成相同错误(例如 500)时发生重定向循环。
重要的是要理解,此关键字并非用于重写服务器返回的错误,而是用于重写 HAProxy 检测并返回的错误。这就是为什么支持的错误列表仅限于一小部分。状态码 200 是为响应匹配“monitor-uri”规则的请求而发出的。请注意,这两个关键字都返回 HTTP 302 状态码,它告诉客户端使用相同的 HTTP 方法获取指定的 URL。对于非 GET 方法(如 POST),这可能会很有问题,因为发送给客户端的 URL 可能不允许 GET 以外的方法。要解决此问题,请使用“errorloc303”,它会发送 HTTP 303 状态码,指示客户端必须使用 GET 请求获取该 URL。
errorloc303 <code> <url>
返回一个到 URL 的 HTTP 重定向,而不是由 HAProxy 生成的错误。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<code> 是 HTTP 状态码。目前,HAProxy 能够生成的状态码有 200, 400, 401, 403, 404, 405, 407, 408, 410, 413, 425, 429, 500, 501, 502, 503, 和 504。 <url> 是 "Location" 头的确切内容。它可以包含指向同一站点上错误页面的相对 URI,或者指向另一站点上错误页面的绝对 URI。应特别注意相对 URI,以避免在 URI 本身可能生成相同错误(例如 500)时发生重定向循环。
重要的是要理解,此关键字并非用于重写服务器返回的错误,而是用于重写 HAProxy 检测并返回的错误。这就是为什么支持的错误列表仅限于一小部分。状态码 200 是为响应匹配“monitor-uri”规则的请求而发出的。请注意,这两个关键字都返回 HTTP 303 状态码,它告诉客户端使用相同的 HTTP GET 方法获取指定的 URL。这解决了与“errorloc”和 302 状态码相关的常见问题。一些在 HTTP/1.1 之前设计的非常旧的浏览器可能不支持它,但到目前为止还没有报告过此类问题。
email-alert from <emailaddr>
声明在电子邮件警报的信封和标头中使用的发件人电子邮件地址。这是发送电子邮件警报的地址。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<emailaddr> 是发送电子邮件警报时使用的发件人电子邮件地址
还需要设置“email-alert mailers”和“email-alert to”,如果设置了,则为该代理启用电子邮件警报发送功能。
声明将发送电子邮件警报的消息的最大日志级别。这充当发送电子邮件警报的过滤器。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<level> 8 个 syslog 级别之一:emerg alert crit err warning notice info debug 以上 syslog 级别从低到高排序。
默认级别是 alert。还需要设置“email-alert from”、“email-alert mailers”和“email-alert to”,如果设置了,则为该代理启用电子邮件警报发送功能。在以下情况下会发送警报: * 一个未暂停的服务器被标记为 down 且 <level> 是 alert 或更低 * 一个已暂停的服务器被标记为 down 且 <level> 是 notice 或更低 * 一个服务器被标记为 up 或进入 drain 状态且 <level> 是 notice 或更低 * 启用了“option log-health-checks”,<level> 是 info 或更低,并且发生了健康检查状态更新
email-alert mailers <mailersect>
声明发送电子邮件警报时要使用的邮件发送器。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<mailersect> 是用于发送电子邮件警报的邮件程序部分的名称。
还需要设置“email-alert from”和“email-alert to”,如果设置了,则为该代理启用电子邮件警报发送功能。
声明与邮件发送器通信时使用的目标主机名地址。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<hostname> 是与邮件程序通信时使用的主机名
默认使用系统的主机名。还需要设置“email-alert from”、“email-alert mailers”和“email-alert to”,如果设置了,则为该代理启用电子邮件警报发送功能。
email-alert to <emailaddr>
声明电子邮件警报的信封中的收件人地址和标头中的收件人地址。这是发送电子邮件警报的目标地址。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<emailaddr> 是发送电子邮件警报时使用的收件人电子邮件地址
还需要设置“email-alert mailers”和“email-alert to”,如果设置了,则为该代理启用电子邮件警报发送功能。
指定在前端发生连接错误时要使用的日志格式字符串。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
该指令指定了用于包含与错误、超时、重试、重新分派或 HTTP 状态码 5xx 相关信息的日志的格式字符串。简而言之,此格式将用于所有会受 “log-separate-errors” 选项影响的日志行,包括在第 8.2.5 节中描述的连接错误。如果在 defaults 部分中使用该指令,所有后续的前端都将使用相同的日志格式。请参阅深入介绍自定义日志格式字符串的第 8.2.6 节。“error-log-format” 指令会覆盖之前的 “error-log-format” 指令。
force-persist { if | unless } <condition>
声明一个条件,以在服务器宕机时强制持久性。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
默认情况下,请求不会分派到停机的服务器。可以使用 "option persist" 强制执行此操作,但它是无条件的,如果设置了 "option redispatch",则会重新分派到有效的服务器。这使得很少有可能强制某些请求到达因维护操作而被人工标记为停机的服务器。"force-persist" 语句允许声明各种基于 ACL 的条件,当满足这些条件时,将导致请求忽略服务器的停机状态,并仍尝试连接到它。这使得启动服务器、仍对健康检查回复错误,并运行专门配置的浏览器来测试服务成为可能。在便捷方法中,可以使用特定的源 IP 地址或特定的 cookie。cookie 还有一个优点是可以在测试页面上轻松地在浏览器上添加/删除。一旦服务通过验证,就可以通过对健康检查返回有效响应来向全世界开放服务。当满足 "if" 条件时,或除非满足 "unless" 条件时,启用强制持久性。使用此功能时,始终禁用最终的重新分派。
filter <名称> [参数*]
将过滤器 <name> 添加到附加到代理的过滤器列表中。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
参数
<name> 是过滤器的名称。官方支持的过滤器在第 9 节中引用。<param*> 是过滤器 <name> 接受的参数列表。这些参数的解析是过滤器的责任。有关支持的参数的所有详细信息,请参阅相应过滤器(第 9 节)的文档。
对于同一个代理,可以多次使用 filter 行。如果需要,可以多次引用同一个过滤器。
示例
listen bind *:80 filter trace name BEFORE-HTTP-COMP filter compression filter trace name AFTER-HTTP-COMP compression algo gzip compression offload server srv1 192.168.0.1:80
fullconn <conns>
指定后端负载达到何种程度时,服务器将达到其 maxconn。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<conns> 是后端上的连接数,该连接数将使服务器使用最大连接数。
当服务器指定了 "maxconn" 参数时,这意味着其并发连接数永远不会更高。此外,如果它有 "minconn" 参数,则表示一个跟随后端负载的动态限制。然后,服务器将始终接受至少 <minconn> 个连接,永远不超过 <maxconn> 个连接,并且当后端具有少于 <conns> 个并发连接时,限制将在两个值之间平稳过渡。这使得在正常负载期间限制服务器上的负载成为可能,但在重要负载期间进一步推进,而不会在特殊负载期间使服务器过载。由于很难正确设置此值,HAProxy 会自动将其设置为所有可能分支到此后端的后端的前端 maxconn 总和的 10%(基于 "use_backend" 和 "default_backend" 规则)。这样,将其保留为未设置是安全的。但是,涉及动态名称的 "use_backend" 不会被计数,因为无法知道它们是否可能匹配。
示例
# 服务器将接受 100 到 1000 个并发连接 # 当后端达到 10000 个连接时,将达到 1000 的最大值。 backend dynamic fullconn 10000 server srv1 dyn1:80 minconn 100 maxconn 1000 server srv2 dyn2:80 minconn 100 maxconn 1000
为有界负载一致性哈希指定平衡因子。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

no

yes
参数
<factor> 是控制发送到服务器的最大并发请求数的参数,表示为所有活动服务器上平均并发请求数的百分比。
为具有 "hash-type consistent" 的服务器指定 "hash-balance-factor" 可启用一种算法,该算法可防止任何一台服务器一次接收过多请求,即使某些哈希桶接收的请求比其他桶多得多。将 <factor> 设置为 0(默认值)会禁用此功能。否则,<factor> 是一个大于 100 的百分比。例如,如果 <factor> 为 150,则不允许任何服务器的负载超过平均负载的 1.5 倍。如果使用服务器权重,它们将受到尊重。如果首选服务器被取消资格,算法将根据请求哈希选择另一台服务器,直到找到具有额外容量的服务器。较高的 <factor> 允许服务器之间存在更大的不平衡,而较低的 <factor> 意味着平均将检查更多服务器,从而影响性能。合理的值范围是 125 到 200。此设置也用于 "balance random",它在内部依赖于一致性哈希机制。
hash-type <method> <function> <modifier>
指定一种用于将哈希映射到服务器的方法。可在以下上下文中使用: tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<method> 是用于从 <function> 计算的哈希中选择服务器的方法: map-based 哈希表是一个包含所有活动服务器的静态数组。哈希将非常平滑,会考虑权重,但将是静态的,即服务器启动时权重的更改将被忽略。这意味着不会有慢启动。此外,由于服务器是根据其在数组中的位置选择的,因此当服务器计数更改时,大多数映射都会更改。这意味着当服务器启动或停机,或将服务器添加到集群时,大多数连接将被重新分配到不同的服务器。例如,这对于缓存可能不方便。 consistent 哈希表是一棵树,其中填充了每个服务器的许多出现。哈希键在树中查找,并选择最近的服务器。此哈希是动态的,它支持在服务器启动时更改权重,因此与慢启动功能兼容。它的优点是当服务器启动或停机时,只有其关联被移动。当将服务器添加到集群时,只有一小部分映射被重新分配,使其成为缓存的理想方法。然而,由于其原理,分布永远不会非常平滑,有时可能需要调整服务器的权重或 ID 才能获得更平衡的分布。为了在多个负载均衡器上获得相同的分布,重要的是所有服务器都具有完全相同的 ID。注意:如果未指定哈希函数,一致性哈希使用 sdbm 和 avalanche。 <function> 是要使用的哈希函数: sdbm 此函数最初是为 sdbm(ndbm 的公共领域重新实现)数据库库创建的。发现在打乱位方面表现良好,导致键的分布更好,分裂更少。它碰巧也是一个具有良好分布的良好通用哈希函数,除非总服务器权重是 64 的倍数,在这种情况下应用 avalanche 修饰符可能会有所帮助。 djb2 此函数多年前由 Dan Bernstein 在 comp.lang.c 上首次提出。研究表明,对于某些工作负载,此函数提供了比 sdbm 更好的分布。它通常适用于基于文本的输入,但对于纯数字输入或当总服务器权重是 33 的倍数时,它可能会表现极差,除非也使用了 avalanche 修饰符。 wt6 此函数是在过去测试其他函数时为 HAProxy 设计的。它不像其他函数那样平滑,但对输入数据集或服务器数量的敏感性要低得多。它可以作为 sdbm+avalanche 或 djb2+avalanche 的替代方案,用于一致性哈希或对数字数据(例如源 IP 地址或 URL 参数中的访问者标识符)进行哈希处理时。 crc32 这是最常见的 CRC32 实现,用于以太网、gzip、PNG 等。它比其他函数慢,但可能提供更好的分布或更不可预测的结果,尤其是在用于字符串时。 none 不对键进行哈希处理,键将用作哈希,这对于使用转换器手动哈希键并让 haproxy 直接使用结果很有用。 <modifier> 指示在哈希键后应用的可选方法: avalanche 此指令指示不应使用上面哈希函数的原始形式结果,而必须首先应用 4 字节的完整雪崩哈希。此步骤的目的是混合前一个哈希的结果位,以避免当输入包含一些有限值或服务器数量是哈希组件之一(SDBM 为 64,DJB2 为 33)的倍数时出现任何不良影响。启用 avalanche 倾向于使结果更不可预测,但也不如使用原始函数时平滑。可能需要对某些工作负载进行一些测试。此哈希是 Bob Jenkins 提出的众多哈希之一。
默认的哈希类型是“map-based”,建议在大多数情况下使用。默认的函数是“sdbm”,函数的选择应基于被哈希值的范围。
http-after-response <动作> <选项...> [ { if | unless } <条件> ]
对所有第 7 层响应(服务器、小程序/服务和内部响应)进行访问控制。可在以下上下文中使用: http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
http-after-response 语句定义了一组应用于第 7 层处理的规则。这些规则在前端、listen 或后端部分中遇到时按其声明顺序进行评估。由于这些规则应用于响应,因此首先应用后端规则,然后应用前端规则。任何规则都可以选择后跟基于 ACL 的条件,在这种情况下,只有当条件评估为真时才会评估该规则。与 http-response 规则不同,这些规则应用于所有响应,服务器响应以及 HAProxy 生成的所有响应。这些规则在响应分析结束时、数据转发阶段之前进行评估。条件在执行操作之前立即评估,并且操作仅执行一次。因此,如果操作更改了作为条件一部分检查的元素,则不会出现问题。这也意味着多个操作可能依赖于同一条件,因此更改条件评估的第一个操作足以隐式禁用其余操作。例如,当尝试在变量为空时从各种来源为其分配值时使用此方法。每个实例的 "http-after-response" 语句数量没有限制。语法中 "http-after-response" 之后的第一个关键字是规则的操作,可选后跟操作的各种参数。受支持的操作及其各自的语法在第 4.3 节“操作”(查找标记“HTTP Aft”的操作)中列举。此指令仅在命名 defaults 部分中可用,而不是匿名部分中可用。defaults 部分中定义的规则在关联的代理部分中的规则之前进行评估。为避免歧义,在这种情况下,具有前端功能的代理和具有后端功能的代理不能使用相同的 defaults 部分。这意味着 listen 部分不能使用定义此类规则的 defaults 部分。注意:在请求解析的早期阶段发出的错误由多路复用器在较低级别处理,在任何 http 分析之前。因此,不会对这些错误评估 http-after-response 规则集。
示例
http-after-response set-header Strict-Transport-Security "max-age=31536000" http-after-response set-header Cache-Control "no-store,no-cache,private" http-after-response set-header Pragma "no-cache"
http-check comment <字符串>
为接下来的 http-check 规则定义一个注释,如果失败,将在日志中报告。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<string> 是如果以下 http-check 规则失败时要在日志中添加的注释消息。
它仅适用于 connect、send 和 expect 规则。这对于进行用户友好的错误报告很有用。
http-check connect [default] [port <表达式>] [addr <ip>] [send-proxy] [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger] [proto <名称>] [comment <消息>]
打开一个新连接以执行 HTTP 健康检查。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义如果规则评估失败要报告的消息。 default 使用服务器行的默认选项进行健康检查。仅当未重新定义时才使用服务器选项。 port <expr> 如果未设置,则使用检查端口或服务器端口。它告诉 HAProxy 在哪里打开连接。<port> 必须是有效的 TCP 端口整数,从 1 到 65535 或样本获取表达式。 addr <ip> 定义要进行健康检查的 IP 地址。 send-proxy 发送 PROXY 协议字符串 via-socks4 使用上游 socks4 代理启用传出健康检查。 ssl 打开加密连接 sni <sni> 指定用于通过 SSL 进行健康检查的 SNI。 alpn <alpn> 定义要使用 ALPN 通告的协议。协议列表由逗号分隔的协议名称列表组成,例如:“h2,http/1.1”。如果未设置,则使用服务器 ALPN。 proto <name> 强制用于此连接的多路复用器协议。它必须是 HTTP mux 协议,并且必须在后端可用。可用协议列表在 haproxy -vv 中报告。 linger 干净地关闭连接,而不是使用单个 RST。
就像 tcp-check 健康检查一样,可以配置用于执行 HTTP 健康检查的连接。此指令也应用于描述涉及多个请求/响应交换的场景,可能在不同的端口上或与不同的服务器。当服务器行上既没有配置 TCP 端口,也没有服务器端口指令时,http-check 序列的第一步必须是使用 “http-check connect” 指定端口。在一个 http-check 规则集中,'connect' 是必需的,并且也必须以 'connect' 规则开始规则集。目的是确保管理员知道他们在做什么。当一个 connect 必须开始规则集时,它前面仍然可以有 set-var、unset-var 或 comment 规则。
示例
# 检查服务器上的 HTTP 和 HTTPs 服务。 # 首先通过服务器行端口指令打开端口 80,然后 # tcp-check 打开端口 443,加密并在其上运行请求: option httpchk http-check connect http-check send meth GET uri / ver HTTP/1.1 hdr host haproxy.1wt.eu http-check expect status 200-399 http-check connect port 443 ssl sni haproxy.1wt.eu http-check send meth GET uri / ver HTTP/1.1 hdr host haproxy.1wt.eu http-check expect status 200-399 server www 10.0.0.1 check port 80
在健康检查响应为 HTTP/404 时启用维护模式。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当设置此选项时,返回 HTTP 404 状态码的服务器将从后续的负载均衡中排除,但仍会接收持久连接。这为 Web 管理员提供了一种非常方便的方法来对其服务器进行平滑关闭。同样重要的是要注意,在此模式下被检测为失败的服务器不会生成警报,只会生成一个通知。如果服务器再次响应 2xx 或 3xx,它将立即重新插入到服务器场中。统计页面上的状态为此模式下的服务器报告为 "NOLB"。重要的是要注意,此选项仅与 “httpchk” 选项一起使用。如果此选项与 “http-check expect” 一起使用,则它优先于后者,因此 404 响应仍将被视为软停止。还要注意,已停止的服务器即使响应 404s 也会保持停止状态。此选项仅对正在运行的服务器进行评估。
http-check expect [min-recv <整数>] [comment <消息>] [ok-status <状态>] [error-status <状态>] [tout-status <状态>] [on-success <格式>] [on-error <格式>] [status-code <表达式>] [!] <匹配> <模式>
使 HTTP 健康检查考虑响应内容或特定状态码。可在以下上下文中使用: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义如果规则评估失败要报告的消息。 min-recv 是可选的,可以定义评估当前 expect 规则所需的最小数据量。如果接收到的字节数低于此限制,检查将等待更多数据。此选项可用于解决一些模糊的匹配规则,或避免对已知仍不完整的内容执行代价高昂的 regex 匹配。如果使用精确字符串,则使用字符串长度和此参数之间的最小值。如果此参数设置为 -1,则忽略它。如果 expect 规则不匹配,检查将等待更多数据。如果设置为 0,则评估结果始终是结论性的。 ok-status <st> 是可选的,可用于设置检查状态,如果 expect 规则成功评估,并且它是 tcp-check 规则集中的最后一条规则。"L7OK"、"L7OKC"、"L6OK" 和 "L4OK" 受支持: - L7OK:检查通过第 7 层 - L7OKC:检查有条件地通过第 7 层,将服务器设置为 NOLB 状态。 - L6OK:检查通过第 6 层 - L4OK:检查通过第 4 层 默认使用 "L7OK"。 error-status <st> 是可选的,可用于设置检查状态,如果在 expect 规则评估期间发生错误。"L7OKC"、"L7RSP"、"L7STS"、"L6RSP" 和 "L4CON" 受支持: - L7OKC:检查有条件地通过第 7 层,将服务器设置为 NOLB 状态。 - L7RSP:第 7 层无效响应 - 协议错误 - L7STS:第 7 层响应错误,例如 HTTP 5xx - L6RSP:第 6 层无效响应 - 协议错误 - L4CON:第 1-4 层连接问题 默认使用 "L7RSP"。 tout-status <st> 是可选的,可用于设置检查状态,如果在 expect 规则评估期间发生超时。"L7TOUT"、"L6TOUT" 和 "L4TOUT" 受支持: - L7TOUT:第 7 层(HTTP/SMTP)超时 - L6TOUT:第 6 层(SSL)超时 - L4TOUT:第 1-4 层超时 默认使用 "L7TOUT"。 on-success <fmt> 是可选的,可用于自定义日志中报告的信息消息,如果 expect 规则成功评估,并且它是 tcp-check 规则集中的最后一条规则。<fmt> 是一个 log-format 字符串。 on-error <fmt> 是可选的,可用于自定义日志中报告的信息消息,如果在 expect 规则评估期间发生错误。<fmt> 是一个 log-format 字符串。 <match> 是一个关键字,指示如何在响应中查找特定模式。关键字可以是 "status"、"rstatus"、"hdr"、"fhdr"、"string" 或 "rstring" 之一。关键字前面可以带有一个感叹号 ("!") 来否定匹配。感叹号和关键字之间允许有空格。有关支持的关键字的更多详细信息,请参见下文。 <pattern> 是要查找的模式。它可以是字符串、正则表达式或具有多个参数的更复杂模式。如果字符串模式包含空格,则必须使用通常的反斜杠 ('\') 进行转义。
By default, "option httpchk" considers that response statuses 2xx and 3xx are valid, and that others are invalid. When "http-check expect" is used, it defines what is considered valid or invalid. Only one "http-check" statement is supported in a backend. If a server fails to respond or times out, the check obviously fails. The available matches are : status <codes> : test the status codes found parsing <codes> string. it must be a comma-separated list of status codes or range codes. A health check response will be considered as valid if the response's status code matches any status code or is inside any range of the list. If the "status" keyword is prefixed with "!", then the response will be considered invalid if the status code matches. rstatus <regex> : test a regular expression for the HTTP status code. A health check response will be considered valid if the response's status code matches the expression. If the "rstatus" keyword is prefixed with "!", then the response will be considered invalid if the status code matches. This is mostly used to check for multiple codes. hdr { name | name-lf } [ -m <meth> ] <name> [ { value | value-lf } [ -m <meth> ] <value> : test the specified header pattern on the HTTP response headers. The name pattern is mandatory but the value pattern is optional. If not specified, only the header presence is verified. <meth> is the matching method, applied on the header name or the header value. Supported matching methods are "str" (exact match), "beg" (prefix match), "end" (suffix match), "sub" (substring match) or "reg" (regex match). If not specified, exact matching method is used. If the "name-lf" parameter is used, <name> is evaluated as a log-format string. If "value-lf" parameter is used, <value> is evaluated as a log-format string. These parameters cannot be used with the regex matching method. Finally, the header value is considered as comma-separated list. Note that matchings are case insensitive on the header names. fhdr { name | name-lf } [ -m <meth> ] <name> [ { value | value-lf } [ -m <meth> ] <value> : test the specified full header pattern on the HTTP response headers. It does exactly the same than "hdr" keyword, except the full header value is tested, commas are not considered as delimiters. string <string> : test the exact string match in the HTTP response body. A health check response will be considered valid if the response's body contains this exact string. If the "string" keyword is prefixed with "!", then the response will be considered invalid if the body contains this string. This can be used to look for a mandatory word at the end of a dynamic page, or to detect a failure when a specific error appears on the check page (e.g. a stack trace). rstring <regex> : test a regular expression on the HTTP response body. A health check response will be considered valid if the response's body matches this expression. If the "rstring" keyword is prefixed with "!", then the response will be considered invalid if the body matches the expression. This can be used to look for a mandatory word at the end of a dynamic page, or to detect a failure when a specific error appears on the check page (e.g. a stack trace). string-lf <fmt> : test a log-format string match in the HTTP response body. A health check response will be considered valid if the response's body contains the string resulting of the evaluation of <fmt>, which follows the log-format rules. If prefixed with "!", then the response will be considered invalid if the body contains the string. It is important to note that the responses will be limited to a certain size defined by the global "tune.bufsize" option, which defaults to 16384 bytes. Thus, too large responses may not contain the mandatory pattern when using "string" or "rstring". If a large response is absolutely required, it is possible to change the default max size by setting the global variable. However, it is worth keeping in mind that parsing very large responses can waste some CPU cycles, especially when regular expressions are used, and that it is always better to focus the checks on smaller resources. In an http-check ruleset, the last expect rule may be implicit. If no expect rule is specified after the last "http-check send", an implicit expect rule is defined to match on 2xx or 3xx status codes. It means this rule is also defined if there is no "http-check" rule at all, when only "option httpchk" is set. Last, if "http-check expect" is combined with "http-check disable-on-404", then this last one has precedence when the server responds with 404.
示例
# 只接受状态码 200 为有效 http-check expect status 200,201,300-310 # 确保设置了 sessid cookie http-check expect header name "set-cookie" value -m beg "sessid=" # 将 SQL 错误视为错误 http-check expect ! string SQL\ Error # 仅将 5xx 状态码视为错误 http-check expect ! rstatus ^5 # 检查在 /html 之前是否有正确的十六进制标签 http-check expect rstring <!--tag:[0-9a-f]*--></html>
http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>] [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }] [comment <msg>]
向 HTTP 健康检查期间发送的请求添加可能的头列表和/或主体。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> defines a message to report if the rule evaluation fails. meth <method> is the optional HTTP method used with the requests. When not set, the "OPTIONS" method is used, as it generally requires low server processing and is easy to filter out from the logs. Any method may be used, though it is not recommended to invent non-standard ones. uri <uri> is optional and set the URI referenced in the HTTP requests to the string <uri>. It defaults to "/" which is accessible by default on almost any server, but may be changed to any other URI. Query strings are permitted. uri-lf <fmt> is optional and set the URI referenced in the HTTP requests using the log-format string <fmt>. It defaults to "/" which is accessible by default on almost any server, but may be changed to any other URI. Query strings are permitted. ver <version> is the optional HTTP version string. It defaults to "HTTP/1.0" but some servers might behave incorrectly in HTTP 1.0, so turning it to HTTP/1.1 may sometimes help. Note that the Host field is mandatory in HTTP/1.1, use "hdr" argument to add it. hdr <name> <fmt> adds the HTTP header field whose name is specified in <name> and whose value is defined by <fmt>, which follows to the log-format rules. body <string> add the body defined by <string> to the request sent during HTTP health checks. If defined, the "Content-Length" header is thus automatically added to the request. body-lf <fmt> add the body defined by the log-format string <fmt> to the request sent during HTTP health checks. If defined, the "Content-Length" header is thus automatically added to the request.
In addition to the request line defined by the "option httpchk" directive, this one is the valid way to add some headers and optionally a body to the request sent during HTTP health checks. If a body is defined, the associate "Content-Length" header is automatically added. Thus, this header or "Transfer-encoding" header should not be present in the request provided by "http-check send". If so, it will be ignored. The old trick consisting to add headers after the version string on the "option httpchk" line is now deprecated. Also "http-check send" doesn't support HTTP keep-alive. Keep in mind that it will automatically append a "Connection: close" header, unless a Connection header has already already been configured via a hdr entry. Note that the Host header and the request authority, when both defined, are automatically synchronized. It means when the HTTP request is sent, when a Host is inserted in the request, the request authority is accordingly updated. Thus, don't be surprised if the Host header value overwrites the configured request authority. Note also for now, no Host header is automatically added in HTTP/1.1 or above requests. You should add it explicitly.
在 HTTP 健康检查中启用状态头的发送。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
When this option is set, HAProxy will systematically send a special header "X-Haproxy-Server-State" with a list of parameters indicating to each server how they are seen by HAProxy. This can be used for instance when a server is manipulated without access to HAProxy and the operator needs to know whether HAProxy still sees it up or not, or if the server is the last one in a farm. The header is composed of fields delimited by semi-colons, the first of which is a word ("UP", "DOWN", "NOLB"), possibly followed by a number of valid checks on the total number before transition, just as appears in the stats interface. Next headers are in the form "<variable>=<value>", indicating in no specific order some values available in the stats interface : - a variable "address", containing the address of the backend server. This corresponds to the <address> field in the server declaration. For unix domain sockets, it will read "unix". - a variable "port", containing the port of the backend server. This corresponds to the <port> field in the server declaration. For unix domain sockets, it will read "unix". - a variable "name", containing the name of the backend followed by a slash ("/") then the name of the server. This can be used when a server is checked in multiple backends. - a variable "node" containing the name of the HAProxy node, as set in the global "node" variable, otherwise the system's hostname if unspecified. - a variable "weight" indicating the weight of the server, a slash ("/") and the total weight of the farm (just counting usable servers). This helps to know if other servers are available to handle the load when this one fails. - a variable "scur" indicating the current number of concurrent connections on the server, followed by a slash ("/") then the total number of connections on all servers of the same backend. - a variable "qcur" indicating the current number of requests in the server's queue. Example of a header received by the application server : >>> X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; \ scur=13/22; qcur=0
http-check set-var(<var-name>[,<cond>...]) <expr>
http-check set-var-fmt(<var-name>[,<cond>...]) <fmt>
此操作设置变量的内容。变量是内联声明的。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<var-name> 变量的名称以其作用域的指示开头。http-check 允许的作用域有: “proc”:变量在整个进程中共享。 “sess”:变量在 tcp-check 会话中共享。 “check”:变量在 tcp-check 的生命周期内声明。 此前缀后跟一个名称。分隔符是‘.’。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '-'。 <cond> 一组必须全部为真才能实际设置变量的条件(例如“ifnotempty”、“ifgt”...)。有关可能条件的完整列表,请参阅 set-var 转换器的描述。 <expr> 是一个样本获取表达式,可能后跟转换器。 <fmt> 这是使用日志格式规则表示的值(请参阅第 8.2.6 节中的自定义日志格式)。
示例
http-check set-var(check.port) int(1234) http-check set-var-fmt(check.port) "name=%H"
在其作用域内释放对变量的引用。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<var-name> 变量的名称以其作用域的指示开头。http-check 允许的作用域有: “proc”:变量在整个进程中共享。 “sess”:变量在 tcp-check 会话中共享。 “check”:变量在 tcp-check 的生命周期内声明。 此前缀后跟一个名称。分隔符是‘.’。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '-'。
示例
http-check unset-var(check.port)
http-error status <code> [content-type <type>] [ { default-errorfiles | errorfile <file> | errorfiles <name> | file <file> | lf-file <file> | string <str> | lf-string <fmt> } ] [ hdr <name> <fmt> ]*
定义一个自定义错误消息,以替代 HAProxy 生成的错误。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
status <code> is the HTTP status code. It must be specified. Currently, HAProxy is capable of generating codes 200, 400, 401, 403, 404, 405, 407, 408, 410, 413, 425, 429, 500, 501, 502, 503, and 504. content-type <type> is the response content type, for instance "text/plain". This parameter is ignored and should be omitted when an errorfile is configured or when the payload is empty. Otherwise, it must be defined. default-errorfiles Reset the previously defined error message for current proxy for the status <code>. If used on a backend, the frontend error message is used, if defined. If used on a frontend, the default error message is used. errorfile <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. errorfiles <name> designates the http-errors section to use to import the error message with the status code <code>. If no such message is found, the proxy's error messages are considered. file <file> specifies the file to use as response payload. If the file is not empty, its content-type must be set as argument to "content-type", otherwise, any "content-type" argument is ignored. <file> is considered as a raw string. string <str> specifies the raw string to use as response payload. The content-type must always be set as argument to "content-type". lf-file <file> specifies the file to use as response payload. If the file is not empty, its content-type must be set as argument to "content-type", otherwise, any "content-type" argument is ignored. <file> is evaluated as a log-format string. lf-string <str> specifies the log-format string to use as response payload. The content-type must always be set as argument to "content-type". hdr <name> <fmt> adds to the response the HTTP header field whose name is specified in <name> and whose value is defined by <fmt>, which follows to the log-format rules. This parameter is ignored if an errorfile is used.
This directive may be used instead of "errorfile", to define a custom error message. As "errorfile" directive, it is used for errors detected and returned by HAProxy. If an errorfile is defined, it is parsed when HAProxy starts and must be valid according to the HTTP standards. The generated response must not exceed the configured buffer size (BUFFSIZE), otherwise an internal error will be returned. Finally, if you consider to use some http-after-response rules to rewrite these errors, the reserved buffer space should be available (see "tune.maxrewrite"). The files are read at the same time as the configuration and kept in memory. For this reason, the errors continue to be returned even when the process is chrooted, and no file change is considered while the process is running. Note: 400/408/500 errors emitted in early stage of the request parsing are handled by the multiplexer at a lower level. No custom formatting is supported at this level. Thus only static error messages, defined with "errorfile" directive, are supported. However, this limitation only exists during the request headers parsing or between two transactions.
http-request <action> [options...] [ { if | unless } <condition> ]
第 7 层请求的访问控制 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
The http-request statement defines a set of rules which apply to layer 7 processing. The rules are evaluated in their declaration order when they are met in a frontend, listen or backend section. Any rule may optionally be followed by an ACL-based condition, in which case it will only be evaluated if the condition evaluates to true. The condition is evaluated just before the action is executed, and the action is performed exactly once. As such, there is no problem if an action changes an element which is checked as part of the condition. This also means that multiple actions may rely on the same condition so that the first action that changes the condition's evaluation is sufficient to implicitly disable the remaining actions. This is used for example when trying to assign a value to a variable from various sources when it's empty. There is no limit to the number of "http-request" statements per instance. The first keyword after "http-request" in the syntax is the rule's action, optionally followed by a varying number of arguments for the action. The supported actions and their respective syntaxes are enumerated in section 4.3 "Actions" (look for actions which tick "HTTP Req"). This directive is only available from named defaults sections, not anonymous ones. Rules defined in the defaults section are evaluated before ones in the associated proxy section. To avoid ambiguities, in this case the same defaults section cannot be used by proxies with the frontend capability and by proxies with the backend capability. It means a listen section cannot use a defaults section defining such rules.
示例
acl nagios src 192.168.129.3 acl local_net src 192.168.0.0/16 acl auth_ok http_auth(L1) http-request allow if nagios http-request allow if local_net auth_ok http-request auth realm Gimme if local_net auth_ok http-request deny
示例
acl key req.hdr(X-Add-Acl-Key) -m found acl add path /addacl acl del path /delacl acl myhost hdr(Host) -f myhost.lst http-request add-acl(myhost.lst) %[req.hdr(X-Add-Acl-Key)] if key add http-request del-acl(myhost.lst) %[req.hdr(X-Add-Acl-Key)] if key del
示例
acl value req.hdr(X-Value) -m found acl setmap path /setmap acl delmap path /delmap use_backend bk_appli if { hdr(Host),map_str(map.lst) -m found } http-request set-map(map.lst) %[src] %[req.hdr(X-Value)] if setmap value http-request del-map(map.lst) %[src] if delmap
http-response <action> <options...> [ { if | unless } <condition> ]
第 7 层响应的访问控制 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
The http-response statement defines a set of rules which apply to layer 7 processing. The rules are evaluated in their declaration order when they are met in a frontend, listen or backend section. Since these rules apply on responses, the backend rules are applied first, followed by the frontend's rules. Any rule may optionally be followed by an ACL-based condition, in which case it will only be evaluated if the condition evaluates to true. The condition is evaluated just before the action is executed, and the action is performed exactly once. As such, there is no problem if an action changes an element which is checked as part of the condition. This also means that multiple actions may rely on the same condition so that the first action that changes the condition's evaluation is sufficient to implicitly disable the remaining actions. This is used for example when trying to assign a value to a variable from various sources when it's empty. There is no limit to the number of "http-response" statements per instance. The first keyword after "http-response" in the syntax is the rule's action, optionally followed by a varying number of arguments for the action. The supported actions and their respective syntaxes are enumerated in section 4.3 "Actions" (look for actions which tick "HTTP Res"). This directive is only available from named defaults sections, not anonymous ones. Rules defined in the defaults section are evaluated before ones in the associated proxy section. To avoid ambiguities, in this case the same defaults section cannot be used by proxies with the frontend capability and by proxies with the backend capability. It means a listen section cannot use a defaults section defining such rules.
示例
acl key_acl res.hdr(X-Acl-Key) -m found acl myhost hdr(Host) -f myhost.lst http-response add-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl http-response del-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl
示例
acl value res.hdr(X-Value) -m found use_backend bk_appli if { hdr(Host),map_str(map.lst) -m found } http-response set-map(map.lst) %[src] %[res.hdr(X-Value)] if value http-response del-map(map.lst) %[src] if ! value
http-reuse { never | safe | aggressive | always }
声明如何在请求之间共享空闲的 HTTP 连接 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
By default, a connection established between HAProxy and the backend server which is considered safe for reuse is moved back to the server's idle connections pool so that any other request can make use of it. This is the "safe" strategy below. The argument indicates the desired connection reuse strategy : - "never" : idle connections are never shared between sessions. This mode may be enforced to cancel a different strategy inherited from a defaults section or for troubleshooting. For example, if an old bogus application considers that multiple requests over the same connection come from the same client and it is not possible to fix the application, it may be desirable to disable connection sharing in a single backend. An example of such an application could be an old HAProxy using cookie insertion in tunnel mode and not checking any request past the first one. - "safe" : this is the default and the recommended strategy. The first request of a session is always sent over its own connection, and only subsequent requests may be dispatched over other existing connections. This ensures that in case the server closes the connection when the request is being sent, the browser can decide to silently retry it. Since it is exactly equivalent to regular keep-alive, there should be no side effects. There is also a special handling for the connections using protocols subject to Head-of-line blocking (backend with h2 or fcgi). In this case, when at least one stream is processed, the used connection is reserved to handle streams of the same session. When no more streams are processed, the connection is released and can be reused. - "aggressive" : this mode may be useful in webservices environments where all servers are not necessarily known and where it would be appreciable to deliver most first requests over existing connections. In this case, first requests are only delivered over existing connections that have been reused at least once, proving that the server correctly supports connection reuse. It should only be used when it's sure that the client can retry a failed request once in a while and where the benefit of aggressive connection reuse significantly outweighs the downsides of rare connection failures. - "always" : this mode is only recommended when the path to the server is known for never breaking existing connections quickly after releasing them. It allows the first request of a session to be sent to an existing connection. This can provide a significant performance increase over the "safe" strategy when the backend is a cache farm, since such components tend to show a consistent behavior and will benefit from the connection sharing. It is recommended that the "http-keep-alive" timeout remains low in this mode so that no dead connections remain usable. In most cases, this will lead to the same performance gains as "aggressive" but with more risks. It should only be used when it improves the situation over "aggressive". When http connection sharing is enabled, a great care is taken to respect the connection properties and compatibility. Indeed, some properties are specific and it is not possibly to reuse it blindly. Those are the SSL SNI, source and destination address and proxy protocol block. A connection is reused only if it shares the same set of properties with the request. Also note that connections with certain bogus authentication schemes (relying on the connection) like NTLM are marked private if possible and never shared. This won't be the case however when using a protocol with multiplexing abilities and using reuse mode level value greater than the default "safe" strategy as in this case nothing prevents the connection from being already shared. A connection pool is involved and configurable with "pool-max-conn". Note: connection reuse improves the accuracy of the "server maxconn" setting, because almost no new connection will be established while idle connections remain available. This is particularly true with the "always" strategy. The rules to decide to keep an idle connection opened or to close it after processing are also governed by the "tune.pool-low-fd-ratio" (default: 20%) and "tune.pool-high-fd-ratio" (default: 25%). These correspond to the percentage of total file descriptors spent in idle connections above which haproxy will respectively refrain from keeping a connection opened after a response, and actively kill idle connections. Some setups using a very high ratio of idle connections, either because of too low a global "maxconn", or due to a lot of HTTP/2 or HTTP/3 traffic on the frontend (few connections) but HTTP/1 connections on the backend, may observe a lower reuse rate because too few connections are kept open. It may be desirable in this case to adjust such thresholds or simply to increase the global "maxconn" value. Similarly, when thread groups are explicitly enabled, it is important to understand that idle connections are only usable between threads from a same group. As such it may happen that unfair load between groups leads to more idle connections being needed, causing a lower reuse rate. The same solution may then be applied (increase global "maxconn" or increase pool ratios).
向请求添加服务器名称。使用由 <header> 给出的头字符串。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<header> 用于发送服务器名称的头字符串。
The "http-send-name-header" statement causes the header field named <header> to be set to the name of the target server at the moment the request is about to be sent on the wire. Any existing occurrences of this header are removed. Upon retries and redispatches, the header field is updated to always reflect the server being attempted to connect to. Given that this header is modified very late in the connection setup, it may have unexpected effects on already modified headers. For example using it with transport-level header such as connection, content-length, transfer-encoding and so on will likely result in invalid requests being sent to the server. Additionally it has been reported that this directive is currently being used as a way to overwrite the Host header field in outgoing requests; while this trick has been known to work as a side effect of the feature for some time, it is not officially supported and might possibly not work anymore in a future version depending on the technical difficulties this feature induces. A long-term solution instead consists in fixing the application which required this trick so that it binds to the correct host name.
id <value>
为代理设置一个持久 ID。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
参数:
为代理设置一个持久 ID。此 ID 必须是唯一的正数。如果未设置,将自动分配一个未使用的 ID。第一个分配的值将是 1。此 ID 当前仅在统计信息中返回。
ignore-persist { if | unless } <condition>
声明一个忽略持久性的条件。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
默认情况下,当启用 cookie 持久性时,每个包含该 cookie 的请求都是无条件持久的(假设目标服务器正常运行)。"ignore-persist" 语句允许声明各种基于 ACL 的条件,当满足这些条件时,请求将忽略持久性。这有时对于负载均衡静态文件的请求很有用,因为这些文件通常不需要持久性。这也可以用于完全禁用特定 User-Agent 的持久性(例如,某些网络爬虫机器人)。 当 "if" 条件满足时,或者除非 "unless" 条件满足时,持久性将被忽略。
示例
acl url_static path_beg /static /images /img /css acl url_static path_end .gif .png .jpg .css .js ignore-persist if url_static
load-server-state-from-file { global | local | none }
允许 HAProxy 的无缝重载。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
此指令将 HAProxy 指向一个文件,该文件中保存了先前运行进程的服务器状态。这样,在启动时,在处理流量之前,新进程可以像没有发生重载一样将旧状态应用于服务器。"load-server-state-from-file" 指令的目的是告诉 HAProxy 使用哪个文件。目前,只有 2 个参数,要么阻止加载状态,要么从包含所有后端和服务器的文件中加载状态。状态文件可以通过在 stats 套接字上运行 "show servers state" 命令并重定向输出来生成。该文件的格式是版本化的,并且非常具体。要理解它,请阅读 "show servers state" 命令的文档(管理指南第 9.3 章)。
参数
global 加载由名为 "server-state-file" 的全局指令指向的文件的内容。 local 如果设置了 "server-state-file-name" 指令,则加载其指向的文件的内容。如果未设置,则使用后端名称作为文件名。 none 不为此后端加载任何状态
注意:- 默认情况下,服务器的 IP 地址在重载时会保留,但顺序可以通过服务器的“init-addr”设置来更改。这意味着在运行时通过 CLI 执行的 IP 地址更改将被保留,并且对本地解析器(例如 /etc/hosts)的任何更改可能不会有任何效果(如果正在使用状态文件)。- 除非在前一个和新的配置文件之间发生了变化,否则将应用前一个运行进程的服务器权重。
示例
最小配置
global stats socket /tmp/socket server-state-file /tmp/server_state defaults load-server-state-from-file global backend bk server s1 127.0.0.1:22 check weight 11 server s2 127.0.0.1:22 check weight 12
然后可以运行: socat /tmp/socket - <<< "show servers state" > /tmp/server_state 文件 /tmp/server_state 的内容将如下所示: 1 # <文档示例中省略了字段名称> 1 bk 1 s1 127.0.0.1 2 0 11 11 4 6 3 4 6 0 0 1 bk 2 s2 127.0.0.1 2 0 12 12 4 6 3 4 6 0 0
示例
最小配置
global stats socket /tmp/socket server-state-base /etc/haproxy/states defaults load-server-state-from-file local backend bk server s1 127.0.0.1:22 check weight 11 server s2 127.0.0.1:22 check weight 12
然后可以运行: socat /tmp/socket - <<< "show servers state bk" > /etc/haproxy/states/bk 文件 /etc/haproxy/states/bk 的内容将如下所示: 1 # <文档示例中省略了字段名称> 1 bk 1 s1 127.0.0.1 2 0 11 11 4 6 3 4 6 0 0 1 bk 2 s2 127.0.0.1 2 0 12 12 4 6 3 4 6 0 0
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]
启用每个实例的事件和流量日志记录。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
前缀:当必须清除记录器列表时,应使用 no。例如,如果您不想从默认记录器列表继承。此前缀不允许有参数。
参数
global should be used when the instance's logging parameters are the same as the global ones. This is the most common usage. "global" replaces <target>, <facility> and <level> with those of the log entries found in the "global" section. Only one "log global" statement may be used per instance, and this form takes no other parameter. <target> indicates where to send the logs. It takes the same format as for the "global" section's logs, and can be one of : - An IPv4 address optionally followed by a colon (':') and a UDP port. If no port is specified, 514 is used by default (the standard syslog port). - An IPv6 address followed by a colon (':') and optionally a UDP port. If no port is specified, 514 is used by default (the standard syslog port). - A filesystem path to a UNIX domain socket, keeping in mind considerations for chroot (be sure the path is accessible inside the chroot) and uid/gid (be sure the path is appropriately 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" formats 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. - A log backend in the form "backend@<name>", which will send log messages to the corresponding log backend responsible for sending the message to the proper server according to the backend's lb settings. A log backend is a backend section with "mode log" set (see "mode" for more information). - An explicit stream address prefix such as "tcp@","tcp6@", "tcp4@" or "uxst@" will allocate an implicit ring buffer with a stream forward server targeting the given address. 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. <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). <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). <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. <level> is optional and can be specified to filter outgoing messages. By default, all messages are sent. If a 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
重要的是要记住,是由前端决定要从连接中记录什么,并且在内容切换的情况下,来自后端的日志条目将被忽略。连接以 "info" 级别记录。然而,后端日志声明定义了服务器状态更改将如何以及在何处被记录。级别 "notice" 将用于指示服务器启动,"warning" 将用于终止信号和最终的服务终止,而 "alert" 将用于服务器宕机时。 注意:根据 RFC3164,消息在发出前会被截断为 1024 字节。
示例
log global log stdout format short daemon # 发送日志到 systemd log stdout format raw daemon # 发送所有内容到 stdout log stderr format raw daemon notice # 发送重要事件到 stderr log 127.0.0.1:514 local0 notice # 仅发送重要事件 log tcp@127.0.0.1:514 local0 notice notice # 相同但限制输出 # 级别并以 tcp 发送 log "${LOCAL_SYSLOG}:514" local0 notice # 发送到本地服务器
log-format <string>
Specifies the log format string to use for traffic logs May be used in the following contexts: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
此指令指定了将用于所有通过使用此行的前端的流量所产生的日志的日志格式字符串。如果该指令在 defaults 部分中使用,所有后续的前端将使用相同的日志格式。请参阅第 8.2.6 节,该节深入介绍了自定义日志格式字符串。也可以定义仅在连接错误情况下使用的特定日志格式,请参见 "error-log-format" 选项。"log-format" 指令会覆盖之前的 "option tcplog"、"log-format"、"option httplog" 和 "option httpslog" 指令。
log-format-sd <string>
Specifies the RFC5424 structured-data log format string May be used in the following contexts: tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
该指令指定了 RFC5424 结构化数据日志格式字符串,该字符串将用于所有通过使用此行的前端的流量产生的日志。如果该指令在 defaults 部分中使用,所有后续的前端将使用相同的日志格式。请参阅第 8.2.6 节,该节深入介绍了日志格式字符串。有关 RFC5424 结构化数据部分的更多信息,请参阅 https://tools.ietf.org/html/rfc5424#section-6.3。注意:此日志格式字符串仅用于将日志格式设置为“rfc5424”的记录器。
示例
log-format-sd [exampleSDID@1234\ bytes=\"%B\"\ status=\"%ST\"]
log-tag <string>
指定用于所有传出日志的日志标签。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
Sets the tag field in the syslog header to this string. It defaults to the log-tag set in the global section, otherwise 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, or to differentiate customer instances running in the same process. In the backend, logs about servers up/down will use this tag. As a hint, it can be convenient to set a log-tag related to a hosted customer in a defaults section then put all the frontends and backends for that customer, then start another customer in a new defaults section. See also the global "log-tag" directive.
设置用于维护 keep-alive 连接的最大服务器队列大小。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
HTTP keep-alive tries to reuse the same server connection whenever possible, but sometimes it can be counter-productive, for example if a server has a lot of connections while other ones are idle. This is especially true for static servers. The purpose of this setting is to set a threshold on the number of queued connections at which HAProxy stops trying to reuse the same server and prefers to find another one. The default value, -1, means there is no limit. A value of zero means that keep-alive requests will never be queued. For very close servers which can be reached with a low latency and which are not sensible to breaking keep-alive, a low value is recommended (e.g. local static server can use a value of 10 or less). For remote servers suffering from a high latency, higher values might be needed to cover for the latency and/or the cost of picking a different server. Note that this has no impact on responses which are maintained to the same server consecutively to a 401 response. They will still go to the same server even if they have to be queued.
设置我们可以为给定客户端会话保持空闲的最大传出连接数。默认值为 5(精确等于在构建时定义的 MAX_SRV_LIST)。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
maxconn <conns>
设置前端的最大并发连接数。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<conns> 是前端将接受服务的最大并发连接数。超出的连接将由系统在套接字的侦听队列中排队,并在一个连接关闭后得到服务。
If the system supports it, it can be useful on big sites to raise this limit very high so that HAProxy manages connection queues, instead of leaving the clients with unanswered connection attempts. This value should not exceed the global maxconn. Also, keep in mind that a connection contains two buffers of tune.bufsize (16kB by default) each, as well as some other data resulting in about 33 kB of RAM being consumed per established connection. That means that a medium system equipped with 1GB of RAM can withstand around 20000-25000 concurrent connections if properly tuned. Also, when <conns> is set to large values, it is possible that the servers are not sized to accept such loads, and for this reason it is generally wise to assign them some reasonable connection limits. When this value is set to zero, which is the default, the global "maxconn" value is used.
mode { tcp|http|log }
设置实例的运行模式或协议

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
tcp The instance will work in pure TCP mode. A full-duplex connection will be established between clients and servers, and no layer 7 examination will be performed. This is the default mode. It should be used for SSL, SSH, SMTP, ... http The instance will work in HTTP mode. The client request will be analyzed in depth before connecting to any server. Any request which is not RFC-compliant will be rejected. Layer 7 filtering, processing and switching will be possible. This is the mode which brings HAProxy most of its value. log When used in a backend section, it will turn the backend into a log backend. Such backend can be used as a log destination for any "log" directive by using the "backend@<name>" syntax. Log messages will be distributed to the servers from the backend according to the lb settings which can be configured using the "balance" keyword. Log backends support UDP servers by prefixing the server's address with the "udp@" prefix. Common backend and server features are supported, but not TCP or HTTP specific ones.
在进行内容切换时,前端和后端必须处于相同的模式(通常是 HTTP),否则配置将被拒绝。
示例
defaults http_instances mode http
monitor fail { if | unless } <condition>
添加一个条件,以便向监控 HTTP 请求报告失败。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
if <cond> 如果条件满足,监控请求将失败,否则将成功。该条件应描述一个组合测试,如果所有条件都满足,则必须导致失败,例如后端及其备份中的服务器数量都很少。 unless <cond> 只有当条件满足时,监控请求才会成功,否则将失败。这样的条件可以基于对后端列表中最小活动服务器数量的存在的测试。
This statement adds a condition which can force the response to a monitor request to report a failure. By default, when an external component queries the URI dedicated to monitoring, a 200 response is returned. When one of the conditions above is met, HAProxy will return 503 instead of 200. This is very useful to report a site failure to an external component which may base routing advertisements between multiple sites on the availability reported by HAProxy. In this case, one would rely on an ACL involving the "nbsrv" criterion. Note that "monitor fail" only works in HTTP mode. Both status messages may be tweaked using "errorfile" or "errorloc" if needed.
示例
frontend www mode http acl site_dead nbsrv(dynamic) lt 2 acl site_dead nbsrv(static) lt 2 monitor-uri /site_alive monitor fail if site_dead
拦截外部组件监控请求使用的 URI。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<uri> 是我们想要拦截以返回 HAProxy 健康状态而不是转发请求的确切 URI。
When an HTTP request referencing <uri> will be received on a frontend, HAProxy will not forward it nor log it, but instead will return either "HTTP/1.0 200 OK" or "HTTP/1.0 503 Service unavailable", depending on failure conditions defined with "monitor fail". This is normally enough for any front-end HTTP probe to detect that the service is UP and running without forwarding the request to a backend server. Note that the HTTP method, the version and all headers are ignored, but the request must at least be valid at the HTTP level. This keyword may only be used with an HTTP-mode frontend. Monitor requests are processed very early, just after the request is parsed and even before any "http-request". The only rulesets applied before are the tcp-request ones. They cannot be logged either, and it is the intended purpose. Only one URI may be configured for monitoring; when multiple "monitor-uri" statements are present, the last one will define the URI to be used. They are only used to report HAProxy's health to an upper component, nothing more. However, it is possible to add any number of conditions using "monitor fail" and ACLs so that the result can be adjusted to whatever check can be imagined (most often the number of available servers in a backend). Note: if <uri> starts by a slash ('/'), the matching is performed against the request's path instead of the request's uri. It is a workaround to let the HTTP/2 requests match the monitor-uri. Indeed, in HTTP/2, clients are encouraged to send absolute URIs only.
示例
# 使用 /haproxy_test 报告 HAProxy 的状态 frontend www mode http monitor-uri /haproxy_test
启用或禁用对队列中待处理的已中止请求的提前丢弃。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
In presence of very high loads, the servers will take some time to respond. The per-instance connection queue will inflate, and the response time will increase respective to the size of the queue times the average per-stream response time. When clients will wait for more than a few seconds, they will often hit the "STOP" button on their browser, leaving a useless request in the queue, and slowing down other users, and the servers as well, because the request will eventually be served, then aborted at the first error encountered while delivering the response. As there is no way to distinguish between a full STOP and a simple output close on the client side, HTTP agents should be conservative and consider that the client might only have closed its output channel while waiting for the response. However, this introduces risks of congestion when lots of users do the same, and is completely useless nowadays because probably no client at all will close the stream while waiting for the response. Some HTTP agents support this behavior (Squid, Apache, HAProxy), and others do not (TUX, most hardware-based load balancers). So the probability for a closed input channel to represent a user hitting the "STOP" button is close to 100%, and the risk of being the single component to break rare but valid traffic is extremely low, which adds to the temptation to be able to abort a stream early while still not served and not pollute the servers. In HAProxy, the user can choose the desired behavior using the option "abortonclose". By default (without the option) the behavior is HTTP compliant and aborted requests will be served. But when the option is specified, a stream with an incoming channel closed will be aborted while it is still possible, either pending in the queue for a connection slot, or during the connection establishment if the server has not yet acknowledged the connection request. This considerably reduces the queue size and the load on saturated servers when users are tempted to click on STOP, which in turn reduces the response time for other users. If this option has been enabled in a "defaults" section, it can be disabled in a specific instance by prepending the "no" keyword before it.
启用或禁用放宽 HTTP 请求解析。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
By default, HAProxy complies with the different HTTP RFCs in terms of message parsing. This means the message parsing is quite strict and causes an error to be returned to the client for malformed messages. This is the desired behavior as such malformed messages are essentially used to build attacks exploiting server weaknesses, and bypass security filtering. Sometimes, a buggy browser will not respect these RCFs for whatever reason (configuration, implementation...) and the issue will not be immediately fixed. In such case, it is possible to relax HAProxy's parser to accept some invalid requests by specifying this option. Most of rules concern the H1 parsing for historical reason. Newer HTTP versions tends to be cleaner and applications follow more stickly these protocols. When this option is set, the following rules are observed: * In H1 only, invalid characters, including NULL character, in header name will be accepted; * In H1 only, NULL character in header value will be accepted; * The list of characters allowed to appear in a URI is well defined by RFC3986, and chars 0-31, 32 (space), 34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'), 96 ('`'), 123 ('{'), 124 ('|'), 125 ('}'), 127 (delete) and anything above are normally not allowed. But here, in H1 only, HAProxy will only block a number of them (0..32, 127); * In H1 and H2, URLs containing fragment references ('#' after the path) will be accepted; * In H1 only, no check will be performed on the authority for CONNECT requests; * In H1 only, no check will be performed against the authority and the Host header value. * In H1 only, tests on the HTTP version will be relaxed. It will allow HTTP/0.9 GET requests to pass through (no version specified), as well as different protocol names (e.g. RTSP), and multiple digits for both the major and the minor version. This option should never be enabled by default as it hides application bugs and open security breaches. It should only be deployed after a problem has been confirmed. When this option is enabled, invalid but accepted H1 requests will be captured in order to permit later analysis using the "show errors" request on the UNIX stats socket.Doing this also helps confirming that the issue has been solved. If this option has been enabled in a "defaults" section, it can be disabled in a specific instance by prepending the "no" keyword before it.
启用或禁用放宽 HTTP 响应解析。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
Similarly to "option accept-invalid-http-request", this option may be used to relax parsing rules of HTTP responses. It should only be enabled for trusted legacy servers to accept some invalid responses. Most of rules concern the H1 parsing for historical reason. Newer HTTP versions tends to be cleaner and applications follow more stickly these protocols. When this option is set, the following rules are observed: * In H1 only, invalid characters, including NULL character, in header name will be accepted; * In H1 only, NULL character in header value will be accepted; * In H1 only, empty values or several "chunked" value occurrences for Transfer-Encoding header will be accepted; * In H1 only, no check will be performed against the authority and the Host header value. * In H1 only, tests on the HTTP version will be relaxed. It will allow different protocol names (e.g. RTSP), and multiple digits for both the major and the minor version. This option should never be enabled by default as it hides application bugs and open security breaches. It should only be deployed after a problem has been confirmed. When this option is enabled, erroneous header names will still be accepted in responses, but the complete response will be captured in order to permit later analysis using the "show errors" request on the UNIX stats socket. Doing this also helps confirming that the issue has been solved. If this option has been enabled in a "defaults" section, it can be disabled in a specific instance by prepending the "no" keyword before it.
选择一次性使用所有备份服务器,还是只使用第一个。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
默认情况下,当所有正常服务器都宕机时,第一个可用的备用服务器将获得所有流量。有时,可能希望一次使用多个备用服务器,因为一个可能不够用。当启用 "option allbackups" 时,当所有正常服务器都不可用时,将在所有备用服务器之间执行负载均衡。将使用相同的负载均衡算法,并遵守服务器的权重。因此,备用服务器之间将不再有任何优先级顺序。此选项主要用于专用于在应用程序完全离线时返回“抱歉”页面的静态服务器群。 如果此选项已在 "defaults" 部分中启用,可以通过在其前面添加 "no" 关键字来在特定实例中禁用它。
分析所有服务器响应并阻止带有可缓存 cookie 的响应。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
Some high-level frameworks set application cookies everywhere and do not always let enough control to the developer to manage how the responses should be cached. When a session cookie is returned on a cacheable object, there is a high risk of session crossing or stealing between users traversing the same caches. In some situations, it is better to block the response than to let some sensitive session information go in the wild. The option "checkcache" enables deep inspection of all server responses for strict compliance with HTTP specification in terms of cacheability. It carefully checks "Cache-control", "Pragma" and "Set-cookie" headers in server response to check if there's a risk of caching a cookie on a client-side proxy. When this option is enabled, the only responses which can be delivered to the client are : - all those without "Set-Cookie" header; - all those with a return code other than 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501, provided that the server has not set a "Cache-control: public" header field; - all those that result from a request using a method other than GET, HEAD, OPTIONS, TRACE, provided that the server has not set a 'Cache-Control: public' header field; - those with a 'Pragma: no-cache' header - those with a 'Cache-control: private' header - those with a 'Cache-control: no-store' header - those with a 'Cache-control: max-age=0' header - those with a 'Cache-control: s-maxage=0' header - those with a 'Cache-control: no-cache' header - those with a 'Cache-control: no-cache="set-cookie"' header - those with a 'Cache-control: no-cache="set-cookie,' header (allowing other fields after set-cookie) If a response doesn't respect these requirements, then it will be blocked just as if it was from an "http-response deny" rule, with an "HTTP 502 bad gateway". The session state shows "PH--" meaning that the proxy blocked the response during headers processing. Additionally, an alert will be sent in the logs so that admins are informed that there's something to be fixed. Due to the high impact on the application, the application should be tested in depth with the option enabled before going to production. It is also a good practice to always activate it during tests, even if it is not used in production, as it will report potentially dangerous application behaviors. If this option has been enabled in a "defaults" section, it can be disabled in a specific instance by prepending the "no" keyword before it.
启用或禁用在客户端发送 TCP keepalive 数据包。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
When there is a firewall or any session-aware component between a client and a server, and when the protocol involves very long sessions with long idle periods (e.g. remote desktops), there is a risk that one of the intermediate components decides to expire a session which has remained idle for too long. Enabling socket-level TCP keep-alives makes the system regularly send packets to the other end of the connection, leaving it active. The delay between keep-alive probes is controlled by the system only and depends both on the operating system and its tuning parameters. It is important to understand that keep-alive packets are neither emitted nor received at the application level. It is only the network stacks which sees them. For this reason, even if one side of the proxy already uses keep-alives to maintain its connection alive, those keep-alive packets will not be forwarded to the other side of the proxy. Please note that this has nothing to do with HTTP keep-alive. Using option "clitcpka" enables the emission of TCP keep-alive probes on the client side of a connection, which should help when session expirations are noticed between HAProxy and a client. If this option has been enabled in a "defaults" section, it can be disabled in a specific instance by prepending the "no" keyword before it.
启用持续的流量统计更新。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
默认情况下,用于统计计算的计数器仅在流结束时递增。这在处理小对象时效果很好,但对于大对象(例如大图片或存档)或音视频流,从 HAProxy 计数器生成的图表看起来像一只刺猬。启用此选项后,计数器会随着流的进行而频繁递增,通常每 5 秒一次,这通常足以生成清晰的图表。重新计数直接触及热路径,因此默认情况下未启用,因为它可能导致大量会话计数的唤醒,并导致轻微的性能下降。
启用或禁用从 HTTP/1.x 客户端连接的隐式 HTTP/2 升级。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
默认情况下,如果 HAProxy 从给定的 HTTP 连接收到的第一个请求与 HTTP/2 连接前言(即字符串 "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")匹配,HAProxy 能够将 HTTP/1.x 客户端连接隐式升级为 HTTP/2 连接。这样,就可以在非 SSL 连接上支持 HTTP/1.x 和 HTTP/2 客户端。必须使用此选项来禁用隐式升级。请注意,此隐式升级仅支持 HTTP 代理,因此此选项也一样。另请注意,可以通过在绑定行上指定 "proto h2" 来强制在明文连接上使用 HTTP/2。最后,此选项适用于所有绑定行。要为特定的绑定行禁用隐式 HTTP/2 升级,可以使用 "proto h1"。如果此选项已在“defaults”部分启用,则可以通过在其前面加上“no”关键字来在特定实例中禁用它。
启用或禁用对正常、成功的连接的日志记录。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
有些大型网站每秒处理数千个连接,日志记录对它们来说是一个主要的痛点。其中一些甚至被迫关闭日志,无法调试生产问题。设置此选项可确保正常的连接,即那些没有经历错误、超时、重试或重新分派的连接,将不会被记录。这为异常情况留下了磁盘空间。在 HTTP 模式下,会检查响应状态码,返回码为 5xx 的仍将被记录。 强烈建议不要使用此选项,因为大多数情况下,复杂问题的关键在于正常的日志中,而这些日志在这里不会被记录。如果您需要分离日志,请改用 "log-separate-errors" 选项。
启用或禁用对空连接的日志记录。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
在某些环境中,有些组件会定期连接到各种系统,以确保它们仍然存活。这可能是来自另一个负载均衡器以及监控系统的情况。默认情况下,即使是简单的端口探测或扫描也会产生一条日志。如果这些连接过多地污染了日志,可以启用选项“dontlognull”,以指示没有传输任何数据的连接将不会被记录,这通常对应于那些探测。请注意,错误仍将返回给客户端并在统计信息中计算。如果这不是期望的,可以使用 http-ignore-probes 选项。通常建议不要在不受控制的环境(例如互联网)中使用此选项,否则扫描和其他恶意活动将不会被记录。如果此选项已在“defaults”部分启用,则可以通过在其前面加上“no”关键字来在特定实例中禁用它。
option forwarded [ proto ] [ host | host-expr <host_expr> ] [ by | by-expr <by_expr> ] [ by_port | by_port-expr <by_port_expr>] [ for | for-expr <for_expr> ] [ for_port | for_port-expr <for_port_expr>]
启用在发送到服务器的请求中插入 rfc 7239 forwarded 头部。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<host_expr> 可选参数,用于指定一个自定义样本表达式,其结果将用作 'host' 参数值 <by_expr> 可选参数,用于指定一个自定义样本表达式,其结果将用作 'by' 参数的 nodename 值 <for_expr> 可选参数,用于指定一个自定义样本表达式,其结果将用作 'for' 参数的 nodename 值 <by_port_expr> 可选参数,用于指定一个自定义样本表达式,其结果将用作 'by' 参数的 nodeport 值 <for_port_expr> 可选参数,用于指定一个自定义样本表达式,其结果将用作 'for' 参数的 nodeport 值
Since HAProxy works in reverse-proxy mode, servers are losing some request context (request origin: client ip address, protocol used...) A common way to address this limitation is to use the well known x-forward-for and x-forward-* friends to expose some of this context to the underlying servers/applications. While this use to work and is widely deployed, it is not officially supported by the IETF and can be the root of some interoperability as well as security issues. To solve this, a new HTTP extension has been described by the IETF: forwarded header (RFC7239). More information here: https://www.rfc-editor.org/rfc/rfc7239.html The use of this single header allow to convey numerous details within the same header, and most importantly, fixes the proxy chaining issue. (the rfc allows for multiple chained proxies to append their own values to an already existing header). This option may be specified in defaults, listen or backend section, but it will be ignored for frontend sections. Setting option forwarded without arguments results in using default implicit behavior. Default behavior enables proto parameter and injects original client ip. The equivalent explicit/manual configuration would be: option forwarded proto for The keyword 'by' is used to enable 'by' parameter ("nodename") in forwarded header. It allows to embed request proxy information. 'by' value will be set to proxy ip (destination address) If not available (ie: UNIX listener), 'by' will be set to "unknown". The keyword 'by-expr' is used to enable 'by' parameter ("nodename") in forwarded header. It allows to embed request proxy information. 'by' value will be set to the result of the sample expression <by_expr>, if valid, otherwise it will be set to "unknown". The keyword 'for' is used to enable 'for' parameter ("nodename") in forwarded header. It allows to embed request client information. 'for' value will be set to client ip (source address) If not available (ie: UNIX listener), 'for' will be set to "unknown". The keyword 'for-expr' is used to enable 'for' parameter ("nodename") in forwarded header. It allows to embed request client information. 'for' value will be set to the result of the sample expression <for_expr>, if valid, otherwise it will be set to "unknown". The keyword 'by_port' is used to provide "nodeport" info to 'by' parameter. 'by_port' requires 'by' or 'by-expr' to be set or it will be ignored. "nodeport" will be set to proxy (destination) port if available, otherwise it will be ignored. The keyword 'by_port-expr' is used to provide "nodeport" info to 'by' parameter. 'by_port-expr' requires 'by' or 'by-expr' to be set or it will be ignored. "nodeport" will be set to the result of the sample expression <by_port_expr>, if valid, otherwise it will be ignored. The keyword 'for_port' is used to provide "nodeport" info to 'for' parameter. 'for_port' requires 'for' or 'for-expr' to be set or it will be ignored. "nodeport" will be set to client (source) port if available, otherwise it will be ignored. The keyword 'for_port-expr' is used to provide "nodeport" info to 'for' parameter. 'for_port-expr' requires 'for' or 'for-expr' to be set or it will be ignored. "nodeport" will be set to the result of the sample expression <for_port_expr>, if valid, otherwise it will be ignored.
示例
# Those servers want the ip address and protocol of the client request # Resulting header would look like this: # forwarded: proto=http;for=127.0.0.1 backend www_default mode http option forwarded #equivalent to: option forwarded proto for # Those servers want the requested host and hashed client ip address # as well as client source port (you should use seed for xxh32 if ensuring # ip privacy is a concern) # Resulting header would look like this: # forwarded: host="haproxy.org";for="_000000007F2F367E:60138" backend www_host mode http option forwarded host for-expr src,xxh32,hex for_port # Those servers want custom data in host, for and by parameters # Resulting header would look like this: # forwarded: host="host.com";by=_haproxy;for="[::1]:10" backend www_custom mode http option forwarded host-expr str(host.com) by-expr str(_haproxy) for for_port-expr int(10) # Those servers want random 'for' obfuscated identifiers for request # tracing purposes while protecting sensitive IP information # Resulting header would look like this: # forwarded: for=_000000002B1F4D63 backend www_for_hide mode http option forwarded for-expr rand,hex
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
启用向发送到服务器的请求中插入 X-Forwarded-For 头部。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<network> 是一个可选参数,用于对匹配 <network> 的源禁用此选项。<name> 是一个可选参数,用于指定一个不同的 "X-Forwarded-For" 头部名称。
由于 HAProxy 工作在反向代理模式下,服务器看到的客户端地址是 HAProxy 的 IP 地址。当服务器日志中需要客户端的 IP 地址时,这有时会很麻烦。为了解决这个问题,HAProxy 可能会向发送给服务器的所有请求添加众所周知的 HTTP 标头 "X-Forwarded-For"。此标头包含一个表示客户端 IP 地址的值。由于此标头始终附加到现有标头列表的末尾,因此必须将服务器配置为仅使用此标头的最后一次出现。请参阅服务器手册以了解如何启用此标准标头的使用。请注意,必须仅使用标头的最后一次出现,因为客户端确实有可能已经带有一个。关键字 "header" 可用于提供不同的标头名称来替换默认的 "X-Forwarded-For"。如果您已经有一个来自不同应用程序(例如 stunnel)的 "X-Forwarded-For" 标头,并且您需要保留它,这将非常有用。此外,如果您的后端服务器不使用 "X-Forwarded-For" 标头并且需要不同的标头(例如 Zeus Web Servers 需要 "X-Cluster-Client-IP")。有时,同一个 HAProxy 实例可能会在直接客户端访问和反向代理访问之间共享(例如,当使用 SSL 反向代理来解密 HTTPS 流量时)。可以通过添加 "except" 关键字后跟网络地址来禁用已知源地址或网络的标头添加。在这种情况下,任何匹配网络的源 IP 都不会导致添加此标头。最常见的用途是私有网络或 127.0.0.1。IPv4 和 IPv6 都受支持。或者,关键字 "if-none" 表示仅当标头不存在时才会添加标头。这应该只在完全受信任的环境中使用,因为如果到达 HAProxy 的标头受最终用户控制,这可能会导致安全问题。此选项可以在 frontend 或 backend 中指定。如果其中至少一个使用它,则会添加标头。请注意,如果同时定义了 backend 和 frontend,则 backend 中标头子参数的设置优先于 frontend。在 "if-none" 参数的情况下,如果 frontend 或 backend 中至少有一个没有指定它,则它希望添加是强制性的,因此它获胜。
示例
# 公共 HTTP 地址,也由同一台机器上的 stunnel 使用 frontend www mode http option forwardfor except 127.0.0.1 # stunnel 已经添加了该标头 # 这些服务器希望在 X-Client 中获取 IP 地址 backend www mode http option forwardfor header X-Client
启用或禁用发送给有问题的客户端的 HTTP/1 头部的大小写调整。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
标头名称没有标准大小写,因为正如 RFC7230 中所述,它们是不区分大小写的。因此,应用程序必须以不区分大小写的方式处理它们。但是一些错误的应用程序违反了标准,并错误地依赖于浏览器最常用的大小写。这个问题在 HTTP/2 中变得至关重要,因为所有标头名称都必须以小写形式交换,HAProxy 也遵循相同的约定。无论 HTTP 版本如何,所有标头名称都以小写形式发送给客户端和服务器。当 HAProxy 收到 HTTP/1 响应时,其标头名称会转换为小写,并以这种方式进行操作并发送给客户端。如果已知某个客户端违反了 HTTP 标准并且无法处理来自 HAProxy 的响应,则可以通过启用此选项并使用全局指令 "h1-case-adjust" 或 "h1-case-adjust-file" 指定要重新格式化的标头列表,在格式化响应并将其发送给客户端时,将小写标头名称转换为不同的格式。这只能作为在客户端修复之前的一种临时解决方法,因为需要此类解决方法的客户端可能容易受到内容走私攻击,并且必须绝对修复。请注意,此选项不会影响符合标准的客户端。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
启用或禁用发送给有问题的服务器的 HTTP/1 头部的大小写调整。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
标头名称没有标准大小写,因为正如 RFC7230 中所述,它们是不区分大小写的。因此,应用程序必须以不区分大小写的方式处理它们。但是一些错误的应用程序违反了标准,并错误地依赖于浏览器最常用的大小写。这个问题在 HTTP/2 中变得至关重要,因为所有标头名称都必须以小写形式交换,HAProxy 也遵循相同的约定。无论 HTTP 版本如何,所有标头名称都以小写形式发送给客户端和服务器。当 HAProxy 收到 HTTP/1 请求时,其标头名称会转换为小写,并以这种方式进行操作并发送给服务器。如果已知某个服务器违反了 HTTP 标准并且无法处理来自 HAProxy 的请求,则可以通过启用此选项并使用全局指令 "h1-case-adjust" 或 "h1-case-adjust-file" 指定要重新格式化的标头列表,在格式化请求并将其发送给服务器时,将小写标头名称转换为不同的格式。这只能作为在服务器修复之前的一种临时解决方法,因为需要此类解决方法的服务器可能容易受到内容走私攻击,并且必须绝对修复。请注意,此选项不会影响符合标准的服务器。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
启用或禁用在处理前等待整个 HTTP 请求体。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
有时,在做出决定之前等待 HTTP 请求的主体是可取的。例如,“balance url_param”就是这样做的。第一个用例是在连接到服务器之前缓冲来自慢速客户端的请求。另一个用例是基于请求主体的内容做出路由决策。此选项放置在前端或后端中,强制 HTTP 处理等待直到接收到整个主体或请求缓冲区已满。它可能与一些滥用 HTTP 的应用程序产生不希望的副作用,这些应用程序期望前端和后端之间有无缓冲的传输,因此绝对不应默认使用。
启用或禁用对空连接和请求超时的日志记录。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
最近一些浏览器开始实现“预连接”功能,即推测性地连接到一些最近访问过的网站,以防用户想要访问它们。这导致与网站建立了许多连接,如果超时先发生,则以 408 Request Timeout 结束,或者如果浏览器决定先关闭它们,则以 400 Bad Request 结束。这些会污染日志并增加错误计数器。已经有 "option dontlognull" 了,但在这种情况下它是不够的。相反,此选项执行以下操作: - 如果在连接关闭之前未收到任何内容,则阻止向客户端发送任何 400/408 消息; - 阻止在这种情况下发出任何日志; - 阻止任何错误计数器增加 这样,空连接就会被静默忽略。请注意,最好不要使用此选项,除非很明显需要它,因为它会隐藏真正的问题。未收到请求并看到 408 的最常见原因是客户端与 VPN 等中间元素之间的 MTU 不一致,这会阻止过大的数据包。这些问题通常出现在 POST 请求以及带有大 cookie 的 GET 请求中。日志通常是检测它们的唯一方法。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
为 HTTP/1.x 连接启用或禁用从客户端到服务器的 HTTP keep-alive。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
默认情况下,HAProxy 在处理持久 HTTP/1.x 连接时以 keep-alive 模式运行:对于每个连接,它处理每个请求和响应,并将连接在两端保持空闲状态。此模式可以通过多种选项更改,例如 "option http-server-close" 或 "option httpclose"。此选项允许重新设置 keep-alive 模式,当在 defaults 部分中使用另一种模式时,这会很有用。设置 "option http-keep-alive" 可在客户端和服务器端启用 HTTP keep-alive 模式。这可在客户端(慢速网络)提供最低延迟,并在服务器端提供最快的会话重用,但代价是维护与服务器的空闲连接。通常,对于小对象,此选项可以实现大约两倍于 "http-server-close" 选项实现的请求率。此选项主要在两种情况下可能有用: - 当服务器不符合 HTTP 规范并对连接而不是请求进行身份验证时(例如 NTLM 身份验证) - 当建立与服务器的连接的成本相对于从服务器检索相关对象的成本而言很高时。后一种情况可能发生在服务器是快速静态服务器或缓存时。目前,日志不会指示请求是否来自同一会话。日志中报告的接受日期对应于上一个请求的结束,请求时间对应于等待新请求所花费的时间。如果未设置,keep-alive 请求时间仍受限于 "timeout http-keep-alive" 或 "timeout http-request" 定义的超时。此选项禁用并替换任何先前的 "option httpclose" 或 "option http-server-close"。
指示系统在 HTTP 中优先考虑低交互延迟而不是性能。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
在 HTTP 中,每个有效负载都是单向的,没有交互性的概念。任何代理都应该将数据排队,以实现合理的低延迟。有一些非常罕见的服务器到服务器应用程序滥用 HTTP 协议,并期望有效负载阶段具有高度交互性,在单个请求中包含许多交错的双向数据块。HTTP 规范绝对不支持此功能,并且在大多数代理或服务器上不起作用。当此类应用程序尝试通过 HAProxy 执行此操作时,它可以工作,但它们会遇到高延迟,因为网络优化通过指示系统等待足够的数据可用以仅发送完整数据包来优先考虑性能。典型的延迟约为每个往返 200 毫秒。请注意,这仅发生在异常使用情况下。CONNECT 请求或 WebSockets 等正常使用不受影响。当连接使用的 frontend 或 backend 中存在 "option http-no-delay" 时,所有此类优化都将被禁用,以便使交换尽可能快。当然,这并不能保证功能正常,因为它可能会在其他地方中断。但是如果它通过 HAProxy 工作,它将以最快的速度工作。除非发现此类有缺陷的应用程序,否则不应默认使用此选项,也不应完全使用此选项。使用此选项的影响是带宽使用和 CPU 使用的增加,这可能会在高延迟环境中显着降低性能。
定义 HAProxy 是否会向服务器宣告 HTTP/1.x 连接的 keepalive。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当使用 "option http-server-close" 或 "option httpclose" 运行时,HAProxy 会向转发到服务器的 HTTP/1.x 请求添加 "Connection: close" 标头。不幸的是,当某些服务器看到此标头时,它们会自动避免对未知长度的响应使用分块编码,而这完全不相关。其结果是客户端或缓存可能会收到不完整的响应而不知道,并认为响应已完成。通过设置 "option http-pretend-keepalive",HAProxy 将使服务器相信它将保持连接处于活动状态。然后服务器将不会回退到上述异常的非期望状态。当 HAProxy 获取整个响应时,它将关闭与服务器的连接,就像使用 "option httpclose" 时一样。这样客户端就会获得一个正常的响应,并且连接在服务器端正确关闭。建议不要默认启用此选项,因为大多数服务器会在最后一个数据包之后更有效地自行关闭连接,并稍早释放其缓冲区。此外,网络上添加的数据包可能会略微降低整体峰值性能。然而值得注意的是,当启用此选项时,HAProxy 需要做的工作会少一些。因此,如果 HAProxy 是整个架构的瓶颈,启用此选项可能会节省一些 CPU 周期。此选项可以在 backend 和 listen 部分中设置。在 frontend 部分中使用它将被忽略,并在启动期间报告警告。这是一个与 backend 相关的选项,因此没有真正的原因在 frontend 上设置它。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
option http-restrict-req-hdr-names { preserve | delete | reject }
设置 HAProxy 关于包含 "[a-zA-Z0-9-]" 字符集之外字符的 HTTP 请求头部名称的策略。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
preserve 禁用过滤。这是没有配置 FastCGI 应用程序的 HTTP 代理的默认模式。 delete 删除名称中包含 "[a-zA-Z0-9-]" 字符集之外字符的请求头部。这是配置了 FastCGI 应用程序的 HTTP 后端的默认模式。 reject 如果请求包含名称中含有 "[a-zA-Z0-9-]" 字符集之外字符的头部,则以 403-Forbidden 响应拒绝该请求。
此选项可用于将请求头部名称限制为字母数字和连字符字符 ([A-Za-z0-9-])。这对于与无法处理头部名称中某些字符的非 HTTP 兼容服务器互操作可能是必需的。对于 FastCGI 应用程序也可能是必需的,因为头部名称中的所有非字母数字字符都会被下划线 ('_') 替换。因此,很容易混淆头部名称并绕过一些规则。例如,"X-Forwarded-For" 和 "X_Forwarded-For" 头部在 FastCGI 中都被转换为 "HTTP_X_FORWARDED_FOR"。请注意,此选项是按代理评估的,并且在 http-request 规则评估之后。
启用或禁用服务器端的 HTTP/1.x 连接关闭。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
默认情况下,HAProxy 在处理持久 HTTP/1.x 连接时以 keep-alive 模式运行:对于每个连接,它处理每个请求和响应,并将连接在两端保持空闲状态。此模式可以通过多种选项更改,例如 "option http-server-close" 或 "option httpclose"。设置 "option http-server-close" 可在服务器端启用 HTTP connection-close 模式,同时保留在客户端支持 HTTP keep-alive 和管线化的能力。这在客户端(慢速网络)提供最低延迟,并在服务器端提供最快的会话重用以节省服务器资源,类似于 "option httpclose"。如果服务器符合 RFC7230 的要求,它还允许将不具备 keep-alive 功能的服务器以 keep-alive 模式提供给客户端。请注意,当某些服务器在请求中看到 "Connection: close" 时,它们并不总是符合这些要求。结果将是 keep-alive 永远不会被使用。一种解决方法是启用 "option http-pretend-keepalive"。目前,日志不会指示请求是否来自同一会话。日志中报告的接受日期对应于上一个请求的结束,请求时间对应于等待新请求所花费的时间。如果未设置,keep-alive 请求时间仍受限于 "timeout http-keep-alive" 或 "timeout http-request" 定义的超时。此选项可以在 frontend 和 backend 中设置。如果持有连接的 frontend 或 backend 中至少有一个启用了它,则会启用它。它禁用并替换任何先前的 "option httpclose" 或 "option http-keep-alive"。请检查第 4 节(“代理”)以了解当 frontend 和 backend 选项不同时此选项如何与其他选项结合。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
使用非标准的 Proxy-Connection 头代替 Connection 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
虽然 RFC7230 明确指出 HTTP/1.1 代理必须使用 Connection 标头来指示其对持久或非持久连接的意愿,但浏览器和代理都忽略了代理连接的此标头,而是使用未记录的、非标准的 Proxy-Connection 标头。当尝试在浏览器和此类代理之间放置负载均衡器时,问题就出现了,因为 HAProxy 所理解的与客户端和代理所同意的之间会存在差异。通过在 frontend 中设置此选项,如果 HAProxy 看到代理请求,它可以自动切换为使用该非标准标头。这里的代理请求定义为 URI 既不以 '/' 也不以 '*' 开头的请求。这与 HTTP 隧道模式不兼容。请注意,此选项只能在 frontend 中指定,并且会影响请求的整个生命周期。此外,当设置此选项时,如果请求本身是代理请求,则需要身份验证的请求将自动切换为使用代理身份验证标头。这使得在现有代理前面检查或强制执行身份验证成为可能。此选项通常不应使用,除非在代理前面。
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
启用 HTTP 协议来检查服务器健康状况 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<method> 是与请求一起使用的可选 HTTP 方法。如果未设置,则使用 "OPTIONS" 方法,因为它通常需要较低的服务器处理能力,并且易于从日志中过滤掉。可以使用任何方法,但不建议发明非标准方法。<uri> 是 HTTP 请求中引用的 URI。它默认为 " / ",几乎所有服务器默认都可以访问,但可以更改为任何其他 URI。允许查询字符串。<version> 是可选的 HTTP 版本字符串。它默认为 "HTTP/1.0",但某些服务器可能在 HTTP 1.0 中行为不正确,因此将其更改为 HTTP/1.1 有时会有帮助。请注意,Host 字段在 HTTP/1.1 中是强制性的,请使用 "http-check send" 指令来添加它。
默认情况下,服务器健康检查仅包括尝试建立 TCP 连接。当指定 "option httpchk" 时,一旦建立 TCP 连接,就会发送一个完整的 HTTP 请求,并且响应 2xx 和 3xx 被认为是有效的,而所有其他响应,包括缺少任何响应,都表示服务器故障。结合 "http-check" 指令,可以自定义 HTTP 健康检查期间发送的请求或响应上的匹配规则。也可以配置 send/expect 序列,就像用于 TCP 健康检查的 "tcp-check" 指令一样。默认使用服务器配置来打开连接以执行 HTTP 健康检查。也可以使用 "http-check connect" 规则覆盖服务器参数。"httpchk" 选项不一定需要 HTTP backend,它也适用于纯 TCP backend。这对于使用 inetd 守护程序检查绑定到某些专用端口的简单脚本特别有用。但是,它始终在内部依赖于 HTX 复用器。因此,这意味着请求格式化和响应解析将是严格的。
示例
# 将 HTTPS 流量中继到 Apache 实例,并使用 HTTP 请求 "OPTIONS * HTTP/1.1" # 在端口 80 上检查服务可用性。 backend https_relay mode tcp option httpchk OPTIONS * HTTP/1.1 http-check send hdr Host www server apache1 192.168.1.1:443 check port 80
启用或禁用 HTTP/1.x 连接关闭 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
默认情况下,HAProxy 在处理持久 HTTP/1.x 连接时以 keep-alive 模式运行:对于每个连接,它处理每个请求和响应,并将连接在两端保持空闲状态。此模式可以通过多种选项更改,例如 "option http-server-close" 或 "option httpclose"。如果设置了 "option httpclose",HAProxy 将关闭客户端或服务器连接,具体取决于该选项设置的位置。frontend 被视为客户端连接,而 backend 被视为服务器连接。如果该选项设置在侦听器上,则它应用于客户端和服务器连接。它将检查每个方向是否已设置 "Connection: close" 标头,如果缺少则添加一个。此选项还可以与 "option http-pretend-keepalive" 结合使用,后者将禁用发送 "Connection: close" 请求标头,但在收到整个响应后仍会导致连接关闭。它禁用并替换任何先前的 "option http-server-close" 或 "option http-keep-alive"。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
启用 HTTP 请求、流状态和计时器的日志记录 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
clf 如果添加了“clf”参数,则输出格式将是 CLF 格式,而不是 HAProxy 的默认 HTTP 格式。当您需要将 HAProxy 的日志输入到只支持 CLF 格式且不可扩展的特定日志分析器时,可以使用此选项。
默认情况下,日志输出格式非常简单,只包含源地址、目标地址和实例名称。通过指定“option httplog”,每条日志行都会变成更丰富的格式,包括但不限于 HTTP 请求、连接计时器、流状态、连接数、捕获的头和 cookie、前端、后端和服务器名称,当然还有源地址和端口。仅指定“option httplog”将自动清除默认设置的“clf”模式。“option httplog”会覆盖任何先前的“log-format”指令。
启用 HTTPS 请求、流状态和计时器的日志记录 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
默认情况下,日志输出格式非常简单,只包含源地址、目标地址和实例名称。通过指定“option httpslog”,每条日志行都会变成更丰富的格式,包括但不限于 HTTP 请求、连接计时器、流状态、连接数、捕获的头和 cookie、前端、后端和服务器名称、SSL 证书验证和 SSL 握手状态,当然还有源地址和端口。“option httpslog”会覆盖任何先前的“log-format”指令。
启用或禁用双向独立的超时处理 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
默认情况下,当通过套接字发送数据时,该套接字的写入超时和读取超时都会刷新,因为我们认为该套接字上有活动,并且我们没有其他方法来猜测是否应该接收数据。虽然这种默认行为适用于几乎所有应用程序,但在某些情况下,最好禁用它,并且仅在有传入数据时才刷新读取超时。这发生在具有大超时和少量交换数据的流上,例如 telnet 会话。如果服务器突然消失,输出数据会累积在系统的套接字缓冲区中,两个超时都会正确刷新,并且无法知道服务器没有收到它们,因此我们不会超时。但是,当底层协议始终回显发送的数据时,仅使用读取超时就足以检测问题。请注意,此问题不会发生在更详细的协议中,因为数据不会长时间累积在套接字缓冲区中。当此选项在 frontend 上设置时,它将禁用发送给客户端的数据的读取超时更新。这种情况可能很少有用。当此选项在 backend 上设置时,它将禁用发送给服务器的数据的读取超时更新。这样做通常会破坏来自慢速线路的大型 HTTP post,因此请谨慎使用。
使用 LDAPv3 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
可以测试服务器是否正确地使用 LDAPv3 通信,而不仅仅是测试它是否接受 TCP 连接。设置此选项后,会向服务器发送一个 LDAPv3 匿名简单绑定消息,并分析响应以查找 LDAPv3 绑定响应消息。只有当 LDAP 响应包含成功 resultCode (http://tools.ietf.org/html/rfc4511#section-4.1.9) 时,服务器才被认为是有效的。绑定请求的日志记录取决于服务器,请参阅您的文档如何配置它。
示例
option ldap-check
使用外部进程进行服务器健康检查 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
可以使用外部命令测试服务器的健康状况。这是通过运行使用 "external-check command" 设置的可执行文件来实现的。需要设置全局的 "external-check"。
避免在软停止期间关闭空闲的前端连接 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
默认情况下,空闲连接将在软停止期间关闭。在某些环境中,与代理通信的客户端可能已经准备了一些空闲连接,以便稍后发送请求。如果没有对写入错误进行适当的重试,这可能导致 haproxy 重新加载时出现错误。尽管适当的实现应该在连接/写入错误时重试,但引入此选项是为了支持与 2.4 版本之前的 haproxy 的向后兼容性。事实上,在 v2.4 之前,haproxy 习惯于等待最后一个请求和响应,然后在关闭之前添加 "connection: close" 标头,从而通知客户端连接不可重用。在一个真实的例子中,在 AWS 中使用 ALB 在 haproxy 前面看到了这种行为。最终结果是 ALB 在 haproxy 重新加载期间发送 502。警告用户,如果连接空闲时间过长,使用此选项可能会增加旧进程的数量。在频繁重新加载的情况下,可能需要相应地调整客户端超时和/或 "hard-stop-after" 参数。
启用或禁用健康检查状态更新的日志记录 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
默认情况下,如果服务器处于 UP 状态,则记录失败的健康检查;如果服务器处于 DOWN 状态,则记录成功的健康检查,因此额外的信息量是有限的。启用此选项后,健康检查状态或服务器健康状况的任何变化都将被记录,这样就可以知道服务器在崩溃前偶尔会检查失败,或者确切知道它何时未能响应有效的 HTTP 状态,然后端口何时开始拒绝连接,以及服务器何时完全停止响应。请注意,此选项有意不记录非健康检查引起的状态变化(例如,在 CLI 上启用/禁用)。
更改非完全成功连接的日志级别 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
有时在日志中查找错误并不容易。此选项使 HAProxy 提高包含潜在有用信息的日志级别,例如错误、超时、重试、重新分派或 HTTP 状态码 5xx。级别从“info”变为“err”。这使得大多数 syslog 守护进程可以将它们单独记录到不同的文件中。请注意不要从原始文件中删除它们,否则会丢失提供非常重要信息的顺序。使用此选项,处理每秒数千个连接的大型站点可以将正常流量记录到循环缓冲区中,并仅归档较小的错误日志。
启用或禁用早期日志记录。 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
默认情况下,当日志格式字符串定义中使用的所有日志格式变量和样本获取都返回值时,或者当流终止时,会发出日志。这允许内置日志格式字符串在日志消息中考虑传输时间或字节数。在处理大文件传输或 RDP 等长时间连接时,请求或连接可能需要一段时间才能出现在日志中。使用 "option logasap",日志消息会在 tcp 模式下建立服务器连接时立即创建,或者在 http 模式下服务器发送完整标头时立即创建。日志中缺失的信息将是总字节数,它仅指示在创建消息之前传输的数据量,以及不考虑连接剩余生命周期或传输时间的总时间。对于 HTTP 的情况,捕获 Content-Length 响应标头是一个很好的做法,这样日志至少可以指示预期传输多少字节。
示例
listen http_proxy 0.0.0.0:80 mode http option httplog option logasap log 192.168.2.200 local3 >>> Feb 6 12:14:14 localhost \ haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \ static/srv1 9/10/7/14/+30 200 +243 - - ---- 3/1/1/1/0 1/0 \ "GET /image.iso HTTP/1.0"
option mysql-check [ user <username> [ { post-41 | pre-41 } ] ]
使用 MySQL 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<username> 这是连接到 MySQL 服务器时将使用的用户名。 post-41 发送与 v4.1 后客户端兼容的检查(默认) pre-41 发送与 v4.1 前客户端兼容的检查
如果您指定了用户名,检查包括发送两个 MySQL 数据包,一个客户端身份验证数据包和一个 QUIT 数据包,以正确关闭 MySQL 会话。然后我们解析 MySQL 握手初始化数据包和/或错误数据包。这是一个基本但有用的测试,不会在服务器上产生错误或中止连接。但是,它需要一个没有密码的已解锁的授权用户。要在 MySQL 中创建具有可选资源限制的基本受限用户:CREATE USER '<username>'@'<ip_of_haproxy|network_of_haproxy/netmask>' /*!50701 WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 */ /*M!100201 MAX_STATEMENT_TIME 0.0001 */; 如果您不指定用户名(不推荐且不推荐),检查仅包括解析 Mysql 握手初始化数据包或错误数据包,在此模式下我们不发送任何内容。据报道,如果检查过于频繁和/或流量不足,它可能会产生锁定。实际上,在这种情况下,您需要检查 MySQL "max_connect_errors" 值,因为如果在上一次连接中断后少于 MySQL "max_connect_errors" 次尝试内成功建立连接,则主机的错误计数将清零。如果 HAProxy 的服务器被阻止,"FLUSH HOSTS" 语句是解除阻止它的唯一方法。请记住,这不会检查数据库是否存在或数据库一致性。为此,您可以使用带有 xinetd 的外部检查。检查需要 MySQL >=3.22,对于旧版本,请使用 TCP 检查。通常,传入的 MySQL 服务器需要查看客户端的 IP 地址用于各种目的,包括 IP 特权匹配和连接日志记录。如果可能,使用 "source" 关键字的 "usesrc" 参数连接到服务器时,伪装客户端的 IP 地址通常是明智的,这要求编译透明代理功能,并且 MySQL 服务器通过托管 HAProxy 的机器路由客户端。
启用或禁用关闭后立即清理会话资源 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
当客户端或服务器以不干净的方式中止连接时(例如,它们被物理断开连接),会话超时触发并关闭会话。但它会在系统中保持 FIN_WAIT1 状态一段时间,占用一些资源并可能限制建立新连接的能力。发生这种情况时,可以激活 "option nolinger",它会强制系统在关闭时立即删除任何套接字挂起的数据。因此,会发出 TCP RST,任何挂起的数据都会被截断,并且会话会立即从系统的表中清除。对于客户端而言,通常可见的效果是,如果关闭发生时有最后一块数据(例如,在重定向或错误响应时),则响应会被截断。在服务器端,当转发客户端中止隧道时,它可能有助于立即释放源端口。在这两种情况下,都会发出 TCP 重置,并且鉴于会话会立即销毁,因此不会有重传。在有损网络上,这可能会增加问题,尤其是当有损端有防火墙时,因为防火墙可能会看到并处理重置(因此清除其会话)并阻止此会话的任何进一步流量,包括来自另一端的重传。因此,如果另一端没有收到它,它将永远不会再次收到任何 RST,并且防火墙可能会记录许多被阻止的数据包。出于所有这些原因,强烈建议不要使用此选项,除非绝对需要作为最后的手段。在大多数情况下,使用 "client-fin" 或 "server-fin" 超时可以获得类似的结果,且行为更可靠。在 Linux 上,也可以使用 "tcp-ut" bind 或 server 设置。此选项可用于 frontends 和 backends,具体取决于需要它的那一端。在 frontend 上用于客户端,在 backend 上用于服务器。虽然此选项在 "defaults" 部分中技术上受支持,但它确实不应该在那里使用,因为它有意外传播到不应使用它的部分并导致问题的风险。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
option originalto [ except <network> ] [ header <name> ]
启用向服务器发送的请求中插入 X-Original-To 头 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<network> 是一个可选参数,用于为匹配 <network> 的源禁用此选项。<name> 是一个可选参数,用于指定一个不同的 "X-Original-To" 标头名称。
由于 HAProxy 可以以透明模式工作,来自客户端的每个请求都可以重定向到代理,HAProxy 本身可以将每个请求代理到一个复杂的 SQUID 环境,并且 SO_ORIGINAL_DST 中的目标主机将丢失。当您想要基于目标 IP 地址的访问规则时,这很麻烦。为了解决这个问题,HAProxy 可能会向发送给服务器的所有请求添加一个新的 HTTP 标头 "X-Original-To"。此标头包含一个表示原始目标 IP 地址的值。由于这必须配置为仅使用此标头的最后一次出现。请注意,必须仅使用标头的最后一次出现,因为客户端确实有可能已经带有一个。关键字 "header" 可用于提供不同的标头名称来替换默认的 "X-Original-To"。如果您可能已经有一个来自不同应用程序的 "X-Original-To" 标头,并且您需要保留它,这将非常有用。此外,如果您的 backend 服务器不使用 "X-Original-To" 标头并且需要不同的标头。有时,同一个 HAProxy 实例可能会在直接客户端访问和反向代理访问之间共享(例如,当使用 SSL 反向代理来解密 HTTPS 流量时)。可以通过添加 "except" 关键字后跟网络地址来禁用已知目标地址或网络的标头添加。在这种情况下,任何匹配网络的源 IP 都不会导致添加此标头。最常见的用途是私有网络或 127.0.0.1。IPv4 和 IPv6 都受支持。此选项可以在 frontend 或 backend 中指定。如果其中至少一个使用它,则会添加标头。请注意,如果同时定义了 backend 和 frontend,则 backend 中标头子参数的设置优先于 frontend。
示例
# 原始目标地址 frontend www mode http option originalto except 127.0.0.1 # 这些服务器希望在 X-Client-Dst 中获取 IP 地址 backend www mode http option originalto header X-Client-Dst
启用或禁用对故障服务器的强制持久性 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当 HTTP 请求到达一个带有引用故障服务器的 cookie 的后端时,默认情况下它会被重新分派到另一台服务器。如果绝对需要,可以使用 "option persist" 强制将请求首先发送到故障服务器。一个常见的用例是当服务器处于极端负载下并不断地出现状态切换时。在这种情况下,用户仍将被导向到他们打开会话的服务器,希望他们能得到正确的服务。建议将 "option redispatch" 与此选项结合使用,以便在无法连接到服务器的情况下(服务器确定故障),客户端最终将被重定向到另一台有效的服务器。如果此选项已在 "defaults" 部分启用,可以通过在其前面加上 "no" 关键字在特定实例中禁用它。
使用 PostgreSQL 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<username> 这是连接到 PostgreSQL 服务器时将使用的用户名。
此检查发送一个 PostgreSQL StartupMessage 并等待认证请求或 ErrorResponse 消息。这是一个基本但有用的测试,不会在服务器上产生错误或中止连接。此检查与 "mysql-check" 相同。
允许多个负载均衡的请求保留在同一台服务器上 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当使用的负载均衡算法不是确定性的,并且之前的请求已发送到 HAProxy 仍保持连接的服务器时,有时希望同一会话上的后续请求尽可能发送到同一服务器。请注意,这与持久性不同,因为我们只表示一种偏好,HAProxy 试图应用它,不提供任何形式的保证。真正的用途是发送到服务器的 keep-alive 连接。使用此选项时,HAProxy 将尝试重用附加到服务器的相同连接,而不是重新平衡到另一台服务器,从而导致连接关闭。这对于静态文件服务器可能是有意义的。将其与哈希算法结合使用意义不大。请注意,当负载均衡算法不是确定性的时,HAProxy 已经自动尝试粘滞到发送 401 的服务器或发送 407(需要身份验证)的代理。这对于使用损坏的 NTLM 身份验证质询是强制性的,并且显着有助于解决某些有缺陷的应用程序。在这些环境中,选项 prefer-last-server 也可能是可取的,以避免在每隔一个响应后重新分配流量。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
启用或禁用在连接失败时会话重新分发 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<interval> 可选的整数值,用于控制重试连接时重新分发的频率。正值 P 表示希望在每第 P 次重试时进行重新分发,负值 N 表示希望在最后一次重试前的第 N 次重试时进行重新分发。例如,默认值 -1 保留了在最后一次重试时重新分发的历史行为,正值 1 表示每次重试都重新分发,正值 3 表示每三次重试重新分发一次。您可以使用值 0 禁用重新分发。
在 HTTP 模式下,如果由 cookie 指定的服务器出现故障,客户端可能会永久粘滞到它,因为他们无法清除 cookie,因此他们将无法再访问该服务。指定 "option redispatch" 将允许代理打破基于 cookie 或一致哈希的持久性,并将它们重新分配给一个正常工作的服务器。活动服务器是从可用服务器列表的子集中选择的。未关闭或处于维护状态(即,未检查其健康状况或已检查为“up”)的活动服务器按以下顺序选择:1. 任何活动的非备份服务器(如果有),或者,2. 如果未设置 "allbackups" 选项,则选择列表中的第一个备份服务器,或者 3. 如果设置了 "allbackups" 选项,则选择任何备份服务器。当发生重试时,HAProxy 会尝试选择与上一个服务器不同的服务器。新服务器是从当前服务器列表中选择的。有时,如果在重试之间更新列表(例如,如果发生多次重试且持续时间长于检查服务器是否关闭、将其从列表中删除并回退到备份服务器列表所需的时间),连接可能会被重定向到备份服务器,尽管如此。它还允许在多次连接失败的情况下重试连接到另一台服务器。当然,它需要将 "retries" 设置为非零值。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
使用 redis 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
可以测试服务器是否正确地使用 REDIS 协议通信,而不仅仅是测试它是否接受 TCP 连接。设置此选项后,会向服务器发送一个 PING redis 命令,并分析响应以查找 "+PONG" 响应消息。
示例
option redis-check
option smtpchk <hello> <domain>
使用 SMTP 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<hello> 是一个可选参数。它是要使用的“hello”命令。它可以是“HELO”(用于 SMTP)或“EHLO”(用于 ESMTP)。所有其他值都将转换为默认命令(“HELO”)。<domain> 是要呈现给服务器的域名。只有在指定了 hello 命令时才能指定(并且是强制性的)。默认情况下,使用“localhost”。
当设置 "option smtpchk" 时,健康检查将包括 TCP 连接,然后是 SMTP 命令。默认情况下,此命令为 "HELO localhost"。分析服务器的返回代码,只有以 "2" 开头的返回代码才被视为有效。所有其他响应,包括缺少响应,都将构成错误并指示服务器已死。此测试旨在用于 SMTP 服务器或中继。根据请求,某些服务器可能不会记录每次连接尝试,因此您可能需要进行试验以改进行为。使用端口 25 上的 telnet 通常比调整配置更容易。通常,传入的 SMTP 服务器需要查看客户端的 IP 地址用于各种目的,包括垃圾邮件过滤、反欺骗和日志记录。如果可能,使用 "source" 关键字的 "usesrc" 参数连接到服务器时,伪装客户端的 IP 地址通常是明智的,这要求编译透明代理功能。
示例
option smtpchk HELO mydomain.org
启用或禁用为每个套接字收集并提供单独的统计信息。 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
启用或禁用双向套接字上的自动内核加速 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
当在 frontend 或 backend 上启用此选项时,HAProxy 将自动评估是否使用内核 tcp splicing 在客户端和服务器之间转发数据(双向)。HAProxy 使用启发式方法来估计内核 splicing 是否可以提高性能。两个方向都是独立处理的。请注意,使用的启发式方法不是很激进,以限制 splicing 的过度使用。此选项要求在编译时启用 splicing,并且可以使用全局选项 "nosplice" 全局禁用。由于 splice 使用管道,因此使用它需要有足够的备用管道。重要说明:基于内核的 TCP splicing 是 Linux 特有的功能,最早出现在内核 2.6.25 中。它提供基于内核的加速,用于在套接字之间传输数据而无需将这些数据复制到用户空间,从而提供显着的性能增益和 CPU 周期节省。由于许多早期实现存在错误、数据损坏和/或效率低下,此功能默认未启用,应谨慎使用。虽然无法检测实现的正确性,但 2.6.29 是第一个提供正常工作实现的版本。如有疑问,可以使用全局 "nosplice" 关键字全局禁用 splicing。
示例
option splice-auto
如果此选项已在 "defaults" 部分启用,可以通过在其前面加上 "no" 关键字在特定实例中禁用它。
启用或禁用请求套接字上的自动内核加速 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
当此选项在前端或后端启用时,HAProxy 将尽可能使用内核 TCP 拼接来转发从客户端到服务器的数据。如果备用管道不足,它可能仍会使用 recv/send 方案。此选项需要在编译时启用拼接,并且可以通过全局选项“nosplice”全局禁用。由于 splice 使用管道,因此使用它需要有足够的备用管道。重要说明:有关使用限制,请参阅“option splice-auto”。
示例
option splice-request
如果此选项已在 "defaults" 部分启用,可以通过在其前面加上 "no" 关键字在特定实例中禁用它。
启用或禁用响应套接字上的自动内核加速 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
当此选项在前端或后端启用时,HAProxy 将尽可能使用内核 TCP 拼接来转发从服务器到客户端的数据。如果备用管道不足,它可能仍会使用 recv/send 方案。此选项需要在编译时启用拼接,并且可以通过全局选项“nosplice”全局禁用。由于 splice 使用管道,因此使用它需要有足够的备用管道。重要说明:有关使用限制,请参阅“option splice-auto”。
示例
option splice-response
如果此选项已在 "defaults" 部分启用,可以通过在其前面加上 "no" 关键字在特定实例中禁用它。
使用 SPOP 健康检查来测试服务器 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
可以测试服务器是否正确地使用 SPOP 协议进行通信,而不仅仅是测试它是否接受 TCP 连接。设置此选项后,HAProxy 和服务器之间会执行 HELLO 握手,并分析响应以检查是否报告了错误。
示例
option spop-check
启用或禁用在服务器端发送 TCP keepalive 数据包 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当客户端和服务器之间存在防火墙或任何会话感知组件时,并且当协议涉及具有长时间空闲期的非常长的会话时(例如远程桌面),存在中间组件决定使空闲时间过长的会话过期​​的风险。启用套接字级 TCP keep-alives 会使系统定期向连接的另一端发送数据包,使其保持活动状态。keep-alive 探测之间​​的延迟仅由系统控制,并且取决于操作系统及其调整参数。重要的是要理解 keep-alive 数据包既不会在应用程序级别发出也不会接收。只有网络堆栈才能看到它们。因此,即使代理的一端已经使用 keep-alives 来保持其连接处于活动状态,这些 keep-alive 数据包也不会转发到代理的另一端。请注意,这与 HTTP keep-alive 无关。使用选项 "srvtcpka" 可在连接的服务器端启用 TCP keep-alive 探测的发射,这应该有助于在 HAProxy 和服务器之间注意到会话过期时。如果此选项已在 "defaults" 部分中启用,则可以通过在其前面加上 "no" 关键字来禁用特定实例中的此选项。
使用 SSLv3 客户端 hello 健康检查来测试服务器 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
当某些基于 SSL 的协议在 TCP 模式下通过 HAProxy 中继时,可以测试服务器是否正确地使用 SSL 协议,而不仅仅是测试它是否接受 TCP 连接。当设置了“option ssl-hello-chk”时,一旦与服务器建立连接,就会发送纯 SSLv3 客户端 hello 消息,并分析响应以查找 SSL 服务器 hello 消息。只有当响应包含此服务器 hello 消息时,服务器才被认为是有效的。所有测试过的服务器都正确地回复了 SSLv3 客户端 hello 消息,并且大多数测试过的服务器甚至不记录仅包含 hello 消息的请求,这是值得赞赏的。请注意,即使 HAProxy 中没有内置 SSL 支持,此检查也能工作,因为它会伪造 SSL 消息。当 SSL 支持可用时,最好使用原生的 SSL 健康检查而不是这个。
使用 tcp-check 发送/期望序列执行健康检查 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
此健康检查方法旨在与 "tcp-check" 命令列表结合使用,以支持 send/expect 类型的健康检查序列。TCP 检查目前支持 4 种操作模式: - 没有 "tcp-check" 指令:健康检查仅包括连接尝试,这仍然是默认模式。 - 仅提及 "tcp-check send" 或 "tcp-check send-binary":这用于在连接打开时发送一个字符串。对于某些协议,例如它有助于发送 "QUIT" 消息,以防止服务器为每个健康检查记录连接错误。检查结果仍将仅基于打开连接的能力。 - 仅提及 "tcp-check expect":这用于测试横幅。连接打开后,HAProxy 等待服务器呈现必须验证某些规则的内容。检查结果将基于内容和规则之间的匹配。这适用于 POP、IMAP、SMTP、FTP、SSH、TELNET。 - 同时提及 "tcp-check send" 和 "tcp-check expect":这用于测试 hello 型协议。HAProxy 发送一条消息,服务器响应并分析其响应。检查结果将基于响应内容和规则之间的匹配。这通常适用于需要绑定或请求/响应模型的协议。LDAP、MySQL、Redis 和 SSL 是此类协议的示例,尽管它们都已经有专用的检查,对各自的协议有更深入的了解。在此模式下,可以发送许多问题并分析许多答案。第五种模式可用于在脚本的不同步骤中插入注释。对于您创建的每个 tcp-check 规则,您可以添加一个 "comment" 指令,后跟一个字符串。此字符串将在调试模式下报告在日志和 stderr 中。它有助于使错误报告更加用户友好。 "comment" 当然是可选的。在执行健康检查期间,可以使用 "tcp-check set-var" 操作提供一个变量范围来存储数据样本。可以使用 "tcp-check unset-var" 释放这些变量。
示例
# 执行 POP 检查(仅分析服务器的横幅) option tcp-check tcp-check expect string +OK\ POP3\ ready comment POP\ protocol # 执行 IMAP 检查(仅分析服务器的横幅) option tcp-check tcp-check expect string *\ OK\ IMAP4\ ready comment IMAP\ protocol # 在确保它正确说话后寻找 redis 主服务器 # redis 协议,然后它正确退出。 # (发送一个命令然后分析响应 3 次) option tcp-check tcp-check comment PING\ phase tcp-check send PING\r\n tcp-check expect string +PONG tcp-check comment role\ check tcp-check send info\ replication\r\n tcp-check expect string role:master tcp-check comment QUIT\ phase tcp-check send QUIT\r\n tcp-check expect string +OK forge a HTTP request, then analyze the response (send many headers before analyzing) option tcp-check tcp-check comment forge\ and\ send\ HTTP\ request tcp-check send HEAD\ /\ HTTP/1.1\r\n tcp-check send Host:\ www.mydomain.com\r\n tcp-check send User-Agent:\ HAProxy\ tcpcheck\r\n tcp-check send \r\n tcp-check expect rstring HTTP/1\..\ (2..|3..) comment check\ HTTP\ response
启用或禁用在接受序列中节省一个 ACK 数据包 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
当 HTTP 连接请求传入时,系统会代表 HAProxy 确认它,然后客户端立即发送其请求,系统在通知 HAProxy 新连接的同时也会确认它。HAProxy 然后读取请求并响应。这意味着系统发送了一个 TCP ACK,但没有任何作用,因为 HAProxy 在发送响应时可以很好地确认请求。出于这个原因,在 HTTP 模式下,HAProxy 会自动要求系统避免在支持它的平台(目前至少是 Linux)上发送这个无用的 ACK。它不会引起任何问题,因为如果响应花费的时间比预期要长,系统仍会在 40 毫秒后发送它。在复杂的网络调试会话期间,可能需要禁用此优化,因为延迟的 ACK 在尝试识别数据包延迟的位置时会使故障排除更加复杂。然后可以通过指定 "no option tcp-smart-accept" 来恢复正常行为。也可以通过简单地指定 "option tcp-smart-accept" 来强制它用于非 HTTP 代理。例如,对于某些服务(例如 SMTP,其中服务器首先发言)来说,它可能是有意义的。建议避免在 defaults 部分中强制使用此选项。如有疑问,请考虑在其前面加上 "default" 关键字将其设置回自动值,或使用 "no" 关键字将其禁用。
启用或禁用在连接序列中节省一个 ACK 数据包 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
在某些系统(至少是 Linux)上,HAProxy 可以请求内核在收到连接请求时不立即发送一个空的 ACK,而是直接发送带有数据的请求。这可以在网络上节省一个数据包,从而提高性能。这对某些服务器也很有用,因为它们可以立即随传入连接一起获取请求。当在后端设置了 "option tcp-smart-connect" 时,此功能被启用。默认情况下不启用,因为它会使网络故障排除变得更加复杂。只在客户端先说话的协议(如 HTTP)中启用它才有意义。在其他情况下,如果没有数据可以代替 ACK 发送,则会发送一个正常的 ACK。如果此选项已在 "defaults" 部分启用,可以通过在其前面加上 "no" 关键字来在特定实例中禁用它。
启用或禁用在两端发送 TCP keepalive 数据包 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
当客户端和服务器之间存在防火墙或任何会话感知组件时,并且当协议涉及具有长时间空闲期的非常长的会话时(例如远程桌面),存在中间组件决定使空闲时间过长的会话过期​​的风险。启用套接字级 TCP keep-alives 会使系统定期向连接的另一端发送数据包,使其保持活动状态。keep-alive 探测之间​​的延迟仅由系统控制,并且取决于操作系统及其调整参数。重要的是要理解 keep-alive 数据包既不会在应用程序级别发出也不会接收。只有网络堆栈才能看到它们。因此,即使代理的一端已经使用 keep-alives 来保持其连接处于活动状态,这些 keep-alive 数据包也不会转发到代理的另一端。请注意,这与 HTTP keep-alive 无关。使用选项 "tcpka" 可在连接的客户端和服务器端启用 TCP keep-alive 探测的发射。请注意,这仅在 "defaults" 或 "listen" 部分中有意义。如果此选项用于 frontend,则只有客户端会获得 keep-alives,如果此选项用于 backend,则只有服务器端会获得 keep-alives。因此,当配置在 frontends 和 backends 之间拆分时,强烈建议显式使用 "option clitcpka" 和 "option srvtcpka"。
启用 TCP 连接的高级日志记录,包含流状态和计时器 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数:
默认情况下,日志输出格式非常简单,只包含源地址和目标地址以及实例名称。通过指定 "option tcplog",每条日志行都会变成一种更丰富的格式,包括但不限于连接计时器、流状态、连接数、前端、后端和服务器名称,当然还有源地址和端口。此选项对于纯 TCP 代理非常有用,可以找出客户端或服务器是哪一方断开连接或超时。对于普通的 HTTP 代理,最好使用 "option httplog",它甚至更完整。 "option tcplog" 会覆盖任何先前的 "log-format" 指令。
启用客户端透明代理 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
引入此选项是为了给第 3 层负载均衡器提供第 7 层持久性。其思想是利用操作系统的能力,将针对远程地址的传入连接重定向到本地进程(此处为 HAProxy),并让该进程知道最初请求的地址。使用此选项时,没有 cookie 的会话将被转发到传入请求的原始目标 IP 地址(该地址应与另一台设备的地址匹配),而带有 cookie 的请求仍将被转发到适当的服务器。请注意,与普遍看法相反,此选项不会使 HAProxy 在建立连接时向服务器呈现客户端的 IP。
执行外部检查时要运行的可执行文件 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<command> 是要运行的外部命令
传递给命令的参数是:<proxy_address> <proxy_port> <server_address> <server_port> <proxy_address> 和 <proxy_port> 源自第一个侦听器,可以是 IPv4、IPv6 或 UNIX 套接字。在 UNIX 套接字侦听器的情况下,proxy_address 将是套接字的路径,<proxy_port> 将是字符串 "NOT_USED"。在 backend 部分中,无法确定侦听器,并且 <proxy_address> 和 <proxy_port> 都将具有字符串值 "NOT_USED"。一些值也通过环境变量提供。环境变量:HAPROXY_PROXY_ADDR 第一个 bind 地址(如果可用)(如果_不适用,则为空,例如在 "backend" 部分中)。HAPROXY_PROXY_ID backend id。HAPROXY_PROXY_NAME backend 名称。HAPROXY_PROXY_PORT 第一个 bind 端口(如果可用)(如果_不适用,则为空,例如在 "backend" 部分中或对于 UNIX 套接字)。HAPROXY_SERVER_ADDR 服务器地址。HAPROXY_SERVER_CURCONN 服务器上的当前连接数。HAPROXY_SERVER_ID 服务器 id。HAPROXY_SERVER_MAXCONN 服务器最大连接数。HAPROXY_SERVER_NAME 服务器名称。HAPROXY_SERVER_PORT 服务器端口(如果可用)(对于 UNIX 套接字为空)。HAPROXY_SERVER_SSL 未使用 SSL 时为 "0",使用时为 "1" HAPROXY_SERVER_PROTO 此服务器使用的协议,可以是 "cli"(haproxy CLI)、"syslog"(syslog TCP 服务器)、"peers"(对等 TCP 服务器)、"h1"(HTTP/1.x 服务器)、"h2"(HTTP/2 服务器)或 "tcp"(任何其他 TCP 服务器)。PATH 执行命令时使用的 PATH 环境变量可以使用 "external-check path" 设置。有关其他变量,另请参阅 "2.3. Environment variables"。如果执行的命令以零状态退出,则认为检查已通过,否则认为检查失败。
示例
external-check command /bin/true
运行外部检查时使用的 PATH 环境变量的值 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<path> 是执行外部命令时使用的路径
默认路径为 ""。
示例
external-check path "/usr/bin:/bin"
启用基于 RDP cookie 的持久性 可在以下上下文中使用:tcp

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<name> 是要检查的可选 RDP cookie 的名称。如果省略,将使用默认的 cookie 名称 "msts"。目前没有更改此名称的有效理由。
此语句启用基于 RDP cookie 的持久性。RDP cookie 包含在已知服务器列表中找到服务器所需的所有信息。因此,当在后端中设置此选项时,将分析请求,如果找到 RDP cookie,则会对其进行解码。如果它与仍然 UP 的已知服务器匹配(或者如果设置了 "option persist"),则连接将被转发到此服务器。请注意,这仅在 TCP 后端中有意义,但要使其工作,前端必须等待足够长的时间以确保 RDP cookie 存在于请求缓冲区中。这与 "rdp-cookie" 负载均衡方法的要求相同。因此,强烈建议将所有语句放在一个 "listen" 部分中。此外,重要的是要理解,终端服务器只有在配置为 "令牌重定向模式" 时才会发出此 RDP cookie,这意味着 "IP 地址重定向" 选项被禁用。
示例
listen tse-farm bind :3389 # 在请求中等待 RDP cookie 最多 5 秒 tcp-request inspect-delay 5s tcp-request content accept if RDP_COOKIE # 应用 RDP cookie 持久性 persist rdp-cookie # 如果服务器未知,让我们在相同的 cookie 上进行负载均衡。 # 或者,"balance leastconn" 也可能有用。 balance rdp-cookie server srv1 1.1.1.1:3389 server srv2 1.1.1.2:3389
设置前端每秒接受的新会话数限制 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<rate> <rate> 参数是一个整数,指定前端每秒接受的最大新会话数。
当 frontend 达到每秒指定的新会话数时,它会停止接受新连接,直到速率再次降至限制以下。在此期间,挂起的会话将保留在套接字的积压中(在系统缓冲区中),HAProxy 甚至不会意识到会话正在挂起。当对高负载服务应用非常低的限制时,使用 "backlog" 关键字来增加套接字的积压可能是有意义的。此功能在阻止对脆弱服务器的基于连接的攻击或服务滥用方面特别有效。由于会话速率是每毫秒测量一次,因此它非常准确。此外,限制立即生效,根本不需要延迟来检测阈值。
示例
将 SMTP 的连接速率限制为最大每秒 10 个
listen smtp mode tcp bind :25 rate-limit sessions 10 server smtp1 127.0.0.1:1025
注意:当达到最大速率时,前端的状态不会改变,但如果启用了 "socket-stats" 选项,其套接字在统计信息中将显示为 "WAITING"。
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]
redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
如果/除非条件匹配,则返回 HTTP 重定向 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
如果/除非条件匹配,HTTP 请求将导致重定向响应。如果未指定条件,则重定向无条件适用。
参数
<loc> 使用 "redirect location",<loc> 中的确切值将放置在 HTTP "Location" 标头中。当在 "http-request" 规则中使用时,<loc> 值遵循日志格式规则,并且可以包含一些动态值(请参阅第 8.2.6 节中的自定义日志格式)。<pfx> 使用 "redirect prefix","Location" 标头是通过连接 <pfx> 和完整的 URI 路径(包括查询字符串)构建的,除非指定了 "drop-query" 选项(见下文)。作为一个特例,如果 <pfx> 恰好等于 "/",则不会在原始 URI 之前插入任何内容。它允许重定向到相同的 URL(例如,插入 cookie)。当在 "http-request" 规则中使用时,<pfx> 值遵循日志格式规则,并且可以包含一些动态值(请参阅第 8.2.6 节中的自定义日志格式)。<sch> 使用 "redirect scheme","Location" 标头是通过将 <sch> 与 "://" 连接,然后是第一个出现的 "Host" 标头,然后是 URI 路径(包括查询字符串,除非指定了 "drop-query" 选项(见下文))来构建的。如果未找到路径或路径为 "*",则使用 "/" 代替。如果未找到 "Host" 标头,则返回一个空主机组件,大多数最近的浏览器将其解释为重定向到同一主机。此指令主要用于将 HTTP 重定向到 HTTPS。当在 "http-request" 规则中使用时,<sch> 值遵循日志格式规则,并且可以包含一些动态值(请参阅第 8.2.6 节中的自定义日志格式)。<code> 代码是可选的。它指示所需的 HTTP 重定向类型。仅支持代码 301、302、303、307 和 308,如果未指定代码,则默认使用 302。301 表示“永久移动”,浏览器可能会缓存 Location。302 表示“暂时移动”,表示浏览器不应缓存重定向。303 与 302 等效,不同之处在于浏览器将使用 GET 方法获取位置。307 就像 302 一样,但明确指出必须重用相同的方法。同样,如果必须使用相同的方法,308 会替换 301。<option> 可以指定几个选项来调整重定向的预期行为: - "drop-query" 当此关键字用于基于前缀的重定向时,将设置不带任何可能的查询字符串的位置,这对于将用户定向到非安全页面很有用。它对位置类型重定向没有影响。 - "append-slash" 此关键字可与 "drop-query" 结合使用,将使用不以 '/' 结尾的 URL 的用户重定向到带有 '/' 的相同 URL。这对于确保搜索引擎只看到一个 URL 会很有用。为此,首选返回代码 301。 - "ignore-empty" 此关键字仅在使用日志格式表达式生成位置时有效(即在 http-request 或 http-response 中使用时)。它表示如果表达式结果为空,则应静默跳过规则。主要用途是允许使用简单的映射对已知路径进行大规模重定向。 - "set-cookie NAME[=value]" 响应中将添加带有 NAME(以及可选的 "=value")的 "Set-Cookie" 标头。这有时用于指示用户已被查看,例如用于防止某些类型的 DoS。未添加其他 cookie 选项,因此 cookie 将是会话 cookie。请注意,对于浏览器来说,不带等号的单个 cookie 名称与带等号的 cookie 不同。 - "clear-cookie NAME[=]" 响应中将添加带有 NAME(以及可选的 "=")的 "Set-Cookie" 标头,但 "Max-Age" 属性设置为零。这将告诉浏览器删除此 cookie。例如,这在退出页面上很有用。重要的是要注意,清除 cookie "NAME" 不会删除使用 "NAME=value" 设置的 cookie。您必须清除 cookie "NAME=",因为浏览器会区分它们。
示例
仅将登录 URL 移动到 HTTPS。
acl clear dst_port 80 acl secure dst_port 8080 acl login_page url_beg /login acl logout url_beg /logout acl uid_given url_reg /login?userid=[^&]+ acl cookie_set hdr_sub(cookie) SEEN=1 redirect prefix https://mysite.com set-cookie SEEN=1 if !cookie_set redirect prefix https://mysite.com if login_page !secure redirect prefix http://mysite.com drop-query if login_page !uid_given redirect location http://mysite.com/ if !login_page secure redirect location / clear-cookie USERID= if logout
示例
为不带 '/' 的文章请求发送重定向。
acl missing_slash path_reg ^/article/[^/]*$ redirect code 301 prefix / drop-query append-slash if missing_slash
示例
当 SSL 由 HAProxy 处理时,将所有 HTTP 流量重定向到 HTTPS。
redirect scheme https if !{ ssl_fc }
示例
在所有没有 'www.' 前缀的主机前添加该前缀
http-request redirect code 301 location \ http://www.%[hdr(host)]%[capture.req.uri] \ unless { hdr_beg(host) -i www }
示例
仅将旧 URL 永久重定向到新 URL
http-request redirect code 301 location \ %[path,map_str(old-blog-articles.map)] ignore-empty
有关 ACL 的用法,请参见第 7 节
retries <value>
设置在服务器失败后对其执行的重试次数 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<value> 是在服务器失败后,请求或连接尝试应重试的次数。
默认情况下,重试仅适用于新的连接尝试。但是,当使用 "retry-on" 指令时,其他条件可能会触发重试(例如空响应、不需要的状态代码),并且每次都会计算一次尝试,当总尝试次数达到此值时,将返回错误。为了避免立即重新连接到正在重新启动的服务器,在同一服务器上发生重试之前应用了 min("timeout connect"、一秒) 的周转计时器。当设置了 "option redispatch" 时,即使 cookie 引用了不同的服务器,也可以在另一台服务器上执行一些重试。默认情况下,这只会是最后一次重试,除非将参数传递给 "option redispatch"。
retry-on [以空格分隔的关键字列表]
指定何时尝试自动重试失败的请求。此设置仅在 "mode" 设置为 http 时有效,否则将被静默忽略。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<keywords> 是一个空格分隔的关键字或 HTTP 状态代码列表,每个关键字或状态代码都代表一种失败事件类型,希望对该事件重试请求。在更改此设置之前,请阅读底部的注释。支持以下关键字:none 永不重试 conn-failure 当连接或 SSL 握手失败且请求无法发送时重试。这是默认值。empty-response 当服务器连接在发送部分请求后关闭,并且未从服务器收到任何内容时重试。此类故障可能是由服务器端的请求超时、网络状况不佳或服务器在处理请求时崩溃或重新启动引起的。junk-response 当服务器返回的内容看起来不像完整的 HTTP 响应时重试。这包括部分响应标头以及非 HTTP 内容。对此类事件重试通常是一个坏主意,这可能是由配置问题(错误的服务器端口)或请求对服务器有害(例如缓冲区溢出攻击)引起的。response-timeout 等待服务器响应请求时服务器超时。这可能是由于网络状况不佳、空闲连接在路径上过期后重用或请求处理成本极高造成的。对于处理繁重数据库处理(全扫描等)的服务器,对此类事件重试通常是一个坏主意,因为它可能会放大拒绝服务攻击。0rtt-rejected 重试通过早期数据发送但被服务器拒绝的请求。这些请求通常被认为是安全的重试。<status> 任何 HTTP 状态代码,包括 "401" (Unauthorized)、"403" (Forbidden)、"404" (Not Found)、"408" (Request Timeout)、"425" (Too Early)、"500" (Server Error)、"501" (Not Implemented)、"502" (Bad Gateway)、"503" (Service Unavailable)、"504" (Gateway Timeout)。all-retryable-errors 对任何被认为是可重试的错误重试请求。这目前激活 "conn-failure"、"empty-response"、"junk-response"、"response-timeout"、"0rtt-rejected"、"500"、"502"、"503" 和 "504"。
使用此指令将替换所有以前的设置;它不是累积的。请注意,使用 "none" 和 "conn-failure" 之外的任何内容都需要分配缓冲区并将整个请求复制到其中,因此它具有内存和性能影响。不适合单个缓冲区的请求将永远不会重试(请参阅全局 tune.bufsize 设置)。您必须确保应用程序具有内置的重放保护机制,例如在请求中传递唯一的事务 ID,或者重放相同的请求没有后果,否则使用除 "conn-failure" 和 "none" 之外的任何 retry-on 值都非常危险。静态文件服务器和缓存通常被认为是安全的,可以抵御任何类型的重试。使用状态代码对于快速离开显示异常行为(内存不足、文件系统问题等)的服务器可能很有用,但在这种情况下,立即将连接重新分配给另一台服务器可能是一个好主意(请参阅 "option redispatch")。最后,重要的是要了解大多数故障原因都是请求本身,并且重试导致服务器行为不端的请求通常会使该服务器的情况,或者在重新分配的情况下使整个服务的情况变得更糟。除非您确切知道应用程序如何处理重放的请求,否则不应使用此指令。默认值为 "conn-failure"。
示例
retry-on 503 504
server <name> <address>[:[port]] [param*]
在后端声明一个服务器 可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<name> 是分配给此服务器的内部名称。此名称将出现在日志和警报中。如果设置了 "http-send-name-header",它将添加到发送到服务器的请求标头中。<address> 是服务器的 IPv4 或 IPv6 地址。或者,支持可解析的主机名,但此名称将在启动期间解析。地址 "0.0.0.0" 或 "*" 具有特殊含义。它表示连接将转发到与客户端连接相同的 IP 地址。这在透明代理架构中很有用,其中客户端的连接被拦截,HAProxy 必须转发到原始目标地址。这或多或少是 "transparent" 关键字所做的,除了使用服务器可以限制并发并报告统计信息。可选地,可以在地址前使用地址族前缀来强制使用该族,而不管地址格式如何,这对于指定没有斜杠 ('/') 的 unix 套接字路径很有用。目前支持的前缀是: - 'ipv4@' -> 地址始终为 IPv4 - 'ipv6@' -> 地址始终为 IPv6 - 'unix@' -> 地址是本地 unix 套接字的路径 - 'abns@' -> 地址位于抽象命名空间中(仅限 Linux) - 'sockpair@' -> 地址是连接的 unix 套接字或 socketpair 的 FD。在连接期间,backend 创建一对连接的套接字,并通过 FD 传递其中一个。bind 部分将使用接收到的套接字作为客户端 FD。应谨慎使用。 - 'rhttp@' [ EXPERIMENTAL ] -> HTTP 反向上下文中被动服务器的自定义地址族。这是一个实验性功能,需要在该服务器前面的行上使用 "expose-experimental-directives"。您可能希望在地址参数中引用一些环境变量,请参阅有关环境变量的第 2.3 节。"init-addr" 设置可用于修改启动时解析 IP 地址的方式。<port> 是可选的端口规范。如果设置,所有连接都将发送到此端口。如果未设置,则使用客户端连接到的同一端口。端口也可以以 "+" 或 "-" 为前缀。在这种情况下,服务器的端口将通过将此值添加到客户端端口来确定。<param*> 是此服务器的参数列表。关键字 "server" 接受大量选项,并有一个完整的章节专门介绍它。请参阅第 5 节了解更多详细信息。
示例
server first 10.1.1.1:1080 cookie first check inter 1000 server second 10.1.1.2:1080 cookie second check inter 1000 server transp ipv4@ server backup "${SRV_BACKUP}:1080" backup server www1_dc1 "${LAN_DC1}.101:80" server www1_dc2 "${LAN_DC2}.101:80"
注意:关于 Linux 的抽象命名空间套接字,HAProxy 使用整个 sun_path 长度作为地址长度。其他一些程序,如 socat,默认只使用字符串长度。在 socat 中对任何抽象套接字定义传递选项 ",unix-tightsocklen=0",以使其与 HAProxy 兼容。
server-state-file-name [ { use-backend-name | <file> } ]
设置要读取、加载并应用于此后端中可用服务器的服务器状态文件。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
它仅在指令 "load-server-state-from-file" 设置为 "local" 时适用。当未提供 <file> 时,如果使用了 "use-backend-name" 或未设置此指令,则使用后端名称。如果 <file> 以斜杠 '/' 开头,则它被视为绝对路径。否则,<file> 将与全局指令 "server-state-base" 连接。
示例
下面的最小配置将使 HAProxy 查找状态服务器文件 '/etc/haproxy/states/bk'
global server-state-file-base /etc/haproxy/states backend bk load-server-state-from-file
server-template <prefix> <num | range> <fqdn>[:<port>] [params*]
设置一个模板来初始化具有共享参数的服务器。这些服务器的名称由 <prefix> 和 <num | range> 参数构建。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<prefix> 要构建的服务器名称的前缀。<num | range> 如果提供了 <num>,此模板将初始化 <num> 个服务器,服务器名称后缀从 1 到 <num>。数字范围 <num_low>-<num_high> 也可用于将 <num_low> 到 <num_high> 用作服务器名称后缀。<fqdn> 此模板初始化的所有服务器的 FQDN。<port> 与 "server" <port> 参数具有相同的含义(请参阅 "server" 关键字)。<params*> "server" 关键字支持的所有其余服务器参数。
示例
# 初始化 3 个服务器,名称分别为 srv1、srv2 和 srv3, # FQDN 为 google.com,并启用了健康检查。 server-template srv 1-3 google.com:80 check # 或 server-template srv 3 google.com:80 check # 将等同于: server srv1 google.com:80 check server srv2 google.com:80 check server srv3 google.com:80 check
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
source <addr>[:<port>] [interface <name>]
设置出站连接的源地址 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<addr> 是 HAProxy 在连接到服务器之前将绑定的 IPv4 地址。此地址也用作健康检查的源地址。默认值 0.0.0.0 意味着系统将选择最合适的地址来到达目的地。可以选择在地址之前使用地址族前缀来强制指定地址族,而不管地址格式如何,这对于指定没有斜杠 ('/') 的 unix 套接字路径很有用。目前支持的前缀有: - 'ipv4@' -> 地址始终为 IPv4 - 'ipv6@' -> 地址始终为 IPv6 - 'unix@' -> 地址是本地 unix 套接字的路径 - 'abns@' -> 地址位于抽象命名空间中(仅限 Linux) 您可能希望在 address 参数中引用一些环境变量,请参阅第 2.3 节关于环境变量的内容。 <port> 是一个可选端口。通常不需要它,但在某些非常特定的上下文中可能有用。默认值零意味着系统将选择一个空闲端口。请注意,后端不支持端口范围。如果要强制使用端口范围,则必须在每行 "server" 上指定它们。 <addr2> 是在全透明代理模式下转发连接时向服务器显示的 IP 地址。目前仅在某些打了补丁的 Linux 内核上支持此功能。指定此地址后,连接到服务器的客户端将显示此地址,而健康检查仍将使用地址 <addr>。 <port2> 是在全透明代理模式下转发连接时向服务器显示的可选端口(请参阅上面的 <addr2>)。默认值零意味着系统将选择一个空闲端口。 <hdr> 是用于获取绑定 IP 的 HTTP 标头的名称。这是一个逗号分隔的标头列表的名称,其中可以包含多个 IP 地址。默认情况下,使用最后一次出现。这旨在与 X-Forwarded-For 标头配合使用,并自动绑定到上一个代理(通常是 Stunnel)看到的客户端 IP 地址。为了使用最后一次出现以外的其他出现,请参阅下面的 <occ> 参数。当找不到标头(或出现)时,不执行绑定,以便使用代理的默认 IP 地址。另请记住,与任何 HTTP 标头一样,标头名称不区分大小写。 <occ> 是要在多值标头中使用的值的出现次数。这与 "hdr_ip(<hdr>)" 结合使用,用于指定用于源 IP 地址的出现次数。正值表示从第一次出现开始的位置,1 是第一次出现。负值表示相对于最后一次出现的位置,-1 是最后一次出现。这对于在基础设施入口点设置 X-Forwarded-For 标头并且必须在多个代理层之外使用的情况很有帮助。如果未指定此值,则假定为 -1。在此处传递零会禁用此功能。 <name> 是一个可选接口名称,用于绑定出站流量。在支持此功能的系统上(目前仅限 Linux),即使系统根据路由表未选择此接口,此功能也允许将所有流量绑定到服务器。使用此功能时应格外小心。请注意,使用此选项需要 root 权限。
"source" 关键字在复杂的环境中非常有用,在这些环境中,只允许特定地址连接到服务器。例如,当必须通过公共网关使用私有地址时,并且已知系统无法自行确定适当的源地址时,可能需要它。在某些打了补丁的 Linux 内核上可用的扩展可以通过 "usesrc" 可选关键字使用。它使得使用不属于系统本身的 IP 地址连接到服务器成为可能。这称为“全透明代理模式”。为此,目标服务器必须通过运行 HAProxy 的机器将流量路由回此地址,并且通常必须在此机器上启用 IP 转发。在这种“全透明代理”模式下,可以强制向服务器显示特定的 IP 地址。实际上很少使用。更常见的用法是告诉 HAProxy 显示客户端的 IP 地址。为此,有两种方法: - 显示客户端的 IP 和端口地址。这是最透明的模式,但当机器上启用了 IP 连接跟踪时,可能会导致问题,因为同一个连接可能会被看到两次,状态不同。但是,此解决方案具有巨大的优势,即不限制系统使用 64k 个出站地址+端口对,因为可以使用所有客户端范围。 - 仅显示客户端的 IP 地址并选择一个备用端口。此解决方案仍然非常优雅,但透明度稍低(下游防火墙日志将与上游不匹配)。它还具有将并发连接数限制为通常的 64k 端口的缺点。然而,由于上游和下游端口不同,机器上的本地 IP 连接跟踪不会因重用同一会话而感到不安。此选项为后端中的所有服务器设置默认源。也可以在 "defaults" 部分中指定。使用 "source" 服务器选项可以在服务器级别指定更精细的源地址。有关详细信息,请参阅第 5 节。为了工作,"usesrc" 需要 root 权限,或者在受支持的系统上需要 "cap_net_raw" 功能。另请参阅 "setcap" 全局指令。
示例
backend private # Connect to the servers using our 192.168.1.200 source address source 192.168.1.200 backend transparent_ssl1 # Connect to the SSL farm from the client's source address source 192.168.1.200 usesrc clientip backend transparent_ssl2 # Connect to the SSL farm from the client's source address and port # not recommended if IP conntrack is present on the local machine. source 192.168.1.200 usesrc client backend transparent_ssl3 # Connect to the SSL farm from the client's source address. It # is more conntrack-friendly. source 192.168.1.200 usesrc clientip backend transparent_smtp # Connect to the SMTP farm from the client's source address/port # with Tproxy version 4. source 0.0.0.0 usesrc clientip backend transparent_http # Connect to the servers using the client's IP as seen by previous # proxy. source 0.0.0.0 usesrc hdr_ip(x-forwarded-for,-1)
srvtcpka-cnt <count>
设置 TCP 在服务器端断开连接之前应发送的最大 keepalive 探测次数。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<count> 是 keepalive 探测的最大次数。
此关键字对应于套接字选项 TCP_KEEPCNT。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_probes)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
srvtcpka-idle <timeout>
设置连接需要保持空闲多长时间后,TCP 开始发送 keepalive 探测(如果在服务器端启用了 TCP keepalive 数据包的发送)。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是连接需要保持空闲的时间,之后 TCP 开始发送 keepalive 探测。默认以秒为单位指定,但如果数字后跟单位后缀,也可以是任何其他单位,如本文档开头所述。
此关键字对应于套接字选项 TCP_KEEPIDLE。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_time)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
srvtcpka-intvl <timeout>
设置服务器端各个 keepalive 探测之间的时间。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是各个 keepalive 探测之间的时间。默认以秒为单位指定,但如果数字后跟单位后缀,也可以是任何其他单位,如本文档开头所述。
此关键字对应于套接字选项 TCP_KEEPINTVL。如果未指定此关键字,则使用系统范围的 TCP 参数 (tcp_keepalive_intvl)。此设置的可用性取决于操作系统。已知在 Linux 上可以工作。
stats admin { if | unless } <cond>
如果/除非条件匹配,则启用统计信息管理级别 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
此语句如果/除非条件匹配,则启用统计信息管理级别。管理级别允许从 Web 界面启用/禁用服务器。出于安全原因,默认情况下统计信息页面是只读的。目前,POST 请求受限于缓冲区大小减去保留的缓冲区空间,这意味着如果服务器列表太长,请求将不会被处理。建议一次只更改少量服务器。
示例
# 仅对 localhost 启用统计信息管理级别 backend stats_localhost stats enable stats admin if LOCALHOST
示例
# 由于身份验证,统计信息管理级别始终启用 backend stats_auth stats enable stats auth admin:AdMiN123 stats admin if TRUE
示例
# 统计信息管理级别取决于经过身份验证的用户 userlist stats-auth group admin users admin user admin insecure-password AdMiN123 group readonly users haproxy user haproxy insecure-password haproxy backend stats_auth stats enable acl AUTH http_auth(stats-auth) acl AUTH_ADMIN http_auth_group(stats-auth) admin stats http-request auth unless AUTH stats admin if AUTH_ADMIN
stats auth <user>:<passwd>
启用带身份验证的统计信息并授予帐户访问权限 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<user> 是要授予访问权限的用户名 <passwd> 是与此用户关联的明文密码
此语句启用具有默认设置的统计信息,并仅限制对声明用户的访问。它可以根据需要重复多次以允许任意数量的用户。当用户尝试访问统计信息而没有有效帐户时,将返回“401 Forbidden”响应,以便浏览器要求用户提供有效的用户和密码。返回给浏览器的真实信息可以使用 "stats realm" 配置。由于身份验证方法是 HTTP Basic Authentication,密码在网络上以明文形式传输。因此,决定配置中也使用明文密码,以提醒用户这些密码不应是敏感的,也不应与其他任何帐户共享。还可以使用 "stats scope" 缩小报告中显示的代理范围。尽管此语句本身足以启用统计信息报告,但建议设置所有其他设置以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
使用默认设置启用统计信息报告 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
此语句使用构建时定义的默认设置启用统计报告。除非另有说明,否则将使用以下设置:- stats uri : /haproxy?stats - stats realm : "HAProxy Statistics" - stats auth : 无身份验证 - stats scope : 无限制 尽管此语句本身足以启用统计报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
启用统计信息并隐藏 HAProxy 版本报告 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
默认情况下,统计页面会报告一些有用的状态信息以及统计数据。其中包括 HAProxy 的版本。但是,通常认为向任何人报告精确的版本是危险的,因为它可能帮助他们利用已知弱点进行特定攻击。“stats hide-version”语句从统计报告中移除版本信息。建议对公共站点或任何具有弱登录名/密码的站点使用此功能。尽管此语句本身足以启用统计报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
stats http-request { allow | deny | auth [realm <realm>] } [ { if | unless } <condition> ]
统计信息访问控制 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
与 "http-request" 类似,这组选项允许精细控制对统计信息的访问。每个选项后面都可以跟 if/unless 和 acl。第一个匹配条件的选项(或没有条件的选项)是最终的。对于 "deny",将返回 403 错误;对于 "allow",将执行正常处理;对于 "auth",将返回 401/407 错误代码,以便要求客户端输入用户名和密码。每个实例的 http-request 语句数量没有固定限制。
stats realm <realm>
启用统计信息并设置身份验证领域 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<realm> 是报告给浏览器的 HTTP 基本认证领域的名称。浏览器用它在弹出窗口中显示,邀请用户输入有效的用户名和密码。
领域被读取为单个词,因此其中的任何空格都应使用反斜杠('\')进行转义。此语句仅在与“stats auth”结合使用时才有用,因为它只与身份验证相关。尽管此语句本身足以启用统计报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
启用带自动刷新的统计信息 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<delay> 是建议的刷新延迟,以秒为单位指定,它将返回给查看报告页面的浏览器。虽然浏览器可以自由应用任何延迟,但通常会遵守它并每隔这么多秒刷新一次页面。刷新间隔可以用任何其他非默认的时间单位指定,方法是在值后面加上单位后缀,如本文档开头所述。
此语句在具有永久报告负载均衡器活动的监控显示器上很有用。设置后,HTML 报告页面将包含一个“刷新”/“停止刷新”链接,以便用户可以选择是否希望页面自动刷新。尽管仅此语句就足以启用统计信息报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
stats scope { <name> | "." }
启用统计信息并限制访问范围 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<name> 是要报告的 listen、frontend 或 backend 部分的名称。特殊名称“.”(一个点)表示该语句所在的节。
指定此语句后,只有使用此语句枚举的部分才会出现在报告中。所有其他部分都将被隐藏。如果需要报告多个部分,此语句可以根据需要出现多次。请注意,名称检查是作为简单的字符串比较执行的,并且从不检查给定的部分名称是否真的存在。尽管此语句本身足以启用统计报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
stats show-desc [ <desc> ]
在统计信息页面上启用描述报告。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
<desc> 是一个可选的要报告的描述。如果未指定,则自动使用全局部分的描述。此语句对于向客户提供共享服务的用户非常有用,其中每个客户的节点或描述应该不同。尽管此语句本身足以启用统计报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。默认情况下不显示描述。
示例
# 内部监控访问(无限制) backend private_monitoring stats enable stats show-desc Master node for Europe, Asia, Africa stats uri /admin?stats stats refresh 5s
在统计信息页面上启用报告附加信息 可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
在统计信息页面上启用报告附加信息: - cap: 功能(代理) - mode: tcp, http 或 health 之一(代理) - id: SNMP ID(代理、套接字、服务器) - IP(套接字、服务器) - cookie(后端、服务器) 尽管仅此语句就足以启用统计信息报告,但建议设置所有其他设置,以避免依赖默认的不明显参数。默认行为是不显示此信息。
启用在统计页面上显示额外的统计模块。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数:
新的列会以工具提示的形式添加到包含额外统计值行的末尾。虽然仅此语句就足以启用统计报告,但建议设置所有其他设置,以避免依赖于默认的不明显参数。默认行为是不显示此信息。
stats show-node [ <name> ]
在统计页面上启用主机名报告。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<name> 是一个可选的要报告的名称。如果未指定,则自动使用全局部分的节点名称。
此语句对于向其客户提供共享服务的用户非常有用,在为每个客户提供的统计页面上,节点或描述可能会有所不同。默认行为是不显示主机名。虽然仅此语句就足以启用统计报告,但建议设置所有其他设置,以避免依赖于默认的不明显参数。
示例
# 内部监控访问(无限制) backend private_monitoring stats enable stats show-node Europe-1 stats uri /admin?stats stats refresh 5s
stats uri <prefix>
启用统计并定义用于访问它们的 URI 前缀。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<prefix> 是任何将被重定向到统计信息的 URI 的前缀。此前缀可能包含一个问号('?')以指示查询字符串的一部分。
统计信息 URI 在转发流量上被拦截,因此它显示为正常应用程序中的页面。强烈建议确保所选 URI 永远不会出现在应用程序中,否则将永远无法在应用程序中访问它。HAProxy 中编译的默认 URI 是 "/haproxy?stats",但这可以在构建时更改,因此最好始终在此处显式指定它。通常在 URI 中包含问号是一个好主意,这样中间代理就不会缓存结果。此外,由于任何以该前缀开头的字符串都将被接受为统计信息请求,因此问号有助于确保没有有效的 URI 以相同的词开头。有时使用 "/" 作为 URI 前缀并将该语句放在自己的 "listen" 实例中非常方便。这使得为统计信息专门分配一个地址或端口变得容易。尽管此语句本身足以启用统计信息报告,但建议设置所有其他设置以避免依赖默认的不明显参数。
示例
# 公共访问(仅限于此后端) backend public_www server srv1 192.168.0.1:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321 # 内部监控访问(无限制) backend private_monitoring stats enable stats uri /admin?stats stats refresh 5s
stick match <pattern> [table <table>] [{if | unless} <cond>]
定义一个请求模式匹配条件,以将用户粘滞(stick)到一台服务器。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<pattern> 是 第 7.3 节 中描述的样本表达式规则。它描述了将分析传入请求或连接的哪些元素,以期在粘性表中找到匹配的条目。此规则是强制性的。 <table> 是一个可选的粘性表名称。如果未指定,则使用相同后端的表。粘性表使用 "stick-table" 语句声明。 <cond> 是一个可选的匹配条件。它使得仅在满足(或不满足)其他条件时才对某个标准进行匹配成为可能。例如,它可以用于匹配源 IP 地址,除非请求通过一个已知的代理,在这种情况下,我们将匹配包含该 IP 地址的头。
某些协议或应用程序需要复杂的粘性规则,并且不能总是简单地依赖 cookie 或哈希。"stick match" 语句描述了一个规则,用于从传入请求或连接中提取粘性标准。有关可能的模式和转换规则的完整列表,请参阅第 7 节。该表必须使用 "stick-table" 语句声明。它必须是与模式兼容的类型。默认情况下,它是同一后端中存在的表。可以通过使用 "table" 关键字引用它来与其他后端共享表。如果引用了另一个表,则使用后端内部的服务器 ID。默认情况下,所有服务器 ID 在每个后端都从 1 开始,因此服务器顺序就足够了。但如有疑问,强烈建议使用服务器的 "id" 设置来强制设置服务器 ID。可以使用后跟条件的 "if" 或 "unless" 来限制 "stick match" 语句适用的条件。有关基于 ACL 的条件,请参阅第 7 节。"stick match" 语句的数量没有限制。第一个适用且匹配的请求将导致请求被定向到与创建条目的请求所使用的服务器相同的服务器。这样,多个匹配可以用作回退。粘性规则在持久性 cookie 之后检查,因此如果已使用 cookie 选择服务器,它们将不会影响粘性。这样,插入 cookie 和匹配 IP 地址以维护 HTTP 和 HTTPS 之间的粘性变得非常容易。
示例
# 将 SMTP 用户转发到他们在过去 30 分钟内 # 刚刚用于 POP 的同一台服务器 backend pop mode tcp balance roundrobin stick store-request src stick-table type ip size 200k expire 30m server s1 192.168.1.1:110 server s2 192.168.1.1:110 backend smtp mode tcp balance roundrobin stick match src table pop server s1 192.168.1.1:25 server s2 192.168.1.1:25
stick on <pattern> [table <table>] [{if | unless} <condition>]
定义一个请求模式,将用户与服务器关联。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
注意:此形式完全等同于后跟 "stick store-request" 的 "stick match",所有参数都相同。请参考这两个关键字以获取详细信息。它仅作为编写更易维护的配置的便利方式提供。
示例
# 以下形式... stick on src table pop if !localhost # ...与此形式完全等价: stick match src table pop if !localhost stick store-request src table pop if !localhost # 对 HTTP 使用 cookie 持久性,对 HTTPS 以及 # 没有 cookie 的 HTTP 使用源地址粘滞。在两种访问之间共享同一个表。 backend http mode http balance roundrobin stick on src table https cookie SRV insert indirect nocache server s1 192.168.1.1:80 cookie s1 server s2 192.168.1.1:80 cookie s2 backend https mode tcp balance roundrobin stick-table type ip size 200k expire 30m stick on src server s1 192.168.1.1:443 server s2 192.168.1.1:443
stick store-request <pattern> [table <table>] [{if | unless} <condition>]
定义一个请求模式,用于在粘滞表中创建一个条目。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<pattern> 是 第 7.3 节 中描述的样本表达式规则。它描述了在选择服务器后,将分析、提取并存储在表中的传入请求或连接的哪些元素。 <table> 是一个可选的粘性表名称。如果未指定,则使用相同后端的表。粘性表使用 "stick-table" 语句声明。 <cond> 是一个可选的存储条件。它使得仅在满足(或不满足)某些条件时才存储某些标准成为可能。例如,它可以用于存储源 IP 地址,除非请求通过一个已知的代理,在这种情况下,我们将存储一个包含该 IP 地址的头的转换形式。
某些协议或应用程序需要复杂的粘性规则,并且不能总是简单地依赖 cookie 或哈希。"stick store-request" 语句描述了一个规则,用于决定从请求中提取什么以及何时提取,以便将其存储到粘性表中,供后续请求使用 "stick match" 语句进行匹配。显然,提取的部分必须有意义,并且有机会在后续请求中匹配。例如,存储客户端的 IP 地址通常是有意义的。存储在 URL 参数中找到的 ID 也是有意义的。存储源端口几乎永远没有意义,因为它会被随机匹配。有关可能的模式和转换规则的完整列表,请参阅第 7 节。该表必须使用 "stick-table" 语句声明。它必须是与模式兼容的类型。默认情况下,它是同一后端中存在的表。可以通过使用 "table" 关键字引用它来与其他后端共享表。如果引用了另一个表,则使用后端内部的服务器 ID。默认情况下,所有服务器 ID 在每个后端都从 1 开始,因此服务器顺序就足够了。但如有疑问,强烈建议使用服务器的 "id" 设置来强制设置服务器 ID。可以使用后跟条件的 "if" 或 "unless" 来限制 "stick store-request" 语句适用的条件。此条件将在解析请求时进行评估,因此可以使用任何标准。有关基于 ACL 的条件,请参阅第 7 节。"stick store-request" 语句的数量没有限制,但每个请求或响应同时存储的数量限制为 8 个。这使得最多可以存储 8 个标准,所有这些标准都从请求或响应中提取,而不管规则的数量如何。只有前 8 个匹配的才会被保留。使用此功能,可以一次向多个表提供数据,以期增加在另一种协议或访问方法上识别用户的机会。使用具有相同表的多个 store-request 规则是可能的,并且可以通过按偏好降序排列规则来用于找到要依赖的最佳标准。对于给定的表,只会存储第一个提取的标准。引用同一表的所有后续 store-request 规则将被跳过,并且不会评估其 ACL。在建立服务器连接后评估 "store-request" 规则,以便表将包含处理请求的实际服务器。
示例
# 将 SMTP 用户转发到他们在过去 30 分钟内 # 刚刚用于 POP 的同一台服务器 backend pop mode tcp balance roundrobin stick store-request src stick-table type ip size 200k expire 30m server s1 192.168.1.1:110 server s2 192.168.1.1:110 backend smtp mode tcp balance roundrobin stick match src table pop server s1 192.168.1.1:25 server s2 192.168.1.1:25
stick-table type {ip | integer | string [len <length>] | binary [len <length>]} size <size> [expire <expire>] [nopurge] [peers <peersect>] [srvkey <srvkey>] [write-to <wtable>] [store <data_type>]*
为当前部分配置粘滞表。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

yes
参数
ip 声明为 "type ip" 的表将仅存储 IPv4 地址。此形式非常紧凑(每个条目约 50 字节),允许非常快的条目查找和存储,几乎没有开销。这主要用于存储客户端源 IP 地址。 ipv6 声明为 "type ipv6" 的表将仅存储 IPv6 地址。此形式非常紧凑(每个条目约 60 字节),允许非常快的条目查找和存储,几乎没有开销。这主要用于存储客户端源 IP 地址。 integer 声明为 "type integer" 的表将存储 32 位整数,例如,它可以表示在请求中找到的客户端标识符。 string 声明为 "type string" 的表将存储最多 <len> 个字符的子字符串。如果模式提取器提供的字符串大于 <len>,则在存储之前将其截断。在匹配期间,表中的字符串与提取的模式之间最多比较 <len> 个字符。如果未指定,则字符串自动限制为 32 个字符。 binary 声明为 "type binary" 的表将存储 <len> 字节的二进制块。如果模式提取器提供的块大于 <len>,则在存储之前将其截断。如果样本表达式提供的块短于 <len>,则会用 0 填充。如果未指定,则块自动限制为 32 个字节。 <length> 是将存储在 "string" 类型表中的最大字符数(请参阅上面的 type "string")。或 "binary" 类型表中的块字节数。更改此参数时要小心,因为内存使用量会成比例增加。 <size> 是表中可以容纳的最大条目数。此值直接影响内存使用量。粗略计算每个条目 50 字节,加上字符串的大小(如果有)。大小支持后缀 "k"、"m"、"g" 分别表示 2^10、2^20 和 2^30 因子。 [nopurge] 指示当表满时我们拒绝清除旧条目。如果未指定且当 HAProxy 想要在其中存储条目时表已满,它将刷新一些最旧的条目以释放一些空间用于新条目。这通常是期望的行为。在某些特定情况下,可能需要拒绝新条目而不是清除旧条目。当要存储的数据量远远超出硬件限制时,或者我们宁愿不向新客户端提供访问权限,也不愿拒绝已连接的客户端时,可能会出现这种情况。使用此参数时,请确保正确设置 "expire" 参数(请参阅下文)。 <peersect> 是用于复制的对等部分名称。将键与服务器 ID 相关联的条目与在此部分中声明的远程对等体保持同步。在软重启期间,所有条目也会自动从本地对等体(旧进程)中学习。 <wtable> 是 stick table 的名称,除了源表之外,对等更新也会写入其中。<wtable> 必须与正在定义的表具有相同的类型,并且必须具有相同的键长度,并且源表本身不能用作目标表。每当通过对等体在源表上接收到条目更新时,haproxy 都会尝试刷新相关的 <wtable> 条目。如果条目尚不存在,它将创建,否则其值和计时器将被更新。请注意,只有不涉及算术运算的类型(例如 server_id、server_key 和 gpt)才会被写入 <wtable>,以防止来自远程表的已处理值干扰在本地目标表上执行的算术运算。(即:防止共享累加计数器无限增长)此选项的一个常见用途是能够在对等集群设置中使用粘性规则(用于服务器持久性),因为匹配键将从远程表学习。 <expire> 定义条目在表中自上次创建、使用 'track-sc' 刷新或使用 'stick match' 或 'stick on' 规则匹配以来的最大持续时间。过期延迟使用标准时间格式定义,类似于各种超时。最大持续时间略高于 24 天。有关详细信息,请参阅第 2.5 节。如果未指定此延迟,则会话不会自动过期,但一旦满,旧条目将被删除。请确保在未指定过期延迟时不要使用 "nopurge" 参数。注意:'table_*' 转换器执行查找,但不会更新接触过期时间,因为它们不需要 'track-sc'。 <srvkey> 指定如何为 stick table 的目的识别每个服务器。有效值是 "name" 和 "addr"。如果给定 "name",则为服务器的 <name> 参数(可能由模板生成)。如果给定 "addr",则通过其当前网络地址(包括端口)识别服务器。" addr" 在使用服务发现为具有对等 stick table 的服务器生成地址并希望在对等体之间始终对粘性令牌使用相同主机时特别有用。 <data_type> 用于在 stick table 中存储附加信息。这可以由 ACL 使用,以控制与匹配 stick table 的客户端活动相关的各种标准。对于此处指定的每个项目,每个条目的大小都会增加,以便可以容纳附加数据。一个条目可以存储多种数据类型。可以在 "store" 关键字之后指定多个数据类型,作为逗号分隔列表。或者,可以重复 "store" 关键字,后跟一个或多个数据类型。除了自动检测和启用的 "server_id" 类型外,所有数据类型都必须显式声明才能存储。如果 ACL 引用了未存储的数据类型,则 ACL 将简单地不匹配。某些数据类型需要一个参数,该参数必须紧跟在类型之后(在括号之间)传递。请参阅下面支持的数据类型及其参数。
可以与条目一起存储的数据类型如下: - server_id:这是一个整数,用于保存分配请求的服务器的数字 ID。它由 "stick match"、"stick store" 和 "stick on" 规则使用。引用时会自动启用。 - gpc(<nb>):通用计数器数组,包含 <nb> 个元素。这是一个正 32 位整数数组,可用于计算任何内容。大多数情况下,它们将用作某些条目上的增量计数器,例如,用于记录达到限制并触发某些操作。此数组最多限制为 100 个元素:gpc0 到 gpc99,以确保对等更新消息的构建可以容纳在缓冲区中。用户应考虑到大量的计数器会增加数据大小和使用对等协议的流量负载,因为每次更新时都会推送所有数据/计数器。此 data_type 将排除在同一表上使用旧版 data_types 'gpc0' 和 'gpc1'。使用 'gpc' 数组 data_type,所有 'gpc0' 和 'gpc1' 相关的获取和操作将应用于此数组的前两个元素。 - gpc_rate(<nb>,<period>):通用计数器在一段时间内的增量率数组。这些元素是正 32 位整数,可用于任何用途。就像 <gpc> 一样,计算事件,但不是保留累积数字,而是维护计数器递增的速率。大多数情况下,它将用于测量某些事件(例如,对特定 URL 的请求)发生的频率。此数组最多限制为 100 个元素:gpt(100) 允许存储 gpc0 到 gpc99,以确保对等更新消息的构建可以容纳在缓冲区中。数组不能包含少于 1 个元素:如果只想存储计数器 gpc0,请使用 gpc(1)。用户应考虑到大量的计数器会增加数据大小和使用对等协议的流量负载,因为每次更新时都会推送所有数据/计数器。此 data_type 将排除在同一表上使用旧版 data_types 'gpc0_rate' 和 'gpc1_rate'。使用 'gpc_rate' 数组 data_type,所有 'gpc0' 和 'gpc1' 相关的获取和操作将应用于此数组的前两个元素。 - gpc0:第一个通用计数器。它是一个正 32 位整数,可用于任何用途。大多数情况下,它将用于在某些条目上放置特殊标签,例如,用于记录检测到特定行为并且必须为将来匹配所知。 - gpc0_rate(<period>):第一个通用计数器在一段时间内的增量率。它是一个正 32 位整数,可用于任何用途。就像 <gpc0> 一样,它计算事件,但不是保留累积数字,而是维护计数器递增的速率。大多数情况下,它将用于测量某些事件(例如,对特定 URL 的请求)发生的频率。 - gpc1:第二个通用计数器。它是一个正 32 位整数,可用于任何用途。大多数情况下,它将用于在某些条目上放置特殊标签,例如,用于记录检测到特定行为并且必须为将来匹配所知。 - gpc1_rate(<period>):第二个通用计数器在一段时间内的增量率。它是一个正 32 位整数,可用于任何用途。就像 <gpc1> 一样,它计算事件,但不是保留累积数字,而是维护计数器递增的速率。大多数情况下,它将用于测量某些事件(例如,对特定 URL 的请求)发生的频率。 - gpt(<nb>):通用标签数组,包含 <nb> 个元素。这是一个正 32 位整数数组,可用于任何用途。大多数情况下,它们将用于在某些条目上放置特殊标签,例如,用于记录检测到特定行为并且必须为将来匹配所知。此数组最多限制为 100 个元素:gpt(100) 允许存储 gpt0 到 gpt99,以确保对等更新消息的构建可以容纳在缓冲区中。数组不能包含少于 1 个元素:如果只想存储标签 gpt0,请使用 gpt(1)。用户应考虑到大量的计数器会增加数据大小和使用对等协议的流量负载,因为每次更新时都会推送所有数据/计数器。此 data_type 将排除在同一表上使用旧版 data_type 'gpt0'。使用 'gpt' 数组 data_type,所有 'gpt0' 相关的获取和操作将应用于此数组的第一个元素。 - gpt0:第一个通用标签。它是一个正 32 位整数,可用于任何用途。大多数情况下,它将用于在某些条目上放置特殊标签,例如,用于记录检测到特定行为并且必须为将来匹配所知。 - conn_cnt:连接计数。它是一个正 32 位整数,用于计算与此条目匹配的客户端接收到的连接的绝对数量。这并不意味着连接被接受,只是意味着它们被接收。 - conn_cur:当前连接数。它是一个正 32 位整数,用于存储条目的并发连接数。一旦传入连接匹配条目,它就会递增,一旦连接离开,它就会递减。这样就可以随时知道条目的确切并发连接数。 - conn_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均传入连接速率,以每周期连接数计算。结果是一个整数,可以使用 ACL 进行匹配。 - sess_cnt:会话计数。它是一个正 32 位整数,用于计算与此条目匹配的客户端接收到的会话的绝对数量。会话是层 4 规则接受的连接。 - sess_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均传入会话速率,以每周期会话数计算。结果是一个整数,可以使用 ACL 进行匹配。 - http_req_cnt:HTTP 请求计数。它是一个正 32 位整数,用于计算与此条目匹配的客户端接收到的 HTTP 请求的绝对数量。无论它们是否是有效请求都无关紧要。请注意,当在客户端使用 keep-alive 时,这与会话不同。 - http_req_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均 HTTP 请求速率,以每周期请求数计算。结果是一个整数,可以使用 ACL 进行匹配。无论它们是否是有效请求都无关紧要。请注意,当在客户端使用 keep-alive 时,这与会话不同。 - http_err_cnt:HTTP 错误计数。它是一个正 32 位整数,用于计算与此条目匹配的客户端引起的 HTTP 请求错误的绝对数量。在无效和截断的请求以及被拒绝或被 tarpit 的请求以及失败的身份验证上计算错误。如果服务器响应 4xx,则该请求也被计为错误,因为它是由客户端触发的错误(例如漏洞扫描)。 - http_err_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均 HTTP 请求错误率,以每周期请求数计算(请参阅上面的 http_err_cnt 了解哪些被计为错误)。结果是一个整数,可以使用 ACL 进行匹配。 - http_fail_cnt:HTTP 失败计数。它是一个正 32 位整数,用于计算与此条目匹配的服务器引起的 HTTP 响应失败的绝对数量。在无效和截断的响应以及除 501 或 505 之外的任何 5xx 响应上计算错误。它旨在与路径或 URI 结合使用以检测服务故障。 - http_fail_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均 HTTP 响应失败率,以每周期请求数计算(请参阅上面的 http_fail_cnt 了解哪些被计为失败)。结果是一个整数,可以使用 ACL 进行匹配。 - bytes_in_cnt:客户端到服务器的字节计数。它是一个正 64 位整数,用于计算与此条目匹配的客户端接收到的累积字节数。标头包含在计数中。这可用于限制照片或视频服务器上上传功能的滥用。 - bytes_in_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均传入字节率,以每周期字节数计算。它可用于检测上传过多过快的用户。警告:对于大上传,上传的数据量可能会在终止时计算一次,从而导致平均传输速度出现峰值,而不是平稳的传输速度。使用 "option contstats" 可以部分平滑,但这还不完美。建议使用 byte_in_cnt 以获得更好的公平性。 - bytes_out_cnt:服务器到客户端的字节计数。它是一个正 64 位整数,用于计算发送到与此条目匹配的客户端的累积字节数。标头包含在计数中。这可用于限制机器人滥用吸取整个站点。 - bytes_out_rate(<period>):频率计数器(占用 12 字节)。它接受一个整数参数 <period>,该参数以毫秒为单位指示测量平均值的周期长度。它报告该周期内的平均传出字节率,以每周期字节数计算。它可用于检测下载过多过快的用户。警告:对于大传输,传输的数据量可能会在终止时计算一次,从而导致平均传输速度出现峰值,而不是平稳的传输速度。使用 "option contstats" 可以部分平滑,但这还不完美。建议使用 byte_out_cnt 以获得更好的公平性。 每个代理只有一个 stick-table。在撰写本文档时,每个代理拥有多个表似乎没有用处。如果需要,只需创建一个带有 stick-table 的虚拟后端并引用它即可。重要的是要理解基于学习信息的粘性有一些限制,包括所有学习到的关联在重新启动时都会丢失,除非对等体配置正确以在重新启动时传输此类信息(推荐)。通常它可以作为补充,但不总是作为唯一的粘性。最后,存储许多数据类型时,内存需求可能很重要。确实,同时在每个条目中存储所有上述指标需要每个条目 116 字节,或者 100 万个条目的表需要 116 MB。这绝对不能忽视。
示例
# 在 5 分钟内跟踪多达 100 万个 IP 地址的计数器 # 并存储一个通用计数器和在 30 秒滑动窗口上计算的 # 平均连接速率。 stick-table type ip size 1m expire 5m store gpc0,conn_rate(30s)
stick store-response <pattern> [table <table>] [{if | unless} <condition>]
定义一个响应模式,用于在粘滞表中创建一个条目。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<pattern> 是 第 7.3 节 中描述的样本表达式规则。它描述了在选择服务器后,将分析、提取并存储在表中的响应或连接的哪些元素。 <table> 是一个可选的粘性表名称。如果未指定,则使用相同后端的表。粘性表使用 "stick-table" 语句声明。 <cond> 是一个可选的存储条件。它使得仅在满足(或不满足)某些条件时才存储某些标准成为可能。例如,它可以用于仅在响应是 SSL 服务器 hello 时存储 SSL 会话 ID。
某些协议或应用程序需要复杂的粘性规则,并且不能总是简单地依赖 cookie 或哈希。"stick store-response" 语句描述了一个规则,用于决定从响应中提取什么以及何时提取,以便将其存储到粘性表中,供后续请求使用 "stick match" 语句进行匹配。显然,提取的部分必须有意义,并且有机会在后续请求中匹配。存储在响应标头中找到的 ID 是有意义的。有关可能的模式和转换规则的完整列表,请参阅第 7 节。该表必须使用 "stick-table" 语句声明。它必须是与模式兼容的类型。默认情况下,它是同一后端中存在的表。可以通过使用 "table" 关键字引用它来与其他后端共享表。如果引用了另一个表,则使用后端内部的服务器 ID。默认情况下,所有服务器 ID 在每个后端都从 1 开始,因此服务器顺序就足够了。但如有疑问,强烈建议使用服务器的 "id" 设置来强制设置服务器 ID。可以使用后跟条件的 "if" 或 "unless" 来限制 "stick store-response" 语句适用的条件。此条件将在解析响应时进行评估,因此可以使用任何标准。有关基于 ACL 的条件,请参阅第 7 节。"stick store-response" 语句的数量没有限制,但每个请求或响应同时存储的数量限制为 8 个。这使得最多可以存储 8 个标准,所有这些标准都从请求或响应中提取,而不管规则的数量如何。只有前 8 个匹配的才会被保留。使用此功能,可以一次向多个表提供数据,以期增加在另一种协议或访问方法上识别用户的机会。使用具有相同表的多个 store-response 规则是可能的,并且可以通过按偏好降序排列规则来用于找到要依赖的最佳标准。对于给定的表,只会存储第一个提取的标准。引用同一表的所有后续 store-response 规则将被跳过,并且不会评估其 ACL。但是,即使 store-request 规则引用了一个表,store-response 规则也可以使用同一个表。这意味着每个表可以从请求中学习一个元素,并从响应中学习一个元素。表将包含处理请求的实际服务器。
示例
# Learn SSL session ID from both request and response and create affinity. backend https mode tcp balance roundrobin # maximum SSL session ID length is 32 bytes. stick-table type binary len 32 size 30k expire 30m acl clienthello req.ssl_hello_type 1 acl serverhello res.ssl_hello_type 2 # use tcp content accepts to detects ssl client and server hello. tcp-request inspect-delay 5s tcp-request content accept if clienthello # no timeout on response inspect delay by default. tcp-response content accept if serverhello # SSL session ID (SSLID) may be present on a client or server hello. # Its length is coded on 1 byte at offset 43 and its value starts # at offset 44. # Match and learn on request if client hello. stick on req.payload_lv(43,1) if clienthello # Learn on response if server hello. stick store-response resp.payload_lv(43,1) if serverhello server s1 192.168.1.1:443 server s2 192.168.1.1:443
tcp-check comment <字符串>
为以下 tcp-check 规则定义一个注释,如果失败,将在日志中报告。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<字符串> 是如果以下 tcp-check 规则失败时要在日志中添加的注释消息。
它仅适用于 connect、send 和 expect 规则。这对于进行用户友好的错误报告很有用。
tcp-check connect [default] [port <表达式>] [addr <ip>] [send-proxy] [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger] [proto <名称>] [comment <消息>]
打开一个新连接。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义如果规则评估失败要报告的消息。 default 使用服务器行的默认选项进行健康检查。仅当未重新定义时才使用服务器选项。 port <expr> 如果未设置,则使用检查端口或服务器端口。它告诉 HAProxy 在哪里打开连接。<port> 必须是有效的 TCP 端口整数,从 1 到 65535 或样本获取表达式。 addr <ip> 定义进行健康检查的 IP 地址。 send-proxy 发送 PROXY 协议字符串 via-socks4 使用上游 socks4 代理启用传出健康检查。 ssl 打开加密连接 sni <sni> 指定用于通过 SSL 进行健康检查的 SNI。 alpn <alpn> 定义要使用 ALPN 通告的协议。协议列表由逗号分隔的协议名称列表组成,例如:“http/1.1,http/1.0”(不带引号)。如果未设置,则使用服务器 ALPN。 proto <name> 强制用于此连接的多路复用器协议。它必须是 TCP mux 协议,并且必须可以在后端使用。可用协议列表在 haproxy -vv 中报告。 linger 正常关闭连接而不是使用单个 RST。
当一个应用程序依赖于多个 TCP 端口,或者当 HAProxy 在一个后端中对许多服务进行负载均衡时,有必要在将服务器视为可运行之前单独探测所有服务。当服务器行上既没有配置 TCP 端口也没有 server port 指令时,那么 'tcp-check connect port <端口>' 必须是序列的第一步。在 tcp-check 规则集中,'connect' 是必需的,并且也必须用 'connect' 规则来开始规则集。目的是确保管理员知道他们在做什么。当一个 connect 必须开始规则集时,它前面仍然可以有 set-var、unset-var 或 comment 规则。
示例
# 检查服务器上的 HTTP 和 HTTPs 服务。 # 首先由于服务器行端口指令打开端口 80,然后 # tcp-check 打开端口 443,加密并在其上运行请求: option tcp-check tcp-check connect tcp-check send GET\ /\ HTTP/1.0\r\n tcp-check send Host:\ haproxy.1wt.eu\r\n tcp-check send \r\n tcp-check expect rstring (2..|3..) tcp-check connect port 443 ssl tcp-check send GET\ /\ HTTP/1.0\r\n tcp-check send Host:\ haproxy.1wt.eu\r\n tcp-check send \r\n tcp-check expect rstring (2..|3..) server www 10.0.0.1 check port 80 # 从单个服务器检查 POP 和 IMAP: option tcp-check tcp-check connect port 110 linger tcp-check expect string +OK\ POP3\ ready tcp-check connect port 143 tcp-check expect string *\ OK\ IMAP4\ ready server mail 10.0.0.1 check
tcp-check expect [min-recv <整数>] [comment <消息>] [ok-status <状态>] [error-status <状态>] [tout-status <状态>] [on-success <格式>] [on-error <格式>] [status-code <表达式>] [!] <匹配> <模式>
指定在通用健康检查期间要收集和分析的数据。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义如果规则评估失败要报告的消息。 min-recv 是可选的,可以定义评估当前 expect 规则所需的最小数据量。如果接收到的字节数低于此限制,则检查将等待更多数据。此选项可用于解决一些模糊的匹配规则,或避免对已知仍不完整的内容执行代价高昂的 regex 匹配。如果使用精确字符串(string 或 binary),则使用字符串长度与此参数之间的最小值。如果此参数设置为 -1,则忽略此参数。如果 expect 规则不匹配,则检查将等待更多数据。如果设置为 0,则评估结果始终是结论性的。 <match> 是一个关键字,指示如何在响应中查找特定模式。关键字可以是 "string"、"rstring"、"binary" 或 "rbinary" 之一。关键字前面可以有感叹号 ("!") 来否定匹配。感叹号和关键字之间允许有空格。有关支持的关键字的更多详细信息,请参阅下文。 ok-status <st> 是可选的,可用于设置检查状态,如果 expect 规则成功评估并且它是 tcp-check 规则集中的最后一条规则。支持 "L7OK"、"L7OKC"、"L6OK" 和 "L4OK": - L7OK:检查通过第 7 层 - L7OKC:检查有条件地通过第 7 层,将服务器设置为 NOLB 状态。 - L6OK:检查通过第 6 层 - L4OK:检查通过第 4 层 默认使用 "L7OK"。 error-status <st> 是可选的,可用于设置检查状态,如果在 expect 规则评估期间发生错误。支持 "L7OKC"、"L7RSP"、"L7STS"、"L6RSP" 和 "L4CON": - L7OKC:检查有条件地通过第 7 层,将服务器设置为 NOLB 状态。 - L7RSP:第 7 层无效响应 - 协议错误 - L7STS:第 7 层响应错误,例如 HTTP 5xx - L6RSP:第 6 层无效响应 - 协议错误 - L4CON:第 1-4 层连接问题 默认使用 "L7RSP"。 tout-status <st> 是可选的,可用于设置检查状态,如果在 expect 规则评估期间发生超时。支持 "L7TOUT"、"L6TOUT" 和 "L4TOUT": - L7TOUT:第 7 层(HTTP/SMTP)超时 - L6TOUT:第 6 层(SSL)超时 - L4TOUT:第 1-4 层超时 默认使用 "L7TOUT"。 on-success <fmt> 是可选的,可用于自定义日志中报告的信息消息,如果 expect 规则成功评估并且它是 tcp-check 规则集中的最后一条规则。<fmt> 是一个 log-format 字符串。 on-error <fmt> 是可选的,可用于自定义日志中报告的信息消息,如果在 expect 规则评估期间发生错误。<fmt> 是一个 log-format 字符串。 status-code <expr> 是可选的,可用于设置日志中报告的检查状态代码,无论成功还是错误。<expr> 是一个标准的 HAProxy 表达式,由样本获取和一些转换器组成。 <pattern> 是要查找的模式。它可以是一个字符串或一个正则表达式。如果模式包含空格,则必须使用通常的反斜杠 ('\') 进行转义。如果 match 设置为 binary,则模式必须以偶数个十六进制数字的形式传递。每两个数字序列将代表一个字节。十六进制数字可以使用大写或小写。
可用的匹配项有意类似于它们的 http-check 对应项: string <string>:测试响应缓冲区中的精确字符串匹配。如果响应缓冲区包含此精确字符串,则健康检查响应将被视为有效。如果 "string" 关键字前面有 "!",则如果正文包含此字符串,则响应将被视为无效。这可用于在协议响应中查找强制模式,或在协议横幅中出现特定错误时检测失败。 rstring <regex>:在响应缓冲区上测试正则表达式。如果响应缓冲区匹配此表达式,则健康检查响应将被视为有效。如果 "rstring" 关键字前面有 "!",则如果正文匹配表达式,则响应将被视为无效。 string-lf <fmt>:在响应缓冲区中测试 log-format 字符串匹配。如果响应缓冲区包含评估 <fmt>(遵循 log-format 规则)产生的字符串,则健康检查响应将被视为有效。如果前面有 "!",则如果缓冲区包含该字符串,则响应将被视为无效。 binary <hexstring>:测试其十六进制形式的精确字符串是否匹配响应缓冲区。如果响应缓冲区包含此精确十六进制字符串,则健康检查响应将被视为有效。目的是匹配二进制协议上的数据。 rbinary <regex>:在响应缓冲区上测试正则表达式,如 "rstring"。但是,响应缓冲区会转换为其十六进制形式,包括 NUL 字节。这允许使用所有 regex 引擎来匹配任何二进制内容。十六进制转换的大小是原始响应的两倍。因此,预期的模式应该在最多一半的响应缓冲区大小上起作用。 binary-lf <hexfmt>:在响应缓冲区中测试其十六进制形式的 log-format 字符串匹配。如果响应缓冲区包含评估 <fmt>(遵循 log-format 规则)产生的十六进制字符串,则健康检查响应将被视为有效。如果前面有 "!",则如果缓冲区包含十六进制字符串,则响应将被视为无效。在匹配响应缓冲区之前,十六进制字符串会转换为二进制字符串。重要的是要注意,响应将限制为由全局 "tune.bufsize" 选项定义的大小,该选项默认为 16384 字节。因此,使用 "string"、"rstring" 或 binary 时,太大的响应可能不包含强制模式。如果绝对需要大响应,可以通过设置全局变量来更改默认最大大小。但是,值得记住的是,解析非常大的响应会浪费一些 CPU 周期,尤其是使用正则表达式时,并且最好始终将检查集中在较小的资源上。此外,在当前状态下,检查将找不到响应中空字符之后的任何字符串或 regex。同样,无法请求匹配空字符。
示例
# 执行 POP 检查 option tcp-check tcp-check expect string +OK\ POP3\ ready # 执行 IMAP 检查 option tcp-check tcp-check expect string *\ OK\ IMAP4\ ready # 查找 redis 主服务器 option tcp-check tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n tcp-check expect string role:master tcp-check send QUIT\r\n tcp-check expect string +OK
tcp-check send <数据> [comment <消息>]
tcp-check send-lf <格式> [comment <消息>]
指定一个字符串或 log-format 字符串作为通用健康检查期间的问题发送。可在以下上下文中使用:tcp、http、log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义在规则评估失败时报告的消息。 <data> 是在通用健康检查会话期间将发送的字符串。 <fmt> 是在通用健康检查会话期间将发送的日志格式字符串(评估后)。
示例
# 查找 redis 主服务器 option tcp-check tcp-check send info\ replication\r\n tcp-check expect string role:master
tcp-check send-binary <十六进制字符串> [comment <消息>]
tcp-check send-binary-lf <十六进制格式> [comment <消息>]
指定一个十六进制数字字符串或十六进制数字 log-format 字符串作为原始 tcp 健康检查期间的二进制问题发送。可在以下上下文中使用:tcp、http、log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
comment <msg> 定义在规则评估失败时报告的消息。 <hexstring> 是在通用健康检查会话期间将发送的十六进制字符串(转换为二进制后)。 <hexfmt> 是在通用健康检查会话期间将发送的十六进制日志格式字符串(评估并转换为二进制后)。
示例
# 二进制 redis 检查 option tcp-check tcp-check send-binary 50494e470d0a # PING\r\n tcp-check expect binary 2b504F4e47 # +PONG
tcp-check set-var(<变量名>[,<条件>...]) <表达式>
tcp-check set-var-fmt(<变量名>[,<条件>...]) <格式>
此操作设置变量的内容。变量是内联声明的。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<var-name> 变量的名称以其作用域的指示开头。tcp-check 允许的作用域有: "proc" :变量在整个进程中共享。 "sess" :变量在 tcp-check 会话中共享。 "check":变量在 tcp-check 的生命周期内声明。 此前缀后跟一个名称。分隔符是'.'。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '-'。 <cond> 一组必须全部为真才能实际设置变量的条件(例如 "ifnotempty"、"ifgt" ...)。有关可能的条件的完整列表,请参见 set-var 转换器的描述。 <expr> 是一个样本提取表达式,可能后跟转换器。 <fmt> 这是使用日志格式规则表示的值(请参见第 8.2.6 节中的自定义日志格式)。
示例
tcp-check set-var(check.port) int(1234) tcp-check set-var-fmt(check.name) "%H"
tcp-check unset-var(<变量名>)
在其作用域内释放对变量的引用。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<var-name> 变量的名称以其作用域的指示开始。tcp-check 允许的作用域有: "proc":变量与整个进程共享。 "sess":变量与 tcp-check 会话共享。 "check":变量在 tcp-check 的生命周期内声明。 此前缀后跟一个名称。分隔符是 '.'。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '-'。
示例
tcp-check unset-var(check.port)
tcp-request connection <动作> <选项...> [ { if | unless } <条件> ]
根据第 4 层条件对传入连接执行一个动作。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

no
参数
<action> 定义了如果条件适用要执行的操作。见下文。<condition> 是一个标准的仅第 4 层的基于 ACL 的条件(见第 7 节)。
在接受新的传入连接后,立即可以评估某些条件,以决定是否必须接受或丢弃此连接或跟踪其计数器。这些条件不能使用任何数据内容,因为连接尚未读取,并且尚未分配缓冲区。这用于以非常低的开销选择性地快速接受或丢弃来自各种来源的连接。如果需要检查某些内容才能做出决定,则必须改用 "tcp-request content" 语句。"tcp-request connection" 规则按照其确切的声明顺序进行评估。如果没有规则匹配或没有规则,则默认操作是接受传入连接。可以插入的规则数量没有特定的限制。任何规则都可以选择后跟基于 ACL 的条件,在这种情况下,只有当条件评估为真时才会评估该规则。在执行操作之前评估条件,并且操作只执行一次。因此,如果操作更改了作为条件一部分检查的元素,则没有问题。这也意味着多个操作可以依赖于相同的条件,因此更改条件评估的第一个操作足以隐式禁用其余操作。例如,当尝试在变量为空时从各种来源向变量分配值时,会使用此功能。语法中 "tcp-request connection" 之后的第一个关键字是规则的操作,可选择后跟可变数量的操作参数。支持的操作及其各自的语法在第 4.3 节“操作”中列举(查找勾选“TCP RqCon”的操作)。此指令仅在命名 defaults 部分中可用,而不是匿名部分中。defaults 部分中定义的规则在关联的代理部分中的规则之前进行评估。为避免歧义,在这种情况下,具有 frontend 功能的代理和具有 backend 功能的代理不能使用相同的 defaults 部分。这意味着 listen 部分不能使用定义此类规则的 defaults 部分。请注意,"if/unless" 条件是可选的。如果未对操作设置条件,则会无条件执行该操作。这对于 "track-sc*" 操作以及将默认操作更改为拒绝很有用。
示例
接受所有来自白名单主机的连接,拒绝过快的连接而不计数,并跟踪已接受的连接。这导致来自滥用来源的连接速率受到限制。
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst } tcp-request connection reject if { src_conn_rate gt 10 } tcp-request connection track-sc0 src
示例
接受所有来自白名单主机的连接,计算所有其他连接并拒绝过快的连接。这导致滥用者只要不减速就会被阻止。
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst } tcp-request connection track-sc0 src tcp-request connection reject if { sc0_conn_rate gt 10 }
示例
为来自所有已知代理的流量启用 PROXY 协议。
tcp-request connection expect-proxy layer4 if { src -f proxies.lst }
有关 ACL 的用法,请参见第 7 节
tcp-request content <action> [{if | unless} <condition>]
根据第 4-7 层条件对新会话执行一个动作。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
参数
<action> 定义了如果条件适用要执行的操作。见下文。<condition> 是一个标准的第 4-7 层基于 ACL 的条件(见第 7 节)。
可以在请求处理的早期阶段(称为“TCP 内容检查”)分析请求的内容。在此阶段,每次更新请求内容时都会评估基于 ACL 的规则,直到 "accept"、"reject" 或 "switch-mode" 规则匹配,或者 TCP 请求检查延迟到期而没有匹配规则。这些规则与 "tcp-request connection" 规则之间的第一个区别是 "tcp-request content" 规则可以使用内容来做出决定。大多数情况下,这些决定会考虑协议识别或有效性。第二个区别是基于内容的规则可以在 frontend 和 backend 中使用。如果是 HTTP keep-alive with the client,则会再次评估所有 tcp-request content 规则,因此 HAProxy 会记录哪些粘性计数器是由 "tcp-request connection" 与 "tcp-request content" 规则分配的,并在处理 HTTP 请求后刷新所有与内容相关的计数器,以便可以再次评估它们以进行下一个请求。当规则跟踪某些 L7 信息或以基于 L7 的 ACL 为条件时,这一点尤为重要,因为跟踪可能会在请求之间发生变化。基于内容的规则按照其确切的声明顺序进行评估。如果没有规则匹配或没有规则,则默认操作是接受内容。可以插入的规则数量没有特定的限制。虽然这不是强制性的,但建议在 "tcp-request connection" 规则中使用 track-sc0,在 frontend 的 "tcp-request content" 规则中使用 track-sc1,在 backend 的 "tcp-request content" 规则中使用 track-sc2,因为这使得配置更具可读性且易于故障排除,但这只是一个指导方针,所有计数器都可以在任何地方使用。语法中 "tcp-request content" 之后的第一个关键字是规则的操作,可选择后跟可变数量的操作参数。支持的操作及其各自的语法在第 4.3 节“操作”中列举(查找勾选“TCP RqCnt”的操作)。此指令仅在命名 defaults 部分中可用,而不是匿名部分中。defaults 部分中定义的规则在关联的代理部分中的规则之前进行评估。为避免歧义,在这种情况下,具有 frontend 功能的代理和具有 backend 功能的代理不能使用相同的 defaults 部分。这意味着 listen 部分不能使用定义此类规则的 defaults 部分。请注意,"if/unless" 条件是可选的。如果未对操作设置条件,则会无条件执行该操作。这对于 "track-sc*" 操作以及将默认操作更改为拒绝很有用。另请注意,建议使用 "tcp-request session" 规则来跟踪*不*依赖于第 7 层内容的信息,尤其是对于 HTTP frontends。某些 HTTP 处理是在会话级别执行的,可能会导致请求被提前拒绝。因此,在这种情况下,内容级别的跟踪可能会受到干扰。启动期间会发出警告,以尽可能防止此类不可靠的使用。使用 TCP 代理的 "tcp-request content" 规则匹配第 7 层内容是完全可能的,因为 HTTP 特定 ACL 匹配能够在提取所需数据之前初步解析缓冲区的内容。如果缓冲的内容未解析为有效的 HTTP 消息,则 ACL 不匹配。此处涉及的解析器与所有其他 HTTP 处理的解析器完全相同,因此不存在以不同方式解析的风险。在 HTTP frontend 或 HTTP backend 中,保证在首次评估规则时 HTTP 内容始终立即存在,因为 HTTP 解析是在连接处理的早期阶段(在会话级别)执行的。但对于此类代理,使用 "http-request" 规则更自然且推荐。跟踪 layer7 信息也是可能的,前提是信息在处理规则时存在。如果需要跟踪的数据尚不可用,规则处理引擎能够等待直到检查延迟到期。
示例
tcp-request content use-service lua.deny if { src -f /etc/haproxy/blacklist.lst }
示例
tcp-request content set-var(sess.my_var) src tcp-request content set-var-fmt(sess.from) %[src]:%[src_port] tcp-request content unset-var(sess.my_var2)
示例
# 接受Host头为"example.com"的HTTP请求 # 并拒绝其他所有请求。(仅适用于HTTP/1连接) acl is_host_com hdr(Host) -i example.com tcp-request inspect-delay 30s tcp-request content accept if is_host_com tcp-request content reject # 接受Host头为"example.com"的HTTP请求 # 并拒绝其他所有请求。(适用于HTTP/1和HTTP/2连接) acl is_host_com hdr(Host) -i example.com tcp-request inspect-delay 5s tcp-request switch-mode http if HTTP tcp-request reject # 此处隐式处理非HTTP流量 ... http-request reject unless is_host_com
示例
# 如果客户端先说话,则拒绝 SMTP 连接 tcp-request inspect-delay 30s acl content_present req.len gt 0 tcp-request content reject if content_present # 仅当客户端说话时才转发 HTTPS 连接 tcp-request inspect-delay 30s acl content_present req.len gt 0 tcp-request content accept if content_present tcp-request content reject
示例
# 跟踪 X-Forwarded-For 中的最后一个 IP(粘滞表类型为 string) tcp-request inspect-delay 10s tcp-request content track-sc0 hdr(x-forwarded-for,-1) # 或者跟踪 X-Forwarded-For 中的最后一个 IP(粘滞表类型为 ip|ipv6) tcp-request content track-sc0 req.hdr_ip(x-forwarded-for,-1)
示例
# 按“base”(Host+URL 的串联)跟踪请求计数 tcp-request inspect-delay 10s tcp-request content track-sc0 base table req-rate
示例
跟踪每个前端和每个后端的计数器,当后端检测到滥用(并标记 gpc0)时,在前端阻止滥用者。
frontend http # 在 SC0 中使用通用计数器 0 作为全局滥用计数器 # 保护我们所有的站点 stick-table type ip size 1m expire 5m store gpc0 tcp-request connection track-sc0 src tcp-request connection reject if { sc0_get_gpc0 gt 0 } ... use_backend http_dynamic if { path_end .php } backend http_dynamic # 如果某个来源对此动态站点发出的请求过快(由 # SC1 跟踪),则在前端全局阻止它。 stick-table type ip size 1m expire 5m store http_req_rate(10s) acl click_too_fast sc1_http_req_rate gt 10 acl mark_as_abuser sc0_inc_gpc0(http) gt 0 tcp-request content track-sc1 src tcp-request content reject if click_too_fast mark_as_abuser
有关 ACL 的用法,请参见第 7 节
设置在内容检查期间等待数据的最大允许时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
使用 HAProxy 作为 TCP 中继的人们通常担心在没有分析的情况下将任何类型的协议传递给服务器的风险。为了能够分析请求内容,我们必须首先保留数据,然后分析它们。此语句只是启用数据保留,最长持续指定的时间量。当连接到达 frontend 时,TCP 内容检查会很早应用,然后当连接转发到 backend 时,它会很早应用。这意味着如果 frontend 和 backend 都有 tcp-request 规则,则连接可能会在 frontend 中经历第一次延迟,在 backend 中经历第二次延迟。请注意,在执行内容检查时,HAProxy 会为进入的每个新块评估整个规则,同时考虑到这些数据是部分的。如果在上述延迟之前没有规则匹配,则会在到期时执行最后一次检查,此时认为内容是最终的。如果未设置延迟,HAProxy 将根本不会等待,并将根据可用信息立即应用判断。显然,这不太可能非常有用,甚至可能存在竞争条件,因此不建议使用此类设置。请注意,如果遇到连接错误或关闭,或者请求缓冲区显示已满,检查延迟会缩短。一旦规则匹配,请求就会释放并照常继续。如果达到超时且没有规则匹配,则默认策略是让它不受影响地通过。对于大多数协议,将其设置为几秒钟就足够了,因为大多数客户端会在连接时立即发送完整的请求。增加 3 秒或更多秒以覆盖 TCP 重传,但仅此而已。对于某些协议,使用较大的值可能是有意义的,例如确保客户端在服务器之前永远不会说话(例如 SMTP),或者等待客户端说话,然后再将数据传递给服务器(例如 SSL)。请注意,客户端超时必须至少覆盖检查延迟,否则它会先过期。如果客户端关闭连接或缓冲区已满,则延迟会立即到期,因为内容将无法再更改。此指令仅在命名 defaults 部分中可用,而不是匿名部分中。代理从其 defaults 部分继承此值。
tcp-request session <动作> [{if | unless} <条件>]
根据第 5 层条件对已验证的会话执行一个动作。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

yes

yes

no
参数
<动作> 定义了如果条件适用时要执行的动作。见下文。 <条件> 是一个标准的仅第 5 层的基于 ACL 的条件(见第 7 节)。
会话验证后(即所有握手完成后),可以评估某些条件,以决定是否必须接受或丢弃此会话或跟踪其计数器。这些条件不能使用任何数据内容,因为尚未分配缓冲区,并且在此阶段处理无法等待。主要用例是将一些早期信息复制到变量中(因为变量在会话中可访问),或者跟踪在握手后收集的一些信息,例如 SSL 级别元素(SNI、密码、客户端证书的 CN)或来自 PROXY 协议标头的信息(例如,跟踪以这种方式转发的源)。因此,提取的信息可以使用 "track-sc" 规则复制到变量中或进行跟踪。当然,也可以像其他规则集一样决定接受/拒绝。此处执行的大多数操作也可以在 "tcp-request content" 规则中执行,除了在 HTTP 中,这些规则是针对每个新请求进行评估的,这可能并不总是可以接受的。例如,规则可能会在每次评估时递增计数器。还可能通过地理位置从源 IP 地址解析国家/地区,将其分配给会话范围的变量,然后为所有请求重写来自 HTTP 标头的源地址。如果需要检查某些内容才能做出决定,则必须改用 "tcp-request content" 语句。"tcp-request session" 规则按照其确切的声明顺序进行评估。如果没有规则匹配或没有规则,则默认操作是接受传入会话。可以插入的规则数量没有特定的限制。语法中 "tcp-request session" 之后的第一个关键字是规则的操作,可选择后跟可变数量的操作参数。支持的操作及其各自的语法在第 4.3 节“操作”中列举(查找勾选“TCP RqSes”的操作)。此指令仅在命名 defaults 部分中可用,而不是匿名部分中。defaults 部分中定义的规则在关联的代理部分中的规则之前进行评估。为避免歧义,在这种情况下,具有 frontend 功能的代理和具有 backend 功能的代理不能使用相同的 defaults 部分。这意味着 listen 部分不能使用定义此类规则的 defaults 部分。请注意,"if/unless" 条件是可选的。如果未对操作设置条件,则会无条件执行该操作。这对于 "track-sc*" 操作以及将默认操作更改为拒绝很有用。
示例
默认跟踪原始源地址,或者对于来自本地代理的连接,跟踪 PROXY 协议头中通告的地址。第一个连接级别的规则为这些连接启用了 PROXY 协议的接收,第二个规则跟踪我们在可选解码后决定保留的任何地址。
tcp-request connection expect-proxy layer4 if { src -f proxies.lst } tcp-request session track-sc0 src
示例
接受所有来自白名单主机的会话,拒绝过快的会话而不对其进行计数,并跟踪已接受的会话。这导致来自滥用来源的会话速率受到限制。
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst } tcp-request session reject if { src_sess_rate gt 10 } tcp-request session track-sc0 src
示例
接受所有来自白名单主机的会话,对所有其他会话进行计数,并拒绝过快的会话。这导致滥用会话被阻止,直到它们减速为止。
tcp-request session accept if { src -f /etc/haproxy/whitelist.lst } tcp-request session track-sc0 src tcp-request session reject if { sc0_sess_rate gt 10 }
有关 ACL 的用法,请参见第 7 节
tcp-response content <action> [{if | unless} <condition>]
根据第 4-7 层的条件对会话响应执行操作。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

no

yes

yes
参数
<action> 定义了如果条件适用要执行的操作。见下文。<condition> 是一个标准的第 4-7 层基于 ACL 的条件(见第 7 节)。
可以在响应处理的早期阶段(称为“TCP 内容检查”)分析响应内容。在此阶段,每次更新响应内容时都会评估基于 ACL 的规则,直到最终规则匹配,或者设置的 TCP 响应检查延迟到期而没有匹配规则。大多数情况下,这些决定会考虑协议识别或有效性。基于内容的规则按照其确切的声明顺序进行评估。如果没有规则匹配或没有规则,则默认操作是接受内容。可以插入的规则数量没有特定的限制。语法中 "tcp-response content" 之后的第一个关键字是规则的操作,可选择后跟可变数量的操作参数。支持的操作及其各自的语法在第 4.3 节“操作”中列举(查找勾选“TCP RsCnt”的操作)。此指令仅在命名 defaults 部分中可用,而不是匿名部分中。defaults 部分中定义的规则在关联的代理部分中的规则之前进行评估。为避免歧义,在这种情况下,具有 frontend 功能的代理和具有 backend 功能的代理不能使用相同的 defaults 部分。这意味着 listen 部分不能使用定义此类规则的 defaults 部分。请注意,"if/unless" 条件是可选的。如果未对操作设置条件,则会无条件执行该操作。这对于将默认操作更改为拒绝很有用。支持几种类型的操作:使用 "tcp-response content" 规则匹配第 7 层内容是完全可能的,但重要的是要确保已缓冲完整的响应,否则不会匹配任何内容。为了实现这一点,最好的解决方案是在检查期间检测 HTTP 协议。有关 ACL 用法,请参阅第 7 节
设置在内容检查期间等待响应的最长允许时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend
是(!)
yes(!)

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
此指令仅在命名的 defaults 部分中可用,不能在匿名部分中使用。代理从其 defaults 部分继承此值。
timeout check <timeout>
设置额外的检查超时,但仅在连接已经建立之后。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
如果设置,HAProxy 使用 min("timeout connect", "inter") 作为检查的连接超时,并使用 "timeout check" 作为附加读取超时。使用 "min" 是为了让运行 *非常* 长 "timeout connect" 的人(例如那些由于队列或 tarpit 而需要此功能的人)不会减慢他们的检查速度。(另请注意,没有有效的理由设置如此长的连接超时,因为 "timeout queue" 和 "timeout tarpit" 始终可用于避免这种情况)。如果未设置 "timeout check",则 HAProxy 使用 "inter" 作为完整的检查超时(连接 + 读取),就像所有 <1.3.15 版本一样。在大多数情况下,检查请求比正常请求简单得多且处理速度更快,人们可能希望踢出滞后的服务器,因此此超时应小于 "timeout server"。此参数特定于后端,但可以在 "defaults" 部分中一次性指定。这实际上是不会忘记它最简单的解决方案之一。
timeout client <timeout>
设置客户端侧的最大不活动时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当客户端需要确认或发送数据时,非活动超时(inactivity timeout)生效。在HTTP模式下,此超时在客户端发送请求的第一阶段以及服务器发送响应且客户端正在读取数据的过程中尤其重要。话虽如此,对于第一阶段,最好设置 "timeout http-request" 以更好地保护 HAProxy 免受类似 Slowloris 的攻击。默认情况下,该值以毫秒为单位指定,但如果数字后带有单位后缀,则可以以任何其他单位表示,具体如本文档开头所述。在TCP模式下(在HTTP模式下程度较低),强烈建议客户端超时与服务器超时保持一致,以避免复杂的调试情况。一个好的做法是,将超时设置略高于3秒的倍数(例如4秒或5秒),以覆盖一个或多个TCP数据包丢失。如果长寿命流与短寿命流混合在一起(例如WebSocket和HTTP),则值得考虑使用 "timeout tunnel",它将覆盖隧道连接的 "timeout client" 和 "timeout server",以及针对半关闭连接的 "timeout client-fin"。此参数特定于前端(frontends),但可以在 "defaults" 部分中一次性指定。这实际上是确保不会遗漏它的最简单方法之一。未指定的超时会导致无限超时,这是不推荐的。这种用法被接受并有效,但在启动期间会报告警告,因为它可能导致系统中过期会话的累积(如果系统超时也没有配置的话)。
为半关闭连接设置客户端侧的不活动超时。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当客户端需要确认或发送数据,而其中一个方向已经关闭时,非活动超时(inactivity timeout)生效。此超时与 "timeout client" 的不同之处在于,它仅适用于在一个方向上已关闭的连接。这对于避免当客户端未干净断开连接时,连接长时间保持在 FIN_WAIT 状态特别有用。这个问题在RDP或WebSocket等长连接中尤为常见。请注意,当连接在一个方向上关闭时,此超时可以覆盖 "timeout tunnel"。在发送 GOAWAY 帧后(通常表示预期连接会迅速结束),它应用于空闲的 HTTP/2 连接。此参数特定于前端(frontends),但可以在 "defaults" 部分中一次性指定。默认情况下未设置,因此半关闭连接将使用其他超时(timeout.client 或 timeout.tunnel)。
设置等待客户端 TLS 握手完成的最长时间。这可用于 TCP 和 QUIC 连接。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
如果未设置此握手超时,则将使用客户端超时来替代。
timeout connect <timeout>
设置等待到服务器的连接尝试成功的最大时间。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
如果服务器与 HAProxy 位于同一局域网内,连接应该是即时的(少于几毫秒)。无论如何,指定略高于 3 秒倍数的超时(例如 4 或 5 秒)以覆盖一个或多个 TCP 数据包丢失是一个好习惯。默认情况下,如果未指定队列和 tarpit 超时,连接超时也会将它们预设为相同的值。此参数特定于后端,但可以在 "defaults" 部分中为所有后端一次性指定。这实际上是避免忘记它的最简单解决方案之一。未指定的超时会导致无限超时,这是不推荐的。这种用法被接受并且可以工作,但在启动时会报告警告,因为如果系统超时也未配置,可能会导致系统中失败会话的累积。
设置等待新 HTTP 请求出现的最长允许时间。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
默认情况下,在保持活动状态(keep-alive)下等待新请求的时间由 "timeout http-request" 设置。然而,这并不总是方便的,因为有些人希望保持活动超时非常短,以便更快地释放连接,而另一些人则希望有更长的超时,但在请求开始呈现后仍有短超时。"http-keep-alive" 超时涵盖了这些需求。它定义了在发送响应后等待新 HTTP 请求开始的时间。一旦看到请求的第一个字节,就会使用 "http-request" 超时来等待完整的请求到来。请注意,新请求之前的空行不会刷新超时,也不会被计为新请求。这两个超时之间还有另一个区别:当连接在 timeout http-keep-alive 期间过期时,不会返回错误,连接只是关闭。如果连接在 "http-request" 期间过期,等待请求完成时,在关闭连接之前会向客户端返回 HTTP 408 错误,除非在前端设置了 "option http-ignore-probes"。通常,"timeout http-keep-alive" 最适合用于防止客户端在短连接较多的站点上,将本应空闲的连接保持过长时间。这可以通过将 HTTP/1.1 中的值设置为几十到几百毫秒来实现。这将使连接在客户端请求页面后关闭,而无需保持该连接打开以等待来自客户端的更多活动。在这种情况下,来自浏览器的新活动将导致TCP和/或SSL层上的新握手。这种情况的一个常见用例是仅提供重定向到HTTPS页面的HTTP站点。这些连接最好不要保持空闲太久,因为它们不会被重用,除非是获取favicon。另一个用例恰恰相反:有些站点希望允许客户端长时间重用空闲连接(例如30秒到一分钟),但又不想等待这么长时间来处理第一个请求,以避免非常廉价的攻击向量。在这种情况下,http-keep-alive 超时会设置为一个大值,而 http-request 则保持较低(几秒钟)。当设置为非常小的值时,除非请求真正被管道化(HTTP/1.1中非常罕见,即连续发送请求而不等待响应),否则未被管道化的附加请求很可能通过另一个连接处理。大多数 HTTP/1.1 实现发送一个请求,等待响应,然后发送另一个请求。对于有数十万客户端的站点,HTTP/1.1的这个小值可能有利于使用更少的内存和套接字,代价是增加握手计算成本。在处理 HTTP/2 时,应特别注意小值。HTTP/2 的本质是在一个连接上多路复用请求,以节省重新连接 TCP 和/或 SSL 层的开销。该协议还使用控制帧,这些帧在早期TCP连接关闭时处理不佳,在非常罕见的情况下,这可能导致数据在离开HAProxy后被销毁时(HAProxy甚至无法记录错误)响应被截断。对于 HTTP/2 连接,建议的较低起始值约为4秒。这将防止大多数现代保持活动实现不必要地保持陈旧连接打开,同时允许后续请求重用连接。但是,应根据需要进行调整,这只是一个起点。如果未设置此参数,则应用 "http-request" 超时,如果两者都未设置,则 "timeout client" 仍应用于较低级别。必须在前端设置才能生效,除非前端处于 TCP 模式,在这种情况下将使用 HTTP 后端的超时。
设置等待一个完整的 HTTP 请求的最长允许时间。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
为了提供 DoS 保护,可能需要降低接受完整 HTTP 请求的最大时间,而不影响客户端超时。这有助于防止在已建立连接上未发送任何内容的情况。客户端超时无法提供针对此滥用的良好保护,因为它是一个非活动超时,这意味着如果攻击者偶尔发送一个字符,超时将不会触发。使用 HTTP 请求超时,无论客户端输入速度如何,如果请求未及时完成,都将被中止。当超时过期时,会向客户端发送 HTTP 408 响应以告知问题,并关闭连接。日志将报告终止代码 "cR"。一些最近的浏览器对这种标准且有良好文档记录的行为存在问题,因此可能需要使用 "option http-ignore-probes" 或 "errorfile 408 /dev/null" 来隐藏 408 代码。有关 "cR" 终止代码的更多详细信息,请参阅 section 8.5 中的解释。默认情况下,此超时仅适用于请求的头部部分,不适用于任何数据。一旦接收到空行,此超时将不再使用。当与 "option http-buffer-request" 结合使用时,此超时也适用于请求主体。如果未设置 "timeout http-keep-alive",则在保持活动连接上会再次使用它来等待第二个请求。通常将其设置为几秒钟就足够了,因为大多数客户端在连接后会立即发送完整的请求。添加3秒或更多以覆盖 TCP 重传,但仅此而已。设置非常低的值(例如50毫秒)通常在本地网络上有效,只要没有数据包丢失。这将防止人们使用 telnet 发送裸 HTTP 请求。如果未设置此参数,则客户端超时仍适用于传入请求的每个块之间。必须在前端设置才能生效,除非前端处于 TCP 模式,在这种情况下将使用 HTTP 后端的超时。
timeout queue <timeout>
设置在队列中等待一个可用连接槽的最长时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当达到服务器的 maxconn 时,连接会被留在队列中等待,这个队列可能是特定于服务器的,也可能是后端全局的。为了避免无限期等待,对队列中等待的请求应用超时。如果达到超时,则认为请求几乎永远不会被服务,因此它被丢弃,并向客户端返回 503 错误。"timeout queue" 语句允许设置请求在队列中等待的最长时间。如果未指定,则使用与后端连接超时相同的值("timeout connect"),以实现与没有 "timeout queue" 参数的旧版本的向后兼容性。
timeout server <timeout>
设置服务器侧的最大不活动时间。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当服务器需要确认或发送数据时,非活动超时(inactivity timeout)生效。在HTTP模式下,此超时在服务器响应的第一阶段尤其重要,即当服务器必须发送头部时,因为它直接代表了服务器对请求的处理时间。要找出要设置的值,通常最好从被认为是不可接受的响应时间开始,然后检查日志以观察响应时间分布,并相应地调整值。默认情况下,该值以毫秒为单位指定,但如果数字后带有单位后缀,则可以以任何其他单位表示,具体如本文档开头所述。在TCP模式下(在HTTP模式下程度较低),强烈建议客户端超时与服务器超时保持一致,以避免复杂的调试情况。无论预期的服务器响应时间如何,一个好的做法是,将超时设置略高于3秒的倍数(例如最少4秒或5秒),以覆盖至少一个或多个TCP数据包丢失。如果长寿命流与短寿命流混合在一起(例如WebSocket和HTTP),则值得考虑使用 "timeout tunnel",它将覆盖隧道连接的 "timeout client" 和 "timeout server"。此参数特定于后端(backends),但可以在 "defaults" 部分中一次性指定。这实际上是确保不会遗漏它的最简单方法之一。未指定的超时会导致无限超时,这是不推荐的。这种用法被接受并有效,但在启动期间会报告警告,因为它可能导致系统中过期会话的累积(如果系统超时也没有配置的话)。
为半关闭连接设置服务器侧的不活动超时。可在以下上下文中使用:tcp, http, log

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当服务器需要确认或发送数据,而其中一个方向已经关闭时,非活动超时(inactivity timeout)生效。此超时与 "timeout server" 的不同之处在于,它仅适用于在一个方向上已关闭的连接。这对于避免当远程服务器未干净断开连接时,连接长时间保持在 FIN_WAIT 状态特别有用。这个问题在RDP或WebSocket等长连接中尤为常见。请注意,当连接在一个方向上关闭时,此超时可以覆盖 "timeout tunnel"。提供此设置是为了完整性,但在大多数情况下,应该不需要它。此参数特定于后端(backends),但可以在 "defaults" 部分中一次性指定。默认情况下未设置,因此半关闭连接将使用其他超时(timeout.server 或 timeout.tunnel)。
timeout tarpit <timeout>
设置被置于 tarpit 状态的连接将维持的时长。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

yes
参数
<timeout> 是 tarpit 的持续时间,默认以毫秒为单位指定,但如果数字后跟单位后缀,也可以是任何其他单位,如本文档开头所述。
当使用 "http-request tarpit" 将一个连接置于 tarpit 状态时,它会在没有任何活动的情况下保持打开一段时间,然后关闭。“timeout tarpit”定义了它将保持打开的时间长度。默认情况下,该值以毫秒为单位指定,但如果数字后跟有单位后缀,则可以是任何其他单位,如本文档开头所述。如果未指定,将使用与后端连接超时(“timeout connect”)相同的值,以向后兼容没有“timeout tarpit”参数的旧版本。
timeout tunnel <timeout>
为隧道设置客户端和服务器侧的最大不活动时间。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数
<timeout> 是默认以毫秒为单位指定的超时值,但如果数字后缀有单位,则可以是任何其他单位,如本文档开头所述。
当客户端和服务器之间建立双向连接,并且连接在两个方向上都保持非活动状态时,隧道超时(tunnel timeout)生效。一旦连接成为隧道,此超时将取代客户端和服务器超时。在TCP中,只要没有分析器附加到任一连接(例如,tcp content rules被接受),就会使用此超时。在HTTP中,当连接升级时(例如,切换到WebSocket协议或将CONNECT请求转发到代理),或者在第一个响应之后未指定 keepalive/close 选项时,就会使用此超时。由于此超时通常与长寿命连接结合使用,因此最好也设置 "timeout client-fin" 以处理客户端突然从网络中消失且未确认关闭,或发送关机但不再确认待处理数据的情况。这可能发生在存在防火墙的有损网络中,并通过存在大量处于 FIN_WAIT 状态的会话来检测。默认情况下,该值以毫秒为单位指定,但如果数字后带有单位后缀,则可以以任何其他单位表示,具体如本文档开头所述。无论预期的正常空闲时间如何,一个好的做法是,将超时设置略高于3秒的倍数(例如最少4秒或5秒),以覆盖至少一个或多个TCP数据包丢失。此参数特定于后端(backends),但可以在 "defaults" 部分中一次性指定。这实际上是确保不会遗漏它的最简单方法之一。
示例
defaults http option http-server-close timeout connect 5s timeout client 30s timeout client-fin 30s timeout server 30s timeout tunnel 1h # 用于 WebSocket 和 CONNECT 的超时
transparent (已弃用)
启用客户端透明代理 可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

no

yes

yes
参数:
引入此关键字是为了向第 3 层负载均衡器提供第 7 层持久性。其思想是利用操作系统的能力将远程地址的传入连接重定向到本地进程(此处为 HAProxy),并让该进程知道最初请求的地址。使用此选项时,没有 cookie 的会话将被转发到传入请求的原始目标 IP 地址(该地址应与另一设备的地址匹配),而带有 cookie 的请求仍将被转发到适当的服务器。" transparent" 关键字已弃用,请改用 "option transparent"。请注意,与普遍看法相反,此选项在建立连接时并不会使 HAProxy 向服务器呈现客户端的 IP。
为每个请求生成一个唯一 ID。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<string> 是一个日志格式字符串。
此关键字使用自定义日志格式为每个请求创建一个ID。唯一的ID对于跟踪通过复杂基础设施中多个组件的请求非常有用。新创建的ID也可以使用日志格式字符串中的%ID标签进行记录。格式应由保证组合后唯一的元素组成。例如,如果涉及多个HAProxy实例,可能需要包含节点名称。通常需要记录传入连接的源和目标地址及端口。请注意,由于可以在同一连接上执行多个请求,因此包含请求计数器可能有助于区分它们。同样,时间戳可以防止计数器翻转。记录进程ID将避免服务重启后发生冲突。建议对许多字段使用十六进制表示法,因为它使它们更紧凑并节省日志空间。
示例
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid 将生成: 7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A
在 HTTP 请求中添加一个唯一 ID 标头。可在以下上下文中使用:http

May be used in sections

defaultsfrontendlistenbackend

yes

yes

yes

no
参数
<name> 是头部的名称。
使用 unique-id-format 在发送到服务器的 HTTP 请求中添加一个 unique-id 头部。如果 unique-id-format 不存在,则无法工作。
示例
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid unique-id-header X-Unique-ID 将生成: X-Unique-ID: 7F000001:8296_7F00001E:1F90_4F7B0A69_0003:790A 另请参阅: "unique-id-format"
use_backend <backend> [{if | unless} <condition>]
如果/除非满足基于 ACL 的条件,则切换到特定的后端。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

yes

yes

no
参数
<backend> 是一个有效的后端或 "listen" 部分的名称,或一个解析为后端名称的 "log-format" 字符串。<condition> 是由 ACL 组成的条件,如 第 7 节 所述。如果省略,则无条件应用该规则。
在进行内容切换时,连接到达前端,然后根据许多条件分派到各种后端。条件与后端之间的关系用 "use_backend" 关键字描述。虽然它通常用于 HTTP 处理,但也可以用于纯 TCP,要么不使用内容,使用无状态 ACL(例如源地址验证),要么与 "tcp-request" 规则结合使用以等待某些有效负载。可以有任意数量的 "use_backend" 规则。所有这些规则都按照声明顺序进行评估,第一个匹配的规则将分配后端。在第一种形式中,如果条件满足,将使用后端。在第二种形式中,如果条件不满足,将使用后端。如果没有条件有效,将使用用 "default_backend" 定义的后端。如果未定义默认后端,则使用同一部分中的服务器(如果是 "listen" 部分),或者如果是前端,则不使用服务器并返回 503 服务不可用响应。请注意,可以将 TCP 前端切换到 HTTP 后端。在这种情况下,要么前端已经检查了协议是 HTTP,后端处理将立即进行,要么后端将等待完整的 HTTP 请求进入。当前端必须在一个唯一端口上解码多种协议(其中之一是 HTTP)时,此功能非常有用。当 <backend> 是一个简单的名称时,它在配置时解析,如果指定的后端不存在,则报告错误。如果 <backend> 是一个日志格式字符串,则在配置时可能不进行检查,因此后端名称在运行时动态解析。如果生成的后端名称与任何有效的后端不对应,则不会评估其他规则,而是应用 default_backend 指令。请注意,在使用动态后端名称时,强烈建议使用其他后端未使用的前缀,以确保无法通过请求强制使用未经授权的后端。值得一提的是,带有显式名称的 "use_backend" 规则用于检测前端和后端之间的关联,以计算后端的 "fullconn" 设置。对于动态名称,无法执行此操作。
定义用于后端的 FastCGI 应用程序。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<name> 是要使用的 FastCGI 应用程序的名称。
有关 FastCGI 应用程序设置的详细信息,请参见第 10.1 节
use-server <server> if <condition>
use-server <server> unless <condition>
仅在/除非满足基于 ACL 的条件时才使用特定服务器。可在以下上下文中使用:tcp, http

May be used in sections

defaultsfrontendlistenbackend

no

no

yes

yes
参数
<server>是同一后端部分中有效服务器的名称,或者是解析为服务器名称的"log-format"字符串。<condition>是由ACL组成的条件,如第7节所述。
默认情况下,到达后端的连接会根据配置的算法在可用服务器之间进行负载均衡,除非在请求中使用了持久性机制(例如cookie)并找到了它。有时需要将特定请求转发到特定服务器,而无需为该服务器声明专用的后端。这可以通过使用 "use-server" 规则来实现。这些规则在评估 "redirect" 规则之后和评估 cookie 之前进行评估,并且它们优先于 cookie。可以有任意数量的 "use-server" 规则。所有这些规则都按照声明顺序进行评估,第一个匹配的规则将分配服务器。如果规则指定的服务器处于关闭状态,并且未使用 "option persist" 且未验证 force-persist 规则,则忽略该规则,评估继续进行下一个规则,直到匹配为止。在第一种形式中,如果条件满足,将使用服务器。在第二种形式中,如果条件不满足,将使用服务器。如果没有条件有效,则继续处理,并将根据其他持久性机制分配服务器。请注意,即使匹配了规则,仍会执行 cookie 处理,但不会分配服务器。这允许剥离带前缀的 cookie 的前缀。"use-server" 语句在 HTTP 和 TCP 模式下都有效。这使得它适用于内容检查。例如,在使用隐式 TLS 的协议时,可以根据 TLS SNI 字段在服务器场中选择服务器(另请参阅 "req.ssl_sni")。如果这些服务器的权重设置为零,则它们将不用于其他流量。
示例
# 基于 SNI 字段拦截传入的 TLS 请求 use-server www if { req.ssl_sni -i www.example.com } server www 192.168.0.1:443 weight 0 use-server mail if { req.ssl_sni -i mail.example.com } server mail 192.168.0.1:465 weight 0 use-server imap if { req.ssl_sni -i imap.example.com } server imap 192.168.0.1:993 weight 0 # 所有其余请求都转发到此服务器 server default 192.168.0.2:443 check
当<server>是一个简单的名称时,它会与配置中现有的服务器进行检查,如果指定的服务器不存在,则报告错误。如果它是一个日志格式,则在解析配置时不会进行检查,如果我们在运行时无法解析出有效的服务器名称,但use-server规则的条件是一个返回true的ACL,则不会应用其他use-server规则,我们将回退到负载均衡。

4.3. 操作关键字矩阵

在请求或响应处理的各个阶段会评估多个规则集,对于在这些规则集中找到的每个规则,如果可选条件满足,则可以执行操作。默认提供了大量操作,它们可以修改内容、接受/阻止处理、更改内部状态等。并且可以在 Lua 中定义新操作(在这种情况下,它们的名称将始终以 "lua." 为前缀)。虽然历史上某些操作仅存在于特定的规则集中,但现在许多操作可用于许多规则集。本节中的列表将指示支持的操作可以在何处使用,通过勾选以下规则集中的相应缩写条目名称:- TCP RqCon:操作对 "tcp-request connection" 规则有效 - TCP RqSes:操作对 "tcp-request session" 规则有效 - TCP RqCnt:操作对 "tcp-request content" 规则有效 - TCP RsCnt:操作对 "tcp-response content" 规则有效 - HTTP Req:操作对 "http-request" 规则有效 - HTTP Res:操作对 "http-response" 规则有效 - HTTP Aft:操作对 "http-after-response" 规则有效 下面 section 4.4 中的引用使用了相同的缩写。
关键字TCP: RqConRqSesRqCntRsCntHTTP: ReqResAft
acceptXXXX   
add-acl    XX 
add-header    XXX
allow    XXX
attach-srv X     
auth    X  
cache-store     X 
cache-use    X  
capture  X XXX
close   X   
del-acl    XX 
del-header    XXX
del-map    XXX
deny    XX 
disable-l7-retry    X  
do-resolve  X X  
early-hint    X  
expect-netscaler-cipX      
expect-proxy layer4X      
normalize-uri    X  
关键字TCP: RqConRqSesRqCntRsCntHTTP: ReqResAft
redirect    XX 
rejectXXXXX  
replace-header    XXX
replace-path    X  
replace-pathq    X  
replace-uri    X  
replace-value    XXX
return    XX 
sc-add-gpcXXXXXXX
sc-inc-gpcXXXXXXX
sc-inc-gpc0XXXXXXX
sc-inc-gpc1XXXXXXX
sc-set-gptXXXXXXX
sc-set-gpt0XXXXXXX
send-spoe-group  XXXX 
set-bandwidth-limit  XXXX 
set-dstXXX X  
set-dst-portXXX X  
set-header    XXX
set-log-level  XXXXX
关键字TCP: RqConRqSesRqCntRsCntHTTP: ReqResAft
set-map    XXX
set-markXXXXXX 
set-method    X  
set-nice  XXXX 
set-path    X  
set-pathq    X  
set-priority-class  X X  
set-priority-offset  X X  
set-query    X  
set-srcXXX X  
set-src-portXXX X  
set-status     XX
set-timeout    XX 
set-tosXXXXXX 
set-uri    X  
set-varXXXXXXX
set-var-fmtXXXXXXX
silent-dropXXXXXX 
strict-mode    XXX
switch-mode  X    
关键字TCP: RqConRqSesRqCntRsCntHTTP: ReqResAft
tarpit    X  
track-sc0XXX XX 
track-sc1XXX XX 
track-sc2XXX XX 
unset-varXXXXXXX
use-service  X X  
wait-for-body    XX 
wait-for-handshake    X  

4.4. 按字母顺序排序的操作参考

本节使用与上述第 4.3 节中描述的相同的规则集术语标记,提供了每个操作及其用法的详细描述。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXX   
这会停止对规则的评估,并允许请求或响应通过检查。此操作是最终的,即对于当前部分,不再评估同一规则集中的后续规则。此操作与 "allow" 操作之间没有区别,只是为了历史兼容性,"accept" 用于 TCP 规则,"allow" 用于 HTTP 规则。另请参阅下面的 "allow" 操作。
add-acl(<file-name>) <key fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
这用于向 ACL 添加新条目。ACL 必须从文件加载(甚至是空的虚拟文件)。要更新的 ACL 文件名放在括号中。它接受一个参数:<key fmt>,它遵循日志格式规则来收集新条目的内容。它在插入之前在 ACL 中执行查找,以避免重复(或更多)的值。它等效于 stats socket 中的 "add acl" 命令,但可以通过 HTTP 请求触发。
add-header <name> <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
这会追加一个 HTTP 头部字段,其名称由 <name> 指定,值由遵循日志格式规则的 <fmt> 定义(参见 section 8.2.6 中的自定义日志格式)。这对于将特定于连接的信息传递给服务器(例如客户端的 SSL 证书),或者将多个头部合并为一个头部特别有用。此规则不是最终规则,因此可以添加其他类似的规则。请注意,头部添加会立即执行,因此一个规则可以重用前一个规则生成的头部。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作停止规则的评估,并让请求通过检查。此操作是最终的,即对于当前部分,不会评估同一规则集中的任何后续规则。此操作与“accept”操作没有区别,只是为了历史兼容性,“accept”用于 TCP 规则,而“allow”用于 HTTP 规则。另请参见上面的“accept”操作。
attach-srv <srv> [name <expr>] [ 实验性 ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
 X     
这用于在正确的 HTTP/2 建立后拦截连接。连接被反转到后端侧,并插入到服务器 <srv> 的空闲池中。这只能与具有 'rhttp@' 地址的服务器一起使用。可以指定一个额外的参数 <expr>。其值被解释为样本表达式,用于命名服务器空闲池中的连接。当通过此服务器路由传出请求时,此名称将与服务器行中的 'sni' 参数匹配。否则,连接将没有名称,并且只匹配没有 SNI 的请求。此规则仅适用于 HTTP 模式下的前端。此外,所有侦听器不得要求与 HTTP/2 不同的协议。反向 HTTP 目前仍在积极开发中。未来的配置机制可能会发生变化。因此,它在内部被标记为实验性,这意味着 "expose-experimental-directives" 必须出现在此指令之前的一行中。
auth [realm <realm>]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
这会停止对规则的评估,并立即返回 HTTP 401 或 407 错误代码,以邀请用户提供有效的用户名和密码。不再评估后续的 "http-request" 规则。支持一个可选的 "realm" 参数,它设置与响应一起返回的身份验证领域(通常是应用程序的名称)。使用相应的代理错误消息。可以使用 "errorfile" 或 "http-error" 指令进行自定义。对于 401 响应,将删除 WWW-Authenticate 标头的所有出现,并替换为包含领域 "<realm>" 的基本身份验证质询的新标头。对于 407 响应,对 Proxy-Authenticate 标头执行相同的操作。如果错误消息不得更改,请考虑改用 "http-request return" 规则。
示例
acl auth_ok http_auth_group(L1) G1 http-request auth unless auth_ok

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
     X 
在缓存中存储一个 http-response。响应头的存储在此步骤完成,这意味着您可以使用其他 http-response 操作在存储响应之前或之后修改头。此操作负责设置缓存存储过滤器。有关缓存设置,请参见第 6.2 节
cache-use <name>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
尝试从缓存 <name> 中提供一个缓存对象。此指令对于存储缓存也是必需的,因为它计算缓存哈希值。如果您想对存储和提供都使用一个条件,最好将其放在此指令之后。有关缓存设置,请参见第 6.2 节
capture <sample> [ len <length> | id <id> ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X XXX
这会从请求或响应缓冲区捕获样本表达式 <sample>,并将其转换为最多 <len> 个字符的字符串。结果字符串存储在下一个 "capture" 插槽中(请求或响应),因此它可能会出现在一些捕获的 HTTP 头部旁边。然后它将自动出现在日志中,并且可以使用样本获取方法提取它以将其馈送到头部或其他任何地方。应限制长度,因为在整个流生命周期中,将为每次捕获分配此大小。请注意,长度仅适用于 "http-request" 规则。请查看 section 7.3(获取样本)、"capture request header" 和 "capture response header" 以获取更多信息。如果使用关键字 "id" 而不是 "len",则操作尝试将捕获的字符串存储在先前声明的捕获插槽中。这对于在后端运行捕获非常有用。插槽 id 可以通过先前的指令 "http-request capture" 或使用 "declare capture" 关键字声明。在后端使用此操作时,请仔细检查相关前端是否具有必需的捕获插槽,否则此规则将在运行时被忽略。由于 HAProxy 能够在运行时动态解析后端名称,因此在配置解析时无法检测到这一点。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
   X   
此操作用于立即关闭与服务器的连接。后续的“tcp-response content”规则将不再被评估。此操作的主要目的是,在应用程序协议期望先经过一段较长的超时时间的情况下,强制结束客户端与服务器之间的交换后的连接。其目标是消除那些在某些协议下会占用大量服务器资源的空闲连接。
del-acl(<file-name>) <key fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
这用于从 ACL 中删除条目。ACL 必须从文件加载(甚至是空的虚拟文件)。要更新的 ACL 文件名放在括号中。它接受一个参数:<key fmt>,它遵循日志格式规则来收集要删除的条目的内容。它等效于 stats socket 中的 "del acl" 命令,但可以通过 HTTP 请求或响应触发。
del-header <name> [ -m <meth> ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作移除所有名称在 <name> 中指定的 HTTP 标头字段。<meth> 是应用于标头名称的匹配方法。支持的匹配方法有“str”(精确匹配)、“beg”(前缀匹配)、“end”(后缀匹配)、“sub”(子串匹配)和“reg”(正则表达式匹配)。如果未指定,则使用精确匹配方法。
del-map(<file-name>) <key fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
这用于从 MAP 中删除条目。MAP 必须从文件加载(甚至是空的虚拟文件)。要更新的 MAP 文件名放在括号中。它接受一个参数:<key fmt>,它遵循日志格式规则来收集要删除的条目的内容。它接受一个参数:"file name" 它等效于 stats socket 中的 "del map" 命令,但可以通过 HTTP 请求或响应触发。
deny [ { status | deny_status } <code> ] [ content-type <type> ] [ { default-errorfiles | errorfile <file> | errorfiles <name> | file <file> | lf-file <file> | string <str> | lf-string <fmt> } ] [ hdr <name> <fmt> ]*

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
此操作停止规则评估并立即拒绝请求或响应。默认情况下,对请求返回 HTTP 403 错误,对响应返回 502 错误,但返回的响应可以使用与“return”操作相同的语法进行自定义。因此,详情请参见下文的“return”。为了兼容性,当没有定义参数,或仅定义了 "deny_status" 时,会隐含 "default-errorfiles" 参数。这意味着 "deny [deny_status <status>]" 是 "deny [status <status>] default-errorfiles" 的别名。此操作是最终的,即同一规则集中的后续规则将不会对当前部分进行评估。另请参阅“return”操作以了解高级语法。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作会禁止任何因连接失败以外的原因而重试请求的尝试。例如,这对于确保 POST 请求在失败时不会被重试非常有用。
do-resolve(<var>,<resolvers>,[ipv4,ipv6]) <expr>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X X  
此操作对  的输出执行 DNS 解析,并将结果存储在变量  中。它使用由  指向的 DNS 解析器部分。可以通过可选参数 'ipv4' 或 'ipv6' 选择解析首选项。执行 DNS 解析时,客户端连接会暂停,等待解析结束。如果找到 IP 地址,则将其存储在  中。如果发生任何错误,则  不会被设置。可以使用此操作来发现服务器 IP 地址并在运行时基于请求中的信息(例如 Host 标头)进行操作。如果此操作用于查找服务器 IP 地址(使用 "set-dst" 操作),则后端中的服务器 IP 地址必须设置为 0.0.0.0。do-resolve 操作接受一个仅主机参数,必须从字符串中删除任何端口。
示例
resolvers mydns nameserver local 127.0.0.53:53 nameserver google 8.8.8.8:53 timeout retry 1s hold valid 10s hold nx 3s hold other 3s hold obsolete 0s accepted_payload_size 8192 frontend fe bind 10.42.0.1:80 http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),host_only http-request capture var(txn.myip) len 40 # return 503 when the variable is not set, # which mean DNS resolution error use_backend b_503 unless { var(txn.myip) -m found } default_backend be backend b_503 # dummy backend used to return 503. # one can use the errorfile directive to send a nice # 503 error page to end users backend be # rule to prevent HAProxy from reconnecting to services # on the local network (forged DNS name used to scan the network) http-request deny if { var(txn.myip) -m ip 127.0.0.0/8 10.0.0.0/8 } http-request set-dst var(txn.myip) server clear 0.0.0.0:0
注意:不要忘记设置“保护”规则,以确保 HAProxy 不会被用于扫描网络,或更糟糕的是,不会循环访问自身……
early-hint <name> <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
这用于在任何其他响应之前构建 HTTP 103 Early Hints 响应。这会向此响应追加一个 HTTP 头部字段,其名称由 <name> 指定,值由遵循日志格式规则的 <fmt> 定义(参见 section 8.2.6 中的自定义日志格式)。这对于向客户端传递一些 Link 头部以预加载渲染 HTML 文档所需的资源特别有用。有关更多信息,请参阅 RFC 8297。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
X      
这将配置面向客户端的连接,以在从套接字读取任何字节之前接收 NetScaler 客户端 IP 插入协议头。这相当于在 "bind" 行上使用 "accept-netscaler-cip" 关键字,不同之处在于使用 TCP 规则允许仅对某些 IP 地址范围使用 ACL 接受 PROXY 协议。当来自公共主机的流量通过多层负载均衡器时,这很方便。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
X      
这将配置面向客户端的连接,以在从套接字读取任何字节之前接收 PROXY 协议头。这相当于在 "bind" 行上使用 "accept-proxy" 关键字,不同之处在于使用 TCP 规则允许仅对某些 IP 地址范围使用 ACL 接受 PROXY 协议。当来自公共主机的流量通过多层负载均衡器时,这很方便。
normalize-uri <normalizer>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
执行请求 URI 的规范化。HAProxy 2.4 中的 URI 规范化目前作为实验性技术预览提供。因此,它要求首先使用全局指令 'expose-experimental-directives' 才能调用它。您应该做好准备,规范化器的行为可能会更改以修复可能的问题,这可能会破坏您基础结构中正常的请求处理。每个规范化器处理一种类型的规范化,以允许对支持的后端选择适当的规范化级别进行细粒度控制。例如,"path-strip-dotdot" 规范化器可能对直接将请求 URI 映射到本地文件系统中路径的静态文件服务器有用。但是,它可能会破坏需要特定路径段数的 API 路由。重要的是要注意,某些规范化器可能会对损坏的 URI 导致不安全的转换。也可能发生的是,单独安全的规范化器组合在一起时,如果组合不当,会导致不安全的转换。例如,当损坏的 URI 包含裸百分号字符时,"percent-decode-unreserved" 规范化器可能会导致意外结果。例如,一个损坏的 URI "/%%36%36" 将被解码为 "/%66",而这又等同于 "/f"。通过指定 "strict" 选项,对此类损坏 URI 的请求将被安全地拒绝。提供以下规范化器:- fragment-encode:将 "#" 编码为 "%23"。应首选 "fragment-strip" 规范化器,除非已知有问题的客户端未正确编码路径组件中的 '#'。
示例
- /#foo -> /%23foo
- fragment-strip: 移除 URI 的“fragment”组件。根据 RFC 3986#3.5,URI 的“fragment”组件不应被发送,而应由用户代理在检索资源后处理。应首先应用此规范化器,以确保片段不被解释为请求路径组件的一部分。
示例
- /#foo -> /
- path-strip-dot: 移除“path”组件内的“/./”段(RFC 3986#6.2.2.3)。包含百分比编码点(“%2E”)的段将不会被检测到。如果不需要这种行为,请先使用“percent-decode-unreserved”规范化器。
示例
- /. -> / - /./bar/ -> /bar/ - /a/./a -> /a/a - /.well-known/ -> /.well-known/ (无变化)
- path-strip-dotdot: 规范化“path”组件内的“/../”段(RFC 3986#6.2.2.3)。这将尝试访问父目录的段与其前面的段合并。空段不作特殊处理。如果不需要这种行为,请先使用“merge-slashes”规范化器。包含百分比编码点(“%2E”)的段将不会被检测到。如果不需要这种行为,请先使用“percent-decode-unreserved”规范化器。
示例
- /foo/../ -> / - /foo/../bar/ -> /bar/ - /foo/bar/../ -> /foo/ - /../bar/ -> /../bar/ - /bar/../../ -> /../ - /foo//../ -> /foo/ - /foo/%2E%2E/ -> /foo/%2E%2E/
如果指定了“full”选项,那么开头的“../”也将被移除
示例
- /../bar/ -> /bar/ - /bar/../../ -> /
- path-merge-slashes: 将“path”组件内相邻的斜杠合并为单个斜杠。
示例
- // -> / - /foo//bar -> /foo/bar
- percent-decode-unreserved: 将未保留的百分比编码字符解码为其常规字符表示(RFC 3986#6.2.2.2)。未保留字符集包括所有字母、所有数字、“-”、“.”、“_”和“~”。
示例
- /%61dmin -> /admin - /foo%3Fbar=baz -> /foo%3Fbar=baz (无变化) - /%%36%36 -> /%66 (不安全) - /%ZZ -> /%ZZ
如果指定了“strict”选项,则无效序列将导致返回 HTTP 400 Bad Request。
示例
- /%%36%36 -> HTTP 400 - /%ZZ -> HTTP 400
- percent-to-uppercase: 将百分比编码序列中的字母大写(RFC 3986#6.2.2.1)。
示例
- /%6f -> /%6F - /%zz -> /%zz
如果指定了“strict”选项,则无效序列将导致返回 HTTP 400 Bad Request。
示例
- /%zz -> HTTP 400
- query-sort-by-name: 按参数名称对查询字符串参数进行排序。参数假定由“&”分隔。较短的名称排在较长的名称之前,相同的参数名称保持其相对顺序。
示例
- /?c=3&a=1&b=2 -> /?a=1&b=2&c=3 - /?aaa=3&a=1&aa=2 -> /?a=1&aa=2&aaa=3 - /?a=3&b=4&a=1&b=5&a=2 -> /?a=3&a=1&a=2&b=4&b=5
redirect <rule>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
这根据重定向规则执行 HTTP 重定向。这与 "redirect" 语句完全相同,只是它插入了一个重定向规则,该规则在其他 "http-request" 或 "http-response" 规则中间处理,并且这些规则使用 "log-format" 字符串。对于响应,只允许 "location" 类型的重定向。此外,当在响应期间执行重定向时,从服务器到 HAProxy 的传输会中断,以便不会将有效负载转发给客户端。这可能会导致 HTTP/1 上的一些连接关闭。此操作是最终的,即对于当前部分,不再评估同一规则集中的后续规则。有关规则语法,请参阅 "redirect" 关键字。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXX  
这会停止对规则的评估,并立即关闭连接而不发送任何响应。对于 HTTP 规则,它的作用类似于 "tcp-request content reject" 规则。它对于强制立即关闭 HTTP/2 连接可能很有用。在 "tcp-request connection" 规则中,被拒绝的连接甚至不会成为会话,这就是为什么它们在统计信息中单独核算为 "denied connections" 的原因。它们不被考虑用于会话速率限制,也不会记录日志。原因是这些规则只应用于过滤极高的连接速率,例如在大规模 DDoS 攻击期间遇到的连接速率。在这些极端条件下,记录每个事件的简单操作将导致系统崩溃,并大大降低过滤能力。如果绝对需要记录日志,则应改用 "tcp-request content" 规则,因为 "tcp-request session" 规则也不会记录日志。当在 "tcp-response content" 规则中使用时,服务器连接将关闭,响应将中止。这通常用于防止敏感信息泄漏,通常是在与 "wait-for-body" 操作结合检查内容之后。
replace-header <name> <match-regex> <replace-fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作将标头字段 <name> 的所有出现的值与 <match-regex> 进行匹配。匹配是区分大小写的。匹配的值被 <replace-fmt> 完全替换。<replace-fmt> 中允许使用格式化字符,其工作方式类似于“http-request add-header”中的 <fmt> 参数。支持使用反斜杠('\')后跟数字的标准反向引用。此操作作用于整个标头行,无论它们可能包含多少个值。因此,它非常适合处理在其值中自然包含逗号的标头,例如 If-Modified-Since 或 Set-Cookie。包含逗号分隔值列表的标头,例如 Accept 或 Cache-Control,应改用“replace-value”操作进行处理。另请参阅“replace-value”操作。
示例
http-request replace-header Cookie foo=([^;]*);(.*) foo=\1;ip=%bi;\2 # 应用于: Cookie: foo=foobar; expires=Tue, 14-Jun-2016 01:40:45 GMT; # 输出: Cookie: foo=foobar;ip=192.168.1.20; expires=Tue, 14-Jun-2016 01:40:45 GMT; # 假设后端 IP 是 192.168.1.20 http-request replace-header User-Agent curl foo # 应用于: User-Agent: curl/7.47.0 # 输出: User-Agent: foo
示例
http-response replace-header Set-Cookie (C=[^;]*);(.*) \1;ip=%bi;\2 # 应用于: Set-Cookie: C=1; expires=Tue, 14-Jun-2016 01:40:45 GMT # 输出: Set-Cookie: C=1;ip=192.168.1.20; expires=Tue, 14-Jun-2016 01:40:45 GMT # 假设后端 IP 是 192.168.1.20。
replace-path <match-regex> <replace-fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作的工作方式类似于“replace-header”,但它作用于请求的路径部分,而不是标头。路径部分从可选的 scheme+authority 之后的第一个“/”开始,到问号之前结束。因此,替换不会修改 scheme、authority 和查询字符串。值得注意的是,正则表达式的评估可能比某些 ACL 更昂贵,因此对于罕见的替换,如果不匹配,使用条件来避免执行评估可能会更有利。
示例
# 在 /foo 前加上前缀:将 /bar?q=1 变为 /foo/bar?q=1: http-request replace-path (.*) /foo\1 # 去除 /foo:将 /foo/bar?q=1 变为 /bar?q=1 http-request replace-path /foo/(.*) /\1 # 或者如果只有部分请求匹配,这样更高效: http-request replace-path /foo/(.*) /\1 if { url_beg /foo/ }
replace-pathq <match-regex> <replace-fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作与 "http-request replace-path" 相同,不同之处在于路径包含了查询字符串(如果存在)。因此,路径和查询字符串都会被替换。
示例
# 在路径后添加后缀 /foo:将 /bar?q=1 变为 /bar/foo?q=1: http-request replace-pathq ([^?]*)(\?(.*))? \1/foo\2
replace-uri <match-regex> <replace-fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
这与 "replace-header" 的工作方式类似,只是它作用于请求的 URI 部分而不是头部。URI 部分可能包含可选的方案、权威或查询字符串。这些被视为与匹配的值的一部分。值得注意的是,评估正则表达式可能比某些 ACL 更昂贵,因此罕见的替换可能受益于条件,以避免在不匹配时完全执行评估。重要提示:历史上在 HTTP/1.x 中,绝大多数浏览器发送的请求使用“origin form”,这与“absolute form”不同,因为它们的 URI 部分不包含方案或权威。只有发送给代理的请求、手动伪造的请求以及某些应用程序发出的请求才使用绝对形式。因此,"replace-uri" 通常在 HTTP/1.x 中使用以 "/" 开头的规则时工作良好。但是对于 HTTP/2,鼓励客户端仅发送绝对 URI,这些 URI 看起来像 HTTP/1 客户端用于与代理通信的 URI。因此,此类部分 replace-uri 规则在 HTTP/2 中可能会失败,而在 HTTP/1 中则有效。要么需要调整规则以可选地匹配方案和权威,要么应使用 replace-path。
示例
# 将所有 "http" 绝对请求重写为 "https": http-request replace-uri ^http://(.*) https://\1 # 添加前缀 /foo:将 /bar?q=1 变为 /foo/bar?q=1: http-request replace-uri ([^/:]*://[^/]*)?(.*) \1/foo\2
replace-value <name> <match-regex> <replace-fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作的工作方式类似于“replace-header”,但它将正则表达式与标头字段 <name> 的每个逗号分隔的值进行匹配,而不是整个标头。这适用于所有允许携带多个值的标头。例如 Accept 请求标头,或者请求或响应的 Cache-Control。
示例
http-request replace-value X-Forwarded-For ^192\.168\.(.*)$ 172.16.\1 # 应用于: X-Forwarded-For: 192.168.10.1, 192.168.13.24, 10.0.0.37 # 输出: X-Forwarded-For: 172.16.10.1, 172.16.13.24, 10.0.0.37
示例
http-after-response replace-value Cache-control ^public$ private # 应用于: Cache-Control: max-age=3600, public # 输出: Cache-Control: max-age=3600, private
return [ status <code> ] [ content-type <type> ] [ { default-errorfiles | errorfile <file> | errorfiles <name> | file <file> | lf-file <file> | string <str> | lf-string <fmt> } ] [ hdr <name> <fmt> ]*

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
这会停止对规则的评估并立即返回响应。用于响应的默认状态码为 200。它可以作为 "status" 的参数可选指定。响应内容类型也可以作为 "content-type" 的参数指定。最后,可以定义响应本身。它可以是指定要使用的 errorfile 的完整 HTTP 响应,也可以是指定要使用的文件或字符串的响应有效负载。遵循这些规则来创建响应:* 如果既没有定义 errorfile 也没有定义要使用的有效负载,则返回一个虚拟响应。仅考虑 "status" 参数。它可以是范围 [200, 599] 中的任何代码。如果存在 "content-type" 参数,则忽略它。* 如果设置了 "default-errorfiles" 参数,则考虑代理的 errorfiles。如果定义了 "status" 参数,它必须是 HAProxy 处理的状态码之一(200、400、403、404、405、408、410、413、425、429、500、501、502、503 和 504)。如果存在 "content-type" 参数,则忽略它。* 如果定义了特定的 errorfile,使用 "errorfile" 参数,则返回包含完整 HTTP 响应的相应文件。仅考虑 "status" 参数。它必须是 HAProxy 处理的状态码之一(200、400、403、404、405、408、410、413、425、429、500、501、502、503 和 504)。如果存在 "content-type" 参数,则忽略它。* 如果定义了 http-errors 部分,使用 "errorfiles" 参数,则返回指定 http-errors 部分中包含完整 HTTP 响应的相应文件。仅考虑 "status" 参数。它必须是 HAProxy 处理的状态码之一(200、400、403、404、405、408、410、413、425、429、500、501、502、503 和 504)。如果存在 "content-type" 参数,则忽略它。* 如果指定了 "file" 或 "lf-file" 参数,则文件内容用作响应有效负载。如果文件不为空,则其内容类型必须设置为 "content-type" 的参数。否则,任何 "content-type" 参数都将被忽略。使用 "lf-file" 参数时,文件内容将作为日志格式字符串进行评估。使用 "file" 参数时,它被视为原始内容。* 如果指定了 "string" 或 "lf-string" 参数,则定义的字符串用作响应有效负载。内容类型必须始终设置为 "content-type" 的参数。使用 "lf-string" 参数时,字符串将作为日志格式字符串进行评估。使用 "string" 参数时,它被视为原始字符串。当响应不是基于 errorfile 时,可以使用 "hdr" 参数向响应追加 HTTP 头部字段。否则,所有 "hdr" 参数都将被忽略。对于每个头部,头部名称由 <name> 指定,值由遵循日志格式规则的 <fmt> 定义。请注意,生成的响应必须小于缓冲区。为了避免任何警告,当加载 errorfile 或原始文件时,为头部重写保留的缓冲区空间也应该空闲。此操作是最终的,即对于当前部分,不再评估同一规则集中的后续规则。
示例
http-request return errorfile /etc/haproxy/errorfiles/200.http \ if { path /ping } http-request return content-type image/x-icon file /var/www/favicon.ico \ if { path /favicon.ico } http-request return status 403 content-type text/plain \ lf-string "Access denied. IP %[src] is blacklisted." \ if { src -f /etc/haproxy/blacklist.lst }
sc-add-gpc(<idx>,<sc-id>) { <int> | <expr> }

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作将与粘性计数器 <sc-id> 关联的数组中索引 <idx> 处的通用目的计数器增加整数 <int> 或表达式 <expr> 的整数评估值。整数和表达式限制为无符号 32 位值。如果发生错误,此操作会静默失败,并且操作评估继续进行。<idx> 是一个介于 0 和 99 之间的整数,<sc-id> 是一个介于 0 和 2 之间的整数。如果此索引处没有存储 GPC,它也会静默失败。即使值为零,表中的条目也会刷新。'gpc_rate' 会自动调整以反映 gpc 值的平均增长率。此操作仅适用于 'gpc' 和 'gpc_rate' 数组数据类型(不适用于旧版 'gpc0'、'gpc1'、'gpc0_rate' 和 'gpc1_rate' 数据类型)。对于旧版数据类型没有等效函数,但如果值始终为 1,请参阅 'sc-inc-gpc()'、'sc-inc-gpc0()' 和 'sc-inc-gpc1()'。也无法减少值,但可以使用 'sc-set-gpt()' 在通用目的标签中存储精确值。此操作的主要用途是计算分数或总卷(例如,服务器或 WAF 报告的每源 IP 估计危险、上传的总字节数等)。
sc-inc-gpc(<idx>,<sc-id>)

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作将与由 <sc-id> 指定的粘性计数器关联的数组中,索引为 <idx> 的通用目的计数器(GPC)递增 1。如果发生错误,此操作将静默失败,并且操作评估继续。<idx> 是 0 到 99 之间的整数,<sc-id> 是 0 到 2 之间的整数。如果在此索引处没有存储 GPC,它也会静默失败。此操作仅适用于 'gpc' 和 'gpc_rate' 数组数据类型(不适用于旧的 'gpc0'、'gpc1'、'gpc0_rate' 或 'gpc1_rate' 数据类型)。
sc-inc-gpc0(<sc-id>)
sc-inc-gpc1(<sc-id>)

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作根据由 <sc-id> 指定的粘性计数器来递增 GPC0 或 GPC1 计数器。如果发生错误,此操作将静默失败,并且操作评估继续。
sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作将与由 <sc-id> 指定的粘性计数器关联的数组中,索引为 <idx> 的 32 位无符号 GPT 设置为 <int>/<expr> 的值。预期结果是一个布尔值。如果发生错误,此操作将静默失败,并且操作评估继续。<idx> 是 0 到 99 之间的整数,<sc-id> 是 0 到 2 之间的整数。如果在此索引处没有存储 GPT,它也会静默失败。此操作仅适用于 'gpt' 数组数据类型(不适用于旧的 'gpt0' 数据类型)。
sc-set-gpt0(<sc-id>) { <int> | <expr> }

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作根据由 <sc-id> 指定的粘性计数器和 <int>/<expr> 的值来设置 32 位无符号 GPT0 标签。预期结果是一个布尔值。如果发生错误,此操作将静默失败,并且操作评估继续。此操作是 "sc-set-gpt(0,<sc-id>)" 的别名。另请参阅“sc-set-gpt”操作。
send-spoe-group <engine-name> <group-name>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  XXXX 
此操作用于触发发送一组 SPOE 消息。为此,必须定义用于发送消息的 SPOE 引擎,以及要发送的 SPOE 组。当然,SPOE 引擎必须引用一个现有的 SPOE 过滤器。如果在 SPOE 过滤器行上未提供引擎名称,则必须使用 SPOE 代理名称。
参数
<engine-name> SPOE 引擎名称。 <group-name> 在引擎配置中指定的 SPOE 组名称。
set-bandwidth-limit <name> [limit {<expr> | <size>}] [period {<expr> | <time>}]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  XXXX 
此操作用于启用带宽限制过滤器 <name>,根据过滤器类型,可以在上传或下载方向上启用。如果且仅当 <name> 引用一个每流带宽限制过滤器时,可以定义自定义的限制和周期。当执行 set-bandwidth-limit 规则时,它首先将过滤器的所有设置重置为其默认值,然后再启用它。因此,如果对同一过滤器执行多个“set-bandwidth-limit”操作,则只有最后一个生效。可以在同一个流上启用多个带宽限制过滤器。请注意,此操作不能在 defaults 部分中使用,因为带宽限制过滤器不能在 defaults 部分中定义。此外,只限制 HTTP 负载传输。HTTP 标头不被考虑。
参数
<expr> 是一个标准的 HAProxy 表达式,由一个样本提取后跟一些转换器组成。结果被转换为一个整数。对于 "limit" 参数,它被解释为以字节为单位的大小;对于 "period" 参数,它被解释为以毫秒为单位的持续时间。 <size> 是一个数字。它遵循 HAProxy 的大小格式,并以字节表示。 <time> 是一个数字。它遵循 HAProxy 的时间格式,并以毫秒表示。
示例
http-request set-bandwidth-limit global-limit http-request set-bandwidth-limit my-limit limit 1m period 10s
关于带宽限制过滤器设置,请参见第 9.7 节
set-dst <expr>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXX X  
此操作用于将目标 IP 地址设置为指定表达式的值。当 HAProxy 前面的代理重写了目标 IP,但在 HTTP 标头中提供了正确的 IP 时,或者您想为隐私目的屏蔽 IP 时,这很有用。如果要连接到新的地址/端口,请在后端中使用 '0.0.0.0:0' 作为服务器地址。
参数
<expr> 是一个标准的 HAProxy 表达式,由一个样本提取后跟一些转换器组成。
示例
http-request set-dst hdr(x-dst) http-request set-dst dst,ipmask(24)
在可能的情况下,只要地址族允许,set-dst 会保留原始目标端口,否则目标端口将被设置为 0。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXX X  
此操作用于将目标端口地址设置为指定表达式的值。如果要连接到新的地址/端口,请在后端中使用 '0.0.0.0:0' 作为服务器地址。
参数
<expr> 是一个标准的 HAProxy 表达式,由一个样本提取后跟一些转换器组成。
示例
http-request set-dst-port hdr(x-port) http-request set-dst-port int(4000)
在可能的情况下,只要地址族支持端口,set-dst-port 就会保留原始目标地址,否则它会在重写端口之前将目标地址强制设置为 IPv4 "0.0.0.0"。
set-header <name> <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作与“add-header”操作相同,不同之处在于,如果标头已存在,会先将其删除。这在向服务器传递安全信息时很有用,因为此时标头不能被外部用户操纵,或者用于强制某些响应标头(如 "Server")以隐藏外部信息。请注意,新值是在删除之前计算的,因此可以将一个值连接到一个现有的标头上。
示例
http-request set-header X-Haproxy-Current-Date %T http-request set-header X-SSL %[ssl_fc] http-request set-header X-SSL-Session_ID %[ssl_fc_session_id,hex] http-request set-header X-SSL-Client-Verify %[ssl_c_verify] http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn] http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)] http-request set-header X-SSL-Issuer %{+Q}[ssl_c_i_dn] http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore] http-request set-header X-SSL-Client-NotAfter %{+Q}[ssl_c_notafter]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  XXXXX
此操作用于在满足特定条件时更改当前请求的日志级别。有效级别是 8 个 syslog 级别(参见“log”关键字)以及特殊级别“silent”,它会禁用此请求的日志记录。此规则不是最终的,因此最后一个匹配的规则生效。此规则可用于禁用来自其他设备的健康检查。
set-map(<file-name>) <key fmt> <value fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
这用于向 map 添加新条目。map 必须从文件加载(甚至是空的虚拟文件)。要更新的 map 文件名放在括号中。它接受2个参数:<key fmt>,它遵循日志格式规则用于收集 map 键,以及 <value fmt>,它遵循日志格式规则用于收集新条目的内容。它在插入之前在 map 中执行查找,以避免重复(或更多)的值。它等效于 stats socket 中的 "set map" 命令,但可以通过 HTTP 请求触发。
set-mark <mark>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXX 
此操作用于在支持此功能的平台上,将发送给客户端的所有数据包的 Netfilter/IPFW MARK 设置为 <标记> 中传递的值。此值是一个无符号的 32 位值,可以被 netfilter/ipfw、路由表或通过 DTrace 监控数据包时匹配。它可以用十进制或十六进制格式(以“0x”为前缀)表示。这对于强制某些数据包走不同的路由(例如,对于批量下载使用更便宜的网络路径)非常有用。此功能在 Linux 内核 2.6.32 及更高版本上有效,并需要管理员权限,在 FreeBSD 和 OpenBSD 上也同样适用。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作使用格式化字符串 <fmt> 的求值结果来重写请求方法。这样做应该有极少数的正当理由,因为它更有可能破坏某些东西而不是修复它。
set-nice <nice>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  XXXX 
这会设置当前正在处理的请求/响应的 "nice" 因子。它仅对同时处理的其他请求产生影响。默认值为 0,除非通过 "bind" 行上的 "nice" 设置进行更改。接受的范围是 -1024..1024。值越高,请求就越“友好”。较低的值将使请求比其他请求更重要。这对于提高某些请求的速度或降低不重要请求的优先级很有用。未经事先试验使用此设置可能会导致重大减速。
set-path <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作使用格式化字符串 <fmt> 的求值结果来重写请求路径。查询字符串(如果有)保持不变。如果在路径之前找到了 scheme 和 authority,它们也保持不变。如果请求没有路径("*"),则该路径将被格式替换。例如,这可以用于在路径前添加一个目录组件。另请参阅 "http-request set-query" 和 "http-request set-uri"。
示例
# 在路径前添加主机名 http-request set-path /%[hdr(host)]%[path]
set-pathq <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作与 "http-request set-path" 相同,不同之处在于查询字符串也被重写。它可用于移除查询字符串,包括问号(使用 "http-request set-query" 是不可能的)。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X X  
此操作用于设置当前请求的队列优先级类别。该值必须是一个样本表达式,其转换结果为 -2047 到 2047 范围内的整数。超出此范围的结果将被截断。优先级类别决定了排队请求的处理顺序。值越低,优先级越高。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X X  
此操作用于设置当前请求的队列优先级时间戳偏移量。该值必须是一个样本表达式,其转换结果为 -524287 到 524287 范围内的整数。超出此范围的结果将被截断。当一个请求进入队列时,它首先按优先级类别排序,然后按当前时间戳加上给定的偏移量(以毫秒为单位)进行排序。值越低,优先级越高。请注意,结果时间戳的跟踪精度仅足以表示 524,287 毫秒(8 分 44 秒 287 毫秒)。如果请求排队时间足够长,以至于调整后的时间戳超过此值,它将被错误地识别为最高优先级。因此,将“timeout queue”设置为一个值,使其与偏移量相加后不超过此限制,这一点很重要。
set-query <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作使用格式化字符串 <fmt> 的求值结果来重写请求中出现在第一个问号("?")之后的查询字符串。问号之前的部分保持不变。如果请求不包含问号且新值不为空,则会在 URI 的末尾添加一个问号,后跟新值。如果问号已存在,即使新值为空,它也永远不会被移除。这可以用于从查询字符串中添加或删除参数。另请参阅 "http-request set-path" 和 "http-request set-uri"。
示例
# 在查询字符串中将“%3D”替换为“=” http-request set-query %[query,regsub(%3D,=,g)]
set-src <expr>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXX X  
此操作用于将源 IP 地址设置为指定表达式的值。当 HAProxy 前面的代理重写了源 IP,但在 HTTP 标头中提供了正确的 IP 时,或者您想为隐私目的屏蔽源 IP 时,这很有用。所有后续对“src”的提取调用都将返回此值(见示例)。
参数
<expr> 是一个标准的 HAProxy 表达式,由一个样本提取后跟一些转换器组成。
另请参阅“option forwardfor”。
示例
http-request set-src hdr(x-forwarded-for) http-request set-src src,ipmask(24) # 经过掩码处理后,这将根据最后字节为零的 IP 地址来跟踪连接。 http-request track-sc0 src
在可能的情况下,只要地址族允许,set-src 会保留原始源端口,否则源端口将被设置为 0。

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXX X  
此操作用于将源端口地址设置为指定表达式的值。
参数
<expr> 是一个标准的 HAProxy 表达式,由一个样本提取后跟一些转换器组成。
示例
http-request set-src-port hdr(x-port) http-request set-src-port int(4000)
在可能的情况下,只要地址族支持端口,set-src-port 就会保留原始源地址,否则它会在重写端口之前将源地址强制设置为 IPv4 "0.0.0.0"。
set-status <status> [reason <str>]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
     XX
此操作将响应状态码替换为 <status>,该值必须是 100 到 999 之间的整数。可选地,可以提供由 <str> 定义的自定义原因文本,否则将使用指定代码的默认原因作为备选。请注意,原因字符串仅存在于 HTTP/1.x 中,并被其他协议版本忽略。
示例
# 返回“431 Request Header Fields Too Large” http-response set-status 431 # 返回“503 Slow Down”,自定义原因 http-response set-status 503 reason "Slow Down".
set-timeout { client | server | tunnel } { <timeout> | <expr> }

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
此操作仅针对当前流覆盖指定的 "client"、"server" 或 "tunnel" 超时。超时可以以毫秒为单位指定,或者如果数字后带有单位后缀,则可以以任何其他单位表示,具体如本文档开头所述。也可以编写一个表达式,该表达式必须返回一个被解释为毫秒超时的数字。请注意,服务器/隧道超时仅与后端侧相关,因此此规则仅适用于具有后端功能的代理。同样,客户端超时仅与前端侧相关。此外,超时值必须为非空才能获得预期结果。
示例
http-request set-timeout tunnel 5s http-request set-timeout server req.hdr(host),map_int(host.lst)
示例
http-response set-timeout tunnel 5s http-response set-timeout server res.hdr(X-Refresh-Seconds),mul(1000)
set-tos <tos>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXX 
此操作用于在支持此功能的平台上,将发送给客户端的数据包的 TOS 或 DSCP 字段值设置为 <tos> 中传递的值。此值代表 IP TOS 字段的全部 8 位,可以用十进制或十六进制格式(以“0x”为前缀)表示。请注意,DSCP 或 TOS 中仅使用较高的 6 位,而较低的两位始终为 0。这可用于根据请求中的某些信息调整边界路由器上的一些路由行为。有关更多信息,请参阅 RFC 2474, 2597, 3260 和 4594。
set-uri <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
此操作使用格式化字符串 <fmt> 的求值结果来重写请求 URI。scheme、authority、path 和查询字符串都会被一次性替换。这可以用于在代理前重写主机,或对 URI 进行复杂的修改,例如在路径和查询字符串之间移动部分。如果设置了绝对 URI,它将按原样发送到 HTTP/1.1 服务器。如果这不是期望的行为,则应分别设置主机、路径和/或查询字符串。另请参阅 "http-request set-path" 和 "http-request set-query"。
set-var(<var-name>[,<cond>...]) <expr>
set-var-fmt(<var-name>[,<cond>...]) <fmt>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
此操作用于设置变量的内容。变量是内联声明的。
参数
<var-name> 变量的名称以指示其范围的前缀开头。允许的范围是:"proc":变量与整个进程共享 "sess":变量与整个会话共享 "txn":变量与事务共享(请求和响应) "req":变量仅在请求处理期间共享 "res":变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是 '.'。名称只能包含字符 'a-z'、'A-Z'、'0-9' 和 '_'。 <cond> 一组条件,必须全部为真才能实际设置变量(例如 "ifnotempty"、"ifgt" ...)。有关可能的条件完整列表,请参阅 set-var 转换器的描述。 <expr> 是一个标准 HAProxy 表达式,由样本获取和一些转换器组成。 <fmt> 这是使用日志格式规则表示的值(参见 section 8.2.6 中的自定义日志格式)。
所有作用域都可用于 HTTP 规则,但作用域“proc”和“sess”是唯一可在无法访问内容的规则集(如“tcp-request connection”和“tcp-request session”)中使用的作用域。
示例
http-request set-var(req.my_var) req.fhdr(user-agent),lower http-request set-var-fmt(txn.from) %[src]:%[src_port]
silent-drop [ rst-ttl <ttl> ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXX 
这会停止对规则的评估,并使用一种系统相关的方式使面向客户端的连接突然消失,该方式试图防止客户端被通知。当不带 rst-ttl 参数调用时,我们尝试使用 TCP_REPAIR 来防止向客户端发送任何 FIN 或 RST 数据包。如果这失败(主要是因为缺少权限),我们会回退到发送一个 TTL 为 1 的 RST 数据包。效果是客户端仍然看到已建立的连接,而 HAProxy 上没有连接,从而节省了资源。然而,放置在 HAProxy 和客户端之间的有状态设备(防火墙、代理、负载均衡器)也会将其会话表中的已建立连接保持。可选的 rst-ttl 更改了这种行为:不使用 TCP_REPAIR,而是发送一个具有可配置 TTL 的 RST 数据包。当设置为合理值时,RST 数据包穿过本地基础架构,删除防火墙和其他系统中的连接,但在到达客户端之前消失。来自客户端的未来数据包将被前端设备丢弃。这些本地 RST 保护本地资源,但不保护客户端资源。除非完全理解这样做的后果,否则不得使用此功能。
strict-mode { on | off }

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XXX
此操作为后续规则启用或禁用严格重写模式。它不影响在其之前声明的规则,并且仅适用于对请求执行重写的规则。当启用严格模式时,任何重写失败都会触发内部错误。否则,此类错误将被静默忽略。严格重写模式的目的是使某些重写是可选的,而其他重写必须执行才能继续请求处理。默认情况下,严格重写模式是启用的。当规则集评估结束时,其值也会被重置。因此,例如,如果您在前端更改模式,当 HAProxy 开始后端规则评估时,默认模式将被恢复。
switch-mode http [ proto <name> ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X    
此操作用于执行连接升级。目前仅支持 HTTP 升级。协议可以可选地指定。此操作仅适用于具有前端能力的代理。连接升级会立即执行,后续的“tcp-request content”规则不会被评估。应优先使用此升级方法,而不是依赖后端模式的隐式方法。使用此方法时,可以在前端设置 HTTP 指令而不会有任何警告。如果执行了 HTTP 升级,这些指令将被有条件地评估。但是,仍然必须选择一个 HTTP 后端。将 HTTP 连接(无论是否升级)路由到 TCP 服务器仍然不受支持。有关 HTTP 升级的更多详细信息,请参见第 4 节关于代理的部分。
tarpit [ { status | deny_status } <code>] [content-type <type>] [ { default-errorfiles | errorfile <file> | errorfiles <name> | file <file> | lf-file <file> | string <str> | lf-string <fmt> } ] [ hdr <name> <fmt> ]*

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
这会停止对规则的评估,并立即阻止请求,延迟时间由 "timeout tarpit" 指定,如果未设置前者,则由 "timeout connect" 指定。在此延迟之后,如果客户端仍处于连接状态,则返回响应,以便客户端不会怀疑它被 tarpit。日志将报告标志 "PT"。tarpit 规则的目标是在攻击期间减慢机器人速度,当时它们受到并发请求数量的限制。它对于非常愚蠢的机器人非常有效,并且与 "deny" 规则相比,将显著减少防火墙上的负载。但是,当面对“正确”开发的机器人时,它可能会迫使 HAProxy 和前端防火墙支持 insane 数量的并发连接,从而使情况变得更糟。默认情况下,返回 HTTP 500 错误。但可以使用与 "http-request return" 规则相同的语法自定义响应。因此,有关详细信息,请参阅 "http-request return"。出于兼容性目的,当未定义参数或仅定义 "deny_status" 时,隐含参数 "default-errorfiles"。这意味着 "http-request tarpit [deny_status <status>]" 是 "http-request tarpit [status <status>] default-errorfiles" 的别名。不再评估后续的 "http-request" 规则。另请参阅 "http-request return" 和 "http-request silent-drop"。
track-sc0 <key> [table <table>]
track-sc1 <key> [table <table>]
track-sc2 <key> [table <table>]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXX XX 
这会启用从当前请求跟踪粘性计数器。这些规则不会停止评估,也不会更改默认操作。同一连接可以同时跟踪的计数器数量由全局 "tune.stick-counters" 设置设置,默认为 MAX_SESS_STKCTR(如果在构建时设置,则在 haproxy -vv 中报告),默认为 3,因此 track-sc 数字介于 0 和 (tune.stick-counters-1) 之间。执行的第一个 "track-sc0" 规则将指定表的计数器作为第一组启用跟踪。执行的第一个 "track-sc1" 规则将指定表的计数器作为第二组启用跟踪。执行的第一个 "track-sc2" 规则将指定表的计数器作为第三组启用跟踪。建议的做法是,将第一组计数器用于每前端计数器,第二组用于每后端计数器。但这只是一个指导方针,所有都可以用于任何地方。
参数
<key> 是强制性的,并且是如 section 7.3 中所述的样本表达式规则。它描述了将分析、提取、组合传入连接、请求或响应的哪些元素,并用于选择要更新计数器的表条目。 <table> 是一个可选表,用于代替默认表,默认表是在当前代理中声明的 stick-table。然后,密钥的所有匹配和更新计数器都将在该表中执行,直到会话结束。
一旦执行了“track-sc*”规则,将在表中查找该键,如果未找到,则会为其分配一个条目。然后,在整个会话生命周期内都会保留一个指向该条目的指针,并且该条目的计数器会尽可能频繁地更新,即每当会话的计数器更新时,以及在会话结束时系统性地更新。计数器只为跟踪开始后发生的事件更新。作为一个例外,连接计数器和请求计数器会系统性地更新,以反映有用的信息。如果该条目跟踪并发连接计数器,只要该条目被跟踪,就会计为一个连接,并且在此期间该条目不会过期。跟踪计数器相比仅检查键值还提供了性能优势,因为对于所有使用它的 ACL 检查,都只执行一次表查找。
unset-var(<var-name>)

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
XXXXXXX
这用于取消设置一个变量。有关 <var-name> 的详细信息,请参阅“set-var”操作。
示例
http-request unset-var(req.my_var)
use-service <service-name>

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
  X X  
此操作会执行配置的 TCP 或 HTTP 服务来响应请求,具体取决于它所在的规则集。该规则是最终的,即在同一规则集中不会再评估其他规则。服务可以选择发送任何有效响应来回复,也可以选择立即关闭连接而不发送任何响应。对于 HTTP 服务,有效响应需要是一个有效的 HTTP 响应。除了原生服务(例如用于 HTTP 服务的 Prometheus 导出器),还可以用 Lua 编写自定义的 TCP 和 HTTP 服务。
参数
<service-name> 是必需的。它是要调用的服务。
示例
http-request use-service prometheus-exporter if { path /metrics }
wait-for-body time <time> [ at-least <bytes> ]

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    XX 
此操作将延迟请求或响应的处理,直到发生以下条件之一: - 收到完整的请求体,此时处理正常进行。 - 当给出 "at-least" 参数且 <字节数> 非零时,已收到 <字节数> 字节,此时处理正常进行。 - 请求缓冲区已满,此时处理正常进行。此缓冲区的大小由“tune.bufsize”选项决定。 - 请求已等待超过 <时间> 毫秒。在这种情况下,HAProxy 将向客户端响应 408 "Request Timeout" 错误并停止处理请求。请注意,如果其他任何条件首先发生,即使尚未收到完整的请求体,此超时也不会发生。此操作可用作“option http-buffer-request”的替代品。
参数
<time> 是必需的。它是等待请求体的最长时间。它遵循 HAProxy 的时间格式,单位为毫秒。<bytes> 是可选的。它是停止等待所需的最小有效负载大小。它遵循 HAProxy 的大小格式,单位为字节。值为 0(默认值)表示没有限制。
示例
如果 METH_POST,则 http-request wait-for-body time 1s at-least 1k

Usable in

TCP RqConRqSesRqCntRsCntHTTP ReqResAft
    X  
这会延迟请求的处理,直到 SSL 握手完成。这主要用于延迟处理早期数据,直到我们确定它们是有效的。
关键字 "bind"、"server" 和 "default-server" 支持许多设置,具体取决于某些构建选项和构建 HAProxy 的系统。这些设置通常每个都包含一个单词,有时后跟一个值,写在与 "bind" 或 "server" 行相同的行上。所有这些选项都在本节中描述。

5.1. Bind 选项

"bind"关键字支持多种设置,这些设置都作为参数在同一行上传递。这些参数出现的顺序无关紧要,只要它们出现在绑定地址之后即可。所有这些参数都是可选的。其中一些由单个单词组成(布尔值),而另一些则需要一个值。在这种情况下,值必须紧跟在设置名称之后。当前支持的设置如下。
accept-netscaler-cip <magic number>
强制在同一行上声明的任何 TCP 套接字接受的所有连接上使用 NetScaler 客户端 IP 插入协议。NetScaler 客户端 IP 插入协议规定了传入连接的第 3/4 层地址,这些地址将在任何使用地址的地方使用,唯一的例外是“tcp-request connection”规则,它只会看到真实的连接地址。日志将反映协议中指定的地址,除非协议被违反,在这种情况下仍将使用真实地址。此关键字与外部组件的支持相结合,可用作 X-Forwarded-For 机制的高效可靠的替代方案,后者并非总是可靠,甚至并非总是可用。另请参阅“tcp-request connection expect-netscaler-cip”,以更精细地设置允许使用该协议的客户端。
强制在由同一行上声明的任何套接字接受的任何连接上使用 PROXY 协议。PROXY 协议的版本 1 和 2 都受支持并能正确检测。PROXY 协议规定了传入连接的第 3/4 层地址,这些地址将在任何使用地址的地方使用,唯一的例外是 "tcp-request connection" 规则,它只会看到真实的连接地址。日志将反映协议中指示的地址,除非协议被违反,在这种情况下仍将使用真实地址。此关键字与外部组件的支持相结合,可以作为 X-Forwarded-For 机制的一种高效可靠的替代方案,该机制并非总是可靠,甚至并非总是可用。另请参阅 "tcp-request connection expect-proxy" 以更精细地设置允许哪些客户端使用该协议。
允许在使用 TLSv1.3 时接收早期数据。由于安全考虑,默认情况下禁用此功能。因为它容易受到重放攻击,您只应为可以安全重放的请求(即幂等请求)允许它。对于任何不适合使用早期数据的请求,您可以使用“wait-for-handshake”操作。
alpn <protocols>
这会启用 TLS ALPN 扩展,并宣传指定的协议列表支持 ALPN。协议列表由逗号分隔的协议名称列表组成,例如:"http/1.1,http/1.0"(不带引号)。这要求 SSL 库在构建时启用了对 TLS 扩展的支持(使用 haproxy -vv 检查)。ALPN 扩展取代了最初的 NPN 扩展。在协议层面上,ALPN 是在 HTTPS 前端上启用 HTTP/2 和在 QUIC 前端上启用 HTTP/3 所必需的。然而,当此类前端没有设置 "npn"、"alpn" 和 "no-alpn" 中的任何一个时,对于常规 HTTPS 前端,将使用默认值 "h2,http/1.1",对于 QUIC 前端,将使用 "h3"。OpenSSL 1.0.2 之前的版本不支持 ALPN,只支持现已过时的 NPN 扩展。在撰写本文时,大多数浏览器仍然支持 HTTP/2 的 ALPN 和 NPN,因此回退到 NPN 可能在一段时间内仍然有效。但应尽可能使用 ALPN。未宣传的协议不会被协商。例如,只接受 HTTP/2 连接可以通过以下方式实现:bind :443 ssl crt pub.pem alpn h2 # explicitly disable HTTP/1.1 QUIC 仅支持 h3 和 hq-interop 作为 ALPN。h3 用于 HTTP/3,hq-interop 用于 http/0.9 和 QUIC interop runner(请参阅 https://interop.seemann.io)。每个 "alpn" 语句将替换前一个语句。要删除它们,请使用 "no-alpn"。请注意,一些旧浏览器(如 Firefox 88)过去在 H2 上的 WebSocket 方面遇到问题,如果遇到此类设置,可能需要明确禁用 HTTP/2 在 "alpn" 字符串中(通过强制将其设置为 "http/1.1" 或 "no-alpn"),或全局启用 "h2-workaround-bogus-websocket-clients"。
backlog <backlog>
将套接字的 backlog 设置为此值。如果未指定或为 0,则使用前端的 backlog,通常默认为 maxconn 值。
ca-file <cafile>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,用于加载验证客户端证书的 CA 证书。可以加载包含多个 CA 的目录,在这种情况下,HAProxy 将尝试加载目录中所有可用的“.pem”、“.crt”、“.cer”和“.crl”文件,以点开头的文件将被忽略。警告:可以使用“@system-ca”参数代替 cafile,以使用您系统的受信任 CA,就像 server 指令一样。但除非您知道自己在做什么,否则不应使用它。这样配置基本上意味着 bind 将接受由您系统上存在的任何 CA 生成的任何客户端证书,这是极其不安全的。
ca-ignore-err [all|<errorID>,...]
此设置仅在内置 OpenSSL 支持时可用。设置在深度 > 0 的验证期间要忽略的以逗号分隔的 errorID 列表。它可以是数字 ID,也可以是常量名称 (X509_V_ERR),可在 OpenSSL 文档中找到:https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES 建议使用常量名称,因为数值在新版本的 OpenSSL 中可能会改变。如果设置为 'all',则忽略所有错误。如果忽略了某个错误,SSL 握手不会中止。
ca-sign-file <cafile>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,其中包含用于创建和签署服务器证书的 CA 证书和 CA 私钥。当启用证书动态生成时,这是一个强制性设置。有关详细信息,请参见 'generate-certificates'。
ca-sign-pass <passphrase>
此设置仅在内置 OpenSSL 支持时可用。它是 CA 私钥的密码。此设置是可选的,仅在启用证书动态生成时使用。有关详细信息,请参见 'generate-certificates'。
此设置指定一个 PEM 文件,用于加载验证客户端证书的 CA 证书。它指定的 CA 证书不应包含在服务器 hello 消息中发送的 CA 名称中。通常,“ca-file”必须用中间证书定义,而“ca-verify-file”则用终止证书链的证书(如根 CA)定义。
ciphers <ciphers>
此设置仅在内置 OpenSSL 支持时可用。它设置描述在 SSL/TLS 握手期间(最高到 TLSv1.2)协商的密码算法列表(“密码套件”)的字符串。该字符串的格式在 OpenSSL 手册页的“man 1 ciphers”中定义。有关背景信息和建议,请参阅(https://wiki.mozilla.org/Security/Server_Side_TLS)和(https://mozilla.github.io/server-side-tls/ssl-config-generator/)。有关 TLSv1.3 密码配置,请检查“ciphersuites”关键字。
ciphersuites <ciphersuites>
此设置仅在内置 OpenSSL 支持且使用 OpenSSL 1.1.1 或更高版本构建 HAProxy 时可用。它设置描述在 TLSv1.3 握手期间协商的密码算法("cipher suite")列表的字符串。字符串的格式在 OpenSSL 手册页的 "man 1 ciphers" 中定义,位于 "ciphersuites" 部分。对于 TLSv1.2 及更早版本的密码配置,请查看 "ciphers" 关键字。此设置可能接受 TLSv1.2 密码套件,但这是一种无文档记录的行为,不推荐使用,因为它可能不一致或有错误。OpenSSL 的默认 TLSv1.3 密码套件是:"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" TLSv1.3 仅支持 5 个密码套件:- TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - TLS_AES_128_CCM_SHA256 - TLS_AES_128_CCM_8_SHA256
示例
ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
client-sigalgs <sigalgs>
此设置仅在内置 OpenSSL 支持时可用。它设置描述与客户端身份验证相关的协商签名算法列表的字符串。该字符串的格式在 OpenSSL 手册页的“man 3 SSL_CTX_set1_client_sigalgs”中定义。如果没有确定特定的用例,不建议使用此设置。
crl-file <crlfile>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,用于加载验证客户端证书的证书吊销列表。您需要为您证书颁发机构链中的每个证书提供一个证书吊销列表。
crt <cert>
此设置仅在内置OpenSSL支持时可用。它指定一个PEM文件,其中包含所需的证书和任何相关的私钥。此文件可以通过将多个PEM文件连接成一个文件来构建(例如 cat cert.pem key.pem > combined.pem)。如果您的CA需要中间证书,也可以将其连接到此文件中。中间证书也可以通过 "issuers-chain-path" 指令在目录中共享。如果文件不包含私钥,HAProxy将尝试加载同一路径下后缀为".key"的密钥。如果所使用的OpenSSL支持Diffie-Hellman,则会加载此文件中存在的参数。如果使用目录名而不是PEM文件,则除非文件名的末尾是'.key'、'.issuer'、'.ocsp'或'.sctl'(保留扩展名),否则该目录中找到的所有文件将按字母顺序加载。以点开头的文件也会被忽略。可以多次指定此指令,以便从多个文件或目录加载证书。这些证书将呈现给提供有效TLS服务器名称指示(SNI)字段的客户端,该字段与证书的CN或alt subjects之一匹配。支持通配符,其中星号 '*' 用于代替第一个主机名组件(例如 *.example.org 匹配 www.example.org,但不匹配 www.sub.example.org)。如果使用空目录,除非使用 "strict-sni" 关键字,否则HAProxy将不会启动。如果客户端未提供SNI,或者SSL库不支持TLS扩展,或者客户端提供的SNI主机名与任何证书都不匹配,则将呈现第一个加载的证书。这意味着当从目录加载证书时,强烈建议将默认证书作为文件首先加载,或确保它始终是目录中的第一个。请注意,同一证书可以多次加载而没有副作用。某些CA(如GoDaddy)在获取证书时提供服务器类型下拉列表,其中不包括HAProxy。如果发生这种情况,请务必选择CA认为需要中间CA的Web服务器(对于GoDaddy,选择Apache Tomcat将获得正确的捆绑包,但许多其他服务器,例如nginx,会导致错误的捆绑包,不适用于某些客户端)。对于每个PEM文件,HAProxy会检查同一路径下后缀为".ocsp"的文件是否存在。如果找到此类文件,则会自动启用对TLS证书状态请求扩展(也称为"OCSP Stapling")的支持。此文件的内容是可选的。如果非空,它必须包含有效的DER格式OCSP响应。为了有效,OCSP响应必须符合以下规则:它必须指示良好状态,它必须是PEM文件证书的单个响应,并且在添加时必须有效。如果不遵守这些规则,OCSP响应将被忽略并发出警告。为了识别OCSP响应适用于哪个证书,需要颁发者证书。如果在PEM文件中找不到颁发者证书,则将从与PEM文件相同路径下后缀为".issuer"的文件中加载(如果存在),否则将失败并显示错误。对于每个PEM文件,HAProxy还会检查同一路径下后缀为".sctl"的文件是否存在。如果找到此类文件,则启用证书透明度(RFC6962)TLS扩展支持。文件必须包含有效的签名证书时间戳列表,如RFC所述。文件将解析以检查基本语法,但不会验证签名。在某些情况下,需要支持多种密钥类型,例如为客户端提供的密码套件中的RSA和ECDSA。这允许支持EC证书的客户端能够使用EC密码,同时支持较旧的仅限RSA的客户端。为此,需要OpenSSL 1.1.1,您可以通过为每种证书类型提供一个crt条目来配置此行为,或者配置一个像HAProxy 1.8之前要求的那样的“证书捆绑包”。请参阅"ssl-load-extra-files"。
此设置仅在内置 OpenSSL 支持时可用。设置在深度 == 0 的验证期间要忽略的以逗号分隔的 errorID 列表。它可以是数字 ID,也可以是常量名称 (X509_V_ERR),可在 OpenSSL 文档中找到:https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES 建议使用常量名称,因为数值在新版本的 OpenSSL 中可能会改变。如果设置为 'all',则忽略所有错误。如果忽略了某个错误,SSL 握手不会中止。
crt-list <file>
此设置仅在内置OpenSSL支持时可用。它指定一个PEM文件列表,其中包含可选的ssl配置和每个证书的SNI过滤器,每行的格式如下:<crtfile> [\[<sslbindconf> ...\]] [[!]<snifilter> ...] sslbindconf支持来自bind行的以下关键字(参见第5.1节. Bind options): - allow-0rtt - alpn - ca-file - ca-verify-file - ciphers - ciphersuites - client-sigalgs - crl-file - curves - ecdhe - no-alpn - no-ca-names - npn - sigalgs - ssl-min-ver - ssl-max-ver - verify 它会覆盖bind行中为证书设置的配置。SNI过滤器中支持通配符。还支持负面过滤器,这在与通配符过滤器结合使用以排除特定SNI时很有用,或者在第一个证书之后使用以从其CN或SAN(Subject Alt Name)中排除模式。这些证书将呈现给提供有效TLS服务器名称指示(SNI)字段的客户端,该字段与SNI过滤器之一匹配。如果未指定SNI过滤器,则使用CN和SAN。此指令可以多次指定。有关更多信息,请参阅 "crt" 选项。默认证书仍然需要满足OpenSSL的期望。如果未使用它,则可以使用“strict-sni”选项。crt-list支持多证书捆绑(参见"ssl-load-extra-files"),只要在crt-list中只提供基本名称即可。SNI过滤器将对所有捆绑证书执行相同的工作。空行以及以哈希('#')开头的行将被忽略。bind行的第一个声明证书用作默认证书,无论是来自crt还是crt-list选项,如果HAProxy没有其他证书匹配,它将在TLS握手中使用此证书。即使在任何crt-list上找到了匹配的SNI过滤器,如果提供的SNI与其CN或SAN匹配,也将使用此证书。SNI过滤器 !* 可以在第一个声明的证书之后使用,以不将其CN和SAN包含在SNI树中,因此除非没有其他证书匹配,否则它永远不会匹配。这样,第一个声明的证书充当后备。未设置ALPN时,使用 "bind" 行的默认值。如果 "bind" 行未设置 "no-alpn"、"alpn" 或 "npn",则将使用取决于协议的默认值(参见上面的"alpn")。但是,如果 "bind" 行具有不同的默认值,或者使用 "no-alpn" 显式禁用ALPN,则可以为证书强制设置特定值。crt-list 文件示例:cert1.pem !* # comment cert2.pem [alpn h2,http/1.1] certW.pem *.domain.tld !secure.domain.tld certS.pem [curves X25519:P-256 ciphers ECDHE-ECDSA-AES256-GCM-SHA384] secure.domain.tld
curves <curves>
此设置仅在内置 OpenSSL 支持时可用。它设置描述在与 ECDHE 的 SSL/TLS 握手期间协商的椭圆曲线算法列表(“曲线套件”)的字符串。该字符串的格式是以冒号分隔的曲线名称列表。
示例
"X25519:P-256" (不带引号)
当设置 "curves" 时,将忽略 "ecdhe" 参数。
是一个可选关键字,仅在某些 Linux 内核上受支持。它规定只有在连接上有数据到达时,或者最坏情况下在第一次重传后,才会接受连接。这只应在客户端首先发言的协议(例如 HTTP)上使用。它可以通过确保在接受连接时大部分请求已经可用,从而略微提高性能。另一方面,它将无法检测到不发言的连接。重要的是要注意,此选项在所有 2.6.31 之前的内核中都是有问题的,因为在客户端发言之前连接永远不会被接受。这可能会导致前端防火墙出现问题,前端防火墙会看到一个已建立的连接,而代理只会看到它处于 SYN_RECV 状态。此选项仅在 TCPv4/TCPv6 套接字上受支持,其他套接字会忽略它。
ecdhe <named curve>
此设置仅在内置 OpenSSL 支持时可用。它设置用于生成 ECDH 临时密钥的命名曲线(RFC 4492)。默认情况下,使用的命名曲线是 prime256v1。
此选项仅可与 stats 套接字一起使用。它使您的 stats 套接字能够将侦听器 FD 传递给另一个 HAProxy 进程。在 master-worker 模式下,不再需要此功能,侦听器将通过 master 和 worker 之间的内部套接字对进行传递。另请参阅管理指南中的“-x”。
此选项强制此侦听器实例化的SSL连接仅使用SSLv3。对于高连接速率,SSLv3通常比TLS对应项的成本更低。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver" 和 "ssl-max-ver"。
此选项强制此侦听器实例化的SSL连接仅使用TLSv1.0。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver" 和 "ssl-max-ver"。
此选项强制此侦听器实例化的SSL连接仅使用TLSv1.1。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver" 和 "ssl-max-ver"。
此选项强制此侦听器实例化的SSL连接仅使用TLSv1.2。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver" 和 "ssl-max-ver"。
此选项强制此侦听器实例化的SSL连接仅使用TLSv1.3。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver" 和 "ssl-max-ver"。
此设置仅在内置 OpenSSL 支持时可用。它启用动态 SSL 证书生成。需要一个 CA 证书及其私钥(参见“ca-sign-file”)。当 HAProxy 配置为透明转发代理时,由于呈现给客户端的证书上的通用名称不匹配,SSL 请求会产生错误。启用此选项后,HAProxy 将尝试使用客户端指示的 SNI 主机名伪造一个证书。这仅在没有证书与 SNI 主机名匹配时才会发生(参见“crt-list”)。如果发生错误,则使用默认证书,否则设置“strict-sni”选项。当 HAProxy 配置为反向代理时,它也可以用于简化具有许多后端的架构的部署。创建 SSL 证书是一项昂贵的操作,因此使用 LRU 缓存来存储伪造的证书(参见“tune.ssl.ssl-ctx-cache-size”)。它增加了 HAProxy 的内存占用,以减少多次使用同一证书时的延迟。
gid <gid>
将 UNIX 套接字的组设置为指定的系统 GID。也可以在全局部分的“unix-bind”语句中默认设置。请注意,某些平台会直接忽略此设置。此设置等同于“group”设置,不同之处在于使用组 ID 而不是其名称。非 UNIX 套接字会忽略此设置。
group <group>
将 UNIX 套接字的组设置为指定的系统组。也可以在全局部分的 "unix-bind" 语句中默认设置。请注意,某些平台会直接忽略此设置。此设置与 "gid" 设置等效,不同之处在于它使用组名而不是组 ID。此设置对非 UNIX 套接字无效。
id <id>
固定套接字 ID。默认情况下,套接字 ID 是自动分配的,但有时为了方便监控而固定它们会更方便。此值必须是严格正数,并且在侦听器/前端内是唯一的。此选项只能在定义单个套接字时使用。
interface <interface>
将套接字限制到特定接口。指定后,只有从该特定接口接收的数据包才会由套接字处理。目前仅在 Linux 上受支持。该接口必须是主系统接口,而不是别名接口。如果多个前端绑定到不同的接口,也可以将它们绑定到同一地址。请注意,绑定到网络接口需要 root 权限。此参数仅与 TCPv4/TCPv6 套接字兼容。指定后,返回流量将使用与入站流量相同的接口及其关联的路由表,即使配置了通过不同接口的显式路由也是如此。当同一客户端 IP 地址需要能够访问托管在不同接口上的前端时,这对于解决非对称路由问题非常有用。
level <level>
此设置仅用于stats sockets,以限制可在套接字上发出的命令的性质。其他套接字会忽略它。<level> 可以是以下之一: - "user" 是权限最低的级别;只能读取非敏感统计信息,不允许更改。在不容易限制对套接字访问的系统上,这很有意义。 - "operator" 是默认级别,适用于大多数常见用途。可以读取所有数据,并且只允许进行非敏感更改(例如清除最大计数器)。 - "admin" 应谨慎使用,因为它允许执行所有操作(例如清除所有计数器)。
maxconn <maxconn>
将套接字限制为此数量的并发连接。多余的连接将保留在系统的 backlog 中,直到释放一个连接。如果未指定,限制将与前端的 maxconn 相同。请注意,在端口范围或多个地址的情况下,相同的值将应用于每个套接字。此设置允许对昂贵的套接字进行不同的限制,例如 SSL 条目,它们很容易耗尽所有内存。
mode <mode>
设置用于定义 UNIX 套接字访问权限的八进制模式。也可以在全局部分的 "unix-bind" 语句中默认设置。请注意,某些平台会直接忽略此设置。此设置对非 UNIX 套接字无效。
mss <maxseg>
设置要在传入连接上通告的 TCP 最大段大小(MSS)值。这可用于为某些特定端口强制使用较低的 MSS,例如用于通过 VPN 的连接。请注意,这依赖于一个内核功能,理论上在 Linux 下受支持,但在 2.6.28 之前的所有版本中都有错误。它可能在其他操作系统上工作,也可能不工作。它也可能不改变通告的值,而是改变传出段的有效大小。在以太网网络上,TCPv4 的通常通告值为 1460 = 1500(MTU) - 40(IP+TCP)。如果此值为正,它将用作通告的 MSS。如果为负,它将指示传出段应比传入连接的通告 MSS 减少多少。此参数仅与 TCP v4/v6 套接字兼容。
name <name>
为这些套接字设置一个可选名称,该名称将在统计页面上报告。
namespace <name>
在 Linux 上,可以指定套接字将属于哪个网络命名空间。此指令使得可以显式地将侦听器绑定到不同于默认命名空间的命名空间。请参考您的操作系统文档以了解有关网络命名空间的更多详细信息。
nbconn <nbconn> [ 实验性 ]
此设置仅对使用反向 HTTP 的侦听器实例有效。这将定义将并行建立的连接数。如果未指定,则使用默认值 1。反向 HTTP 目前仍在积极开发中。配置机制将来可能会改变。因此,它在内部被标记为实验性,这意味着在使用此指令之前必须在一行上出现“expose-experimental-directives”。
nice <nice>
设置从套接字发起的连接的“友好度”(niceness)。值必须在 -1024 到 1024(含)之间,默认为零。正值意味着此类连接对其他连接更友好,并且容易在调度器中让出位置。相反,负值意味着连接希望以比其他连接更高的优先级运行。这种差异仅在高负载下,当系统接近饱和时才会发生。负值适用于低延迟或管理服务,而高值通常推荐用于 CPU 密集型任务,如 SSL 处理或对延迟不那么敏感的批量传输。例如,为 SMTP 套接字使用正值,为 RDP 套接字使用负值可能是有意义的。
禁用ALPN处理(从技术上讲,这将ALPN字符串设置为空字符串,不会进行通告)。它允许取消先前出现的 "alpn" 设置并禁用应用层协议协商。它还可用于防止侦听器与HTTPS或QUIC侦听器上的客户端协商ALPN;默认情况下,HTTPS侦听器将通告"h2,http/1.1",QUIC侦听器将通告"h3"。另请参阅上面的 "alpn"。请注意,使用 "crt-list" 时,证书可能会覆盖 "alpn" 设置并重新启用其处理。
此设置仅在内置 OpenSSL 支持时可用。它在使用 ca-file 时阻止在服务器 hello 消息中发送 CA 名称。请使用“ca-verify-file”代替带有“no-ca-names”的“ca-file”。
此设置仅在内置OpenSSL支持时可用。如果支持SSL,它会禁用此侦听器实例化的任何套接字上的SSLv3支持。请注意,SSLv2在代码中被强制禁用,不能使用任何配置选项启用。此选项也可用于全局语句 "ssl-default-bind-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。
此设置仅在内置 OpenSSL 支持时可用。它禁用无状态会话恢复(RFC 5077 TLS Ticket 扩展)并强制使用有状态会话恢复。无状态会话恢复在 CPU 使用方面成本更高。此选项在全局语句“ssl-default-bind-options”中也可用。TLS ticket 机制仅用于 TLS 1.2 及以下版本。除非定期轮换 ticket 密钥(通过 reload 或使用“tls-ticket-keys”),否则使用 TLS ticket 会损害前向保密性。
此设置仅在内置OpenSSL支持时可用。如果支持SSL,它会禁用此侦听器实例化的任何套接字上的TLSv1.0支持。请注意,SSLv2在代码中被强制禁用,不能使用任何配置选项启用。此选项也可用于全局语句 "ssl-default-bind-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。
此设置仅在内置OpenSSL支持时可用。如果支持SSL,它会禁用此侦听器实例化的任何套接字上的TLSv1.1支持。请注意,SSLv2在代码中被强制禁用,不能使用任何配置选项启用。此选项也可用于全局语句 "ssl-default-bind-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。
此设置仅在内置OpenSSL支持时可用。如果支持SSL,它会禁用此侦听器实例化的任何套接字上的TLSv1.2支持。请注意,SSLv2在代码中被强制禁用,不能使用任何配置选项启用。此选项也可用于全局语句 "ssl-default-bind-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。
此设置仅在内置OpenSSL支持时可用。如果支持SSL,它会禁用此侦听器实例化的任何套接字上的TLSv1.3支持。请注意,SSLv2在代码中被强制禁用,不能使用任何配置选项启用。此选项也可用于全局语句 "ssl-default-bind-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。
npn <protocols>
这将启用NPN TLS扩展,并通告指定的协议列表支持NPN。协议列表是一个逗号分隔的协议名称列表,例如:"http/1.1,http/1.0"(不带引号)。这需要构建SSL库时启用了对TLS扩展的支持(使用 haproxy -vv 检查)。请注意,NPN扩展已被ALPN扩展取代(参见 "alpn" 关键字),尽管后者仅从OpenSSL 1.0.2开始可用。如果需要在较旧版本的OpenSSL上使用HTTP/2,NPN可能仍然可以使用,因为在撰写本文时大多数客户端仍然支持它。可以同时启用NPN和ALPN,尽管除了测试之外可能没有任何意义。
ocsp-update [ off | on ] (crt-list only)
设置为“on”时启用自动OCSP响应更新,否则禁用。其值默认为“off”。请注意,目前此选项只能在crt-list行中使用,不能直接在bind行中使用。它位于此“Bind options”部分,因为它仍然是一个frontend选项。设置此限制是为了使该选项一次仅适用于一个证书。如果给定证书在具有不同“ocsp-update”设置值的多个crt-list中使用,则会引发错误。以下是启用它的示例配置:haproxy.cfg:frontend fe bind :443 ssl crt-list haproxy.list haproxy.list: server_cert.pem [ocsp-update on] foo.bar 当选项设置为“on”时,只要在frontend的证书中找到ocsp uri,我们就会尝试获取ocsp响应。此模式的唯一限制是必须知道证书的颁发者才能构建OCSP certid。每个OCSP响应将至少每小时更新一次,如果给定OCSP响应的到期日期早于此一小时限制,则更新频率更高。仍然存在5分钟的最小更新间隔,以避免更新过于频繁的响应,这些响应的到期时间非常短,甚至根本没有“Next Update”。由于此硬限制,请注意,当自动更新设置为“on”或“auto”时,在初始化期间加载的任何OCSP响应将不会更新,直到至少5分钟后,即使其到期时间在now+5m之前结束。这应该不会造成太大麻烦,因为OCSP响应在初始化期间加载时必须有效(其到期时间必须在将来),因此此响应在初始化后如此短的时间内到期的可能性很小。另一方面,如果证书指定了OCSP uri且没有OCSP响应,则将此选项设置为“on”将确保在初始化后立即自动获取OCSP响应。默认的最小和最大延迟(分别为5分钟和1小时)可以通过全局选项 "tune.ssl.ocsp-update.maxdelay" 和 "tune.ssl.ocsp-update.mindelay" 进行配置。每当自动更新任务更新OCSP响应或调用"update ssl ocsp-response" CLI命令时,都会发出专用的日志行。它遵循一个专用的日志格式,其中包含以下标头"%ci:%cp [%tr] %ft",后跟特定的OCSP相关信息: - 相应frontend证书的路径 - 数字更新状态 - 文本更新状态 - 给定响应的更新失败次数 - 给定响应的更新成功次数 有关错误代码和错误消息的完整列表,请参阅 "show ssl ocsp-updates" CLI命令。无论相关OCSP响应更新成功还是失败,都会发出此行。OCSP请求/响应通过设置了dontlog-normal选项的http_client实例发送和接收,如果发生错误(例如无法访问OCSP响应程序),则使用常规HTTP日志格式。如果发生此类错误,则会发出另一行包含HTTP相关信息的日志行,同时发出“常规”OCSP日志行(其文本状态可能为“HTTP error”)。但是,如果发生纯粹的HTTP错误(例如无法访问OCSP响应程序),则会发出遵循常规HTTP日志格式的额外日志行。以下是此类日志行的两个示例,首先是成功的OCSP更新日志行,然后是HTTP错误示例,其中包含两条不同的行(为了可读性,行已拆分且URL已缩短):<134>Mar 6 11:16:53 haproxy[14872]: -:- [06/Mar/2023:11:16:52.808] \ <OCSP-UPDATE> /path_to_cert/foo.pem 1 "Update successful" 0 1 <134>Mar 6 11:18:55 haproxy[14872]: -:- [06/Mar/2023:11:18:54.207] \ <OCSP-UPDATE> /path_to_cert/bar.pem 2 "HTTP error" 1 0 <134>Mar 6 11:18:55 haproxy[14872]: -:- [06/Mar/2023:11:18:52.200] \ <OCSP-UPDATE> -/- 2/0/-1/-1/3009 503 217 - - SC-- 0/0/0/0/3 0/0 {} \ "GET http://127.0.0.1:12345/MEMwQT HTTP/1.1" 故障排除:使用let's encrypt证书时可能发生的常见错误是DNS解析提供IPv6地址,而您的系统没有有效的传出IPv6路由。在这种情况下,您可以创建适当的路由或在全局部分中设置 "httpclient.resolvers.prefer ipv4" 选项。如果出现“OCSP response check failure”错误,您可能需要检查您提供的颁发者证书是否有效。
在选择密码套件时使用客户端的偏好,默认情况下强制使用服务器的偏好。此选项也可在全局语句“ssl-default-bind-options”中使用。请注意,对于 OpenSSL >= 1.1.1,如果 ChaCha20-Poly1305 密码位于客户端密码列表的顶部,ChaCha20-Poly1305 无论如何都会被重新优先排序(无需设置此选项)。
proto <name>
强制多路复用器的协议用于传入连接。它必须与frontend的模式(TCP或HTTP)兼容。它也必须在frontend端可用。可用协议列表在 haproxy -vv 中报告。报告了协议属性:模式(TCP/HTTP)、端(FE/BE)、mux名称及其标志。某些协议在服务器端容易出现行首阻塞(flag=HOL_RISK)。最后,某些协议不支持升级(flag=NO_UPG)。还报告了HTX兼容性(flag=HTX)。以下是可在bind行上用作 "proto" 指令参数的协议:h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG 此选项背后的想法是绕过为此侦听套接字实例化的所有连接选择最佳多路复用器协议。例如,可以通过在bind行上指定 "proto h2" 来强制在清除TCP上使用http/2。
quic-cc-algo { cubic | newreno }
quic-cc-algo { cubic | newreno }(max_window)
这是一个特定于QUIC的设置,用于为配置的QUIC侦听器的任何连接尝试选择拥塞控制算法。它们类似于TCP使用的算法。可选值(以字节为单位)可用于指定最大窗口大小。它必须大于10k且小于4g。默认值:cubic 默认窗口值:tune.quic.frontend.conn-tx-buffers.limit * tune.bufsize
示例
# newreno 拥塞控制算法 quic-cc-algo newreno # cubic 拥塞控制算法,窗口大小为 1MB quic-cc-algo cubic(1m)
这是一个 QUIC 特定设置,它强制为所有到配置的 QUIC 监听器的连接尝试使用 QUIC Retry 功能。它包括验证对端是否能够在其用于发起新连接的传输地址上接收数据包,方法是向它们发送一个包含令牌的 Retry 数据包。此令牌必须被发回给 Retry 数据包的发送方,后者是唯一能够验证该令牌的一方。请注意,即使设置了 Retry 阈值(参见“tune.quic.retry-threshold”设置),QUIC Retry 也将始终被使用。此设置要求设置集群密钥,否则在启动时会报告错误(参见“cluster-secret”)。有关 QUIC retry 的更多信息,请参见 https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1.2。
quic-socket [ connection | listener ]
这个 QUIC 特定设置允许为特定监听器定义套接字分配模式。有关其用法的完整描述,请参见“tune.quic.socket-owner”。
此设置仅与 stats 套接字一起使用,用于配置附加到信息反馈消息前的严重性级别输出。消息的严重性级别范围可以在 0 到 7 之间,符合 syslog rfc5424。请求数据的有效且成功的套接字命令(例如“show map”、“get acl foo”等)绝不会附加严重性级别。其他套接字会忽略此设置。<format> 可以是以下之一:- “none”(默认)不向反馈消息前附加严重性级别。- “number” 严重性级别作为数字附加。- “string” 严重性级别作为遵循 rfc5424 约定的字符串附加。
shards <number> | by-thread | by-group
在多线程模式下,在支持同一IP:端口上的多个侦听器的操作系统上,这将自动为此行创建多个相同数量的侦听器,所有侦听器都绑定到此侦听器所附线程数的公平份额。当使用非常大的线程数时,单个套接字上的内核锁定开始导致显着的开销时,这有时很有用。在这种情况下,传入流量分布在多个套接字上,减少了争用。请注意,这样做很容易通过使更多线程工作一点来增加CPU使用率。如果碎片数量高于可用线程数量,它将自动修剪为线程数量(即每个线程一个碎片)。特殊的“by-thread”值还会创建与 "bind" 行上的线程一样多的碎片。由于系统将在所有这些碎片之间均匀分配传入流量,因此此数字是线程数的整数除数非常重要。或者,另一个特殊值“by-group”将为每个线程组创建一个碎片。当处理许多线程并且不想创建太多套接字时,这很有用。负载分配会稍微不那么理想,但争用(尤其是在系统中)仍会低于单个套接字。在不支持绑定到同一地址的多个套接字的操作系统上,“by-thread”和“by-group”将自动回退到单个碎片。对于“by-group”,这是在没有任何警告的情况下完成的,因为它不会对单个组产生任何影响,并且无论如何都会导致套接字为每个组重复。但是,对于“by-thread”,如果发生这种情况,将发出诊断警告,因为生成的侦听器数量将不是预期的数量。
sigalgs <sigalgs>
此设置仅在内置 OpenSSL 支持时可用。它设置一个字符串,描述在 TLSv1.2 和 TLSv1.3 握手期间协商的签名算法列表。字符串的格式在 OpenSSL 手册页的“man 3 SSL_CTX_set1_sigalgs”中定义。不建议使用此设置,除非需要与中间件兼容。
此设置仅在内置 OpenSSL 支持时可用。它在此监听器实例化的连接上启用 SSL 解密。需要一个证书(参见上面的“crt”)。缓冲区中的所有内容都将以明文形式出现,因此 ACL 和 HTTP 处理只能访问解密后的内容。默认情况下禁用 SSLv3,使用“ssl-min-ver SSLv3”来启用它。
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
此选项强制此侦听器实例化的SSL连接使用 <version> 或更低版本。在不使用 "ssl-min-ver" 的情况下使用此设置可能会产生歧义,因为默认ssl-min-ver值可能会在未来的HAProxy版本中更改。此选项也可用于全局语句 "ssl-default-bind-options"。另请参阅 "ssl-min-ver"。
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
此选项强制在此监听器实例化的 SSL 连接上使用 <version> 或更高版本。默认值为“TLSv1.2”。此选项也适用于全局语句“ssl-default-bind-options”。另请参见“ssl-max-ver”。
此设置仅在内置 OpenSSL 支持时可用。仅当客户端提供的 SNI 与证书匹配时,才允许 SSL/TLS 协商。不使用默认证书。此选项还允许在 bind 行上没有任何证书的情况下启动,因此可以使用一个空目录,然后从 stats 套接字填充。有关更多信息,请参见“crt”选项。参见管理指南中的“add ssl crt-list”命令。
tcp-ut <delay>
为从此监听套接字实例化的所有传入连接设置 TCP 用户超时。此选项自 Linux 2.6.37 版本起可用。它允许 HAProxy 为包含未在配置的延迟内收到确认的数据的套接字配置超时。这对于经历长空闲期的长连接(例如远程终端或数据库连接池)特别有用,其中客户端和服务器超时必须保持较高以允许长时间的空闲,但同时检测客户端是否已消失以释放与其连接(及服务器会话)相关的所有资源又非常重要。参数是一个以毫秒为单位的延迟,默认情况下。这仅适用于常规 TCP 连接,对其他协议无效。
是一个可选关键字,仅在 Linux 内核版本 >= 3.7 上受支持。它在监听套接字上启用 TCP 快速打开(TCP Fast Open),这意味着支持此功能的客户端将能够在第二次连接开始的三次握手期间发送请求并接收响应,从而在第一次连接后节省一次往返时间。这仅对连接率高且每次往返都很重要的协议有意义。这可能会导致许多防火墙出现问题,因为它们不接受 SYN 数据包上的数据,因此只应在经过充分测试后才启用此选项。此选项仅在 TCPv4/TCPv6 套接字上受支持,并被其他套接字忽略。如果您的 libc 未定义 TCP_FASTOPEN,您可能需要使用 USE_TFO=1 来构建 HAProxy。
thread [<thread-group>/]<thread-set>[,...]
这限制了允许此侦听器运行的线程列表。它不会强制其中任何一个,但会消除不匹配的线程。它限制了允许处理此侦听器传入连接的线程。有两种编号方案。默认情况下,线程编号在进程中是绝对的,介于1和global.nbthread中指定的值之间。也可以使用其在线程组中的相对编号来指定线程编号,方法是首先指定线程组编号,然后是斜杠('/')和相对线程编号。在这种情况下,线程编号也从1开始,并根据平台以32或64结束。指定绝对线程编号时,一旦知道线程组,它们将自动转换为相对编号。通常,简单配置首选绝对编号,而CPU排列对性能很重要的复杂配置首选相对编号。在可选的线程组编号之后,“thread-set”规范必须使用以下格式:“all” | "odd" | "even" | [number][-[number]]顾名思义,“all”验证集合中的所有线程(如果指定了组,则验证组中的所有线程,否则验证进程中的所有线程),"odd" 验证所有奇数编号线程(从1开始的每隔一个线程),无论是进程还是组,"even" 验证所有偶数编号线程(从2开始的每隔一个线程)。如果改用线程编号范围,则验证从第一个到最后一个线程编号范围内的所有线程。编号是相对于组还是绝对的,取决于是否存在线程组编号。如果省略第一个线程编号,则使用“1”,表示组中的第一个线程或进程中的第一个线程。如果省略最后一个线程编号,则使用组中的最后一个线程编号(32或64)或进程中的最后一个线程编号(global.nbthread)。这些范围可以重复并用逗号分隔,以便可以指定不连续的线程集,并且如果存在组,则必须为每个新范围再次指定该组。请注意,不允许混合使用组相对和绝对规范,因为整个 "bind" 行必须使用绝对表示法或相对表示法,因为未设置的表示法将在解析结束时解析。重要的是要知道,"bind" 行描述的每个侦听器至少创建一个由至少一个文件描述符表示的套接字。由于文件描述符不能跨越多个线程组,如果 "bind" 行指定跨越多个组的线程范围,则会自动创建多个文件描述符,以便每个组至少有一个。从技术上讲,它们在内核中都指向同一个套接字,但它们将在haproxy中获得不同的标识符,并且如果使用 "option socket-stats",它们甚至会有一个专用的stats条目。主要目的是让多个bind行共享相同的IP:端口,但在侦听器中不共享相同的线程,以便系统可以将传入连接分配到多个队列中,绕过haproxy的内部队列负载平衡。目前已知Linux 3.9及更高版本支持此功能。另请参阅上面的 "shards" 关键字,它使 "bind" 行的重复及其对多个线程组的分配自动化。此关键字与反向HTTP绑定兼容。但是,对于此类侦听器,禁止指定跨越多个线程组的线程集,因为这可能会导致 "nbconn" 无法按预期工作。
tls-ticket-keys <keyfile>
设置从中加载密钥的 TLS 票证密钥文件。根据使用 aes128 还是 aes256,密钥需要是 48 或 80 字节长,并使用 base64 编码,每行一个密钥(例如 openssl rand 80 | openssl base64 -A | xargs echo)。第一个密钥决定了后续密钥使用的密钥长度:您不能混合使用 aes128 和 aes256 密钥。密钥数量由 TLS_TICKETS_NO 构建选项指定(默认为 3),文件中至少需要存在同样数量的密钥。最后的 TLS_TICKETS_NO 个密钥将用于解密,倒数第二个密钥用于加密。这通过简单地将新密钥追加到文件并重新加载进程来实现轻松的密钥轮换。密钥必须定期轮换(例如每 12 小时),否则完美前向保密性会受到损害。将密钥远离任何永久性存储设备(如硬盘)也是一个好主意(提示:使用 tmpfs 并且不要交换这些文件)。生命周期提示可以使用 tune.ssl.timeout 进行更改。
是一个可选关键字,仅在某些 Linux 内核上受支持。它表示即使地址不属于本地机器,也会绑定这些地址,并且目标为这些地址的数据包将被截获,就好像这些地址是本地配置的一样。这通常需要启用 IP 转发。注意!不要将此与默认地址 '*' 一起使用,因为它会重定向指定端口的所有流量。此关键字仅在 HAProxy 使用 USE_LINUX_TPROXY=1 构建时可用。此参数仅与 TCPv4 和 TCPv6 套接字兼容,具体取决于内核版本。一些发行版的内核包含该功能的向后移植版本,因此请向您的供应商查询支持情况。
uid <uid>
将 UNIX 套接字的所有者设置为指定的系统 UID。也可以在全局部分的“unix-bind”语句中默认设置。请注意,某些平台会直接忽略此设置。此设置等同于“user”设置,不同之处在于使用用户的数字 ID 而不是其名称。非 UNIX 套接字会忽略此设置。
user <user>
将 UNIX 套接字的所有者设置为指定的系统用户。它也可以在全局部分的“unix-bind”语句中默认设置。请注意,某些平台会直接忽略此设置。此设置与“uid”设置等效,不同之处在于使用的是用户名而不是其 uid。此设置被非 UNIX 套接字忽略。
是一个可选关键字,仅在包括 Linux 内核版本 >= 2.4.21 在内的大多数最新系统上受支持。它用于在使用默认地址时将套接字同时绑定到 IPv4 和 IPv6。在默认情况下仅绑定到 IPv6 的系统上,这样做有时是必要的。它对非 IPv6 套接字没有影响,并被“v6only”选项覆盖。
是一个可选关键字,仅在包括 Linux 内核版本 >= 2.4.21 在内的大多数最新系统上受支持。它用于在使用默认地址时将套接字仅绑定到 IPv6。这样做有时比系统范围的设置更受欢迎,因为它是针对每个监听器的。它对非 IPv6 套接字没有影响,并优先于“v4v6”选项。
verify [none|optional|required]
此设置仅在构建时包含 OpenSSL 支持时可用。如果设置为 'none',则不请求客户端证书。这是默认设置。在其他情况下,会请求客户端证书。如果客户端在请求后未提供证书,并且 'verify' 设置为 'required',则握手将中止,而如果设置为 'optional',则会成功。客户端提供的证书始终使用来自 'ca-file' 的 CA 和来自 'crl-file' 的可选 CRL 进行验证。验证失败时,握手将中止,无论 'verify' 选项如何设置,除非错误代码与 'ca-ignore-err' 或 'crt-ignore-err' 中列出的错误代码完全匹配。

5.2. 服务器和默认服务器选项

"server" 和 "default-server" 关键字支持一定数量的设置,所有这些设置都作为参数在服务器行上传递。这些参数出现的顺序无关紧要,并且它们都是可选的。其中一些设置是单个单词(布尔值),而另一些则要求在它们之后有一个或多个值。在这种情况下,这些值必须紧跟在设置名称之后。除了default-server之外,所有这些设置如果使用都必须在服务器地址之后指定:server <name> <address>[:port] [settings ...] default-server [settings ...] 请注意,"server" 和 "default-server" 关键字都支持所有这些设置,除了 "id" 仅由 "server" 支持。当前支持的设置为以下内容。
addr <ipv4|ipv6>
使用“addr”参数,可以为发送健康检查或探测 agent-check 使用不同的 IP 地址。在某些服务器上,可能需要将一个 IP 地址专用于能够执行复杂测试的特定组件,这些测试比应用程序本身更适合进行健康检查。如果未设置“check”参数,则此参数将被忽略。另请参见“port”参数。
启用辅助代理检查,该检查独立于常规健康检查运行。代理健康检查是通过对由 "agent-port" 参数设置的端口建立TCP连接并读取以第一个 '\r' 或 '\n' 终止的ASCII字符串来执行的。该字符串由一系列单词组成,这些单词由空格、制表符或逗号分隔,顺序不限,每个单词包括: - 正整数百分比的ASCII表示形式,例如 "75%"。此格式的值将设置与HAProxy启动时配置的服务器初始权重成比例的权重。请注意,零权重在统计信息页面上报告为“DRAIN”,因为它对服务器具有相同的效果(它从LB场中删除)。 - 字符串 "maxconn:",后跟一个整数(之间没有空格)。此格式的值将设置服务器的maxconn。通告的最大连接数需要乘以使用此健康检查的负载均衡器和不同后端的数量,才能获得服务器可能接收的总连接数。示例:maxconn:30 - 单词 "ready"。这将把服务器的管理状态转变为READY模式,从而取消任何DRAIN或MAINT状态。 - 单词 "drain"。这将把服务器的管理状态转变为DRAIN模式,因此它不会接受任何新连接,除了通过持久性接受的连接。 - 单词 "maint"。这将把服务器的管理状态转变为MAINT模式,因此它根本不会接受任何新连接,并且健康检查将停止。 - 单词 "down"、"fail" 或 "stopped",可选后跟一个描述字符串(在sharp ('#') 之后)。所有这些都将服务器的操作状态标记为DOWN,但由于单词本身在统计信息页面上报告,因此差异允许管理员知道情况是否在预期之中:服务可能被有意停止、可能看起来正常但未通过某些有效性测试、或者可能被视为down(例如缺少进程或端口无响应)。 - 单词 "up" 将服务器的操作状态设置回UP,如果健康检查也报告该服务可访问。未由代理通告的参数不会更改。例如,代理可能旨在监视CPU使用率,只报告相对权重,而不与操作状态交互。同样,代理可以设计为具有3个单选按钮的最终用户界面,允许管理员仅更改管理状态。但是,重要的是要考虑只有代理才能恢复其自己的操作,因此如果使用代理将服务器设置为DRAIN模式或DOWN状态,则代理必须实现其他等效操作才能使服务重新投入运行。无法连接到代理不被视为错误,因为连接性由常规健康检查测试,该检查由 "check" 参数启用。但请注意,在代理报告“down”后停止代理不是一个好主意,因为只有报告“up”的代理才能再次将服务器设置为up。需要设置 "agent-port" 参数。另请参阅 "agent-inter" 和 "no-agent-check" 参数。
agent-send <string>
如果指定了此选项,HAProxy 将在连接时将给定的字符串(逐字)发送到 agent 服务器。例如,您可以将后端名称编码到此字符串中,这将使您的 agent 能够根据后端发送不同的响应。如果您想用换行符终止请求,请确保包含一个 '\n'。
agent-inter <delay>
agent-inter”参数将两次 agent 检查之间的间隔设置为 <delay> 毫秒。如果未指定,延迟默认为 2000 毫秒。与所有其他基于时间的参数一样,它可以输入任何其他明确的单位,如 { us, ms, s, m, h, d }。“agent-inter”参数在未设置“timeout check”时也用作 agent 检查的超时。为了减少当多个服务器托管在同一硬件上时的“共振”效应,所有服务器的 agent 和健康检查都以一个小的时差启动。也可以使用全局“spread-checks”关键字在 agent 和健康检查间隔中添加一些随机噪声。例如,当许多后端使用相同的服务器时,这样做是有意义的。另请参见“agent-check”和“agent-port”参数。
agent-addr <addr>
agent-addr”参数设置 agent 检查的地址。您可以将 agent-check 卸载到另一个目标,这样您就可以在一个地方管理 HAProxy 中定义的服务器的状态和权重,以防您无法创建自我感知和自我管理的服务。您可以指定 IP 或主机名,它将被解析。
agent-port <port>
agent-port”参数设置用于 agent 检查的 TCP 端口。另请参见“agent-check”和“agent-inter”参数。
在使用 TLS 1.3 时,允许向服务器发送早期数据。请注意,只有当客户端使用了早期数据,或者后端使用了带有“0rtt-rejected”关键字的“retry-on”时,才会发送早期数据。
alpn <protocols>
这会启用 TLS ALPN 扩展,并将指定的协议列表作为 ALPN 之上支持的协议进行通告。协议列表由逗号分隔的协议名称组成,例如:“http/1.1,http/1.0”(不含引号)。这要求 SSL 库在构建时启用了对 TLS 扩展的支持(请使用 haproxy -vv 检查)。ALPN 扩展取代了最初的 NPN 扩展。ALPN 是连接到 HTTP/2 服务器所必需的。OpenSSL 1.0.2 之前的版本不支持 ALPN,只支持现已过时的 NPN 扩展。如果期望同时支持 HTTP/2 和 HTTP/1.1,可以按优先顺序通告两个版本,如下所示: server 127.0.0.1:443 ssl crt pub.pem alpn h2,http/1.1 另请参见“ws”以对 websocket 流使用替代的 ALPN。
当 server 行上存在“backup”时,该服务器仅在所有其他非备份服务器都不可用时才用于负载均衡。但是,带有引用该服务器的持久性 cookie 的请求将始终被处理。默认情况下,只使用第一个可操作的备份服务器,除非在后端设置了“allbackups”选项。另请参见“no-backup”和“allbackups”选项。
ca-file <cafile>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,从中加载用于验证服务器证书的 CA 证书。可以加载包含多个 CA 的目录,在这种情况下,HAProxy 将尝试加载目录中所有以“.pem”、“.crt”、“.cer”和“.crl”结尾的文件,以点开头的文件将被忽略。为了使用您系统的受信任 CA,可以使用“@system-ca”参数代替 cafile。此目录的位置可以通过设置 SSL_CERT_DIR 环境变量来覆盖。
此选项在服务器上启用健康检查: - 未设置时,不执行健康检查,服务器始终被视为可用。 - 设置且未配置其他检查方法时,当可以在最高配置的传输层建立连接时,服务器被视为可用。这意味着默认情况下为TCP,或者当设置了 "ssl" 或 "check-ssl" 时为SSL/TLS,两者都可能与连接前缀结合使用,例如当设置了 "send-proxy" 或 "check-send-proxy" 时为PROXY协议标头。对于动态服务器,此行为略有不同,请阅读以下段落了解更多详细信息。 - 设置且定义了应用层健康检查时,应用层交换在配置的传输层之上执行,如果所有交换都成功,则服务器被视为可用。默认情况下,健康检查在与服务器配置的相同地址和端口上执行,使用相同的封装参数(SSL/TLS、代理协议标头等...)。可以使用 "addr" 更改目标地址,使用 "port" 更改端口。完成此操作后,假定服务器未在服务端口上检查,并且不会重用配置的封装参数。必须显式设置 "check-send-proxy" 以发送连接标头,设置 "check-ssl" 以使用SSL/TLS。请注意,对于动态服务器,不会执行ssl和PROXY协议的隐式配置。在这种情况下,即使未覆盖检查端口,如果需要,也需要显式使用 "check-ssl" 和 "check-send-proxy"。当在服务器行上设置了 "sni" 或 "alpn" 时,其值不用于健康检查,必须使用 "check-sni" 或 "check-alpn"。健康检查流量的默认源地址与后端中定义的源地址相同。可以使用 "source" 关键字更改。可以使用 "inter" 关键字设置两次检查之间的间隔,并可以使用 "rise" 和 "fall" 关键字定义需要多少次成功的或失败的健康检查才能将服务器标记为可用或不可用。可选的应用层健康检查可以使用 "option httpchk"、"option mysql-check"、"option smtpchk"、"option pgsql-check"、"option ldap-check" 或 "option redis-check" 进行配置。
示例
# 简单的 tcp 检查 backend foo server s1 192.168.0.1:80 check # 这会执行 tcp 连接 + tls 握手 backend foo server s1 192.168.0.1:443 ssl check # 简单的 tcp 检查足以使检查成功 backend foo option tcp-check tcp-check connect server s1 192.168.0.1:443 ssl check
此选项强制在出站健康检查中发送 PROXY 协议行,无论服务器是否为正常流量使用 send-proxy。默认情况下,如果 PROXY 协议已为正常流量启用,并且不存在“port”或“addr”指令,则为健康检查启用 PROXY 协议。但是,如果存在此类指令,则需要使用“check-send-proxy”选项来强制使用该协议。有关更多信息,请参见“send-proxy”选项。
check-alpn <protocols>
定义要通过 ALPN 通告的协议。协议列表由逗号分隔的协议名称组成,例如:“http/1.1,http/1.0”(不含引号)。如果未设置,将使用服务器的 ALPN。
强制多路复用器的协议用于服务器的健康检查连接。它必须与健康检查类型(TCP或HTTP)兼容。它也必须在后端端可用。可用协议列表在 haproxy -vv 中报告。报告了协议属性:模式(TCP/HTTP)、端(FE/BE)、mux名称及其标志。某些协议在服务器端容易出现行首阻塞(flag=HOL_RISK)。最后,某些协议不支持升级(flag=NO_UPG)。还报告了HTX兼容性(flag=HTX)。以下是可在服务器行上用作 "check-proto" 指令参数的协议:h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG 此选项背后的想法是绕过为此服务器建立的健康检查连接选择最佳多路复用器协议。如果未定义,将使用服务器的协议(如果已设置)。
check-sni <sni>
此选项允许您指定在通过 SSL 进行健康检查时使用的 SNI。只能使用字符串来设置 <sni>。如果您想为代理的流量设置 SNI,请参见“sni”。
此选项强制通过SSL加密所有健康检查,无论服务器是否将SSL用于正常流量。当指定了显式 "port" 或 "addr" 指令且未继承SSL健康检查时,通常使用此选项。重要的是要理解,此选项在检查下方插入了一个SSL传输层,因此简单的TCP连接检查变成了SSL连接,取代了旧的ssl-hello-chk。最常见的用法是将 "httpchk" 与SSL检查结合使用以发送HTTPS检查。所有SSL设置对于健康检查和流量都是通用的(例如ciphers)。有关更多信息,请参阅 "ssl" 选项,并参阅 "no-check-ssl" 禁用此选项。
此选项启用使用上游 socks4 代理的传出运行状况检查。默认情况下,即使已为主流量启用 Socks 隧道,运行状况检查也不会通过 Socks 隧道。
ciphers <ciphers>
此设置仅在内置 OpenSSL 支持时可用。此选项设置一个字符串,该字符串描述了在与服务器进行 SSL/TLS 握手期间协商的密码算法列表。字符串的格式定义在 OpenSSL man 页面的“man 1 ciphers”中。有关背景信息和建议,请参阅例如 (https://wiki.mozilla.org/Security/Server_Side_TLS) 和 (https://mozilla.github.io/server-side-tls/ssl-config-generator/)。对于 TLSv1.3 密码配置,请检查“ciphersuites”关键字。
ciphersuites <ciphersuites>
此设置仅在内置OpenSSL支持且用于构建HAProxy的OpenSSL为1.1.1或更高版本时可用。此选项设置描述在TLS 1.3握手中与服务器协商的密码算法列表的字符串。字符串的格式在OpenSSL手册页中 "man 1 ciphers" 的 "ciphersuites" 部分中定义。对于TLSv1.2及更早版本的密码配置,请检查 "ciphers" 关键字。
client-sigalgs <sigalgs>
此设置仅在内置 OpenSSL 支持时可用。它设置描述与客户端身份验证相关的协商签名算法列表的字符串。该字符串的格式在 OpenSSL 手册页的“man 3 SSL_CTX_set1_client_sigalgs”中定义。如果没有确定特定的用例,不建议使用此设置。
cookie <value>
"cookie" 参数将分配给服务器的cookie值设置为 <value>。将在传入请求中检查此值,并选择具有相同值的第一个操作服务器。反过来,在cookie插入或重写模式下,此值将分配给发送到客户端的cookie。多个服务器共享相同的cookie值没有问题,这在正常服务器和备份服务器之间实际上很常见。另请参阅后端部分中的 "cookie" 关键字。
crl-file <crlfile>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,用于加载用于验证服务器证书的证书吊销列表。
crt <cert>
此设置仅在内置 OpenSSL 支持时可用。它指定一个 PEM 文件,从中加载证书和关联的私钥。此文件可以通过将两个 PEM 文件连接成一个来构建。如果服务器发送客户端证书请求,则将发送此证书。如果文件不包含私钥,HAProxy 将尝试在同一路径(后缀为“.key”)加载密钥(前提是相应设置了“ssl-load-extra-files”选项)。
curves <curves>
此设置仅在内置 OpenSSL 支持时可用。它设置描述在与 ECDHE 的 SSL/TLS 握手期间协商的椭圆曲线算法列表(“曲线套件”)的字符串。该字符串的格式是以冒号分隔的曲线名称列表。
示例
"X25519:P-256" (不带引号)
"disabled" 关键字以 "disabled" 状态启动服务器。这意味着它在维护模式下被标记为down,除了持久模式允许的连接之外,不会有任何连接到达它。这非常适合设置新服务器,因为正常流量永远不会到达它们,同时仍然可以通过使用force-persist机制来测试服务。另请参阅 "enabled" 设置。
此选项可用作“server”设置,以重置从“default-server”指令继承的任何“disabled”设置作为默认值。它也可作为“default-server”设置,以重置任何以前的“default-server”“disabled”设置。
error-limit <count>
如果启用了运行状况监视,“error-limit”参数指定触发“on-error”选项所选事件的连续错误次数。默认设置为 10 次连续错误。另请参阅“check”、“error-limit”和“on-error”。
fall <count>
fall”参数表示服务器将在 <count> 次连续不成功的运行状况检查后被视为死亡。如果未指定,此值默认为 3。另请参阅“check”、“inter”和“rise”参数。
此选项强制仅使用 SSLv3,当 SSL 用于与服务器通信时。SSLv3 对于高连接速率通常比 TLS 对应项成本更低。此选项在全局语句“ssl-default-server-options”上也可使用。另请参阅“ssl-min-ver”和 ssl-max-ver”。
此选项强制仅使用 TLSv1.0,当 SSL 用于与服务器通信时。此选项在全局语句“ssl-default-server-options”上也可使用。另请参阅“ssl-min-ver”和 ssl-max-ver”。
此选项强制仅使用 TLSv1.1,当 SSL 用于与服务器通信时。此选项在全局语句“ssl-default-server-options”上也可使用。另请参阅“ssl-min-ver”和 ssl-max-ver”。
此选项强制仅使用 TLSv1.2,当 SSL 用于与服务器通信时。此选项在全局语句“ssl-default-server-options”上也可使用。另请参阅“ssl-min-ver”和 ssl-max-ver”。
此选项强制仅使用 TLSv1.3,当 SSL 用于与服务器通信时。此选项在全局语句“ssl-default-server-options”上也可使用。另请参阅“ssl-min-ver”和 ssl-max-ver”。
id <value>
为服务器设置一个持久化 ID。此 ID 必须是正数且对代理是唯一的。如果未设置,将自动分配一个未使用的 ID。第一个分配的值将是 1。此 ID 目前仅在统计信息中返回。
init-addr {last | libc | none | <ip>},[...]*
指示如果服务器使用FQDN,则在启动时应按什么顺序解析服务器地址。尝试通过依次应用逗号分隔列表中的每种方法来解析地址。使用第一个成功的方法。如果到达列表末尾但未找到有效方法,则会引发错误。方法“last”建议选择出现在状态文件中的地址(请参阅 "server-state-file")。方法“libc”使用libc的内部解析器(gethostbyname()或getaddrinfo(),具体取决于操作系统和构建选项)。方法“none”专门指示服务器应在down状态下启动,不带任何有效的IP地址。这对于忽略启动时的一些DNS问题很有用,等待稍后修复情况。最后,可以提供IP地址(IPv4或IPv6)。它可以是服务器当前已知的地址(例如由配置生成器填充),也可以是用于捕获旧会话并向其显示合理的错误消息的虚拟服务器的地址。当使用“first”负载均衡算法时,此IP地址可以指向一个用于触发新实例即时创建的假服务器。此选项默认为“last,libc”,表示首先使用状态文件中找到的上一个地址(如果有),否则使用libc的解析器。这确保了与历史行为的持续兼容性。
示例
defaults # 地址解析永不失败 default-server init-addr last,libc,none
inter <delay>
fastinter <delay>
downinter <delay>
"inter" 参数将两次连续健康检查之间的时间间隔设置为 <delay> 毫秒。如果未指定,则延迟默认为2000毫秒。也可以使用 "fastinter" 和 "downinter" 根据服务器状态优化检查之间的延迟
服务器状态使用的间隔
UP 100% (非过渡状态)inter
过渡性 UP (正在变为 down "fall"),
过渡性 DOWN (正在变为 up "rise"),
或尚未检查。
如果设置了“fastinter”,则使用它,
否则使用“inter”。
DOWN 100% (非过渡状态)
如果设置了“downinter”,则使用它,
否则使用“inter”。
与所有其他基于时间的参数一样,它们可以以 { us, ms, s, m, h, d } 中的任何其他显式单位输入。如果未设置 "timeout check",则 "inter" 参数也用作发送到服务器的健康检查的超时。为了减少当多个服务器托管在同一硬件上时的“共振”效应,所有服务器的代理和健康检查都以很小的时间偏移开始。也可以使用全局 "spread-checks" 关键字在代理和健康检查间隔中添加一些随机噪声。例如,当许多后端使用相同的服务器时,这很有意义。全局 "tune.max-checks-per-thread" 设置(如果定义为非零值)将限制在任何给定线程上同时执行的检查数量。为了实现这一点,haproxy会将即将开始在达到此限制的线程上开始的检查放入队列中,直到另一个检查完成。这将导致有效的检查间隔延长。在这种情况下,减小 "inter" 设置的效果非常有限,因为它无法减少在队列中花费的时间。
log-bufsize <bufsize>
"log-bufsize" 指定用于与日志后端中的日志服务器关联的隐式环的环大小。如果未指定,则默认为BUFSIZE。使用更大的值会增加内存使用量,但有助于防止与慢速服务器相关的日志消息丢失,因为缓冲区将能够容纳更多待处理消息。此关键字只能在日志后端部分中使用(使用 "mode log")
log-proto <logproto>
"log-proto" 指定用于将事件消息转发到日志或环部分中配置的服务器的协议。可能的值为 "legacy" 和 "octet-count",分别对应于rfc6587中的 "Non-transparent-framing" 和 "Octet counting"。"legacy" 是默认值。
maxconn <maxconn>
"maxconn" 参数指定将发送到此服务器的最大并发连接数。如果传入并发连接数高于此值,它们将被排队,等待释放插槽。此参数非常重要,因为它可以防止脆弱的服务器在极端负载下崩溃。如果指定了 "minconn" 参数,则限制变为动态。默认值为“0”,表示无限制。另请参阅 "minconn" 和 "maxqueue" 参数,以及后端的 "fullconn" 关键字。在HTTP模式下,此参数限制并发请求数而不是连接数。多个请求可能会通过单个TCP连接多路复用到服务器。例如,如果您指定maxconn为50,您可能会看到1到50个实际服务器连接,但并发请求不超过50个。
maxqueue <maxqueue>
"maxqueue" 参数指定将在此服务器队列中等待的最大连接数。如果达到此限制,下一个请求将被重新分配到其他服务器,而不是无限期地等待服务。这会破坏持久性,但可能允许人们在他们尝试连接的服务器即将崩溃时快速重新登录。某些负载均衡算法(例如leastconn)会考虑到这一点,如果明确设置为大于零的值,则接受将请求添加到服务器队列中,直到此值,这通常允许在处理个位数maxconn值时更好地平滑负载。默认值为“0”,表示队列无限制。另请参阅 "maxconn" 和 "minconn" 参数以及 "balance leastconn"。
max-reuse <count>
max-reuse”参数指示 HTTP 连接处理器,它们不应将服务器连接重复使用超过此次数来发送新请求。允许的值为 -1(默认值),它禁用此限制,或任何正值。值为零将有效禁用 keep-alive。这仅用于解决某些服务器随时间推移而导致资源泄漏的 bug。由于可能存在技术限制使其无法强制执行,因此底层可能不会完全遵守此参数。至少 HTTP/2 连接到服务器会遵守它。
minconn <minconn>
设置 "minconn" 参数时,maxconn限制将成为跟随后端负载的动态限制。服务器将始终接受至少 <minconn> 个连接,绝不超过 <maxconn> 个连接,并且当后端并发连接少于 <fullconn> 时,限制将在两个值之间平稳过渡。这使得在正常负载期间限制服务器上的负载成为可能,但在重要负载期间进一步推动它,同时又不会在异常负载期间使服务器过载。另请参阅 "maxconn" 和 "maxqueue" 参数,以及 "fullconn" 后端关键字。
namespace <name>
在 Linux 上,可以指定套接字属于哪个网络命名空间。此指令使得可以明确地将服务器绑定到不同于默认命名空间的命名空间。有关网络命名空间的更多详细信息,请参阅您的操作系统文档。
此选项可用作 "server" 设置,以重置任何从 "default-server" 指令继承的 "agent-check" 设置。它也可用作 "default-server" 设置,以重置任何先前 "default-server" "agent-check" 设置。
此选项可用作 "server" 设置,以重置任何从 "default-server" 指令继承的 "backup" 设置。它也可用作 "default-server" 设置,以重置任何先前 "default-server" "backup" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "check" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "check" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "check-ssl" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "check-ssl" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "send-proxy" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "send-proxy" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "send-proxy-v2" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "send-proxy-v2" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "send-proxy-v2-ssl" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "send-proxy-v2-ssl" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "send-proxy-v2-ssl-cn" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "send-proxy-v2-ssl-cn" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "ssl" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "ssl" 设置。请注意,使用 `default-server ssl` 设置并在服务器上使用 `no-ssl` 仍然会初始化 SSL 连接,因此可以通过运行时 API 稍后启用:请参阅管理文档中的 `set server` 命令。
此选项在 SSL 用于与服务器通信时禁用 SSL 会话重用。它将强制服务器为每个新连接执行完整的握手。这可能只对基准测试、故障排除和多疑用户有用。
当使用 SSL 与服务器通信时,此选项会禁用对 SSLv3 的支持。请注意,SSLv2 在代码中已被禁用,无法使用任何配置选项启用。请改用 "ssl-min-ver" 和 "ssl-max-ver"。在 default-server 中支持: 否
此设置仅在构建时支持 OpenSSL 时可用。它禁用无状态会话恢复(RFC 5077 TLS Ticket 扩展)并强制使用有状态会话恢复。无状态会话恢复在服务器的 CPU 使用率方面成本更高。此选项也可用在全局语句 "ssl-default-server-options" 中。TLS Ticket 机制仅用于 TLS 1.2 及以下版本。前向保密会因 TLS Ticket 而受到损害,除非 Ticket 密钥被定期轮换(通过重载或使用 "tls-ticket-keys")。另请参阅 "tls-tickets"。
当使用 SSL 与服务器通信时,此选项会禁用对 TLSv1.0 的支持。请注意,SSLv2 在代码中已被禁用,无法使用任何配置选项启用。TLSv1 比 SSLv3 的开销更大,因此在与本地服务器通信时禁用它通常是有意义的。此选项也可用于全局语句 "ssl-default-server-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。在 default-server 中支持: 否
当使用 SSL 与服务器通信时,此选项会禁用对 TLSv1.1 的支持。请注意,SSLv2 在代码中已被禁用,无法使用任何配置选项启用。TLSv1 比 SSLv3 的开销更大,因此在与本地服务器通信时禁用它通常是有意义的。此选项也可用于全局语句 "ssl-default-server-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。在 default-server 中支持: 否
当使用 SSL 与服务器通信时,此选项会禁用对 TLSv1.2 的支持。请注意,SSLv2 在代码中已被禁用,无法使用任何配置选项启用。TLSv1 比 SSLv3 的开销更大,因此在与本地服务器通信时禁用它通常是有意义的。此选项也可用于全局语句 "ssl-default-server-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。在 default-server 中支持: 否
当使用 SSL 与服务器通信时,此选项会禁用对 TLSv1.3 的支持。请注意,SSLv2 在代码中已被禁用,无法使用任何配置选项启用。TLSv1 比 SSLv3 的开销更大,因此在与本地服务器通信时禁用它通常是有意义的。此选项也可用于全局语句 "ssl-default-server-options"。请改用 "ssl-min-ver" 和 "ssl-max-ver"。在 default-server 中支持: 否
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "verifyhost" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "verifyhost" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "tfo" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "tfo" 设置。
永远不要将分配给此服务器的连接添加到 stick-table。这可以与 backup 结合使用,以确保为 backup 服务器禁用 stick-table 持久性。
npn <protocols>
这会启用 NPN TLS 扩展,并在 NPN 之上声明支持的协议列表。协议列表是一系列由逗号分隔的协议名称,例如:"http/1.1,http/1.0"(不带引号)。这要求 SSL 库在启用 TLS 扩展支持的情况下构建(通过 haproxy -vv 检查)。请注意,NPN 扩展已被 ALPN 扩展取代(请参阅 "alpn" 关键字),尽管后者仅在 OpenSSL 1.0.2 及以上版本可用。
observe <mode>
此选项启用基于观察与服务器通信的健康状况调整。默认情况下,此功能被禁用,启用它还需要启用健康检查。支持两种模式:"layer4" 和 "layer7"。在 layer4 模式下,只有成功的/不成功的 tcp 连接是重要的。在 layer7 模式下(仅允许用于 http 代理),会验证从服务器收到的响应,例如有效的/无效的 http 代码、无法解析的头信息、超时等。有效的状态码包括 100 到 499、501 和 505。另请参阅 "check"、"on-error" 和 "error-limit"。
on-error <mode>
选择在检测到足够多的连续错误时应执行的操作。目前提供四种模式:- fastinter:强制 fastinter - fail-check:模拟失败的检查,也强制 fastinter(默认) - sudden-death:模拟一个预致命的健康检查失败,再多一次失败的检查将导致服务器标记为宕机,强制 fastinter - mark-down:立即将服务器标记为宕机并强制 fastinter 另请参阅 "check"、"observe" 和 "error-limit"。
修改当服务器被标记为“down”时发生的情况。目前有一个可用的动作:- shutdown-sessions:关闭对等流。启用此设置后,当服务器宕机时,与服务器的所有连接将立即终止。如果健康检查检测到比简单连接状态更复杂的情况,并且长时间超时会导致服务长时间无响应,则可以使用此设置。例如,健康检查可能会检测到数据库卡住,并且无法再重用现有连接。以这种方式终止的连接将记录为“D”终止代码(表示“Down”)。默认情况下禁用操作。
on-marked-up <action>
修改当服务器被标记为“up”时发生的情况。目前有一个可用的动作:- shutdown-backup-sessions:关闭所有备份服务器上的流。仅当服务器未处于备份状态且未禁用时(其有效权重必须 > 0)才执行此操作。在处理长时间会话(例如 LDAP、SQL 等)时,有时可以使用此方法强制活动服务器在恢复后重新接管所有流量。这样做可能会带来比试图解决的问题更多的麻烦(例如,不完整的事务),因此请谨慎使用此功能。因服务器启动而被终止的流将记录为“U”终止代码(表示“Up”)。默认情况下禁用操作。
pool-low-conn <最大值>
设置服务器空闲连接数的低阈值,低于此阈值时,线程不会尝试从另一个线程窃取连接。这对于涉及许多速度非常快的服务器的场景非常有用,以改善 CPU 使用模式,确保所有线程始终保持少量空闲连接,而不是让它们在某个线程上累积并从线程迁移到线程。典型的两倍于线程数的数值似乎已经能以亚毫秒级的响应时间显示出非常好的性能。默认值为零,表示任何空闲连接都可以在任何时候使用。对于正常使用,这是推荐的设置。这仅适用于根据与适用于 "http-reuse" 相同的原则可以共享的连接。如果通过 "tune.idle-pool.shared" 禁用线程之间的连接共享,则使用此设置以确保每个线程始终拥有少量连接非常重要,否则随着线程数的增加,连接重用率会下降。
pool-max-conn <最大值>
设置服务器的空闲连接最大数量。-1 表示无限连接,0 表示无空闲连接。默认值为 -1。启用空闲连接后,不再属于任何客户端会话的孤立空闲连接将被移至专用池,以便未来的客户端可以使用它们。这仅适用于可以根据与 "http-reuse" 相同的原则共享的连接。
设置开始清除空闲连接的延迟。每隔 <delay> 时间间隔,一半的空闲连接将被关闭。0 表示不保留任何空闲连接。默认值为 5 秒。
port <port>
使用“port”参数,可以使用不同的端口发送健康检查或探测代理检查。在某些服务器上,可能希望将端口专用于能够执行复杂测试的特定组件,这些测试比应用程序更适合健康检查。例如,在 inetd 中运行一个简单脚本是很常见的。如果未设置“check”参数,则忽略此参数。另请参阅“addr”参数。
proto <名称>
强制用于与此服务器建立的传出连接的多路复用器协议。它必须与后端的模式(TCP 或 HTTP)兼容。它还必须在后端侧可用。可用协议列表在 haproxy -vv 中报告。协议属性会报告:模式(TCP/HTTP)、侧(FE/BE)、mux 名称及其标志。某些协议在服务器端容易出现头部阻塞(flag=HOL_RISK)。最后,某些协议不支持升级(flag=NO_UPG)。HTX 兼容性也会报告(flag=HTX)。以下是可用作服务器行上的 "proto" 指令参数的协议:h2:mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG fcgi:mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG h1:mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG none:mode=TCP side=FE|BE mux=PASS flags=NO_UPG 此选项背后的想法是绕过为与此服务器建立的所有连接选择最佳多路复用器协议。另请参阅 "ws" 以使用 websocket 流的替代协议。
redir <prefix>
"redir" 参数为此服务器上所有寻址的 GET 和 HEAD 请求启用重定向模式。这意味着 HAProxy 不会转发请求到服务器,而是会发送一个 "HTTP 302" 响应,其中 "Location" 标头由此前缀组成,紧随其后的是所请求的 URI,从路径组件的开头 '/' 开始。这意味着  之后不应使用尾部斜杠。所有无效请求都将被拒绝,所有非 GET 或 HEAD 请求将由服务器正常服务。请注意,由于响应是完全伪造的,因此响应中不可能进行标头修改或 cookie 插入。然而,请求中的 cookie 仍然会被分析,这使得此解决方案在本地发生灾难时将用户导向远程位置完全可用。主要用途是通过让客户端直接连接到静态服务器来增加其带宽。注意:切勿在此处使用相对位置,否则会导致客户端和 HAProxy 之间出现循环!
示例
server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
rise <count>
"rise" 参数指定服务器将在连续 <count> 次成功的健康检查后被视为可运行。如果未指定,此值默认为 2。另请参阅 "check"、"inter" 和 "fall" 参数。
resolve-opts <选项>,<选项>,...
以逗号分隔的选项列表,应用于与此服务器关联的DNS解析。可用选项: * allow-dup-ip 默认情况下,HAProxy在运行时DNS解析操作时会阻止后端中IP地址重复。也就是说,在某些情况下,两个服务器(在同一个后端,由同一个FQDN解析)具有相同的IP地址是有意义的。对于这种情况,只需启用此选项。这与prevent-dup-ip相反。 * ignore-weight 忽略SRV记录中设置的任何权重。当您希望使用其他方法(例如使用"agent-check"或通过运行时API)控制权重时,此功能非常有用。 * prevent-dup-ip 确保HAProxy的默认行为在服务器上强制执行:防止在同一后端中,共享相同FQDN的服务器之间重复使用已设置的IP地址。这与allow-dup-ip相反。
示例
backend b_myapp default-server init-addr none resolvers dns server s1 myapp.example.com:80 check resolve-opts allow-dup-ip server s2 myapp.example.com:81 check resolve-opts allow-dup-ip
设置了 allow-dup-ip 选项后:* 如果域名服务器返回单个 IP 地址,则两个服务器都将使用它 * 如果域名服务器返回 2 个 IP 地址,则每个服务器将选择一个不同的地址 默认值:未设置
当为服务器启用 DNS 解析并且返回了来自不同族的多个 IP 地址时,HAProxy 将优先使用 "resolve-prefer" 参数中指定的族中的 IP 地址。可用族:"ipv4" 和 "ipv6" 默认值:ipv6
示例
server s1 app1.domain.com:80 resolvers mydns resolve-prefer ipv6
resolve-net <网络>[,<网络[,...]]
此选项优先选择匹配网络的 IP 地址。这在云环境中很有用,可以优先选择本地 IP。在某些情况下,云高可用服务可以通过多个数据中心上的多个 IP 地址进行 anúnciate。数据中心之间的延迟不可忽略,因此此补丁允许优先选择本地数据中心。如果没有任何地址与配置的网络匹配,则会选择其他地址。
示例
server s1 app1.domain.com:80 resolvers mydns resolve-net 10.0.0.0/8
指向一个现有的 "resolvers" 部分,以解析当前服务器的主机名。
示例
server s1 app1.domain.com:80 check resolvers mydns
另请参见 第 5.3 节
"send-proxy" 参数强制在与此服务器建立的任何连接上使用 PROXY 协议。PROXY 协议通知另一端传入连接的第 3/4 层地址,以便它可以知道客户端的地址或它访问的公共地址,无论上层协议是什么。对于由 "accept-proxy" 或 "accept-netscaler-cip" 侦听器接受的连接,将使用广告的地址。仅支持 TCPv4 和 TCPv6 地址族。其他族(例如 Unix 套接字)将报告 UNKNOWN 族。使用此选项的服务器可以完全链接到另一个 HAProxy 实例,该实例使用 "accept-proxy" 设置进行侦听。如果服务器不知道该协议,则不得使用此设置。当健康检查发送到服务器时,如果设置了此选项,则会自动使用 PROXY 协议,除非有显式的 "port" 或 "addr" 指令,在这种情况下,还需要显式的 "check-send-proxy" 指令才能使用 PROXY 协议。另请参阅此部分中的 "no-send-proxy" 选项以及 "bind" 关键字的 "accept-proxy" 和 "accept-netscaler-cip" 选项。
"send-proxy-v2" 参数强制在与此服务器建立的任何连接上使用 PROXY 协议版本 2。PROXY 协议通知另一端传入连接的第 3/4 层地址,以便它可以知道客户端的地址或它访问的公共地址,无论上层协议是什么。如果协商了 ALPN,它还会发送 ALPN 信息。如果服务器不知道此版本的协议,则不得使用此设置。另请参阅此部分中的 "no-send-proxy-v2" 选项以及 "bind" 关键字的 send-proxy" 选项。
"set-proxy-v2-tlv-fmt" 参数用于发送任意 PROXY 协议版本 2 TLV。有关定义的 TLV 类型()范围,请参阅 section 2.2.8. of the proxy protocol specification。但是,只要值不超过 65,535 字节的最大长度,就可以自由选择。它也可用于转发 TLV,方法是使用 fetch "fc_pp_tlv" 从前端检索收到的 TLV。它可以用作服务器或 default-server 选项。它必须与 send-proxy-v2 结合使用,以便实际发送 PPv2 TLV。
示例
server srv1 192.168.1.1:80 send-proxy-v2 set-proxy-v2-tlv-fmt(0x20) %[fc_pp_tlv(0x20)]
在这种情况下,我们以字符串形式获取类型为 0x20 的 TLV,并将其设置为新创建的 TLV 的值,该 TLV 的类型也为 0x20。
proxy-v2-options <选项>[,<选项>]*
"proxy-v2-options"参数在使用"send-proxy-v2"时,向PROXY协议版本2添加要发送的选项。可用选项有: - ssl:另请参阅"send-proxy-v2-ssl"。 - cert-cn:另请参阅"send-proxy-v2-ssl-cn"。 - ssl-cipher:使用的密码名称。 - cert-sig:使用的证书的签名算法。 - cert-key:使用的证书的密钥算法。 - authority:客户端传递的主机名值(仅支持TLS连接中的SNI)。 - crc32c:PROXYv2头的校验和。 - unique-id:在PROXYv2头中发送使用前端"unique-id-format"生成的唯一ID。此unique-id主要用于“mode tcp”。在“mode http”中可能会导致意外结果,因为生成的unique ID也用于Keep-Alive连接中的第一个HTTP请求。
"send-proxy-v2-ssl" 参数强制在与此服务器建立的任何连接上使用 PROXY 协议版本 2。PROXY 协议通知另一端传入连接的第 3/4 层地址,以便它可以知道客户端的地址或它访问的公共地址,无论上层协议是什么。此外,PROXY 协议的 SSL 信息扩展会添加到 PROXY 协议标头中。如果服务器不知道此版本的协议,则不得使用此设置。另请参阅此部分中的 "no-send-proxy-v2-ssl" 选项以及 "bind" 关键字的 "send-proxy-v2" 选项。
"send-proxy-v2-ssl" 参数强制在与此服务器建立的任何连接上使用 PROXY 协议版本 2。PROXY 协议通知另一端传入连接的第 3/4 层地址,以便它可以知道客户端的地址或它访问的公共地址,无论上层协议是什么。此外,PROXY 协议的 SSL 信息扩展以及客户端证书主题中的通用名称(如果有)会添加到 PROXY 协议标头中。如果服务器不知道此版本的协议,则不得使用此设置。另请参阅此部分中的 "no-send-proxy-v2-ssl-cn" 选项以及 "bind" 关键字的 "send-proxy-v2" 选项。
shard <shard>
此参数仅在 stick-tables 与 peers 协议同步的上下文中使用。"shard" 参数标识将接收具有此分片作为分发哈希的密钥的所有 stick-table 更新的对等方。接受的值是从 0 到 "peers" 部分中指定的 "shards" 参数值。0 值是默认值,表示对等方将接收所有密钥更新。大于 "shards" 的值将被忽略。对于提供给本地对等方的任何值也是如此。
示例
peers mypeers shards 3 peer A 127.0.0.1:40001 # 没有分片值的本地对等体 (内部为0) peer B 127.0.0.1:40002 shard 1 peer C 127.0.0.1:40003 shard 2 peer D 127.0.0.1:40004 shard 3
sigalgs <sigalgs>
此设置仅在内置 OpenSSL 支持时可用。它设置一个字符串,描述在 TLSv1.2 和 TLSv1.3 握手期间协商的签名算法列表。字符串的格式在 OpenSSL 手册页的“man 3 SSL_CTX_set1_sigalgs”中定义。不建议使用此设置,除非需要与中间件兼容。
slowstart <start_time_in_ms>
服务器的 "slowstart" 参数接受一个毫秒值,表示服务器在恢复正常运行后需要多长时间才能全速运行。与所有其他基于时间的参数一样,它可以输入 { us, ms, s, m, h, d } 中的任何其他显式单位。在此期间,速度从 0% 线性增长到 100%。此限制适用于两个参数: - maxconn:服务器接受的连接数将从 1 增长到通常动态限制(minconn、maxconn、fullconn)的 100%。- weight:当后端使用动态加权算法时,权重从 1 线性增长到 100%。在这种情况下,权重会在每次健康检查时更新。因此,重要的是 "inter" 参数小于 "slowstart",以最大化步数。slowstart 永远不会在 HAProxy 启动时应用,否则会对正在运行的服务器造成麻烦。它仅在先前被视为失败的服务器恢复时应用。
sni <expression>
"sni" 参数评估样本获取表达式,将其转换为字符串,并使用结果作为 SNI TLS 扩展中发送给服务器的主机名。一个典型的用例是在桥接 TCP/SSL 场景中发送从客户端接收到的 SNI,使用 "ssl_fc_sni" 样本获取表达式。这不应用于 HTTPS,其中应使用 req.hdr(host),因为 HTTPS 中的 SNI 必须始终与 Host 字段匹配,并且允许客户端在同一连接上使用不同的主机名。如果设置了 "verify required"(这是推荐的设置),则结果名称也将与服务器证书的名称匹配。有关更多详细信息,请参阅 "verify" 指令。如果要为健康检查设置 SNI,请参阅 "check-sni" 指令以获取更多详细信息。
source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
source <addr>[:<pl>[-<ph>]] [interface <name>] ...
"source" 参数设置连接到服务器时将使用的源地址。它遵循与后端 "source" 关键字完全相同的参数和原理,只是它仅适用于引用它的服务器。有关详细信息,请参阅 "source" 关键字。此外,服务器行上的 "source" 语句允许通过指示由短划线('-')分隔的下限和上限来指定源端口范围。某些操作系统可能要求在指定源端口范围时提供有效的 IP 地址。允许多个服务器具有相同的 IP/范围。这样做可以绕过总并发连接数 64k 的最大限制。此时限制将达到每个服务器 64k 个连接。自 Linux 4.2/libc 2.23 起,对于指定没有端口的源地址的连接,设置了 IP_BIND_ADDRESS_NO_PORT。
此选项启用与服务器的传出连接上的 SSL 加密。在使用 SSL 连接到服务器时,使用 "verify" 验证服务器证书至关重要,否则通信容易受到琐碎的中间人攻击,使 SSL 毫无用处。使用此选项时,健康检查也会自动以 SSL 发送,除非有 "port" 或 "addr" 指令指示检查应发送到其他位置。请参阅 "no-ssl" 以禁用 "ssl" 选项,并参阅 "check-ssl" 选项以强制执行 SSL 健康检查。
ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
使用 SSL 与服务器通信时,此选项强制使用 <version> 或更低版本。此选项也可用在全局语句 "ssl-default-server-options" 中。另请参阅 "ssl-min-ver"。
ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
使用 SSL 与服务器通信时,此选项强制使用 <version> 或更高版本。此选项也可用在全局语句 "ssl-default-server-options" 中。另请参阅 "ssl-max-ver"。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "no-ssl-reuse" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "no-ssl-reuse" 设置。
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "non-stick" 设置。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "non-stick" 设置。
socks4 <地址>:<端口>
此选项为到服务器的出站连接启用上游 socks4 隧道。使用此选项默认不会强制健康检查通过 socks4。您需要使用关键字 "check-via-socks4" 来启用它。
tcp-ut <delay>
为所有到此服务器的传出连接设置TCP用户超时。此选项自Linux 2.6.37版本起可用。它允许HAProxy为包含未接收到配置延迟的确认数据的套接字配置超时。这对于长期存在的连接(例如远程终端或数据库连接池)特别有用,这些连接会经历长时间的空闲期,其中客户端和服务器超时必须保持较高以允许长时间空闲,但检测服务器已消失以释放与其连接(和客户端会话)相关的所有资源也很重要。一个典型的用例是在健康检查过慢或软重新加载时强制死服务器连接终止,因为健康检查在此期间被禁用。参数默认为毫秒表示的延迟。这仅适用于常规TCP连接,对于其他协议则忽略。
此选项允许在连接到支持TCP快速打开的系统上的服务器时使用TCP快速打开(目前仅限Linux内核>= 4.11)。有关TCP快速打开的更多信息,请参阅"tfo"绑定选项。请注意,在使用tfo时,您还应该为"retry-on"使用“conn-failure”、“empty-response”和“response-timeout”关键字,否则HAProxy将无法在失败时重试连接。另请参阅"no-tfo"。
track [<后端>/]<服务器>
此选项通过跟踪另一个服务器来设置服务器的当前状态。可以跟踪一个本身跟踪另一个服务器的服务器,前提是链的末端有一个启用了健康检查的服务器。如果省略 <backend>,则使用当前服务器。如果使用了 disable-on-404,则必须在两个代理上都启用它。
示例
backend A server a1 1.1.1.1:80 track B/b1 server a2 1.1.1.2:80 track B/b1 backend B server b1 2.2.2.2:80 check
此选项可用作 "server" 设置,用于重置任何从 "default-server" 指令作为默认值继承而来的 "no-tls-tickets" 设置。TLS 票据机制仅用于 TLS 1.2。TLS 票据会损害前向保密性,除非定期轮换票据密钥(通过重新加载或使用 "tls-ticket-keys")。它也可用作 "default-server" 设置,用于重置任何先前的 "default-server" "no-tls-tickets" 设置。
verify [none|required]
此设置仅在内置 OpenSSL 支持时可用。如果设置为 'none',则不验证服务器证书。在另一种情况下,服务器提供的证书将使用来自 'ca-file' 的 CA 和来自 'crl-file' 的可选 CRL 进行验证,在检查证书主题和 subjectAlternateNames 属性中提供的名称是否与使用 "sni" 指令传递的名称匹配,或者如果未提供,则与使用 "verifyhost" 指令传递的静态主机名匹配之后。如果未找到名称,则忽略证书的名称。因此,如果没有 SNI,使用 "verifyhost" 非常重要。如果验证失败,握手将中止。在使用 SSL 连接到服务器时,验证服务器证书至关重要,否则通信容易受到琐碎的中间人攻击,使 SSL 完全无用。除非 "ssl_server_verify" 出现在全局部分中,否则 "verify" 默认设置为 "required"。
verifyhost <hostname>
此设置仅在内置 OpenSSL 支持时可用,并且仅在同时指定了 'verify required' 时才生效。此指令设置一个默认静态主机名,用于在未用于连接到服务器时检查服务器证书。如果未使用 SNI,这是启用主机名验证的唯一方法。设置此静态主机名后,它也将用于健康检查(无法提供 SNI 值)。如果证书中的任何主机名与指定的主机名不匹配,则握手将中止。服务器提供的证书中的主机名可能包含通配符。另请参阅 "verify"、"sni" 和 "no-verifyhost" 选项。
weight <weight>
weight”参数用于调整服务器相对于其他服务器的权重。所有服务器将根据其权重相对于所有权重总和的比例接收负载,因此权重越高,负载越高。默认权重为 1,最大值为 256。值为 0 表示服务器不参与负载均衡,但仍接受持久连接。如果使用此参数根据服务器容量分配负载,建议从可以增长和收缩的值开始,例如 10 到 100 之间,以便为以后调整留出足够的空间。
ws { auto | h1 | h2 }
此选项允许配置中继 websocket 流时使用的协议。当使用不支持 RFC8441 的 H2 websockets 的 HTTP/2 后端时,这特别有用。默认模式是 "auto"。这将重用与主协议相同的协议。唯一的区别是在使用 ALPN 时。在这种情况下,如果配置的服务器 ALPN 包含 "http/1.1",它可以尝试仅针对 websocket 流将 ALPN 降级为 "http/1.1"。值 "h1" 用于通过 ALPN 强制 HTTP/1.1 用于 websockets 流(如果服务器的 SSL ALPN 已激活)。同样,"h2" 可用于强制 HTTP/2.0 websockets。请谨慎使用此值:服务器必须支持 RFC8441,否则 haproxy 在中继 websockets 时将报告错误。请注意,NPN 不会被考虑在内,因为它的使用已被弃用,取而代之的是 ALPN 扩展。另请参阅 "alpn" 和 "proto"。

5.3. 使用 DNS 进行服务器 IP 地址解析

HAProxy 允许在服务器行中使用主机名通过名称服务器检索其 IP 地址。默认情况下,HAProxy 在解析配置文件时解析名称,并在启动时缓存结果,并在进程生命周期内缓存该结果。这在某些情况下不够用,例如在 Amazon 中,服务器的 IP 地址在重启后可能会发生变化,或者 ELB 虚拟 IP 地址会根据当前工作负载而变化。本章介绍 HAProxy 如何配置为在运行时处理服务器名称解析。无论是否启用了运行时服务器名称解析,HAProxy 在解析配置时都会继续进行第一次解析。

5.3.1. 总体概述

正如我们在引言中所见,HAProxy 中的名称解析发生在流程生命的两个不同步骤:1. 在启动时,HAProxy 解析服务器行定义并匹配主机名。它使用 libc 函数来解析主机名。此解析依赖于 /etc/resolv.conf 文件。2. 在运行时,HAProxy 会对需要 DNS 解析的服务器定期执行名称解析。其他一些事件可以在运行时触发名称解析:- 当服务器的健康检查以连接超时结束时:这可能是因为服务器有了新的 IP 地址。因此我们需要触发名称解析以了解这个新的 IP。使用解析器时,服务器名称可以是主机名,也可以是 SRV 标签。HAProxy 将任何以下划线开头的名称视为 SRV 标签。如果指定了 SRV 标签,则将从 DNS 服务器检索相应的 SRV 记录,并使用提供的主机名。SRV 标签将定期检查,如果添加或删除了任何服务器,HAProxy 将自动执行相同的操作。需要注意的几点:- 所有名称服务器都会同时查询。HAProxy 将处理第一个有效的响应。- 当所有服务器都返回错误时,解析被视为无效(NX、超时、拒绝)。

5.3.2. resolvers 部分

本节专门讨论与 HAProxy 中的名称解析相关的主机信息。可以根据需要配置任意数量的解析器部分。每个部分可以包含多个名称服务器。在启动时,如果没有在配置中命名为 "default" 的部分,HAProxy 会尝试生成一个名为 "default" 的解析器部分。此部分默认由 httpclient 使用,并使用 parse-resolv-conf 关键字。如果 HAProxy 自动生成此部分失败,则不会发出错误或警告。当解析器部分中配置了多个名称服务器时,HAProxy 使用第一个有效的响应。在无效响应的情况下,只处理最后一个响应。目的是让慢速服务器有机会在快速故障或过时的服务器之后提供有效的答案。当每个服务器返回不同的错误类型时,HAProxy 仅使用最后一个错误。以下处理应用于此错误:1. HAProxy 使用新的查询类型重试相同的 DNS 查询。A 查询切换到 AAAA 或反之。此处不涉及 SRV 查询。超时错误也排除在外。2. 当查询类型回退完成(或不适用)时,HAProxy 使用首选查询类型重试原始 DNS 查询。3. HAProxy 重试前述步骤  次。如果之后没有收到有效的响应,它将停止 DNS 解析并报告错误。例如,如果解析器部分中配置了 2 个名称服务器,则可能出现以下场景:- 第一个响应有效并直接应用,第二个响应被忽略 - 第一个响应无效,第二个响应有效,则应用第二个响应 - 第一个响应是 NX 域,第二个响应是截断响应,则 HAProxy 使用新类型重试查询 - 第一个响应是 NX 域,第二个响应是超时,则 HAProxy 使用新类型重试查询 - 两个名称服务器的查询都超时,则 HAProxy 使用相同的查询类型重试 如果 DNS 服务器可能无法在一个 DNS 请求中回答所有 IP,HAProxy 会保留以前答案的缓存,如果没有返回 IP,答案将在  秒后被视为过时。
resolvers <resolvers id>
创建一个新的名为 <resolvers id> 的域名服务器列表。resolvers 部分接受以下参数:
定义 HAProxy 接受并向此 resolvers 部分中配置的所有域名服务器通告的最大有效负载大小。<nb> 以字节为单位。如果未设置,HAProxy 通告 512。(RFC 6891 定义的最小值)注意:允许的最大值为 65535。UDP 的推荐值为 4096,不建议超过 8192,除非您确定您的系统和网络可以处理此大小(超过 65507 没有意义,因为这是 UDP 的最大有效负载大小)。如果您只使用 TCP 域名服务器来处理巨大的 DNS 响应,您应该将此值设置为最大值:65535。
nameserver <名称> <地址>[:端口] [参数*]
用于配置名称服务器。名称服务器的  应是唯一的。默认情况下,
被认为是数据报类型。这意味着如果配置了 IPv4 或 IPv6 而没有特殊的地址前缀(第 11 段),将使用 UDP 协议。如果使用了流协议地址前缀,则名称服务器将被视为流服务器(例如 TCP),并且将考虑第 5.2 段中与 DNS 解析相关的 "server" 参数。注意:目前在 TCP 模式下,4 个查询在同一连接上进行流水线处理。每 5 秒移除一批空闲连接。可以配置 "maxconn" 来限制这些并发连接的数量,如果服务器支持,TLS 也应该可用。
将 /etc/resolv.conf 中找到的所有域名服务器添加到此 resolvers 域名服务器列表中。顺序如同 /etc/resolv.conf 中的每个域名服务器被单独放置在此指令的位置。
hold <status> <period>
在收到 DNS 响应  后,确定服务器的状态是否应从 UP 变为 DOWN。为了做出此判断,它会检查在过去  内是否收到了任何有效的状态,以抵消刚刚收到的无效状态。:上次名称解析状态。nx 收到 NXDOMAIN 状态后,检查在结束期间是否有任何有效的状态。refused 收到 REFUSED 状态后,检查在结束期间是否有任何有效的状态。timeout "timeout retry" 触发后,检查在结束期间是否有任何有效的状态。other 收到任何其他无效状态后,检查在结束期间是否有任何有效的状态。valid 仅适用于 "http-request do-resolve" 和 "tcp-request content do-resolve" 操作。它定义了服务器在触发另一次解析之前保持有效响应的期限。它不影响服务器的动态解析。obsolete 定义在收到更新的答案记录后等待多长时间才移除过时的 DNS 记录。它适用于 SRV 记录。:在过去收到了有效响应的时间长度。它遵循 HAProxy 时间格式,默认单位为毫秒。对于依赖动态 DNS 解析来确定其 IP 地址的服务器,接收无效 DNS 响应(例如 NXDOMAIN)将导致服务器状态从 UP 变为 DOWN。hold 指令定义了回顾过去以查找有效响应的时间长度。如果在  内收到了有效的响应,则刚刚收到的无效状态将被忽略。除非在结束期间收到了有效的响应,否则服务器将被标记为 DOWN。例如,如果设置了 "hold nx 30s",并且最后收到的 DNS 响应是 NXDOMAIN,则除非在最近 30 秒内收到了有效的响应,否则服务器将被标记为 DOWN。处于 DOWN 状态的服务器在收到来自 DNS 服务器的有效状态后将立即被标记为 UP。对于 "hold valid" 和 "hold obsolete" 存在单独的行为。
定义在放弃之前为解析服务器名称而发送的查询次数 <nb>。默认值:3。当名称服务器超时或完整的 DNS 查询类型故障转移序列结束并且我们需要从默认的 ANY 查询类型重新开始时,会发生重试。
timeout <event> <time>
定义与名称解析相关的超时。<event>:<time> 超时周期适用的事件。可用事件有: - resolve:当没有其他时间适用时,触发名称解析的默认时间。默认值:1s - retry:两次 DNS 查询之间的时间,当没有收到有效响应时。默认值:1s <time>:与事件相关的时间。它遵循 HAProxy 时间格式。<time> 以毫秒表示。
示例
resolvers mydns nameserver dns1 10.0.0.1:53 nameserver dns2 10.0.0.2:53 nameserver dns3 tcp@10.0.0.3:53 parse-resolv-conf resolve_retries 3 timeout resolve 1s timeout retry 1s hold other 30s hold refused 30s hold nx 30s hold timeout 30s hold valid 10s hold obsolete 30s
HAProxy 提供了一个缓存,设计用于缓存小对象(favicon、css...)。这是一个极简、低维护的内存缓存。该缓存基于所有线程共享的内存区域,并分割成 1kB 的块。如果一个对象不再使用,它可以被删除以存储一个新对象,而与其过期日期无关。当我们尝试分配一个新对象时,最旧的对象会首先被删除。缓存使用主机头和 URI 的哈希作为键。可以使用 Unix 套接字命令 "show cache" 查看缓存状态,有关更多详细信息,请参阅管理指南的 第 9.3 节 “Unix 套接字命令”。当从缓存中传递对象时,日志中的服务器名称将被替换为“<CACHE>”。

6.1. 限制

在以下情况下,缓存不会存储也不会交付对象:- 如果响应不是 200 - 如果响应包含 Vary 标头,并且 process-vary 选项被禁用,或者在 Vary 值中指定了当前未管理的标头(目前仅管理 accept-encoding、referer 和 origin)- 如果 Content-Length + 标头大小大于 "max-object-size" - 如果响应不可缓存 - 如果响应没有明确的过期时间(s-maxage 或 max-age Cache-Control 指令或 Expires 标头)或验证器(ETag 或 Last-Modified 标头)- 如果 process-vary 选项启用,并且已经有 max-secondary-entries 条目与当前响应具有相同的主键 - 如果 process-vary 选项启用,并且响应具有未知编码(未在 https://www.iana.org/assignments/http-parameters/http-parameters.xhtml 中提及),同时在 accept-encoding 客户端标头上有所变化 - 如果请求不是 GET - 如果请求的 HTTP 版本小于 1.1 - 如果请求包含 Authorization 标头

6.2. 设置

要设置缓存,您必须定义一个 cache 部分,并在代理中使用相应的 http-request 和 http-response 动作来使用它。

6.2.1. 缓存部分

cache <名称>
声明一个缓存部分,分配一个名为 <name> 的共享缓存内存,缓存大小是强制性的。
total-max-size <兆字节>
以兆字节为单位定义缓存的 RAM 大小。此大小被分成 1kB 的块,供缓存条目使用。其最大值为 4095。
定义要缓存的对象最大大小。不得大于 “total-max-size” 的一半。如果未设置,则等于缓存大小的 256 分之一。所有大小大于 “max-object-size” 的对象将不会被缓存。
max-age <秒>
定义最大过期持续时间。过期时间设置为 Cache-Control 响应标头中的 s-maxage 或 max-age(按此顺序)指令与此值之间的最小值。默认值为 60 秒,这意味着默认情况下您不能缓存超过 60 秒的对象。
process-vary <on/off>
启用或禁用对 Vary 标头的处理。禁用时,包含此类标头的响应将永远不会被缓存。启用时,我们需要对所有传入请求的请求标头子集计算一个初步哈希(这可能会带来 cpu 成本),该哈希将用于为给定请求构建一个二级键(参见 RFC 7234#4.1)。目前,二级键是根据 'accept-encoding'、'referer' 和 'origin' 标头的内容构建的。默认值为 off(禁用)。
定义缓存中具有相同主键的同时二级条目的最大数量。这需要启用 vary 支持。其默认值为 10,应传递一个严格的正整数。

6.2.2. 代理部分

使用缓存的代理部分将需要在 “http-request” 规则集中包含 “cache-use” 动作,以便从缓存中查找请求的对象,并在 “http-response” 规则集中包含 “cache-store” 动作,以便将检索到的对象存储或更新到缓存中。这些动作中的每一个都可以选择性地包含条件。例如,可以决定对某个已知不可缓存的子目录跳过 “cache-use” 动作,或者对某些已知无价值的内容类型跳过 “cache-store” 动作。请注意,缓存索引键是在 “cache-use” 动作期间计算的,因此如果跳过此动作,则无论如何都不会在响应路径上尝试更新缓存。
示例
backend bck1 mode http http-request cache-use foobar http-response cache-store foobar server srv1 127.0.0.1:80 cache foobar total-max-size 4 max-age 240
HAProxy 能够从请求或响应流、客户端或服务器信息、表、环境信息等中提取数据……提取此类数据的操作称为获取样本。一旦检索到,这些样本可用于各种目的,例如作为粘滞表的键,但最常见的用法是将其与称为模式的预定义常量数据进行匹配。

7.1. ACL 基础

使用访问控制列表(ACL)提供了一种灵活的解决方案,可以根据从请求、响应或任何环境状态中提取的内容执行内容切换,并通常根据这些内容做出决策。其原理很简单:- 从流、表或环境中提取数据样本- (可选)对提取的样本应用一些格式转换- 对该样本应用一个或多个模式匹配方法- 仅当模式匹配样本时执行操作操作通常包括阻止请求、选择后端或添加标头。为了定义测试,使用了“acl”关键字。语法如下:acl <aclname> <criterion> [flags] [operator] [<value>] ...这将创建一个新的 ACL <aclname> 或用新测试完成现有 ACL。这些测试应用于在 <criterion> 中指定的请求/响应部分,并且可以使用可选标志 [flags] 进行调整。某些条件还支持在值集之前指定的操作符。可选地,可以对样本应用一些转换操作符,它们将作为关键字的逗号分隔列表紧随第一个关键字之后指定。值是标准支持的类型,并用空格分隔。ACL 名称必须由大小写字母、数字、“-”(破折号)、“_”(下划线)、“.”(点)和“:”组成。ACL 名称区分大小写,这意味着“my_acl”和“My_Acl”是两个不同的 ACL。ACL 数量没有强制限制。未使用的 ACL 不会影响性能,它们只会消耗少量内存。条件通常是样本获取方法的名称,或者是其 ACL 特定变体之一。默认测试方法由该样本获取方法的输出类型暗示。ACL 变体可以描述同一样本获取方法的替代匹配方法。样本获取方法是唯一支持转换的方法。样本获取方法返回的数据可以是以下类型之一:- 布尔值- 整数(有符号或无符号)- IPv4 或 IPv6 地址- 字符串- 数据块转换器将其中任何一种数据转换为其中任何一种。例如,某些转换器可能会将字符串转换为小写字符串,而其他转换器则会将字符串转换为 IPv4 地址,或将网络掩码应用于 IP 地址。结果样本的类型是应用于列表的最后一个转换器的类型,默认为样本获取方法的类型。每个样本或转换器都返回特定类型的数据,在本文档中用其关键字指定。当使用标准样本获取方法声明 ACL 时,某些类型会自动涉及默认匹配方法,如下表所示:+---------------------+-----------------+ | 样本或转换器 | 默认 | | 输出类型 | 匹配方法 | +---------------------+-----------------+ | boolean | bool | +---------------------+-----------------+ | integer | int | +---------------------+-----------------+ | ip | ip | +---------------------+-----------------+ | string | str | +---------------------+-----------------+ | binary | none, use "-m" | +---------------------+-----------------+请注意,为了匹配二进制样本,必须指定匹配方法,详见下文。ACL 引擎可以将这些类型与以下类型的模式进行匹配:- 布尔值- 整数或整数范围- IP 地址 / 网络- 字符串(精确、子字符串、后缀、前缀、子目录、域)- 正则表达式- 十六进制块目前支持以下 ACL 标志:-i:匹配时忽略所有后续模式的大小写。-f:从文件中加载模式。-m:使用特定的模式匹配方法。-n:禁止 DNS 解析。-M:将 -f 指向的文件加载为映射文件。-u:强制 ACL 的唯一 ID。--:强制结束标志。当字符串看起来像其中一个标志时很有用。“-f”标志后跟一个文件名,该文件中的所有行都将被读取为单个值。如果需要从多个文件加载模式,甚至可以传递多个“-f”参数。空行以及以井号('#')开头的行将被忽略。所有前导空格和制表符都将被去除。如果绝对有必要插入以井号开头的有效模式,只需在前面加上一个空格,以免被误认为是注释。根据数据类型和匹配方法,HAProxy 可能会将这些行加载到二叉树中,从而实现非常快速的查找。这对于 IPv4 和精确字符串匹配是成立的。在这种情况下,重复项将自动删除。“-M”标志允许 ACL 使用映射文件。如果设置了此标志,则该文件将解析为两列文件。第一列包含 ACL 使用的模式,第二列包含样本。样本可以稍后用于映射。这在某些罕见情况下很有用,即 ACL 仅用于在应用映射之前检查映射中是否存在模式。“-u”标志强制 ACL 的唯一 ID。此唯一 ID 用于套接字接口,以识别 ACL 并动态更改其值。请注意,即使设置了 ID,文件也始终通过其名称进行标识。另请注意,“-i”标志适用于后续条目,而不适用于其前面的从文件加载的条目。例如:acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test在此示例中,“exact-ua.lst”中的每一行都将与请求的“user-agent”标头进行精确匹配。然后,“generic-ua”中的每一行都将进行不区分大小写的匹配。然后,单词“test”也将进行不区分大小写的匹配。“-m”标志用于选择输入样本上的特定模式匹配方法。所有 ACL 特定条件都暗示了模式匹配方法,通常不需要此标志。但是,此标志对于通用样本获取方法很有用,用于描述它们将如何与模式匹配。对于返回数据类型(例如字符串或二进制)没有明显匹配方法的样本获取,这是必需的。当指定“-m”并后跟模式匹配方法名称时,将使用此方法而不是条件的默认方法。这使得可以以最初未计划的方式匹配内容,或者使用返回字符串的样本获取方法。匹配方法也会影响模式的解析方式。“-n”标志禁止 DNS 解析。它与 IP 文件加载一起使用。默认情况下,如果解析器无法解析 IP 地址,它会认为解析后的字符串可能是域名并尝试 DNS 解析。标志“-n”禁用此解析。它对于检测格式错误的 IP 列表很有用。请注意,如果 DNS 服务器不可访问,HAProxy 配置解析可能需要数分钟等待超时。在此期间不会显示错误消息。标志“-n”禁用此行为。另请注意,在运行时,此功能对于动态 ACL 修改是禁用的。然而,存在一些限制。并非所有方法都可以与所有样本获取方法一起使用。此外,如果“-m”与“-f”结合使用,它必须放在首位。模式匹配方法必须是以下之一:- “found”:只检查是否在流中找到了请求的样本,但不将其与任何模式进行比较。建议不要传递任何模式以避免混淆。此匹配方法特别适用于检测某些内容(如标头、cookie 等)的存在,即使它们为空,且不与任何内容进行比较或计数。- “bool”:将值检查为布尔值。它只能应用于返回布尔值或整数值的获取,并且不带模式。值零或 false 不匹配,所有其他值匹配。- “int”:将值匹配为整数。它可以用于整数和布尔样本。布尔 false 是整数 0,true 是整数 1。- “ip”:将值匹配为 IPv4 或 IPv6 地址。它仅与 IP 地址样本兼容,因此它是隐含的,永远不需要。- “bin”:将内容与表示二进制序列的十六进制字符串匹配。这可用于二进制或字符串样本。- “len”:将样本的长度匹配为整数。这可用于二进制或字符串样本。- “str”:精确匹配:将内容与字符串匹配。这可用于二进制或字符串样本。- “sub”:子字符串匹配:检查内容是否包含至少一个提供的字符串模式。这可用于二进制或字符串样本。- “reg”:正则表达式匹配:将内容与正则表达式列表匹配。这可用于二进制或字符串样本。- “beg”:前缀匹配:检查内容是否以提供的字符串模式开头。这可用于二进制或字符串样本。- “end”:后缀匹配:检查内容是否以提供的字符串模式结尾。这可用于二进制或字符串样本。- “dir”:子目录匹配:检查内容中斜杠分隔的部分是否精确匹配提供的字符串模式之一。这可用于二进制或字符串样本。- “dom”:域匹配:检查内容中点分隔的部分是否精确匹配提供的字符串模式之一。这可用于 URL 使用。模式中的前导和尾随分隔符将被忽略。ACL 匹配是否与其中任何一个匹配。因此,在示例字符串“http://www1.dc-eu.example.com:80/blah”中,模式“http”、“www1”、“dc-eu”、“example”、“com”、“80”、“dc-eu.example”、“blah”、“:www1:”、“dc-eu.example:80”将匹配,但“eu”或“dc”不匹配。使用它来匹配域后缀进行过滤或路由通常不是一个好主意,因为通过在另一个域前面加上匹配前缀,路由很容易被欺骗。ACL 特定条件都暗示了默认匹配方法。大多数情况下,这些条件是通过连接原始样本获取方法的名称和匹配方法组成的。例如,“hdr_beg”将“beg”匹配应用于使用“hdr”获取方法检索的样本。此匹配方法仅在关键字单独使用时可用,不带任何转换器。如果在此 ACL 关键字之后应用了任何此类转换器,则 ACL 关键字的默认匹配方法将被简单地忽略,因为匹配重要的是最后一个转换器的输出类型。由于所有 ACL 特定条件都依赖于样本获取方法,因此始终可以使用原始样本获取方法和使用“-m”的显式匹配方法来代替。如果在使用 ACL 特定条件时使用“-m”指定了替代匹配,则匹配方法将简单地应用于底层样本获取方法。例如,以下所有 ACL 都是完全等效的:acl short_form hdr_beg(host) www.acl alternate1 hdr_beg(host) -m beg www.acl alternate2 hdr_dom(host) -m beg www.acl alternate3 hdr(host) -m beg www.下表总结了样本或转换器类型与要获取的模式类型之间的兼容性矩阵。它显示了每种兼容组合要使用的匹配方法的名称,当该方法是默认方法且默认情况下无需“-m”即可工作时,用尖括号“>”和“<”包围。+-------------------------------------------------+ | 输入样本类型 | +----------------------+---------+---------+---------+---------+---------+ | 模式类型 | boolean | integer | ip | string | binary | +----------------------+---------+---------+---------+---------+---------+ | none (presence only) | found | found | found | found | found | +----------------------+---------+---------+---------+---------+---------+ | none (boolean value) |> bool <| bool | | bool | | +----------------------+---------+---------+---------+---------+---------+ | integer (value) | int |> int <| int | int | | +----------------------+---------+---------+---------+---------+---------+ | integer (length) | len | len | len | len | len | +----------------------+---------+---------+---------+---------+---------+ | IP address | | |> ip <| ip | ip | +----------------------+---------+---------+---------+---------+---------+ | exact string | str | str | str |> str <| str | +----------------------+---------+---------+---------+---------+---------+ | prefix | beg | beg | beg | beg | beg | +----------------------+---------+---------+---------+---------+---------+ | suffix | end | end | end | end | end | +----------------------+---------+---------+---------+---------+---------+ | substring | sub | sub | sub | sub | sub | +----------------------+---------+---------+---------+---------+---------+ | subdir | dir | dir | dir | dir | dir | +----------------------+---------+---------+---------+---------+---------+ | domain | dom | dom | dom | dom | dom | +----------------------+---------+---------+---------+---------+---------+ | regex | reg | reg | reg | reg | reg | +----------------------+---------+---------+---------+---------+---------+ | hex block | | | | bin | bin | +----------------------+---------+---------+---------+---------+---------+

7.1.1. 匹配布尔值

为了匹配布尔值,不需要任何值,所有值都会被忽略。布尔匹配默认用于所有类型为“boolean”的获取方法。当使用布尔匹配时,获取的值会按原样返回,这意味着布尔值“true”将始终匹配,而布尔值“false”将永远不匹配。布尔匹配也可以通过在返回整数值的获取方法上使用“-m bool”来强制执行。然后,整数值 0 会被转换为布尔值“false”,所有其他值都会被转换为“true”。

7.1.2. 匹配整数

整数匹配默认应用于整数获取方法。也可以使用“-m int”在布尔获取上强制执行。在这种情况下,“false”转换为整数 0,“true”转换为整数 1。整数匹配还支持整数范围和运算符。请注意,整数匹配仅适用于正值。范围是用冒号分隔的下限和上限表示的值,两者都可以省略。例如,“1024:65535”是表示非特权端口范围的有效范围,“1024:”也适用。“0:1023”是特权端口的有效表示,“:1023”也适用。作为特例,一些 ACL 函数支持小数点数字,这实际上是用点分隔的两个整数。这用于某些版本检查。所有整数属性都适用于这些小数点数字,包括范围和运算符。为了更方便使用,还支持比较运算符。请注意,将运算符与范围一起使用意义不大,强烈不鼓励。同样,对一组值执行顺序比较意义不大。整数匹配可用的运算符有:eq:如果测试值等于至少一个值,则为 truege:如果测试值大于或等于至少一个值,则为 truegt:如果测试值大于至少一个值,则为 truele:如果测试值小于或等于至少一个值,则为 truelt:如果测试值小于至少一个值,则为 true例如,以下 ACL 匹配任何负的 Content-Length 标头:acl negative-length req.hdr_val(content-length) lt 0这个匹配 SSL 版本在 3.0 和 3.1 之间(含):acl sslv3 req.ssl_ver 3:3.1

7.1.3. 匹配字符串

字符串匹配适用于字符串或二进制获取方法,并存在 6 种不同形式:- 精确匹配 (-m str):提取的字符串必须与模式精确匹配;- 子字符串匹配 (-m sub):在提取的字符串中查找模式,如果找到其中任何一个,则 ACL 匹配;- 前缀匹配 (-m beg):将模式与提取的字符串开头进行比较,如果其中任何一个匹配,则 ACL 匹配。- 后缀匹配 (-m end):将模式与提取的字符串结尾进行比较,如果其中任何一个匹配,则 ACL 匹配。- 子目录匹配 (-m dir):在提取的字符串中查找任意位置,用斜杠 (“/”)、字符串开头或结尾分隔的模式。如果其中任何一个匹配,则 ACL 匹配。因此,字符串“/images/png/logo/32x32.png”将匹配“/images”、“/images/png”、“images/png”、“/png/logo”、“logo/32x32.png”或“32x32.png”,但不匹配“png”或“32x32”。- 域匹配 (-m dom):在提取的字符串中查找任意位置,用点 (“.”)、冒号 (“:”)、斜杠 (“/”)、问号 (“?”)、字符串开头或结尾分隔的模式。这用于 URL。模式中的前导和尾随分隔符将被忽略。如果其中任何一个匹配,则 ACL 匹配。因此,在示例字符串“http://www1.dc-eu.example.com:80/blah”中,模式“http”、“www1”、“dc-eu”、“example”、“com”、“80”、“dc-eu.example”、“blah”、“:www1:”、“dc-eu.example:80”将匹配,但“eu”或“dc”不匹配。使用它来匹配域后缀进行过滤或路由通常不是一个好主意,因为通过在另一个域前面加上匹配前缀,路由很容易被欺骗。字符串匹配适用于按原样传递的逐字字符串,但反斜杠 (“\”) 除外,它使得可以转义某些字符(例如空格)。如果在第一个字符串之前传递“-i”标志,则匹配将忽略大小写。为了匹配字符串“-i”,要么将其设置为第二个,要么在第一个字符串之前传递“--”标志。当然,匹配字符串“--”也适用。不要将字符串匹配用于可能包含空字节 (0x00) 的二进制获取,因为比较会在遇到第一个空字节时停止。相反,首先使用 hex 转换器将二进制获取转换为十六进制字符串。
示例
# 如果字符串 <tag> 存在于二进制样本中,则匹配 acl tag_found req.payload(0,0),hex -m sub 3C7461673E

7.1.4. 匹配正则表达式 (regexes)

与字符串匹配一样,正则表达式匹配也适用于按字面传递的字符串,但反斜杠("\")除外,它使得可以转义某些字符,如空格。如果在第一个正则表达式之前传递了“-i”标志,则匹配将忽略大小写。为了匹配字符串“-i”,要么将其放在第二个位置,要么在第一个正则表达式之前传递“--”标志。当然,匹配字符串“--”也适用相同的原则。

7.1.5. 匹配任意数据块

可以将一些提取的样本与一个可能无法安全地表示为字符串的二进制块进行匹配。为此,当匹配方法设置为二进制时,模式必须以偶数个十六进制数字的形式传递。每两个数字的序列将代表一个字节。十六进制数字可以使用大写或小写。
示例
# 在输入流中匹配 "Hello\n" (\x48 \x65 \x6c \x6c \x6f \x0a) acl hello req.payload(0,6) -m bin 48656c6c6f0a

7.1.6. 匹配 IPv4 和 IPv6 地址

IPv4 地址值可以指定为纯地址,也可以附加网络掩码,在这种情况下,只要 IPv4 地址在网络内,它就匹配。纯地址也可以替换为可解析的主机名,但通常不鼓励这种做法,因为它使配置更难阅读和调试。如果使用主机名,您至少应确保它们存在于 /etc/hosts 中,以便配置不依赖于解析配置时任何随机 DNS 匹配。支持点分 IPv4 地址表示法,包括常规形式和省略全零八位字节的缩写形式:+------------------+------------------+------------------+ | 示例 1 | 示例 2 | 示例 3 | +------------------+------------------+------------------+ | 192.168.0.1 | 10.0.0.12 | 127.0.0.1 | | 192.168.1 | 10.12 | 127.1 | | 192.168.0.1/22 | 10.0.0.12/8 | 127.0.0.1/8 | | 192.168.1/22 | 10.12/8 | 127.1/8 | +------------------+------------------+------------------+请注意,这与 RFC 4632 CIDR 地址表示法不同,其中 192.168.42/24 等效于 192.168.42.0/24。IPv6 可以按其常用形式输入,附加或不附加网络掩码。IPv6 网络掩码只接受位计数。为了避免随机解析 IP 地址带来的任何风险,IPv6 模式中绝不允许使用主机名。HAProxy 还能够在以下情况下将 IPv4 地址与 IPv6 地址匹配:- 测试地址是 IPv4,模式地址是 IPv4,匹配在 IPv4 中应用,使用提供的掩码(如果有)。- 测试地址是 IPv6,模式地址是 IPv6,匹配在 IPv6 中应用,使用提供的掩码(如果有)。- 测试地址是 IPv6,模式地址是 IPv4,如果 IPv6 地址与 2002:IPV4::、::IPV4 或 ::ffff:IPV4 匹配,则匹配在 IPv4 中应用,使用模式的掩码,否则失败。- 测试地址是 IPv4,模式地址是 IPv6,IPv4 地址首先通过在其前面加上 ::ffff: 转换为 IPv6,然后匹配在 IPv6 中应用,使用提供的 IPv6 掩码。

7.2. 使用 ACL 形成条件

某些操作仅在有效条件满足时执行。条件是 ACL 与运算符的组合。支持 3 个运算符:- AND(隐式)- OR(使用“or”关键字或“||”运算符显式)- 否定(使用感叹号“!”)条件以析取形式构成:[!]acl1 [!]acl2 ... [!]acln { or [!]acl1 [!]acl2 ... [!]acln } ...此类条件通常在“if”或“unless”语句之后使用,指示何时触发操作。例如,阻止 HTTP 请求到“*”URL,但方法不是“OPTIONS”,以及没有 content-length 的 POST 请求,以及 content-length 大于 0 的 GET 或 HEAD 请求,最后是所有不是 GET/HEAD/POST/OPTIONS 的请求!acl missing_cl req.hdr_cnt(Content-length) eq 0 http-request deny if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl http-request deny if METH_GET HTTP_CONTENT http-request deny unless METH_GET or METH_POST or METH_OPTIONS要为“www”站点上的静态内容请求以及“img”、“video”、“download”和“ftp”主机上的所有请求选择不同的后端:acl url_static path_beg /static /images /img /css acl url_static path_end .gif .png .jpg .css .js acl host_www hdr_beg(host) -i www acl host_static hdr_beg(host) -i img. video. download. ftp. # now use backend "static" for all static-only hosts, and for static URLs # of host "www". Use backend "www" for the rest. use_backend static if host_static or host_www url_static use_backend www if host_www也可以使用“匿名 ACL”形成规则。这些是动态构建的未命名 ACL 表达式,无需声明。它们必须用大括号括起来,每个大括号前后都有一个空格(因为大括号必须被视为独立的单词)。示例:以下规则:acl missing_cl req.hdr_cnt(Content-length) eq 0 http-request deny if METH_POST missing_cl也可以这样写:http-request deny if METH_POST { req.hdr_cnt(Content-length) eq 0 }通常不建议使用这种结构,因为以这种方式编写时更容易在配置中留下错误。但是,对于仅匹配一个源 IP 地址的非常简单的规则,使用它们可能比声明带有随机名称的 ACL 更有意义。另一个很好的用例是:使用命名 ACL:acl site_dead nbsrv(dynamic) lt 2 acl site_dead nbsrv(static) lt 2 monitor fail if site_dead使用匿名 ACL:monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }有关“http-request deny”和“use_backend”关键字的详细帮助,请参阅第 4.2 节

7.3. 获取样本

从历史上看,样本获取方法仅用于检索数据以使用 ACL 与模式匹配。随着 stick-tables 的出现,创建了一类新的样本获取方法,它们通常与其 ACL 对应项共享相同的语法。这些样本获取方法也称为“获取”(fetches)。截至目前,ACL 和获取已经融合。所有 ACL 获取方法都已作为获取方法提供,ACL 也可以使用任何样本获取方法。本节详细介绍了所有可用的样本获取方法及其输出类型。一些样本获取方法具有已弃用的别名,用于保持与现有配置的兼容性。它们被明确标记为已弃用,不应在新设置中使用。ACL 派生词(如果可用)也已注明,并附带各自的匹配方法。这些都具有明确定义的默认模式匹配方法,因此无需(尽管允许)传递“-m”选项来指示样本将如何使用 ACL 进行匹配。如上文样本类型与匹配兼容性矩阵所示,在 ACL 中使用通用样本获取方法时,除非样本类型是布尔值、整数、IPv4 或 IPv6 之一,否则“-m”选项是强制性的。当相同的关键字作为 ACL 关键字和标准获取方法存在时,ACL 引擎将默认自动选择仅限 ACL 的关键字。其中一些关键字支持一个或多个必需参数,以及一个或多个可选参数。这些参数是强类型的,在解析配置时会进行检查,以确保不会出现使用不正确参数(例如,未解析的后端名称)的风险。获取函数参数放在括号之间,并用逗号分隔。当参数是可选的时,它将用方括号 ('[ ]') 指示。当所有参数都可选时,可以省略括号。因此,标准样本获取方法的语法是以下之一:- name- name(arg1)- name(arg1,arg2)

7.3.1. 转换器

样本获取方法可以与应用于获取样本的转换相结合(也称为“转换器”)。这些组合构成了所谓的“样本表达式”,结果是“样本”。最初这仅由“stick on”和“stick store-request”指令支持,但现在已扩展到可以使用样本的所有地方(ACL、log-format、unique-id-format、add-header 等)。这些转换作为一系列特定关键字在样本获取方法之后枚举。这些关键字也可以紧跟在获取关键字的参数之后附加,用逗号分隔。这些关键字也可以支持一些参数(例如网络掩码),这些参数必须放在括号中传递。一类转换器是按位和算术运算符,支持对整数执行基本操作。支持一些按位操作(and、or、xor、cpl),支持一些算术操作(add、sub、mul、div、mod、neg)。提供了一些比较器(odd、even、not、bool),使得无需编写 ACL 即可报告匹配。支持以下关键字
关键字输入类型输出类型
51d.single(prop[,prop*])字符串字符串
add(value)整数整数
add_item(delim,[var][,suff]])字符串字符串
aes_gcm_dec(bits,nonce,key,aead_tag)二进制二进制
and(value)整数整数
b64dec字符串二进制
base64二进制字符串
be2dec(separator,chunk_size,[truncate])二进制字符串
be2hex([separator],[chunk_size],[truncate])二进制字符串
bool整数布尔
bytes(offset[,length])二进制二进制
capture-req(id)字符串字符串
capture-res(id)字符串字符串
concat([start],[var],[end])字符串字符串
cpl整数整数
crc32([avalanche])二进制整数
crc32c([avalanche])二进制整数
cut_crlf字符串字符串
da-csv-conv(prop[,prop*])字符串字符串
debug([prefix][,destination])任意相同
关键字输入类型输出类型
digest(algorithm)二进制二进制
div(value)整数整数
djb2([avalanche])二进制整数
even整数布尔
field(index,delimiters[,count])字符串字符串
fix_is_valid二进制布尔
fix_tag_value(tag)二进制二进制
hex二进制字符串
hex2i二进制整数
hmac(algorithm,key)二进制二进制
host_only字符串字符串
htonl整数整数
http_date([offset],[unit])整数字符串
iif(true,false)布尔字符串
in_table(table)字符串布尔
ipmask(mask4,[mask6])地址地址
json([input-code])字符串字符串
json_query(json_path,[output_type])字符串_outtype_
jwt_header_query([json_path],[output_type])字符串字符串
jwt_payload_query([json_path],[output_type])字符串字符串
关键字输入类型输出类型
jwt_verify(alg,key)字符串整数
language(value[,default])字符串字符串
length字符串整数
lower字符串字符串
ltime(format[,offset])整数字符串
ltrim(chars)字符串字符串
map(map_name[,default_value])字符串字符串
map_match(map_name[,default_value])_match_字符串
map_match_output(map_name[,default_value])_match__output_
mod(value)整数整数
mqtt_field_value(pkt_type,fieldname_or_prop_ID)二进制二进制
mqtt_is_valid二进制布尔
ms_ltime(format[,offset])整数字符串
ms_utime(format[,offset])整数字符串
mul(value)整数整数
nbsrv字符串整数
neg整数整数
not整数布尔
odd整数布尔
or(value)整数整数
关键字输入类型输出类型
param(name,[delim])字符串字符串
port_only字符串整数
protobuf(field_number,[field_type])二进制二进制
regsub(regex,subst[,flags])字符串字符串
rfc7239_field(field)字符串字符串
rfc7239_is_valid字符串布尔
rfc7239_n2nn字符串地址 / str
rfc7239_n2np字符串整数 / str
rtrim(chars)字符串字符串
sdbm([avalanche])二进制整数
secure_memcmp(var)字符串布尔
set-var(var[,cond...])任意相同
sha1二进制二进制
sha2([bits])二进制二进制
srv_queue字符串整数
strcmp(var)字符串布尔
sub(value)整数整数
table_bytes_in_rate(table)字符串整数
table_bytes_out_rate(table)字符串整数
table_conn_cnt(table)字符串整数
关键字输入类型输出类型
table_conn_cur(table)字符串整数
table_conn_rate(table)字符串整数
table_expire(table[,default_value])字符串整数
table_gpc(idx,table)字符串整数
table_gpc0(table)字符串整数
table_gpc0_rate(table)字符串整数
table_gpc1(table)字符串整数
table_gpc1_rate(table)字符串整数
table_gpc_rate(idx,table)字符串整数
table_gpt(idx,table)字符串整数
table_gpt0(table)字符串整数
table_http_err_cnt(table)字符串整数
table_http_err_rate(table)字符串整数
table_http_fail_cnt(table)字符串整数
table_http_fail_rate(table)字符串整数
table_http_req_cnt(table)字符串整数
table_http_req_rate(table)字符串整数
table_idle(table[,default_value])字符串整数
table_kbytes_in(table)字符串整数
table_kbytes_out(table)字符串整数
关键字输入类型输出类型
table_server_id(table)字符串整数
table_sess_cnt(table)字符串整数
table_sess_rate(table)字符串整数
table_trackers(table)字符串整数
ub64dec字符串字符串
ub64enc字符串字符串
ungrpc(field_number,[field_type])二进制二进制 / 整数
unset-var(var)任意相同
upper字符串字符串
url_dec([in_form])字符串字符串
url_enc([enc_type])字符串字符串
us_ltime(format[,offset])整数字符串
us_utime(format[,offset])整数字符串
utime(format[,offset])整数字符串
word(index,delimiters[,count])字符串字符串
wt6([avalanche])二进制整数
x509_v_err_str整数字符串
xor(value)整数整数
xxh3([seed])二进制整数
xxh32([seed])二进制整数
以下是转换器关键字的详细列表
51d.single(<prop>[,<prop>*])
以字符串形式返回所请求属性的值,值之间由“51degrees-property-separator”指定的分隔符分隔。设备通过传递给转换器的 User-Agent 标头来识别。该函数最多可以传递五个属性名称,如果找不到属性名称,则返回“NoData”值。
示例
# 此处,标头 "X-51D-DeviceTypeMobileTablet" 被添加到请求中, # 它包含了通过传递给转换器的 User-Agent 所请求的三个属性的值。 frontend http-in bind *:8081 default_backend servers http-request set-header X-51D-DeviceTypeMobileTablet \ %[req.fhdr(User-Agent),51d.single(DeviceType,IsMobile,IsTablet)]
add(<value>)
将 <value> 添加到有符号整数类型的输入值中,并将结果作为有符号整数返回。<value> 可以是数值或变量名。变量名以作用域指示开头。允许的作用域是:“proc”:变量与整个进程共享“sess”:变量与整个会话共享“txn”:变量与事务(请求和响应)共享“req”:变量仅在请求处理期间共享“res”:变量仅在响应处理期间共享此前缀后面跟着一个名称。分隔符是“.”。名称只能包含字符“a-z”、“A-Z”、“0-9”、“.”和“_”。
add_item(<delim>,[<var>][,<suff>]])
在当前样本之后连接最少 2 个、最多 3 个字段,然后将当前样本转换为字符串。第一个字段 <delim> 是一个常量字符串,如果现有样本不为空且 <var> 或 <suff> 不为空,则将紧跟在现有样本之后附加。第二个字段 <var> 是一个变量名。将查找该变量,将其内容转换为字符串,并紧跟在 <delim> 部分之后附加。如果未找到变量,则不附加任何内容。它是可选的,并且可以选择后跟一个常量字符串 <suff>,但是如果省略 <var>,则 <suff> 是必需的。此转换器类似于 concat 转换器,可用于构建由一系列其他变量组成的新变量,但主要区别在于它会检查添加分隔符是否有意义,例如如果当前样本为空,则不会添加分隔符。这种情况需要使用 concat 转换器实现两条单独的规则,其中第一条规则必须在添加分隔符之前检查当前样本字符串是否为空。如果逗号或右括号需要用作分隔符,则必须用引号或反斜杠保护它们,反斜杠本身也需要保护,以免被第一级解析器剥离(有关引用和转义,请参阅第 2.2 节)。请参阅下面的示例。
示例
http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score1,"(site1)") if src,in_table(site1)' http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score2,"(site2)") if src,in_table(site2)' http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score3,"(site3)") if src,in_table(site3)' http-request set-header x-tagged %[var(req.tagged)] http-request set-var(req.tagged) 'var(req.tagged),add_item(",",req.score1),add_item(",",req.score2)' http-request set-var(req.tagged) 'var(req.tagged),add_item(",",,(site1))' if src,in_table(site1)
aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>)
根据 <bits> 参数,使用 AES128-GCM、AES192-GCM 或 AES256-GCM 算法解密原始字节输入。所有其他参数都需要进行 base64 编码,返回的结果是原始字节格式。如果 <aead_tag> 验证失败,转换器不会返回任何数据。<nonce>、<key> 和 <aead_tag> 可以是字符串或变量。此转换器至少需要 OpenSSL 1.0.1。
示例
http-response set-header X-Decrypted-Text %[var(txn.enc),\ aes_gcm_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]
and(<value>)
对 <value> 与输入的有符号整数值执行按位“AND”操作,并将结果作为有符号整数返回。 <value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享 "req" : 变量仅在请求处理期间共享 "res" : 变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
将 base64 编码的输入字符串转换(解码)为其二进制表示。它执行 base64() 的反向操作。对于 base64url(“URL 和文件名安全字母表”(RFC 4648))变体,请参见“ub64dec”。
将二进制输入样本转换为 base64 字符串。它用于以可靠传输的方式记录或传输二进制内容(例如,SSL ID 可以复制到标头中)。对于 base64url(“URL 和文件名安全字母表”(RFC 4648))变体,请参见“ub64enc”。
be2dec(<separator>,<chunk_size>,[<truncate>])
将大端二进制输入样本转换为一个字符串,其中每个 <chunk_size> 输入字节对应一个无符号整数。如果指定,<separator> 会每 <chunk_size> 个二进制输入字节插入一次。<truncate> 标志指示二进制输入是否在 <chunk_size> 边界处被截断。<chunk_size> 的最大值受 long long int(8 字节)大小的限制。
示例
bin(01020304050607),be2dec(:,2) # 258:772:1286:7 bin(01020304050607),be2dec(-,2,1) # 258-772-1286 bin(01020304050607),be2dec(,2,1) # 2587721286 bin(7f000001),be2dec(.,1) # 127.0.0.1
be2hex([<separator>],[<chunk_size>],[<truncate>])
将大端二进制输入样本转换为一个十六进制字符串,其中每个输入字节对应两个十六进制数字。它用于以可靠的方式记录或传输某些二进制输入数据的十六进制转储(例如,可以将 SSL ID 复制到标头中)。如果指定,<separator> 会每 <chunk_size> 个二进制输入字节插入一次。<truncate> 标志指示二进制输入是否在 <chunk_size> 边界处被截断。
示例
bin(01020304050607),be2hex # 01020304050607 bin(01020304050607),be2hex(:,2) # 0102:0304:0506:07 bin(01020304050607),be2hex(--,2,1) # 0102--0304--0506 bin(0102030405060708),be2hex(,3,1) # 010203040506
如果类型为有符号整数的输入值非空,则返回布尔值 TRUE,否则返回 FALSE。与 and() 结合使用,可用于报告输入值的位测试的真/假(例如,验证标志的存在)。
bytes(<offset>[,<length>])
从输入二进制样本中提取一些字节。结果是一个二进制样本,从原始样本的偏移量(以字节为单位)开始,并可选地在给定的长度处截断。<offset> 和 <length> 可以是数值或变量名。如果 <offset> 或 <length> 无效,转换器将返回一个空样本。无效的 <offset> 意味着负值或大于等于输入样本长度的值。无效的 <length> 意味着负值,或者在某些情况下,大于输入样本长度的值。
示例
http-request set-var(txn.input) req.hdr(input) # 假设输入是 "012345" http-response set-header bytes_0 "%[var(txn.input),bytes(0)]" # 输出 "012345" http-response set-header bytes_1_3 "%[var(txn.input),bytes(1,3)]" # 输出 "123" http-response set-var(txn.var_start) int(1) http-response set-var(txn.var_length) int(3) http-response set-header bytes_var1_var3 "%[var(txn.input),bytes(txn.var_start,txn.var_length)]" # 输出 "123"
捕获请求槽 <id> 中的字符串条目,并按原样返回该条目。如果槽不存在,捕获将静默失败。
捕获响应槽 <id> 中的字符串条目,并按原样返回该条目。如果槽不存在,捕获将静默失败。
concat([<start>],[<var>],[<end>])
在当前样本之后最多连接 3 个字段,然后将当前样本转换为字符串。第一个字段 <start> 是一个常量字符串,将紧跟在现有样本之后附加。如果未使用,可以省略。第二个字段 <var> 是一个变量名。将查找该变量,将其内容转换为字符串,并紧跟在 <start> 部分之后附加。如果未找到变量,则不附加任何内容。它也可以省略。第三个字段 <end> 是一个常量字符串,将附加在变量之后。它也可以省略。这些元素共同允许将变量与分隔符连接到现有变量集。这可用于构建由一系列其他变量组成的新变量,例如冒号分隔的值。如果逗号或右括号需要用作分隔符,则必须用引号或反斜杠保护它们,反斜杠本身也需要保护,以免被第一级解析器剥离。这通常用于从其他变量构建复合变量,但有时使用具有多个字段的格式字符串可能更方便。请参阅下面的示例。
示例
tcp-request session set-var(sess.src) src tcp-request session set-var(sess.dn) ssl_c_s_dn tcp-request session set-var(txn.sig) str(),concat(<ip=,sess.ip,>),concat(<dn=,sess.dn,>) tcp-request session set-var(txn.ipport) "str(),concat('addr=(',sess.ip),concat(',',sess.port,')')" tcp-request session set-var-fmt(txn.ipport) "addr=(%[sess.ip],%[sess.port])" ## 功能相同 http-request set-header x-hap-sig %[var(txn.sig)]
获取类型为有符号整数的输入值,应用取反(翻转所有位)并以有符号整数的形式返回结果。
crc32([<avalanche>])
使用 CRC32 哈希函数将二进制输入样本哈希成一个无符号 32 位量。可选地,如果可选的 <avalanche> 参数等于 1,则可以对输出应用完整的雪崩哈希函数。此转换器使用与各种基于哈希的负载均衡算法相同的函数,因此它将提供完全相同的结果。它旨在与其他需要对某些输入键计算 CRC32 的软件兼容,因此它遵循在以太网、Gzip、PNG 等中最常见的实现。它比其他算法慢,但可能提供更好或至少更不可预测的分布。它不得用于安全目的,因为 32 位哈希很容易被破解。另请参见“djb2”、“sdbm”、“wt6”、“crc32c”和“hash-type”指令。
crc32c([<avalanche>])
使用 CRC32C 哈希函数将二进制输入样本哈希成一个无符号 32 位量。可选地,如果可选的 <avalanche> 参数等于 1,则可以对输出应用完整的雪崩哈希函数。此转换器使用 RFC4960 附录 B [8] 中描述的相同函数。它旨在与其他需要对某些输入键计算 CRC32C 的软件兼容。它比其他算法慢,并且不得用于安全目的,因为 32 位哈希很容易被破解。另请参见“djb2”、“sdbm”、“wt6”、“crc32”和“hash-type”指令。
在找到的第一个回车符('\r')或换行符('\n')处截断输入样本的字符串表示。仅更新字符串长度。
da-csv-conv(<prop>[,<prop>*])
请求 DeviceAtlas 转换器识别输入的 User Agent 字符串,并发出一个由参数中枚举的属性连接而成的字符串,属性之间由全局关键字“deviceatlas-property-separator”定义的分隔符分隔,默认分隔符为管道符('|')。HAProxy 配置语言对不同属性的数量有 12 个的限制。
示例
frontend www bind *:8881 default_backend servers http-request set-header X-DeviceAtlas-Data %[req.fhdr(User-Agent),da-csv(primaryHardwareType,osName,osVersion,browserName,browserVersion,browserRenderingEngine)]
debug([<prefix][,<destination>])
此转换器用作调试工具。它捕获输入样本并将其发送到事件接收器 <destination>,该接收器可以指定一个环形缓冲区,如“buf0”,以及“stdout”或“stderr”。可用的接收器可以在运行时通过在 CLI 上发出“show events”来检查。如果未指定,输出将是“buf0”,可以通过 CLI 的“show events”命令进行查询。可以传递一个可选的前缀 <prefix> 来帮助区分来自多个表达式的输出。然后它将出现在输出消息的冒号之前。输入样本按原样传递到输出,因此将调试转换器插入链中的任何位置都是安全的,即使对于不可打印的样本类型也是如此。
示例
tcp-request connection track-sc0 src,debug(track-sc)
digest(<algorithm>)
将二进制输入样本转换为消息摘要。结果是一个二进制样本。<algorithm> 必须是一个 OpenSSL 消息摘要名称(例如 sha256)。请注意,此转换器仅在 HAProxy 使用 USE_OPENSSL 编译时可用。
div(<value>)
将输入的有符号整数值除以 <value>,并将结果作为有符号整数返回。如果 <value> 为 null,则返回最大的无符号整数(通常为 2^63-1)。<value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享 "req" : 变量仅在请求处理期间共享 "res" : 变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
djb2([<avalanche>])
使用 DJB2 哈希函数将二进制输入样本哈希成一个无符号 32 位量。可选地,如果可选的 <avalanche> 参数等于 1,则可以对输出应用完整的雪崩哈希函数。此转换器使用与各种基于哈希的负载均衡算法相同的函数,因此它将提供完全相同的结果。它主要用于调试,但可以用作粘性表条目来收集粗略统计。它不得用于安全目的,因为 32 位哈希很容易被破解。另请参见“crc32”、“sdbm”、“wt6”、“crc32c”和“hash-type”指令。
如果类型为有符号整数的输入值为偶数,则返回布尔值 TRUE,否则返回 FALSE。它在功能上等同于 "not,and(1),bool"。
field(<index>,<delimiters>[,<count>])
从输入字符串中,根据给定的分隔符,从开头(正索引)或结尾(负索引)提取给定索引处的子字符串。索引从 1 或 -1 开始,分隔符是格式化为字符串的字符列表。您可以选择指定要提取的字段数量 <count>(默认为 1)。值为 0 表示提取所有剩余字段。
示例
str(f1_f2_f3__f5),field(4,_) # <空> str(f1_f2_f3__f5),field(5,_) # f5 str(f1_f2_f3__f5),field(2,_,0) # f2_f3__f5 str(f1_f2_f3__f5),field(2,_,2) # f2_f3 str(f1_f2_f3__f5),field(-2,_,3) # f2_f3_ str(f1_f2_f3__f5),field(-3,_,0) # f1_f2_f3
解析二进制有效载荷并执行关于 FIX(金融信息交换)的健全性检查: - 检查所有标签 ID 和值不为空,并且标签 ID 是有效的数字 - 检查 BeginString 标签是第一个具有有效 FIX 版本的标签 - 检查 BodyLength 标签是第二个具有正确正文长度的标签 - 检查 MsgType 标签是第三个标签。 - 检查消息中的最后一个标签是具有有效校验和的 CheckSum 标签 由于当前的 HAProxy 设计,只能解析客户端和服务器发送的第一个消息。此转换器返回一个布尔值,如果有效载荷包含有效的 FIX 消息,则为 true,否则为 false。另请参见 fix_tag_value 转换器。
示例
tcp-request inspect-delay 10s tcp-request content reject unless { req.payload(0,0),fix_is_valid }
解析一个 FIX(金融信息交换)消息并从标签 <tag> 中提取值。<tag> 可以是一个字符串或一个指向所需标签的整数。任何整数值都被接受,但只有以下字符串被翻译成它们的整数等价物:BeginString、BodyLength、MsgType、SenderCompID、TargetCompID、CheckSum。可以轻松添加更多的标签名。由于当前的 HAProxy 设计,只能解析客户端和服务器发送的第一个消息。此转换器不执行任何消息验证。强烈建议首先使用 fix_is_valid 转换器验证消息。另请参见 fix_is_valid 转换器。
示例
tcp-request inspect-delay 10s tcp-request content reject unless { req.payload(0,0),fix_is_valid } # MsgType 标签 ID 是 35,所以下面两行将返回相同的内容 tcp-request content set-var(txn.foo) req.payload(0,0),fix_tag_value(35) tcp-request content set-var(txn.bar) req.payload(0,0),fix_tag_value(MsgType)
将二进制输入样本转换为十六进制字符串,其中每个输入字节对应两个十六进制数字。它用于以可靠的方式记录或传输某些二进制输入数据的十六进制转储(例如,可以将 SSL ID 复制到标头中)。
将每个输入字节包含两个十六进制数字的十六进制字符串转换为整数。如果输入值无法转换,则返回零。
hmac(<algorithm>,<key>)
使用给定的密钥将二进制输入样本转换为消息认证码。结果是一个二进制样本。<algorithm> 必须是已注册的 OpenSSL 消息摘要名称之一(例如 sha256)。<key> 参数必须是 base64 编码的,并且可以是字符串或变量。请注意,此转换器仅在 HAProxy 使用 USE_OPENSSL 编译时可用。
转换包含 Host 标头值的字符串并移除其端口。输入必须遵守 Host 标头值的格式 (rfc9110#section-7.2)。它将支持以下类型的输入:hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80。此转换器还会将字符串设置为小写。
将输入整数值转换为其网络字节序的 32 位二进制表示。因为样本获取拥有有符号 64 位整数,当使用此转换器时,输入整数值首先被转换为无符号 32 位整数。
http_date([<offset],[<unit>])
将一个假定包含自纪元以来日期的整数转换为适合在 HTTP 标头字段中使用的字符串表示形式。如果指定了偏移值,则在进行转换之前将其添加到日期中。这对于发出 Date 标头字段、响应中与正偏移量结合使用的 Expires 值,或者当偏移量为负时使用的 Last-Modified 值特别有用。如果指定了单位值,则将时间戳视为“s”(秒,默认行为)、“ms”(毫秒)或“us”(微秒)自纪元以来。偏移量假定与输入时间戳具有相同的单位。
iif(<true>,<false>)
如果输入值为 true,则返回 <true> 字符串。否则返回 <false> 字符串。
示例
http-request set-header x-forwarded-proto %[ssl_fc,iif(https,http)]
in_table(<table>)
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回布尔 false。否则,返回布尔 true。这可用于验证表中是否存在某个键,该表跟踪某些元素(例如,是否已看到源 IP 地址或 Authorization 标头)。
ipmask(<mask4>,[<mask6>])
将掩码应用于 IP 地址,并使用结果进行查找和存储。这可用于使某个掩码内的所有主机共享相同的表条目,从而使用相同的服务器。mask4 可以以点分十进制形式(例如 255.255.255.0)或 CIDR 形式(例如 24)传递。mask6 可以以四元组形式(例如 ffff:ffff::)或 CIDR 形式(例如 64)传递。如果未提供 mask6,出于向后兼容的原因,IPv6 地址将转换失败。
json([<input-code>])
转义输入字符串并生成 ASCII 输出字符串,可用于 JSON 字符串。转换器尝试根据 <input-code> 参数解码输入字符串。它可以是 "ascii"、"utf8"、"utf8s"、"utf8p" 或 "utf8ps"。“ascii”解码器永远不会失败。“utf8”解码器检测 3 种类型的错误:- 错误的 UTF-8 序列(孤立的连续字节、错误的连续字节数等)- 无效范围(解码值在 UTF-8 禁止范围内)- 字符过长(值用比必要更多的字节编码)。UTF-8 JSON 编码在 UTF-8 字符大于 0xffff 时可能产生“值过长”错误,因为 JSON 字符串转义规范仅授权 4 个十六进制数字用于值编码。UTF-8 解码器有 4 种变体,由两个后缀字母组合指定:“p”代表“permissive”(宽松)和“s”代表“silently ignore”(静默忽略)。解码器的行为是:- "ascii":永远不会失败;- "utf8":在任何检测到的错误上失败;- "utf8s":永远不会失败,但会删除对应于错误的字符;- "utf8p":接受并修复过长错误,但在任何其他错误上失败;- "utf8ps":永远不会失败,接受并修复过长错误,但会删除对应于其他错误的字符。此转换器对于构建正确转义的 JSON 以记录到使用 JSON 格式流量日志的服务器特别有用。
示例
capture request header Host len 15 capture request header user-agent len 150 log-format '{"ip":"%[src]","user-agent":"%[capture.req.hdr(1),json(utf8s)]"}'
来自客户端 127.0.0.1 的输入请求: GET / HTTP/1.0 User-Agent: Very "Ugly" UA 1/2 输出日志: {"ip":"127.0.0.1","user-agent":"Very \"Ugly\" UA 1\/2"}
json_query(<json_path>,[<output_type>])
json_query 转换器支持 JSON 类型 string、boolean、number 和 array。浮点数将作为字符串返回。通过指定 output_type 'int',该值将被转换为整数。数组将作为字符串返回,以方括号开头和结尾。内容是 CSV。根据数据类型,数组值可能被引用。如果数组值是复杂类型,则字符串包含每个值的完整 json 表示,并用逗号分隔。例如,对 JWT 进行角色查询的结果:["manage-account","manage-account-links","view-profile"]如果无法转换,json_query 转换器将失败。<json_path> 必须是 https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/ 中定义的有效 JSON Path 字符串
示例
# 从请求体中获取一个整数值 # "{"integer":4}" => 5 http-request set-var(txn.pay_int) req.body,json_query('$.integer','int'),add(1) # 获取名称中带'.'的键 # {"my.key":"myvalue"} => myvalue http-request set-var(txn.pay_mykey) req.body,json_query('$.my\\.key') # {"boolean-false":false} => 0 http-request set-var(txn.pay_boolean_false) req.body,json_query('$.boolean-false') # 从JWT Bearer令牌中获取'iss'键的值 http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec,json_query('$.iss')
jwt_header_query([<json_path>],[<output_type>])
当输入为 JSON Web Token (JWT) 时,如果没有提供参数,则返回令牌的已解码头部部分(JWT 的第一个 base64-url 编码部分);否则,对令牌的已解码头部部分执行 json_query 操作。有关接受的 json_path 和 output_type 参数的详细信息,请参见“json_query”转换器。请注意,此转换器仅在 HAProxy 编译时使用了 USE_OPENSSL 时才可用。
jwt_payload_query([<json_path>],[<output_type>])
当输入为 JSON Web Token (JWT) 时,如果没有提供参数,则返回令牌的已解码负载部分(JWT 的第二个 base64-url 编码部分);否则,对令牌的已解码负载部分执行 json_query 操作。有关接受的 json_path 和 output_type 参数的详细信息,请参见“json_query”转换器。请注意,此转换器仅在 HAProxy 编译时使用了 USE_OPENSSL 时才可用。
jwt_verify(<alg>,<key>)
使用 <alg> 算法和 <key> 参数对输入中的 JSON Web Token (JWT) 执行签名验证,<key> 参数应包含密钥或公共证书的路径。验证成功返回 1,验证错误返回 0,任何其他错误返回严格负值。由于所有这些非空错误返回值,此转换器的结果不应转换为布尔值。有关可能的返回值完整列表,请参阅下文。目前,只能处理使用 Compact Serialization 格式的 JWS 令牌(三个由点分隔的 base64-url 编码字符串)。支持 RFC7518 第 3.1 节中提到的所有算法(HS、ES、RS 和 PS,具有 256、384 或 512 密钥大小,以及特殊的“none”情况)。如果使用的算法是 HMAC 家族,<key> 应该是用于 HMAC 签名计算的密钥。否则,<key> 应该是可用于验证令牌签名的公共证书的路径。必须在初始化期间知道所有可能用于验证 JWT 的证书,以便将其添加到专用证书缓存中,从而在运行时无需访问磁盘。因此,任何使用的证书必须至少在 jwt_verify 调用中显式提及一次。因此,不建议将中间变量作为第二个参数传递。此转换器仅验证令牌的签名,不执行 RFC7519 第 7.2 节中指定的完整 JWT 验证。例如,我们不确保标头和负载内容在解码后是完全有效的 JSON,也不对它们各自的内容执行任何检查。可能的返回值如下:+----+----------------------------------------------------------------------+ | ID | message | +----+----------------------------------------------------------------------+ | 0 | "Verification failure" | | 1 | "Verification success" | | -1 | "Unknown algorithm (not mentioned in RFC7518)" | | -2 | "Unmanaged algorithm" | | -3 | "Invalid token" | | -4 | "Out of memory" | | -5 | "Unknown certificate" | +----+----------------------------------------------------------------------+请注意,此转换器仅在 HAProxy 使用 USE_OPENSSL 编译时可用。
示例
# 从授权标头获取 JWT,提取其 JOSE 标头的 "alg" 字段 # 并使用公共证书验证签名 http-request set-var(txn.bearer) http_auth_bearer http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg') http-request deny unless { var(txn.jwt_alg) -m str "RS256" } http-request deny unless { var(txn.bearer),jwt_verify(txn.jwt_alg,"/path/to/crt.pem") 1 }
language(<value>[,<default>])
从 "accept-language" 标头中使用 "req.fhdr" 提取的列表中返回具有最高 q-factor 的值。没有 q-factor 的值其 q-factor 为 1。q-factor 为 0 的值被丢弃。只有属于分号分隔的 <values> 列表中的值才会被考虑。<value> 参数的语法是 "lang[;lang[;lang[;...]]]"。如果没有值与给定列表匹配,并且提供了默认值,则返回默认值。请注意,语言名称在破折号('-')后可能有变体。如果此变体存在于列表中,它将被匹配,但如果不存在,则只检查基础语言。匹配是区分大小写的,输出字符串始终是参数中提供的字符串之一。参数的顺序没有意义,只有请求中值的顺序有意义,因为在共享相同 q-factor 的多个值中,第一个值被使用。
示例
# 此配置根据请求切换到匹配 # 给定语言的后端: acl es req.fhdr(accept-language),language(es;fr;en) -m str es acl fr req.fhdr(accept-language),language(es;fr;en) -m str fr acl en req.fhdr(accept-language),language(es;fr;en) -m str en use_backend spanish if es use_backend french if fr use_backend english if en default_backend choose_your_language
获取字符串的长度。这只能放在字符串样本提取函数或返回字符串类型的转换关键字之后。结果是整数类型。
将字符串样本转换为小写。这只能放在字符串样本获取函数之后或返回字符串类型的转换关键字之后。结果类型为字符串。
ltime(<format>[,<offset>])
将一个应包含自纪元以来日期的整数转换为表示该日期的本地时间的字符串,使用 strftime(3) 定义的 <format> 字符串。目的是允许在日志中使用任何日期格式。可以对输入日期应用一个可选的 <offset>(正或负,以秒为单位)。有关操作系统支持的格式,请参阅 strftime() 手册页。另请参阅 utime 转换器。
示例
# 输出两列,一列是本地时间,另一列是 ip:port # 例如 20140710162350 127.0.0.1:57325 log-format %[date,ltime(%Y%m%d%H%M%S)]\ %ci:%cp
ltrim(<chars>)
从输入样本的字符串表示的开头跳过任何属于 <chars> 的字符。
map(<map_file>[,<default_value>])
map_<match_type>(<map_file>[,<default_value>]) map_<match_type>_<output_type>(<map_file>[,<default_value>])使用 <match_type> 匹配方法在 <map_file> 中搜索输入值,并返回转换为 <output_type> 类型的关联值。如果在 <map_file> 中找不到输入值,则转换器返回 <default_value>。如果未设置 <default_value>,则转换器失败,并表现为无法获取输入值。如果未设置 <match_type>,则默认为“str”。同样,如果未设置 <output_type>,则默认为“str”。为方便起见,“map”关键字是“map_str”的别名,用于将一个字符串映射到另一个字符串。重要的是避免键之间的重叠:IP 地址和字符串存储在树中,因此将使用最精确匹配的第一个匹配。其他键存储在列表中,因此将使用第一个匹配的出现。下表包含按输入类型、匹配类型和输出类型排序的所有可用映射函数的列表。
输入类型匹配方法输出类型 str输出类型 int输出类型 ip
strstrmap_strmap_str_intmap_str_ip
strbegmap_begmap_beg_intmap_end_ip
strsubmap_submap_sub_intmap_sub_ip
strdirmap_dirmap_dir_intmap_dir_ip
strdommap_dommap_dom_intmap_dom_ip
strendmap_endmap_end_intmap_end_ip
strregmap_regmap_reg_intmap_reg_ip
strregmap_regmmap_reg_intmap_reg_ip
intintmap_intmap_int_intmap_int_ip
ipipmap_ipmap_ip_intmap_ip_ip
名为“map_regm”的特殊映射在正则表达式中期望匹配区域,并修改输出,将反向引用(如“\1”)替换为相应的匹配文本。文件包含每行一个键+值。以“#”开头的行被忽略,空行也是如此。删除前导制表符和空格。然后,键是第一个“word”(一系列非空格/制表符字符),值是该系列空格/制表符之后直到行尾的内容,不包括尾随空格/制表符。
示例
# 这是一条注释,会被忽略 2.22.246.0/23 United Kingdom \n <-><-----------><--><------------><----> | | | | `- 尾部空格被忽略 | | | `---------- 值 | | `-------------------- 中间空格被忽略 | `---------------------------- 键 `------------------------------------ 前导空格被忽略
mod(<value>)
将输入的有符号整数值除以 <value>,并将余数作为有符号整数返回。如果 <value> 为 null,则返回零。<value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享 "req" : 变量仅在请求处理期间共享 "res" : 变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
mqtt_field_value(<packettype>,<fieldname_or_property_ID>)
返回在输入 MQTT 负载中找到的 <fieldname> 的值,输入 MQTT 负载的类型为 <packettype>。<packettype> 可以是字符串(不区分大小写匹配)或对应于我们要提取数据的数据包类型的数值。支持的字符串和整数可以在这里找到:https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022<fieldname> 取决于 <packettype>,可以是以下任意一项(请注意,<fieldname> 匹配不区分大小写)。<property id> 只能在 MQTT v5.0 流中找到。查看此表:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901029- CONNECT(或 1):flags, protocol_name, protocol_version, client_identifier, will_topic, will_payload, username, password, keepalive 或任何 property ID 作为数值(仅适用于 MQTT v5.0 数据包):17: Session Expiry Interval 33: Receive Maximum 39: Maximum Packet Size 34: Topic Alias Maximum 25: Request Response Information 23: Request Problem Information 21: Authentication Method 22: Authentication Data 18: Will Delay Interval 1: Payload Format Indicator 2: Message Expiry Interval 3: Content Type 8: Response Topic 9: Correlation Data 暂不支持:38: User Property- CONNACK(或 2):flags, protocol_version, reason_code 或任何 property ID 作为数值(仅适用于 MQTT v5.0 数据包):17: Session Expiry Interval 33: Receive Maximum 36: Maximum QoS 37: Retain Available 39: Maximum Packet Size 18: Assigned Client Identifier 34: Topic Alias Maximum 31: Reason String 40; Wildcard Subscription Available 41: Subscription Identifiers Available 42: Shared Subscription Available 19: Server Keep Alive 26: Response Information 28: Server Reference 21: Authentication Method 22: Authentication Data 暂不支持:38: User Property由于当前 HAProxy 设计,只能解析客户端和服务器发送的第一条消息。因此,此转换器只能从 CONNECT 和 CONNACK 数据包类型中提取数据。CONNECT 是客户端发送的第一条消息,CONNACK 是服务器发送的第一个响应。
示例
acl data_in_buffer req.len ge 4 tcp-request content set-var(txn.username) \ req.payload(0,0),mqtt_field_value(connect,protocol_name) \ if data_in_buffer # 与上面相同 tcp-request content set-var(txn.username) \ req.payload(0,0),mqtt_field_value(1,protocol_name) \ if data_in_buffer
检查二进制输入是否为有效的 MQTT 报文。它返回一个布尔值。由于当前 HAProxy 的设计,只能解析客户端和服务器发送的第一个消息。因此,此转换器只能从 CONNECT 和 CONNACK 报文类型中提取数据。CONNECT 是客户端发送的第一个消息,CONNACK 是服务器发送的第一个响应。仅支持 MQTT 3.1、3.1.1 和 5.0。
示例
acl data_in_buffer req.len ge 4 tcp-request content reject unless { req.payload(0,0),mqtt_is_valid }
ms_ltime(<format>[,<offset>])
此转换器功能类似“ltime”,但输入单位是毫秒。它还支持受 date(1) 启发的 %N 转换说明符。将一个假定包含自纪元以来日期的整数,使用由 <format> 字符串定义的格式,通过 strftime(3) 转换为表示本地时间的字符串。目的是允许在日志中使用任何日期格式。可以对输入日期应用一个可选的以毫秒为单位的 <offset>(正或负)。有关您的操作系统支持的格式,请参见 strftime() 手册页。%N 转换说明符允许您输出日期的纳秒部分,但由于输入是毫秒,精度有限 (000000000..999000000)。%N 可以在 % 和 N 之间接受一个宽度参数。这对于显示毫秒 (%3N) 或微秒 (%6N) 很有用。默认和最大宽度为 9 (%N = %9N)。另请参见用于 UTC 的 utime 转换器,以及“ltime”和“us_ltime”转换器。
示例
# 输出 3 列,本地时间、时区和另一列 ip:port # 例如 2023/07/24/11:53:02.196 +0200 127.0.0.1:41530 log-format %[accept_date(ms),ms_ltime("%Y/%m/%d/%H:%M:%S.%3N %z")]\ %ci:%cp
ms_utime(<format>[,<offset>])
此转换器功能类似“utime”,但输入单位是毫秒。它还支持受 date(1) 启发的 %N 转换说明符。将一个假定包含自纪元以来日期的整数,使用由 <format> 字符串定义的格式,通过 strftime(3) 转换为表示 UTC 时间的字符串。目的是允许在日志中使用任何日期格式。可以对输入日期应用一个可选的以毫秒为单位的 <offset>(正或负)。有关您的操作系统支持的格式,请参见 strftime() 手册页。%N 转换说明符允许您输出日期的纳秒部分,但由于输入是毫秒,精度有限 (000000000..999000000)。%N 可以在 % 和 N 之间接受一个宽度参数。这对于显示毫秒 (%3N) 或微秒 (%6N) 很有用。默认和最大宽度为 9 (%N = %9N)。另请参见用于本地时间的 ltime 转换器,以及“utime”和“us_utime”转换器。
示例
# 输出 3 列,UTC 时间、时区和另一列 ip:port # 例如 2023/07/24/09:53:02.196 +0000 127.0.0.1:41530 log-format %[accept_date(ms),ms_utime("%Y/%m/%d/%H:%M:%S.%3N %z")]\ %ci:%cp
mul(<value>)
将输入的有符号整数值乘以 <value>,并将乘积作为有符号整数返回。在溢出的情况下,将返回符号的最大可能值,以便操作不会环绕。<value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享 "req" : 变量仅在请求处理期间共享 "res" : 变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
接受一个字符串类型的输入值,将其解释为后端名称,并返回该后端中可用服务器的数量。可用于需要从动态名称(如 map 查找的结果)查找后端的地方。
获取类型为有符号整数的输入值,计算其相反值,并以有符号整数的形式返回余数。0 是单位元。此运算符用于反向减法:为了从一个常量中减去输入值,只需执行 "neg,add(value)"。
如果输入的有符号整数值非零,则返回布尔值 FALSE,否则返回 TRUE。与 and() 结合使用,可用于报告输入值的位测试结果是真还是假(例如,验证某个标志是否存在)。
如果类型为有符号整数的输入值为奇数,则返回布尔值 TRUE,否则返回 FALSE。它在功能上等同于 "and(1),bool"。
or(<value>)
对 <value> 和输入的有符号整数值执行按位“OR”操作,并将结果作为有符号整数返回。<value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享 "req" : 变量仅在请求处理期间共享 "res" : 变量仅在响应处理期间共享 此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
param(<name>,[<delim>])
这会提取输入字符串中 <name> 参数的第一个匹配项,其中参数由 <delim> 分隔,默认为“&”,参数的名称和值由“=”分隔。如果在参数段结束之前没有“=”和值,则将其视为等同于空字符串值。这对于从查询字符串或可能是 x-www-form-urlencoded 正文提取参数很有用。特别是,`query,param(<name>)` 可以用作 `urlp(<name>)` 的替代方案,后者仅使用“&”作为分隔符,而“urlp”还使用“?”和“;”。请注意,此转换器不会对 URL 编码字符执行任何特殊操作。如果要解码值,可以在输出上使用 url_dec 转换器。如果输入中的参数名称可能包含编码字符,您可能需要在调用“param”之前对输入进行规范化。这可以通过使用“http-request normalize-uri”(特别是 percent-decode-unreserved 和 percent-to-uppercase 选项)来完成。
示例
str(a=b&c=d&a=r),param(a) # b str(a&b=c),param(a) # "" str(a=&b&c=a),param(b) # "" str(a=1;b=2;c=4),param(b,;) # 2 query,param(redirect_uri),urldec()
将包含 Host 标头值的字符串转换为一个整数,方法是返回其端口。输入必须遵循 Host 标头值的格式 (rfc9110#section-7.2)。它将支持以下类型的输入:hostname, hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80。如果输入中未提供端口,它将返回 0。
protobuf(<field_number>,[<field_type>])
这会以原始模式提取输入二进制样本表示的协议缓冲区消息字段,如果不存在 <field_type>,则使用 <field_number> 作为字段编号(点表示法),如果存在此字段,则作为整数样本(另请参见下面的“ungrpc”)。授权类型列表如下:“int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”用于“varint”线型 0、“fixed64”、“sfixed64”、“double”用于 64 位线型 1、“fixed32”、“sfixed32”、“float”用于线型 5。请注意,“string”被视为长度分隔类型,因此不需要任何 <field_type> 参数来提取。有关协议缓冲区消息字段类型的更多信息,请参阅此处:https://developers.google.com/protocol-buffers/docs/encoding
regsub(<regex>,<subst>[,<flags>])
对输入字符串应用基于正则表达式的替换。它执行与众所周知的 "sed" 工具中 "s/<regex>/<subst>/" 相同的操作。默认情况下,它将用替换字符串 <subst> 替换输入字符串中与正则表达式 <regex> 匹配的最大部分的第一个匹配项。通过在第三个参数 <flags> 中添加标志 "g",可以替换所有匹配项。通过在 <flags> 中添加标志 "i",可以使正则表达式不区分大小写。由于 <flags> 是一个字符串,它由所有所需标志的连接组成。因此,如果需要 "i" 和 "g",使用 "gi" 或 "ig" 将具有相同的效果。此转换器的主要用途是替换某些字符或字符序列。强烈建议使用受保护的引号将正则表达式部分括起来,以提高清晰度,并避免正则表达式中的右括号与函数中的括号混淆。就像在 Bourne shell 中一样,第一级引号在行上定界单词组时进行处理,第二级引号可用于参数。建议在外部使用单引号,因为它们不会尝试解析反斜杠或美元符号。
示例
# 去除 "x-path" 标头中的重复 "/"。 # 输入: x-path: /////a///b/c/xzxyz/ # 输出: x-path: /a/b/c/xzxyz/ http-request set-header x-path "%[hdr(x-path),regsub('/+','/','g')]" # 将查询字符串复制到 x-query 并删除所有前导的 '?', ';' 和 '&' http-request set-header x-query "%[query,regsub([?;&]*,'')]" # 捕获组和反向引用 # 两行代码作用相同。 http-request redirect location %[url,'regsub("(foo|bar)([0-9]+)?","\2\1",i)'] http-request redirect location %[url,regsub(\"(foo|bar)([0-9]+)?\",\"\2\1\",i)]
rfc7239_field(<field>)
从符合 RFC 7239 的标头值输入中提取单个字段/参数。支持的字段有: - proto: 'http' 或 'https' - host: http 兼容的主机 - for: RFC7239 节点 - by: RFC7239 节点 更多信息请见:https://www.rfc-editor.org/rfc/rfc7239.html#section-6
示例
# 从 forwarded 标头中提取 host 字段并将其存储在 req.fhost 变量中 http-request set-var(req.fhost) req.hdr(forwarded),rfc7239_field(host) #输入: "proto=https;host=\"haproxy.org:80\"" # 输出: "haproxy.org:80" # 从 forwarded 标头中提取 for 字段并将其存储在 req.ffor 变量中 http-request set-var(req.ffor) req.hdr(forwarded),rfc7239_field(for) #输入: "proto=https;host=\"haproxy.org:80\";for=\"127.0.0.1:9999\"" # 输出: "127.0.0.1:9999"
如果输入标头是符合 RFC 7239 的标头值,则返回 true,否则返回 false。
示例
acl valid req.hdr(forwarded),rfc7239_is_valid #输入: "for=127.0.0.1;proto=http" # 输出: TRUE #输入: "proto=custom" # 输出: FALSE
将 RFC7239 节点(由 'for' 或 'by' 7239 标头字段提供)转换为其对应的最终节点名称形式: - ipv4 地址 - ipv6 地址 - 'unknown' - '_obfs' 标识符
示例
# 从 forwarded 标头中提取 'for' 字段,从 # 结果节点标识符中提取节点名,并将结果存储在 req.fnn 中 http-request set-var(req.fnn) req.hdr(forwarded),rfc7239_field(for),rfc7239_n2nn #输入: "127.0.0.1:9999" # 输出: 127.0.0.1 (ipv4) #输入: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998" # 输出: ab:cd:ff:ff:ff:ff:ff:ff (ipv6) #输入: "_name:_port" # 输出: "_name" (string)
将 RFC7239 节点(由 'for' 或 'by' 7239 标头字段提供)转换为其对应的最终节点端口形式: - 无符号整数 - '_obfs' 标识符
示例
# 从 forwarded 标头中提取 'by' 字段,从 # 结果节点标识符中提取节点端口,并将结果存储在 req.fnp 中 http-request set-var(req.fnp) req.hdr(forwarded),rfc7239_field(by),rfc7239_n2np #输入: "127.0.0.1:9999" # 输出: 9999 (integer) #输入: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998" # 输出: 9998 (integer) #输入: "_name:_port" # 输出: "_port" (string)
rtrim(<chars>)
从输入样本的字符串表示的末尾跳过任何属于 <chars> 的字符。
sdbm([<avalanche>])
使用 SDBM 哈希函数将二进制输入样本哈希成一个无符号 32 位整数。可选地,如果可选的 <avalanche> 参数等于 1,可以对输出应用一个完整的雪崩哈希函数。此转换器使用与各种基于哈希的负载均衡算法相同的函数,因此它将提供完全相同的结果。它主要用于调试,但可以用作粘滞表条目来收集粗略的统计数据。它不应用于安全目的,因为 32 位哈希很容易被破解。另请参见“crc32”、“djb2”、“wt6”、“crc32c”和“hash-type”指令。
将 <var> 的内容与输入值进行比较。两个值都被视为二进制字符串。返回一个布尔值,指示两个二进制字符串是否匹配。如果两个二进制字符串长度相同,则比较将在恒定时间内执行。请注意,此转换器仅在 HAProxy 编译时使用了 USE_OPENSSL 时才可用。
示例
http-request set-var(txn.token) hdr(token) # 检查客户端发送的令牌是否与密钥令牌 # 的值匹配,而不会通过时间攻击泄露内容。 acl token_given str(my_secret_token),secure_memcmp(txn.token)
set-var(<var>[,<cond>...])
使用输入内容设置变量,如果所有指定条件都为 true(有关可能的条件列表,请参阅下文),则按原样返回内容。变量保留值和关联的输入类型。变量名称以指示其范围的前缀开头。允许的范围是:“proc”:变量与整个进程共享“sess”:变量与整个会话共享“txn”:变量与事务共享(请求和响应)“req”:变量仅在请求处理期间共享“res”:变量仅在响应处理期间共享。此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。您可以向转换器传递最多四个条件,这些条件包括:- "ifexists"/"ifnotexists":检查变量在当前 set-var 调用之前是否已存在。变量通常是通过成功的 set-var 调用创建的。请注意,范围为“proc”的变量是在配置解析期间创建的,因此“ifexists”条件对它们始终为 true。- "ifempty"/"ifnotempty":检查输入是否为空。标量类型永远不为空,因此无论输入内容如何(整数、布尔值、IP 等),ifempty 条件都将为 false。- "ifset"/"ifnotset":检查变量以前是否已设置,或者是否对变量调用了 unset-var。尚未存在的变量被视为未设置。一个“proc”变量可以存在但未设置,因为它们是在配置解析期间创建的。- "ifgt"/"iflt":检查变量内容是否“大于”或“小于”输入。此检查只能在输入和变量都是整数类型时执行。否则,检查默认为 true。
将二进制输入样本转换为 SHA-1 摘要。结果是一个长度为 20 字节的二进制样本。
sha2([<bits>])
将二进制输入样本转换为 SHA-2 家族的摘要。结果是一个长度为 <bits>/8 字节的二进制样本。<bits> 的有效值为 224、256、384、512,分别对应 SHA-<bits>。默认值为 256。请注意,此转换器仅在 HAProxy 编译时使用了 USE_OPENSSL 时才可用。
接受字符串类型的输入值,可以是服务器名称或 <backend>/<server> 格式,并返回该服务器上排队流的数量。当需要从动态名称(如 cookie 值,例如 req.cook(SRVID),srv_queue)查找排队流并据此做出决定以打破持久性或将请求定向到其他地方时,可以使用它。
strcmp(<var>)
将 <var> 的内容与字符串类型的输入值进行比较。返回一个与 strcmp(3) 兼容的有符号整数结果:如果两个字符串相同,则为 0。如果左侧字符串在字典序上小于右侧字符串或左侧字符串更短,则返回小于 0 的值。否则返回大于 0 的值(右侧字符串大于左侧字符串或右侧字符串更短)。如果您需要以恒定时间比较两个二进制字符串,另请参见 secure_memcmp 转换器。
示例
http-request set-var(txn.host) hdr(host) # 检查客户端是否正在尝试域前置(domain fronting)。 acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0
sub(<value>)
从输入的有符号整数值中减去 <value>,并将结果作为有符号整数返回。注意:为了从常量中减去输入,只需执行“neg,add(value)”。<value> 可以是数值或变量名。变量名以其作用域的指示开头。允许的作用域有:"proc" : 变量与整个进程共享 "sess" : 变量与整个会话共享 "txn" : 变量与事务(请求和响应)共享,"req" : 变量仅在请求处理期间共享,"res" : 变量仅在响应处理期间共享。此前缀后跟一个名称。分隔符是“.”。名称只能包含字符 'a-z'、'A-Z'、'0-9'、'.' 和 '_'。
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中输入样本关联的平均客户端到服务器字节速率,以字节量/周期(在表中配置)衡量。另请参阅 sc_bytes_in_rate 样本获取关键字。
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中输入样本关联的平均服务器到客户端字节速率,以字节量/周期(在表中配置)衡量。另请参阅 sc_bytes_out_rate 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回与指定表中输入样本关联的传入连接的累积数量。另请参见 sc_conn_cnt 样本获取关键字。
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中输入样本关联的当前并发跟踪连接数。另请参阅 sc_conn_cur 样本获取关键字。
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中输入样本关联的平均传入连接速率。另请参阅 sc_conn_rate 样本获取关键字。
table_expire(<table>[,<default_value>])
使用输入样本在指定表中进行查找。如果在表中找不到键,则转换器将失败,除非设置了 <default_value>:这会使转换器成功并返回 <default_value>。如果找到键,则转换器将返回与指定表中输入样本关联的键过期延迟。另请参见 table_idle 样本获取关键字。
table_gpc(<idx>,<table>)
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的数组中索引为 <idx> 的通用目的计数器的当前值。<idx> 是介于 0 和 99 之间的整数。如果在此索引处没有存储 GPC,它还将返回布尔值 0。这仅适用于“gpc”数组数据类型(而不适用于旧版“gpc0”或“gpc1”数据类型)。另请参见 sc_get_gpc 样本获取关键字。
table_gpc0(<table>)
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中输入样本关联的第一个通用目的计数器的当前值。另请参阅 sc_get_gpc0 样本获取关键字。
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回在表中配置的周期内 gpc0 计数器递增的频率,与指定表中输入样本相关联。另请参阅 sc_get_gpc0_rate 样本获取关键字。
table_gpc1(<table>)
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的第二个通用目的计数器的当前值。另请参见 sc_get_gpc1 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的 gpc1 计数器在表中配置的时间段内增量的频率。另请参见 sc_get_gpc1_rate 样本获取关键字。
table_gpc_rate(<idx>,<table>)
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表(stick-table)中与输入样本关联的数组中索引为 <idx> 的全局目的计数器在配置的时间段内增量的频率。<idx> 是介于 0 和 99 之间的整数。如果在此索引处没有存储 gpc_rate,它还将返回布尔值 0。这仅适用于“gpc_rate”数组数据类型(而不适用于旧版“gpc0_rate”或“gpc1_rate”数据类型)。另请参见 sc_gpc_rate 样本获取关键字。
table_gpt(<idx>,<table>)
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回布尔值零。否则,转换器将返回指定表中与输入样本关联的数组中索引为 <idx> 的通用目的标签的当前值。<idx> 是介于 0 和 99 之间的整数。如果在此索引处没有存储 GPT,它还将返回布尔值 0。这仅适用于“gpt”数组数据类型(而不适用于旧版“gpt0”数据类型)。另请参见 sc_get_gpt 样本获取关键字。
table_gpt0(<table>)
使用输入样本的字符串表示形式在指定的表中执行查找。如果在表中找不到键,则返回布尔值零。否则,转换器返回与指定表中输入样本关联的第一个通用目的标签的当前值。另请参阅 sc_get_gpt0 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的 HTTP 错误累积数量。另请参见 sc_http_err_cnt 样本获取关键字。
使用输入样本的字符串表示形式在指定表中执行查找。如果在表中找不到键,则返回整数值零。否则,返回与指定表中的输入样本关联的 HTTP 错误的平均速率,以表中配置的时间段内的错误数量来衡量。另请参阅 sc_http_err_rate 样本提取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的 HTTP 故障累积数量。另请参见 sc_http_fail_cnt 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的 HTTP 故障平均速率,该速率在表中配置的时间段内测量。另请参见 sc_http_fail_rate 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的 HTTP 请求累积数量。另请参见 sc_http_req_cnt 样本获取关键字。
使用输入样本的字符串表示形式在指定表中执行查找。如果在表中找不到键,则返回整数值零。否则,返回与指定表中的输入样本关联的 HTTP 请求的平均速率,以表中配置的时间段内的请求数量来衡量。另请参阅 sc_http_req_rate 样本提取关键字。
table_idle(<table>[,<default_value>])
使用输入样本在指定表中进行查找。如果在表中找不到键,则转换器将失败,除非设置了 <default_value>:这会使转换器成功并返回 <default_value>。如果找到键,则转换器将返回自上次更新以来,指定表中与输入样本关联的键条目的空闲时间。另请参见 table_expire 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的客户端到服务器数据的累积数量,以千字节为单位。当前测试是在 32 位整数上进行的,这会将值限制在 4 TB。另请参见 sc_kbytes_in 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的服务器到客户端数据的累积数量,以千字节为单位。当前测试是在 32 位整数上进行的,这会将值限制在 4 TB。另请参见 sc_kbytes_out 样本获取关键字。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的服务器 ID。当连接到服务器成功时,服务器 ID 通过“stick”规则进行关联。服务器 ID 零表示没有与此键关联的服务器。
使用输入样本的字符串表示形式在指定表中进行查找。如果在表中找不到键,则返回整数值零。否则,转换器将返回指定表中与输入样本关联的传入会话的累积数量。请注意,此处会话是指由“tcp-request connection”规则集接受的传入连接。另请参见 sc_sess_cnt 样本获取关键字。
使用输入样本的字符串表示形式在指定表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回与指定表中的输入样本关联的平均传入会话速率。请注意,此处的会话指的是被“tcp-request connection”规则集接受的传入连接。另请参阅 sc_sess_rate 样本提取关键字。
使用输入样本的字符串表示形式在指定表中执行查找。如果在表中找不到键,则返回整数值零。否则,转换器返回在指定表中跟踪与输入样本相同键的当前并发连接数。它与 table_conn_cur 的不同之处在于,它不依赖任何存储的信息,而是依赖于表的引用计数(即在 CLI 上通过“show table”返回的“use”值)。这有时可能更适合于第 7 层跟踪。例如,它可以用来告诉服务器来自给定地址的并发连接数。另请参阅 sc_trackers 样本提取关键字。
此转换器是 b64dec 转换器的 base64url 变体。base64url 编码是 base64 编码的“URL 和文件名安全字母表”变体。它也是 JWT (JSON Web Token) 标准中使用的编码。
示例
# 解码 JWT 负载: http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec
此转换器是 base64 转换器的 base64url 变体。
ungrpc(<field_number>,[<field_type>])
这会以原始模式提取输入二进制样本表示的 gRPC 消息字段,如果不存在 <field_type>,则使用 <field_number> 作为字段编号(点表示法),如果存在此字段,则作为整数样本。授权类型列表如下:“int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”用于“varint”线型 0、“fixed64”、“sfixed64”、“double”用于 64 位线型 1、“fixed32”、“sfixed32”、“float”用于线型 5。请注意,“string”被视为长度分隔类型,因此不需要任何 <field_type> 参数来提取。有关协议缓冲区消息字段类型的更多信息,请参阅此处:https://developers.google.com/protocol-buffers/docs/encoding
示例
// 这是一个根据 // https://github.com/grpc/grpc/blob/master/examples/protos/route_guide.proto 改编的 protocol buffer .proto 文件内容 message Point { int32 latitude = 1; int32 longitude = 2; } message PPoint { Point point = 59; } message Rectangle { // 矩形的一个角。 PPoint lo = 48; // 矩形的另一个角。 PPoint hi = 49; }
假设主体请求由一个“Rectangle”对象值(两个 PPoint 协议缓冲区消息)组成,这四个协议缓冲区字段可以使用这些“ungrpc”指令提取:req.body,ungrpc(48.59.1,int32) # “lo”第一个 PPoint 的“latitude”req.body,ungrpc(48.59.2,int32) # “lo”第一个 PPoint 的“longitude”req.body,ungrpc(49.59.1,int32) # “hi”第二个 PPoint 的“latitude”req.body,ungrpc(49.59.2,int32) # “hi”第二个 PPoint 的“longitude”我们还可以按如下方式将中间的 48.59 字段提取为二进制样本:req.body,ungrpc(48.59)由于 gRPC 消息始终由 gRPC 标头后跟协议缓冲区消息组成,在前面的示例中,“lo”第一个 PPoint 的“latitude”可以使用这些等效指令提取:req.body,ungrpc(48.59),protobuf(1,int32)req.body,ungrpc(48),protobuf(59.1,int32)req.body,ungrpc(48),protobuf(59),protobuf(1,int32)请注意,第一个转换器必须是“ungrpc”,其余的必须是“protobuf”,并且只有最后一个可以有或没有第二个参数来解释前一个二进制样本。
unset-var(<var>)
如果输入内容已定义,则取消设置变量。变量名以指示其范围的指示符开头。允许的作用域是:“proc”:变量与整个进程共享;“sess”:变量与整个会话共享;“txn”:变量与事务(请求和响应)共享;“req”:变量仅在请求处理期间共享;“res”:变量仅在响应处理期间共享。此前缀后跟一个名称。分隔符是“.”。名称只能包含字符“a-z”、“A-Z”、“0-9”、“.”和“_”。
将字符串样本转换为大写。这只能放在字符串样本提取函数之后或返回字符串类型的转换关键字之后。结果为字符串类型。
url_dec([<in_form>])
接受一个经过 URL 编码的字符串作为输入,并返回其解码后的版本作为输出。输入和输出的类型都是字符串。如果将 <in_form> 参数设置为非零整数值,则假定输入字符串是表单或查询字符串的一部分,并且“+”字符将被转换为空格(' ')。否则,只有在表示查询字符串的问号(“?”)之后才会发生这种情况。
url_enc([<enc_type>])
接受一个字符串作为输入,并返回其编码后的版本作为输出。输入和输出的类型都是字符串。默认情况下,编码类型用于`query`类型。目前不支持其他类型,但可选参数是为了将来的更改而保留的。
us_ltime(<format>[,<offset>])
这与“ltime”类似,但输入以微秒为单位。它还支持受 date(1) 启发的 %N 转换说明符。将一个被认为是自纪元以来的日期的整数转换为表示该日期的本地时间字符串,使用 strftime(3) 定义的 <format> 字符串。目的是允许在日志中使用任何日期格式。可选的 <offset>(微秒,正或负)可以应用于输入日期。有关您的操作系统支持的格式,请参阅 strftime() 手册页。%N 转换说明符允许您输出日期的纳秒部分,精度有限,因为输入是微秒。(000000000..999999000)。%N 可以在 % 和 N 之间使用宽度参数。它对于显示毫秒 (%3N) 或微秒 (%6N) 非常有用。默认和最大宽度为 9 (%N = %9N)。另请参阅 UTC 的“utime”转换器以及“ltime”和“ms_ltime”转换器。
示例
# 输出 3 个部分:本地时间、时区和另一个包含 ip:port 的部分 # 例如 2023/07/24/09:53:02.196234 +0000 127.0.0.1:41530 log-format %[accept_date(us),us_ltime("%Y/%m/%d/%H:%M:%S.%6N %z")]\ %ci:%cp
us_utime(<format>[,<offset>])
这与“utime”类似,但输入以微秒为单位。它还支持受 date(1) 启发的 %N 转换说明符。将一个被认为是自纪元以来的日期的整数转换为表示该日期的 UTC 时间字符串,使用 strftime(3) 定义的 <format> 字符串。目的是允许在日志中使用任何日期格式。可选的 <offset>(微秒,正或负)可以应用于输入日期。有关您的操作系统支持的格式,请参阅 strftime() 手册页。%N 转换说明符允许您输出日期的纳秒部分,精度有限,因为输入是微秒。(000000000..999999000)。%N 可以在 % 和 N 之间使用宽度参数。它对于显示毫秒 (%3N) 或微秒 (%6N) 非常有用。默认和最大宽度为 9 (%N = %9N)。另请参阅本地时间的“ltime”转换器以及“utime”和“ms_utime”转换器。
示例
# 输出 3 个部分:UTC 时间、时区和另一个包含 ip:port 的部分 # 例如 2023/07/24/09:53:02.196234 +0000 127.0.0.1:41530 log-format %[accept_date(us),us_utime("%Y/%m/%d/%H:%M:%S.%6N %z")]\ %ci:%cp
utime(<format>[,<offset>])
将一个应包含自纪元以来日期的整数,使用由 <format> 字符串定义的格式,通过 strftime(3) 转换为表示 UTC 时间的字符串。目的是允许在日志中使用任何日期格式。可以对输入日期应用一个可选的 <offset>(单位为秒,可正可负)。有关您的操作系统支持的格式,请参阅 strftime() 手册页。另请参阅“ltime”转换器以及“ms_utime”和“us_utime”。
示例
# 输出两个部分,一个包含 UTC 时间,另一个包含 ip:port # 例如 20140710162350 127.0.0.1:57325 log-format %[date,utime(%Y%m%d%H%M%S)]\ %ci:%cp
word(<index>,<delimiters>[,<count>])
根据给定的分隔符,从输入字符串中提取从头开始(正索引)或从尾开始(负索引)计数的第 n 个单词。索引从 1 或 -1 开始,分隔符是格式化为字符串的字符列表。空单词会被跳过。这意味着输入字符串开头或结尾的分隔符会被忽略,输入字符串内的连续分隔符被视为单个分隔符。您可以选择性地指定要提取的单词数 <count>(默认为 1)。值为 0 表示提取所有剩余的单词。
示例
str(f1_f2_f3__f5),word(4,_) # f5 str(f1_f2_f3__f5),word(5,_) # <未找到> str(f1_f2_f3__f5),word(2,_,0) # f2_f3__f5 str(f1_f2_f3__f5),word(3,_,2) # f3__f5 str(f1_f2_f3__f5),word(-2,_,3) # f1_f2_f3 str(f1_f2_f3__f5),word(-3,_,0) # f1_f2 str(/f1/f2/f3/f4),word(1,/) # f1 str(/f1////f2/f3/f4),word(1,/) # f2
wt6([<avalanche>])
使用 WT6 哈希函数将二进制输入样本哈希为一个无符号 32 位整数。可选地,如果可选的 <avalanche> 参数等于 1,则可以对输出应用全雪崩哈希函数。此转换器使用与各种基于哈希的负载均衡算法相同的函数,因此它将提供完全相同的结果。它主要用于调试,但可以用作粘滞表条目以收集粗略的统计数据。它不得用于安全目的,因为 32 位哈希很容易被破解。另请参阅“crc32”、“djb2”、“sdbm”、“crc32c”和“hash-type”指令。
将数值转换为其对应的 X509_V_ERR 常量名称。这在 ACL 中很有用,以便在不同版本的 OpenSSL 中配置都能正常工作,因为某些代码可能会随着版本更改而更改。当找不到相应的常量名称时,将数值作为字符串输出。OpenSSL 提供的常量列表可以在这里找到:https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get_error.html#ERROR-CODES 请务必阅读正确 OpenSSL 版本的页面。
示例
bind :443 ssl crt common.pem ca-file ca-auth.crt verify optional crt-ignore-err X509_V_ERR_CERT_REVOKED,X509_V_ERR_CERT_HAS_EXPIRED acl cert_expired ssl_c_verify,x509_v_err_str -m str X509_V_ERR_CERT_HAS_EXPIRED acl cert_revoked ssl_c_verify,x509_v_err_str -m str X509_V_ERR_CERT_REVOKED acl cert_ok ssl_c_verify,x509_v_err_str -m str X509_V_OK http-response add-header X-SSL Ok if cert_ok http-response add-header X-SSL Expired if cert_expired http-response add-header X-SSL Revoked if cert_revoked http-response add-header X-SSL-verify %[ssl_c_verify,x509_v_err_str]
xor(<value>)
对 <value> 和类型为有符号整数的输入值执行按位“XOR”(异或)操作,并将结果作为有符号整数返回。<value> 可以是数字值或变量名。变量名以指示其范围的指示符开头。允许的作用域是:“proc”:变量与整个进程共享;“sess”:变量与整个会话共享;“txn”:变量与事务(请求和响应)共享;“req”:变量仅在请求处理期间共享;“res”:变量仅在响应处理期间共享。此前缀后跟一个名称。分隔符是“.”。名称只能包含字符“a-z”、“A-Z”、“0-9”、“.”和“_”。
xxh3([<seed>])
使用 XXhash 哈希函数的 XXH3 64 位变体将二进制输入样本哈希为一个有符号 64 位整数。此哈希支持一个种子,默认为零,但可以通过 <seed> 参数传递不同的值。此哈希以其优异性能和极快速度而闻名,因此可用于哈希 URL 和/或 URL 参数,作为粘滞表键来收集具有低碰撞率的统计数据,但必须注意,该算法不被认为是密码学安全的。
xxh32([<seed>])
使用 XXHash 哈希函数的 32 位变体将二进制输入样本哈希为一个无符号 32 位整数。此哈希支持一个种子,默认为零,但可以通过 <seed> 参数传递不同的值。此哈希以其优异性能和极快速度而闻名,因此可用于哈希 URL 和/或 URL 参数,作为粘滞表键来收集具有低碰撞率的统计数据,但必须注意,该算法不被认为是密码学安全的。
xxh64([<seed>])
使用 XXHash 哈希函数的 64 位变体将二进制输入样本哈希为一个有符号 64 位整数。此哈希支持一个种子,默认为零,但可以通过 <seed> 参数传递不同的值。此哈希以其优异性能和极快速度而闻名,因此可用于哈希 URL 和/或 URL 参数,作为粘滞表键来收集具有低碰撞率的统计数据,但必须注意,该算法不被认为是密码学安全的。

7.3.2. 从内部状态提取样本

第一组样本提取方法适用于甚至与任何客户端信息都无关的内部信息。这些有时与“monitor fail”指令一起使用,以向外部观察者报告内部状态。本节中描述的样本提取方法可在任何地方使用。本节中样本提取方法及其各自类型的摘要
关键字输出类型
act_conn整数
acl([!]<name>[,...])布尔
always_false布尔
always_true布尔
avg_queue([<backend>])整数
be_conn([<backend>])整数
be_conn_free([<backend>])整数
be_sess_rate([<backend>])整数
bin(<hex>)bin
bool(<bool>)bool
connslots([<backend>])整数
cpu_calls整数
cpu_ns_avg整数
cpu_ns_tot整数
date([<offset>],[<unit>])整数
date_us整数
env(<name>)字符串
fe_conn([<frontend>])整数
fe_req_rate([<frontend>])整数
fe_sess_rate([<frontend>])整数
关键字输出类型
hostname字符串
int(<integer>)signed
ipv4(<ipv4>)ipv4
ipv6(<ipv6>)ipv6
last_rule_file字符串
last_rule_line整数
lat_ns_avg整数
lat_ns_tot整数
meth(<method>)method
nbsrv([<backend>])整数
prio_class整数
prio_offset整数
pid整数
proc整数
queue([<backend>])整数
quic_enabled布尔
rand([<range>])整数
srv_conn([<backend>/]<server>)整数
srv_conn_free([<backend>/]<server>)整数
srv_is_up([<backend>/]<server>)布尔
关键字输出类型
srv_queue([<backend>/]<server>)整数
srv_sess_rate([<backend>/]<server>)整数
srv_iweight([<backend>/]<server>)整数
srv_uweight([<backend>/]<server>)整数
srv_weight([<backend>/]<server>)整数
stopping布尔
str(<string>)字符串
table_avl([<table>])整数
table_cnt([<table>])整数
thread整数
txn.id32整数
txn.conn_retries整数
txn.sess_term_state字符串
uuid([<version>])字符串
var(<var-name>[,<default>])undefined
wait_end布尔
详细列表
act_conn : integer
返回进程上的活动并发连接总数。
acl([!]<name>[,...]) : boolean
如果所有指定 ACL 的评估结果都为 true,则返回 true,否则返回 false。最多可以提供 12 个 ACL,每个 ACL 用逗号分隔。每个指定的 ACL 都可以以“!”为前缀来反转结果。如果任何评估产生错误,则样本也返回错误。请注意,HAProxy 不会对引用的 ACL 执行任何验证检查,例如在响应上下文中使用使用 http 请求样本的 ACL。此行为将来可能会更改。
always_false : 布尔值
始终返回布尔值“false”。在调整配置时,它可以与 ACL 一起用作另一个 ACL 的临时替代品。
always_true : 布尔值
始终返回布尔值“true”。在调整配置时,它可以与 ACL 一起用作另一个 ACL 的临时替代品。
avg_queue([<backend>]) : 整数
返回指定后端排队连接总数除以活动服务器数量的值。如果未指定后端,则使用当前后端。这与“queue”非常相似,只是考虑了场的大小,以便更准确地测量新连接处理所需的时间。主要用途是与 ACL 一起使用,以便在新用户确定将获得降级服务时返回抱歉页面,或者将其传递给后端服务器的标头,以便他们决定在降级模式下工作或禁用某些功能以加快处理速度。请注意,如果不再有任何活动服务器,则排队连接数的两倍将被视为测量值。这是一个公平的估计,因为我们预计一台服务器很快会恢复,但我们仍然更愿意将新流量发送到另一个状况更好的后端。另请参阅“queue”、“be_conn”和“be_sess_rate”样本获取。
be_conn([<backend>]) : 整数
适用于后端上当前已建立的连接数,可能包括正在评估的连接。如果未指定后端名称,则使用当前后端。但也可以检查另一个后端。当标称服务器组已满时,它可用于使用特定的服务器组。另请参见“fe_conn”、“queue”、“be_conn_free”和“be_sess_rate”标准。
be_conn_free([<backend>]) : integer
返回一个整数值,对应于后端中可用服务器上的可用连接数。不包括队列槽位。也不包括备份服务器,除非所有其他服务器都已关闭。如果未指定后端名称,则使用当前后端。但也可以检查另一个后端。当标称服务器组已满时,它可用于使用特定的服务器组。另请参见“be_conn”、“connslots”和“srv_conn_free”标准。其他注意事项和说明:如果任何服务器的 maxconn 或 maxqueue 为 0(表示无限制),则此提取显然没有意义,在这种情况下返回的值将为 -1。
be_sess_rate([<backend>]) : 整数
返回一个整数值,对应于后端上的会话创建速率,以每秒新会话数表示。这与 ACL 一起使用,以便在昂贵或脆弱的后端达到过高的会话速率时切换到备用后端,或限制服务滥用(例如防止在线词典被爬取)。使用 log-format 指令将此元素添加到日志中也很有用。
示例
# 如果字典请求过于频繁,则重定向到错误页面 backend dynamic mode http acl being_scanned be_sess_rate gt 100 redirect location /denied.html if being_scanned
bin(<hex>) : bin
返回一个二进制链。输入是字符串的十六进制表示。
bool(<bool>) : 布尔值
返回一个布尔值。<bool> 可以是 'true'、'false'、'1' 或 '0'。'false' 和 '0' 相同。'true' 和 '1' 相同。
connslots([<backend>]) : 整数
返回一个整数值,对应于后端中仍然可用的连接槽数量,通过汇总所有服务器的最大连接数和最大队列大小。这可能只与 ACL 一起使用。这里的基本思想是能够测量仍然可用的连接“槽”数量(连接 + 队列),以便任何超出此范围的(预期用途;请参阅“use_backend”关键字)可以重定向到不同的后端。“connslots”=可用服务器连接槽数 + 可用服务器队列槽数。请注意,虽然可以使用“fe_conn”,但当您遇到流量流向单个 IP,并拆分为多个后端(可能使用 ACL 进行基于名称的负载平衡)的情况时,“connslots”特别有用,并且您希望能够区分不同的后端及其可用的“connslots”。此外,虽然“nbsrv”仅测量实际 *down* 的服务器,此获取更精细,并查看可用连接槽的数量。另请参阅“queue”和“avg_queue”。其他注意事项和注释:目前,代码不处理动态连接。此外,如果任何服务器 maxconn 或 maxqueue 为 0,则此获取显然没有意义,在这种情况下返回的值将为 -1。
cpu_calls : integer
返回自处理流或当前请求的任务分配以来对其的调用次数。在 HTTP keep-alive 的情况下,每次新请求都会在同一连接上重置此数字。此值通常应较低且稳定(对于典型的简单请求约为 2 次调用),但如果执行了某些处理(压缩、缓存或分析),则可能会变高。这纯粹是为了性能监控。
cpu_ns_avg : integer
返回处理流或当前请求的每个任务调用的平均纳秒数。在 HTTP keep-alive 的情况下,每次新请求都会在同一连接上重置此数字。此值表示每次调用处理请求或连接的总体成本。没有好坏之分,但调用中花费的时间会自动导致其他处理的延迟(参见下面的 lat_ns_avg),并可能影响其他连接的表观响应时间。某些操作(如压缩、复杂正则表达式匹配或繁重的 Lua 操作)可能会直接影响此值,将其记录在日志中将更容易发现需要修复以恢复良好性能的错误处理。注意:此值正好是 cpu_ns_tot 除以 cpu_calls。
cpu_ns_tot : integer
返回处理流或当前请求的每个任务调用的总纳秒数。在 HTTP keep-alive 的情况下,每次新请求都会在同一连接上重置此数字。此值表示每次调用处理请求或连接的总体成本。没有好坏之分,但调用中花费的时间会自动导致其他处理的延迟(参见下面的 lat_ns_avg),导致机器上的 CPU 成本,并可能影响其他连接的表观响应时间。某些操作(如压缩、复杂正则表达式匹配或繁重的 Lua 操作)可能会直接影响此值,将其记录在日志中将更容易发现需要修复以恢复良好性能的错误处理。由于 cpu_calls 计数较高(例如,在处理许多 HTTP 块时),该值可能会人为地偏高,因此通常首选记录 cpu_ns_avg。
date([<offset>],[<unit>]) : integer
以纪元(自 1970 年 1 月 1 日以来的秒数)形式返回当前日期。如果指定了偏移值,则在返回值之前将其添加到当前日期。这对于计算相对日期特别有用,因为允许正负偏移。与 http_date 转换器结合使用时很有用。<unit> 是可选的,可以设置为“s”表示秒(默认行为)、“ms”表示毫秒或“us”表示微秒。如果设置了 unit,则返回值是一个整数,反映自纪元以来的秒数、毫秒数或微秒数,再加上偏移量。当需要不到一秒的时间分辨率时,这很有用。
示例
# 在每个响应中设置一个到期头,时间为现在+1小时 http-response set-header Expires %[date(3600),http_date] # 在每个响应中设置一个到期头,时间为现在+1小时, # 具有毫秒级粒度 http-response set-header Expires %[date(3600000,ms),http_date(0,ms)]
date_us : integer
返回日期的微秒部分(“秒”部分由 date 样本返回)。此样本与 date 样本一致,因为它来自相同的 timeval 结构。
env(<name>) : 字符串
返回一个包含环境变量 <name> 值的字符串。提醒一下,环境变量是每个进程的,并在进程启动时采样。这对于将一些信息传递给下一跳服务器,或者与 ACL 结合使用以在进程以特定方式启动时采取特定操作很有用。
示例
# 将 Via 头传递给下一跳,其中包含本地主机名 http-request add-header Via 1.1\ %[env(HOSTNAME)] # 当设置了 STOP 环境变量时,拒绝无 cookie 的请求 http-request deny if !{ req.cook(SESSIONID) -m found } { env(STOP) -m found }
fe_conn([<frontend>]) : 整数
返回前端上当前已建立的连接数,可能包括正在评估的连接。如果未指定前端名称,则使用当前前端。但也可以检查另一个前端。它可用于在硬阻塞之前返回一个“抱歉”页面,或者在服务器场被认为已满时使用特定的后端来处理新请求。这主要与 ACL 一起使用,但也可以用于在 HTTP 头中将一些统计信息传递给服务器。另请参阅“dst_conn”、“be_conn”、“fe_sess_rate”提取。
fe_req_rate([<frontend>]) : 整数
返回一个整数值,对应于每秒发送到前端的 HTTP 请求数。在启用客户端保持连接(keep-alive)的情况下,此数字可能与“fe_sess_rate”不同。
fe_sess_rate([<frontend>]) : 整数
返回一个整数值,对应于前端上的会话创建速率,单位为每秒新会话数。这与 ACL 一起使用,将传入会话速率限制在可接受的范围内,以便尽早防止服务滥用,例如,当与其他第 4 层 ACL 结合使用时,以强制客户端等待一段时间,直到速率下降到限制以下。使用 log-format 指令将此元素添加到日志中也很有用。另请参阅前端中使用的“rate-limit sessions”指令。
示例
# 此前端将传入邮件限制为 10/s,最多 100 个 # 并发连接。我们接受低于 10/s 的任何连接,并 # 强制超出的客户端等待 100 毫秒。由于客户端限制为 # 最多 100 个,因此每秒传入的邮件不能超过 10 封。 frontend mail bind :25 mode tcp maxconn 100 acl too_fast fe_sess_rate ge 10 tcp-request inspect-delay 100ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END
hostname : string
返回系统主机名。
int(<integer>) : 有符号整数
返回一个有符号整数。
ipv4(<ipv4>) : ipv4
返回一个 IPv4 地址。
ipv6(<ipv6>) : ipv6
返回一个 IPv6 地址。
返回在流分析期间匹配的最后一个最终规则所在的配置文件的名称。最终规则是终止规则集评估的规则(例如“accept”、“deny”或“redirect”)。这适用于在“content”规则集上运行的 TCP 请求和响应规则,以及来自“http-request”、“http-response”和“http-after-response”规则集的 HTTP 规则。不支持旧版“redirect”规则集(此类信息未存储在那里),也不支持“tcp-request connection”和“tcp-request session”规则集,因为信息存储在流级别,而在这些规则期间流不存在。此函数的主要目的是能够在日志中报告给出最终裁决的规则所在的位置,以便帮助查明请求被拒绝的原因。另请参阅“last_rule_line”。
last_rule_line : integer
返回在流分析期间匹配的最后一个最终规则所在的配置文件的行号。最终规则是终止规则集评估的规则(例如“accept”、“deny”或“redirect”)。这适用于在“content”规则集上运行的 TCP 请求和响应规则,以及来自“http-request”、“http-response”和“http-after-response”规则集的 HTTP 规则。不支持旧版“redirect”规则集(此类信息未存储在那里),也不支持“tcp-request connection”和“tcp-request session”规则集,因为信息存储在流级别,而在这些规则期间流不存在。此函数的主要目的是能够在日志中报告给出最终裁决的规则所在的位置,以便帮助查明请求被拒绝的原因。另请参阅“last_rule_file”。
lat_ns_avg : integer
返回处理流的任务被唤醒和实际调用之间花费的平均纳秒数。在 HTTP keep-alive 的情况下,每次在新连接上处理新请求时,此数字都会重置。此值指示并行处理的所有其他请求对当前请求造成的总延迟,是感知性能的直接指标,归因于嘈杂的邻居。为了保持低值,可以通过使用“tune.runqueue-depth”减少调度程序的运行队列深度,通过使用“tune.maxpollevents”减少一次处理的并发事件数,通过在“bind”行或前端上使用“nice”选项来降低流的 nice 值,通过使用“tune.sched.low-latency”启用低延迟调度,或者通过在日志中查找其他重请求(显示出大的“cpu_ns_avg”值的请求),调整或修复其处理。大缓冲区的压缩可能是罪魁祸首,例如重型正则表达式或长正则表达式列表。注意:此值正好是 lat_ns_tot 除以 cpu_calls。
lat_ns_tot : integer
返回处理流的任务被唤醒和实际调用之间花费的总纳秒数。在 HTTP keep-alive 的情况下,每次在新连接上处理新请求时,此数字都会重置。此值指示并行处理的所有其他请求对当前请求造成的总延迟,是感知性能的直接指标,归因于嘈杂的邻居。为了保持低值,可以通过使用“tune.runqueue-depth”减少调度程序的运行队列深度,通过使用“tune.maxpollevents”减少一次处理的并发事件数,通过在“bind”行或前端上使用“nice”选项来降低流的 nice 值,通过使用“tune.sched.low-latency”启用低延迟调度,或者通过在日志中查找其他重请求(显示出大的“cpu_ns_avg”值的请求),调整或修复其处理。大缓冲区的压缩可能是罪魁祸首,例如重型正则表达式或长正则表达式列表。注意:虽然直观上总延迟似乎会增加传输时间,但这几乎从不正确,因为当任务等待 CPU 时,网络缓冲区会继续填充,下一次调用将一次处理更多内容。由于 cpu_calls 计数很高,此值可能会人为地很高,例如在处理许多 HTTP 块时,因此通常最好记录 lat_ns_avg,这是一个更相关的性能指标。
meth(<method>) : 方法
返回一个方法。
nbsrv([<backend>]) : 整数
返回一个整数值,对应于当前后端或指定后端的可用服务器数量。这主要与 ACL 一起使用,但在添加到日志中时也很有用。这通常用于在服务器数量过低而无法处理某些负载时切换到备用后端。当与“monitor fail”结合使用时,报告故障很有用。
prio_class : integer
返回当前流(对于 http 模式)或连接(对于 tcp 模式)的优先级类别。该值将是最后一次调用“http-request set-priority-class”或“tcp-request content set-priority-class”所设置的值。
prio_offset : integer
返回当前流(对于 http 模式)或连接(对于 tcp 模式)的优先级偏移量。该值将是最后一次调用“http-request set-priority-offset”或“tcp-request content set-priority-offset”所设置的值。
pid : integer
返回当前进程的 PID。在大多数情况下,这是工作进程的 PID。
proc : 整数
始终返回值 1(历史上它会返回调用进程号)。
queue([<backend>]) : 整数
返回指定后端的排队连接总数,包括服务器队列中的所有连接。如果未指定后端名称,则使用当前后端,但也可以检查另一个后端。这对于 ACL 或将统计信息传递给后端服务器很有用。这可用于在排队超过已知水平时采取行动,这通常表示流量激增或服务器大规模减速。一个可能的操作是拒绝新用户但仍然接受老用户。另请参阅“avg_queue”、“be_conn”和“be_sess_rate”提取。
quic_enabled : boolean
当 QUIC 传输协议的支持已编译且该协议未被“no-quic”全局选项禁用时,返回 true。另请参阅“no-quic”全局选项。
rand([<range>]) : 整数
返回一个在 <range> 个可能值范围内的随机整数值,从零开始。如果未指定范围,则默认为 2^32,即数字介于 0 和 4294967295 之间。例如,传递一些需要用于做出某些路由决策的值可能很有用,或者仅仅用于调试目的。此随机数不得用于安全目的。
srv_conn([<backend>/]<server>) : 整数
返回一个整数值,对应于指定服务器上当前已建立的连接数,可能包括正在评估的连接。如果省略 <backend>,则在当前后端中查找服务器。当一台服务器已满时,它可用于使用特定的服务器组,或告知服务器我们对其活动连接数的看法。另请参见“fe_conn”、“be_conn”、“queue”和“srv_conn_free”提取方法。
srv_conn_free([<backend>/]<server>) : integer
返回一个整数值,对应于指定服务器上的可用连接数,可能包括正在评估的连接。该值不包括队列槽位。如果省略 <backend>,则在当前后端中查找服务器。当一台服务器已满时,它可用于使用特定的服务器组,或告知服务器我们对其活动连接数的看法。另请参见“be_conn_free”和“srv_conn”提取方法。其他注意事项和说明:如果服务器的 maxconn 为 0,则此提取显然没有意义,在这种情况下返回的值将为 -1。
srv_is_up([<backend>/]<server>) : 布尔值
当指定服务器处于 UP 状态时返回 true,当其处于 DOWN 或维护模式时返回 false。如果省略 <backend>,则在当前后端中查找服务器。它主要用于根据通过健康检查报告的外部状态采取行动(例如,地理站点的可用性)。另一种可能的用途,更像是一种技巧,是使用虚拟服务器作为布尔变量,可以从 CLI 启用或禁用,以便可以实时调整依赖于这些 ACL 的规则。
srv_queue([<backend>/]<server>) : integer
返回一个整数值,对应于当前在指定服务器队列中等待的连接数。如果省略 <backend>,则在当前后端中查找服务器。有时可以与“use-server”指令一起使用,以在已知更快的服务器负载不大时强制使用它。另请参见“srv_conn”、“avg_queue”和“queue”样本提取方法。
srv_sess_rate([<backend>/]<server>) : 整数
返回一个对应于指定服务器上的会话创建速率的整数,以每秒新会话数表示。如果省略 <backend>,则在当前后端中查找服务器。这主要与 ACL 一起使用,但在日志中也可能有意义。这用于在昂贵或脆弱的服务器达到过高的会话速率时切换到备用后端,或限制服务滥用(例如防止潜在请求使服务器过载)。
示例
# 重定向到单独的后端 acl srv1_full srv_sess_rate(be1/srv1) gt 50 acl srv2_full srv_sess_rate(be1/srv2) gt 50 use_backend be2 if srv1_full or srv2_full
srv_iweight([<backend>/]<server>) : integer
返回一个对应于服务器初始权重的整数。如果省略 <backend>,则在当前后端中查找服务器。另请参见“srv_weight”和“srv_uweight”。
srv_uweight([<backend>/]<server>) : integer
返回一个对应于用户可见服务器权重的整数。如果省略 <backend>,则在当前后端中查找服务器。另请参见“srv_weight”和“srv_iweight”。
srv_weight([<backend>/]<server>) : integer
返回一个对应于当前(或有效)服务器权重的整数。如果省略 <backend>,则在当前后端中查找服务器。另请参见“srv_iweight”和“srv_uweight”。
stopping : 布尔值
如果调用该函数的进程当前正在停止,则返回 TRUE。这对于日志记录,或在优雅关闭时放宽某些检查或帮助关闭某些连接很有用。
str(<string>) : 字符串
返回一个字符串。
table_avl([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中可用条目的总数。另请参阅 table_cnt。
table_cnt([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中当前使用的条目总数。有关其他条目计数方法,请参阅 src_conn_cnt 和 table_avl。
thread : integer
返回一个整数值,对应于调用该函数的线程的位置,介于 0 和 (global.nbthread-1) 之间。这对于日志记录和调试目的很有用。
txn.id32 : integer
返回内部事务 ID。它是一个 32 位整数。因此,从绝对值来看,它的值不是唯一的,事务 ID 可能会回绕。回绕周期取决于请求速率。在实践中,这应该不是问题。对于真正的唯一 ID,请参见“unique-id-format”指令。
返回此流在尝试连接到服务器时经历的连接重试次数。在连接完全建立之前,此值可能会发生变化。对于 HTTP 连接,L7 重试可能会影响该值。
返回日志中报告的 TCP 或 HTTP 流终止状态。它是一个 2 个字符的字符串,后跟导致其终止的事件。有关断开连接时的流状态,请参阅第 8.5 节以获取可能的事件列表。返回评估样本获取时当前的值。它可能会更改。除非在“http-after-response”规则集或日志消息中与 ACL 一起使用,否则它将始终为“--”。
示例
# 如果流在队列中超时,则返回 429-Too-Many-Requests http-after-response set-status 429 if { txn.sess_term_state "sQ" }
uuid([<version>]) : string
返回遵循RFC4122标准的UUID。如果未指定版本,则返回UUID版本4(完全随机)。目前,仅支持版本4。
var(<var-name>[,<default>]) : undefined
返回具有存储类型的变量。如果变量未设置,则样本获取失败,除非提供了默认值,在这种情况下,它将作为字符串返回。允许空字符串。变量名以指示其范围的指示符开头。允许的作用域是:“proc”:变量与整个进程共享;“sess”:变量与整个会话共享;“txn”:变量与事务(请求和响应)共享;“req”:变量仅在请求处理期间共享;“res”:变量仅在响应处理期间共享。此前缀后跟一个名称。分隔符是“.”。名称只能包含字符“a-z”、“A-Z”、“0-9”、“.”和“_”。
wait_end : boolean
此获取在检查周期结束时返回 true,否则不获取任何内容。它仅用于 ACL 中,与内容分析结合使用,以避免过早返回错误的判断。它也可用于延迟某些操作,例如对某些特殊地址进行延迟拒绝。由于它要么停止规则评估,要么立即返回 true,因此建议将此 acl 用作规则中的最后一个。请注意,默认的 ACL "WAIT_END" 始终可用,无需事先声明。此测试旨在与 TCP 请求内容检查一起使用。
示例
# 将每个传入请求延迟 2 秒 tcp-request inspect-delay 2s tcp-request content accept if WAIT_END # 不要立即告诉坏家伙他们被拒绝了 tcp-request inspect-delay 10s acl goodguys src 10.0.0.0/24 acl badguys src 10.0.1.0/24 tcp-request content accept if goodguys tcp-request content reject if badguys WAIT_END tcp-request content reject

7.3.3. 在第 4 层提取样本

第 4 层通常仅描述传输层,在 HAProxy 中,传输层最接近连接,此时尚无内容可用。除非需要未来的信息,否则此处描述的获取方法可以在“tcp-request connection”规则集中使用。这些通常包括 TCP/IP 地址和端口,以及与传入连接相关的 stick-table 中的元素。对于从粘性计数器检索值,可以使用预定义的 "sc0_"、"sc1_" 或 "sc2_" 前缀将计数器编号显式设置为 0、1 或 2。只有当全局“tune.stick-counters”值不超过 3 时,才能使用这三个预定义前缀,否则在使用 "sc_" 前缀时,计数器编号可以指定为第一个整数参数,从 "sc_0" 到 "sc_N",其中 N 是 (tune.stick-counters-1)。可以使用 "sc*" 形式指定可选表,在这种情况下,将在该备用表中查找当前跟踪的密钥,而不是当前正在跟踪的表。本节中样本获取方法及其各自类型的摘要
关键字输出类型
accept_date([<unit>])整数
bc.timer.connect整数
bc_dstip
bc_dst_port整数
bc_err整数
bc_err_name字符串
bc_err_str字符串
bc_glitches整数
bc_http_major整数
bc_srcip
bc_src_port整数
be_id整数
be_name字符串
bc_rtt(<unit>)整数
bc_rttvar(<unit>)整数
be_server_timeout整数
be_tunnel_timeout整数
bytes_in整数
bytes_out整数
cur_server_timeout整数
关键字输出类型
cur_tunnel_timeout整数
cur_client_timeout整数
dstip
dst_conn整数
dst_is_local布尔
dst_port整数
fc.timer.handshake整数
fc.timer.total整数
fc_dstip
fc_dst_is_local布尔
fc_dst_port整数
fc_err整数
fc_err_name字符串
fc_err_str字符串
fc_fackets整数
fc_glitches整数
fc_http_major整数
fc_lost整数
fc_pp_authority字符串
fc_pp_unique_id字符串
关键字输出类型
fc_pp_tlv(<id>)字符串
fc_rcvd_proxy布尔
fc_reordering整数
fc_retrans整数
fc_rtt(<unit>)整数
fc_rttvar(<unit>)整数
fc_sacked整数
fc_srcip
fc_src_is_local布尔
fc_src_port整数
fc_unacked整数
fe_defbe字符串
fe_id整数
fe_name字符串
fe_client_timeout整数
res.timer.data整数
sc_bytes_in_rate(<ctr>[,<table>])整数
sc0_bytes_in_rate([<table>])整数
sc1_bytes_in_rate([<table>])整数
sc2_bytes_in_rate([<table>])整数
关键字输出类型
sc_bytes_out_rate(<ctr>[,<table>])整数
sc0_bytes_out_rate([<table>])整数
sc1_bytes_out_rate([<table>])整数
sc2_bytes_out_rate([<table>])整数
sc_clr_gpc(<idx>,<ctr>[,<table>])整数
sc_clr_gpc0(<ctr>[,<table>])整数
sc0_clr_gpc0([<table>])整数
sc1_clr_gpc0([<table>])整数
sc2_clr_gpc0([<table>])整数
sc_clr_gpc1(<ctr>[,<table>])整数
sc0_clr_gpc1([<table>])整数
sc1_clr_gpc1([<table>])整数
sc2_clr_gpc1([<table>])整数
sc_conn_cnt(<ctr>[,<table>])整数
sc0_conn_cnt([<table>])整数
sc1_conn_cnt([<table>])整数
sc2_conn_cnt([<table>])整数
sc_conn_cur(<ctr>[,<table>])整数
sc0_conn_cur([<table>])整数
sc1_conn_cur([<table>])整数
关键字输出类型
sc2_conn_cur([<table>])整数
sc_conn_rate(<ctr>[,<table>])整数
sc0_conn_rate([<table>])整数
sc1_conn_rate([<table>])整数
sc2_conn_rate([<table>])整数
sc_get_gpc(<idx>,<ctr>[,<table>])整数
sc_get_gpc0(<ctr>[,<table>])整数
sc0_get_gpc0([<table>])整数
sc1_get_gpc0([<table>])整数
sc2_get_gpc0([<table>])整数
sc_get_gpc1(<ctr>[,<table>])整数
sc0_get_gpc1([<table>])整数
sc1_get_gpc1([<table>])整数
sc2_get_gpc1([<table>])整数
sc_get_gpt(<idx>,<ctr>[,<table>])整数
sc_get_gpt0(<ctr>[,<table>])整数
sc0_get_gpt0([<table>])整数
sc1_get_gpt0([<table>])整数
sc2_get_gpt0([<table>])整数
sc_gpc_rate(<idx>,<ctr>[,<table>])整数
关键字输出类型
sc_gpc0_rate(<ctr>[,<table>])整数
sc0_gpc0_rate([<table>])整数
sc1_gpc0_rate([<table>])整数
sc2_gpc0_rate([<table>])整数
sc_gpc1_rate(<ctr>[,<table>])整数
sc0_gpc1_rate([<table>])整数
sc1_gpc1_rate([<table>])整数
sc2_gpc1_rate([<table>])整数
sc_http_err_cnt(<ctr>[,<table>])整数
sc0_http_err_cnt([<table>])整数
sc1_http_err_cnt([<table>])整数
sc2_http_err_cnt([<table>])整数
sc_http_err_rate(<ctr>[,<table>])整数
sc0_http_err_rate([<table>])整数
sc1_http_err_rate([<table>])整数
sc2_http_err_rate([<table>])整数
sc_http_fail_cnt(<ctr>[,<table>])整数
sc0_http_fail_cnt([<table>])整数
sc1_http_fail_cnt([<table>])整数
sc2_http_fail_cnt([<table>])整数
关键字输出类型
sc_http_fail_rate(<ctr>[,<table>])整数
sc0_http_fail_rate([<table>])整数
sc1_http_fail_rate([<table>])整数
sc2_http_fail_rate([<table>])整数
sc_http_req_cnt(<ctr>[,<table>])整数
sc0_http_req_cnt([<table>])整数
sc1_http_req_cnt([<table>])整数
sc2_http_req_cnt([<table>])整数
sc_http_req_rate(<ctr>[,<table>])整数
sc0_http_req_rate([<table>])整数
sc1_http_req_rate([<table>])整数
sc2_http_req_rate([<table>])整数
sc_inc_gpc(<idx>,<ctr>[,<table>])整数
sc_inc_gpc0(<ctr>[,<table>])整数
sc0_inc_gpc0([<table>])整数
sc1_inc_gpc0([<table>])整数
sc2_inc_gpc0([<table>])整数
sc_inc_gpc1(<ctr>[,<table>])整数
sc0_inc_gpc1([<table>])整数
sc1_inc_gpc1([<table>])整数
关键字输出类型
sc2_inc_gpc1([<table>])整数
sc_kbytes_in(<ctr>[,<table>])整数
sc0_kbytes_in([<table>])整数
sc1_kbytes_in([<table>])整数
sc2_kbytes_in([<table>])整数
sc_kbytes_out(<ctr>[,<table>])整数
sc0_kbytes_out([<table>])整数
sc1_kbytes_out([<table>])整数
sc2_kbytes_out([<table>])整数
sc_sess_cnt(<ctr>[,<table>])整数
sc0_sess_cnt([<table>])整数
sc1_sess_cnt([<table>])整数
sc2_sess_cnt([<table>])整数
sc_sess_rate(<ctr>[,<table>])整数
sc0_sess_rate([<table>])整数
sc1_sess_rate([<table>])整数
sc2_sess_rate([<table>])整数
sc_tracked(<ctr>[,<table>])布尔
sc0_tracked([<table>])布尔
sc1_tracked([<table>])布尔
关键字输出类型
sc2_tracked([<table>])布尔
sc_trackers(<ctr>[,<table>])整数
sc0_trackers([<table>])整数
sc1_trackers([<table>])整数
sc2_trackers([<table>])整数
so_id整数
so_name字符串
srcip
src_bytes_in_rate([<table>])整数
src_bytes_out_rate([<table>])整数
src_clr_gpc(<idx>,[<table>])整数
src_clr_gpc0([<table>])整数
src_clr_gpc1([<table>])整数
src_conn_cnt([<table>])整数
src_conn_cur([<table>])整数
src_conn_rate([<table>])整数
src_get_gpc(<idx>,[<table>])整数
src_get_gpc0([<table>])整数
src_get_gpc1([<table>])整数
src_get_gpt(<idx>[,<table>])整数
关键字输出类型
src_get_gpt0([<table>])整数
src_gpc_rate(<idx>[,<table>])整数
src_gpc0_rate([<table>])整数
src_gpc1_rate([<table>])整数
src_http_err_cnt([<table>])整数
src_http_err_rate([<table>])整数
src_http_fail_cnt([<table>])整数
src_http_fail_rate([<table>])整数
src_http_req_cnt([<table>])整数
src_http_req_rate([<table>])整数
src_inc_gpc(<idx>,[<table>])整数
src_inc_gpc0([<table>])整数
src_inc_gpc1([<table>])整数
src_is_local布尔
src_kbytes_in([<table>])整数
src_kbytes_out([<table>])整数
src_port整数
src_sess_cnt([<table>])整数
src_sess_rate([<table>])整数
src_updt_conn_cnt([<table>])整数
关键字输出类型
srv_id整数
srv_name字符串
txn.conn_retries整数
详细列表
accept_date([<unit>]) : integer
这是 HAProxy 接收到连接的确切日期(如果系统中存在一些排队,可能与网络上观察到的日期略有不同)。这通常是任何上游防火墙日志中可能出现的日期。当在 HTTP 模式下使用时,accept_date 字段将被重置为连接准备好接收新请求的第一个时刻(HTTP/1 的前一个响应结束,HTTP/2 的前一个请求之后立即)。返回自纪元以来的秒数。 <unit> 是可选的,可以设置为“s”表示秒(默认行为)、“ms”表示毫秒或“us”表示微秒。如果设置了 unit,返回值将是一个整数,表示自纪元以来的秒、毫秒或微秒。当需要小于一秒的时间分辨率时,它很有用。
建立到服务器的 TCP 连接的总时间。这是日志格式中 %Tc 的等效项。以毫秒 (ms) 为单位报告。有关更多信息,请参阅第 8.4 节“计时事件”。
bc_dst : ip
这是服务器端的连接的目标 IP 地址,即 HAProxy 连接到的服务器地址。它属于 IP 类型,并且适用于 IPv4 和 IPv6 表。在 IPv6 表中,IPv4 地址根据 RFC 4291 映射到其 IPv6 等效项。
bc_dst_port : integer
返回一个整数值,对应于服务器端的连接的目标 TCP 端口,即 HAProxy 连接到的端口。
bc_err : integer
返回可能发生在当前后端连接上的错误的 ID。有关错误代码及其对应错误消息的完整列表,请参阅“fc_err_str”提取。
bc_err_name : string
返回描述后端连接上发生的问题并导致连接失败的内部错误名称。此字符串由一个单词组成,在没有错误时为空。它对应于“fc_err_str”关键字中表格的“name”列。
bc_err_str : string
返回描述当前后端连接上发生的问题并导致连接失败的错误消息。有关错误代码及其对应错误消息的完整列表,请参阅“fc_err_str”提取。
bc_glitches : integer
返回后端连接上计数的协议故障数量。这些通常涵盖协议违规以及表明服务器错误或行为异常的小异常,这些异常可能导致基础设施出现问题(例如,导致连接提前中止,引起频繁的 TLS 重新协商)。这些也可能由于响应过大而无法装入单个缓冲区而导致,从而解释 HTTP 502 错误。理想情况下,此数字应保持为零,尽管与请求总数相比,它保持非常低通常是可以的。这些值通常不应被视为令人警觉(尤其是小的),尽管突然跳变可能表明某个地方存在异常。并非所有协议复用器都测量此指标,并且要获取事件的更多详细信息的唯一方法是启用跟踪以捕获所有交换。
bc_http_major : integer
返回后端连接的 HTTP 主版本编码,可以是 1(用于 HTTP/0.9 到 HTTP/1.1)或 2(用于 HTTP/2)。请注意,这基于线上传输的编码,而不是请求标头中存在的版本。
bc_src : ip
这是服务器端的连接源 IP 地址,即 HAProxy 从中连接的服务器地址。它属于 IP 类型,并且适用于 IPv4 和 IPv6 表。在 IPv6 表中,IPv4 地址根据 RFC 4291 映射到其 IPv6 等效项。
bc_src_port : integer
返回一个整数值,对应于服务器端的连接的 TCP 源端口,即 HAProxy 连接的端口。
be_id : 整数
返回一个整数,包含当前后端的 ID。它可以在前端使用响应来检查哪个后端处理了请求。如果在前端使用并且没有使用后端,它将返回当前前端的 ID。它也可以在 tcp-check 或 http-check 规则集中使用。
be_name : string
返回一个字符串,包含当前后端的名称。它可以在前端使用响应来检查哪个后端处理了请求。如果在前端使用并且没有使用后端,它将返回当前前端的名称。它也可以在 tcp-check 或 http-check 规则集中使用。
bc_rtt(<unit>) : integer
返回内核为后端连接测量的往返时间 (RTT)。<unit> 是可选的,默认单位是毫秒。<unit> 可以设置为“ms”表示毫秒或“us”表示微秒。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
bc_rttvar(<unit>) : integer
返回内核为后端连接测量的往返时间 (RTT) 方差。<unit> 是可选的,默认单位是毫秒。<unit> 可以设置为“ms”表示毫秒或“us”表示微秒。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
返回当前后端服务器超时配置值(以毫秒为单位)。此超时可以通过“set-timeout”规则覆盖。另请参阅“cur_server_timeout”。
返回当前后端隧道超时配置值(以毫秒为单位)。此超时可以通过“set-timeout”规则覆盖。另请参阅“cur_tunnel_timeout”。
bytes_in : integer
此函数返回从客户端上传到服务器的字节数。
bytes_out : integer
这是从服务器传输到客户端的字节数。
返回流当前应用的服务器超时(以毫秒为单位)。在默认情况下,这将等于 be_server_timeout,除非应用了“set-timeout”规则。另请参阅“be_server_timeout”。
返回流当前应用的隧道超时(以毫秒为单位)。在默认情况下,这将等于 be_tunnel_timeout,除非应用了“set-timeout”规则。另请参阅“be_tunnel_timeout”。
返回流当前应用的客户端超时(以毫秒为单位)。在默认情况下,这将等于 fe_client_timeout,除非应用了“set-timeout”规则。另请参阅“fe_client_timeout”。
dst : ip
这是客户端上的连接目标 IP 地址,即客户端连接到的地址。任何 tcp/http 规则都可能更改此地址。在透明模式下运行时可能很有用。它属于 IP 类型,并且适用于 IPv4 和 IPv6 表。在 IPv6 表中,IPv4 地址根据 RFC 4291 映射到其 IPv6 等效项。当传入连接经过地址转换或涉及连接跟踪的重定向时,将报告重定向之前的原始目标地址。在 Linux 系统上,由于晚期响应可能会重新打开已超时的连接并切换被认为是源和目标的地址,如果设置了 nf_conntrack_tcp_loose sysctl,源和目标可能很少出现颠倒。
dst_conn : 整数
返回一个整数值,对应于同一套接字上当前建立的连接数,包括正在评估的连接。它通常与 ACL 一起使用,但也可以用于在 HTTP 头中或日志中将信息传递给服务器。它可以用于在硬阻塞之前返回一个“抱歉”页面,或者在套接字被认为饱和时使用特定的后端来处理新请求。这提供了为不同的侦听端口或地址分配不同限制的能力。另请参阅“fe_conn”和“be_conn”提取。
dst_is_local : boolean
如果传入连接的目标地址是本地系统地址,则返回 true;如果地址不存在于系统中(意味着它在透明模式下被拦截),则返回 false。这对于默认情况下对转发流量应用某些规则,而对定向到机器实际地址的流量应用其他规则可能很有用。例如,统计页面可能仅在该地址上提供,或者 SSH 访问可能被本地重定向。请注意,该检查涉及一些系统调用,因此最好每个连接只执行一次。
dst_port : 整数
返回客户端上的连接目标 TCP 端口的整数值,即客户端连接到的端口。任何 tcp/http 规则都可能更改此地址。在透明模式下运行时,为某个应用程序会话为某些客户端分配动态端口,将所有用户粘性到同一服务器,或通过 HTTP 标头将目标端口信息传递给服务器时,可以使用此端口。
接受 TCP 连接并执行低级协议握手(当前包括 proxy-protocol 和 SSL)的总时间。这是日志格式中 %Th 的等效项。以毫秒 (ms) 为单位报告。有关更多信息,请参阅第 8.4 节“计时事件”。
fc.timer.total : integer
流的总持续时间,从代理接受它到两端都关闭。这是日志格式中 %Tt 的等效项。以毫秒 (ms) 为单位报告。有关更多信息,请参阅第 8.4 节“计时事件”。
fc_dst : ip
这是客户端上的连接的原始目标 IP 地址。只有“tcp-request connection”规则可能更改此地址。有关详细信息,请参阅“dst”。
fc_dst_is_local : boolean
如果传入连接的原始目标地址是本地系统地址,则返回 true;如果地址不存在于系统中,则返回 false。有关详细信息,请参阅“dst_is_local”。
fc_dst_port : integer
返回客户端上的连接的原始目标 TCP 端口的整数值。只有“tcp-request connection”规则可能更改此地址。有关详细信息,请参阅“dst-port”。
fc_err : integer
返回可能发生在当前连接上的错误的 ID。此提取器的任何严格正值都表示连接不成功,并且将导致输出错误日志(如 第 8.2.5 节 中所述)。有关错误代码及其对应错误消息的完整列表,请参阅“fc_err_str”提取。
fc_err_name : string
返回描述前端连接上发生的问题并导致连接失败的内部错误名称。此字符串由一个单词组成,在没有错误时为空。它对应于“fc_err_str”关键字中表格的“name”列。
fc_err_str : string
返回描述当前连接上发生的问题的错误消息,导致连接失败。此字符串对应于错误日志格式的“message”部分(请参阅第 8.2.5 节)。有关错误代码及其相应错误消息的完整列表,请参阅下文:+----+------------------+-------------------------------------------------------------------------+ | ID | name | message | +----+------------------+-------------------------------------------------------------------------+ | 0 | - | "Success" | | 1 | CONF_FDLIM | "Reached configured maxconn value" | | 2 | PROC_FDLIM | "Too many sockets on the process" | | 3 | SYS_FDLIM | "Too many sockets on the system" | | 4 | SYS_MEMLIM | "Out of system buffers" | | 5 | NOPROTO | "Protocol or address family not supported" | | 6 | SOCK_ERR | "General socket error" | | 7 | PORT_RANGE | "Source port range exhausted" | | 8 | CANT_BIND | "Can't bind to source address" | | 9 | FREE_PORTS | "Out of local source ports on the system" | | 10 | ADDR_INUSE | "Local source address already in use" | | 11 | PRX_EMPTY | "Connection closed while waiting for PROXY protocol header" | | 12 | PRX_ABORT | "Connection error while waiting for PROXY protocol header" | | 13 | PRX_TIMEOUT | "Timeout while waiting for PROXY protocol header" | | 14 | PRX_TRUNCATED | "Truncated PROXY protocol header received" | | 15 | PRX_NOT_HDR | "Received something which does not look like a PROXY protocol header" | | 16 | PRX_BAD_HDR | "Received an invalid PROXY protocol header" | | 17 | PRX_BAD_PROTO | "Received an unhandled protocol in the PROXY protocol header" | | 18 | CIP_EMPTY | "Connection closed while waiting for NetScaler Client IP header" | | 19 | CIP_ABORT | "Connection error while waiting for NetScaler Client IP header" | | 20 | CIP_TIMEOUT | "Timeout while waiting for a NetScaler Client IP header" | | 21 | CIP_TRUNCATED | "Truncated NetScaler Client IP header received" | | 22 | CIP_BAD_MAGIC | "Received an invalid NetScaler Client IP magic number" | | 23 | CIP_BAD_PROTO | "Received an unhandled protocol in the NetScaler Client IP header" | | 24 | SSL_EMPTY | "Connection closed during SSL handshake" | | 25 | SSL_ABORT | "Connection error during SSL handshake" | | 26 | SSL_TIMEOUT | "Timeout during SSL handshake" | | 27 | SSL_TOO_MANY | "Too many SSL connections" | | 28 | SSL_NO_MEM | "Out of memory when initializing an SSL connection" | | 29 | SSL_RENEG | "Rejected a client-initiated SSL renegotiation attempt" | | 30 | SSL_CA_FAIL | "SSL client CA chain cannot be verified" | | 31 | SSL_CRT_FAIL | "SSL client certificate not trusted" | | 32 | SSL_MISMATCH | "Server presented an SSL certificate different from the configured one" | | 33 | SSL_MISMATCH_SNI | "Server presented an SSL certificate different from the expected one" | | 34 | SSL_HANDSHAKE | "SSL handshake failure" | | 35 | SSL_HANDSHAKE_HB | "SSL handshake failure after heartbeat" | | 36 | SSL_KILLED_HB | "Stopped a TLSv1 heartbeat attack (CVE-2014-0160)" | | 37 | SSL_NO_TARGET | "Attempt to use SSL on an unknown target (internal error)" | | 38 | SSL_EARLY_FAILED | "Server refused early data" | | 39 | SOCKS4_SEND | "SOCKS4 Proxy write error during handshake" | | 40 | SOCKS4_RECV | "SOCKS4 Proxy read error during handshake" | | 41 | SOCKS4_DENY | "SOCKS4 Proxy deny the request" | | 42 | SOCKS4_ABORT | "SOCKS4 Proxy handshake aborted by server" | | 43 | SSL_FATAL | "SSL fatal error" | | 44 | REVERSE | "Reverse connect failure" | | 45 | POLLERR | "Poller reported POLLERR" | | 46 | EREFUSED | "ECONNREFUSED returned by OS" | | 47 | ERESET | "ECONNRESET returned by OS" | | 48 | EUNREACH | "ENETUNREACH returned by OS" | | 49 | ENOMEM | "ENOMEM returned by OS" | | 50 | EBADF | "EBADF returned by OS" | | 51 | EFAULT | "EFAULT returned by OS" | | 52 | EINVAL | "EINVAL returned by OS" | | 53 | ENCONN | "ENCONN returned by OS" | | 54 | ENSOCK | "ENSOCK returned by OS" | | 55 | ENOBUFS | "ENOBUFS returned by OS" | | 56 | EPIPE | "EPIPE returned by OS" | +----+------------------+-------------------------------------------------------------------------+
fc_fackets : integer
返回内核为客户端连接测量的 fack 计数器。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
fc_glitches : integer
返回在前端连接上计数的协议故障数。这些通常涵盖协议违规以及小异常,这些异常通常表明客户端存在问题或行为不当,可能导致基础架构出现问题,例如日志中错误过多,或者许多连接过早中止,导致频繁的 TLS 重新协商。这些也可能由过大的请求导致,这些请求无法放入单个缓冲区,从而导致 HTTP 400 错误。理想情况下,此数字应保持为零,尽管某些浏览器在协议边界上操作时可能会偶尔触发它。这些值通常不应被视为警报(尤其是小值),尽管突然跳跃可能表明某处存在异常。大值(即每次连接数百到数千次,或与请求一样多)可能表明客户端是故意构建的,试图对协议栈进行指纹识别或攻击。并非所有协议多路复用器都测量此指标,获取有关事件的更多详细信息的唯一方法是启用跟踪以捕获所有交换。
fc_http_major : integer
报告前端连接的 HTTP 主版本编码,可以是 1(用于 HTTP/0.9 到 HTTP/1.1)或 2(用于 HTTP/2)。请注意,这基于线上传输的编码,而不是请求标头中存在的版本。
fc_lost : integer
返回内核为客户端连接测量的丢失计数器。如果服务器连接未建立,连接不是 TCP,或者操作系统不支持 TCP_INFO(例如 Linux 内核 2.4 之前的版本),则样本获取失败。
返回客户端在 PROXY 协议头中发送的第一个 authority TLV(如果存在)。
返回客户端在 PROXY 协议头中发送的第一个 unique ID TLV(如果存在)。
fc_pp_tlv(<id>) : string
返回给定 TLV ID 的 TLV 值。ID 必须是 0 到 255 之间的数值,或者是以下支持的符号名称之一,这些名称对应于 PPv2 规范中的 TLV 常量后缀:“ALPN”:PP2_TYPE_ALPN、“AUTHORITY”:PP2_TYPE_AUTHORITY、“CRC32”:PP2_TYPE_CRC32C、“NETNS”:PP2_TYPE_NETNS、“NOOP:PP2_TYPE_NOOP”、“SSL”:PP2_TYPE_SSL、“SSL_CIPHER”:PP2_SUBTYPE_SSL_CIPHER、“SSL_CN”:PP2_SUBTYPE_SSL_CN、“SSL_KEY_ALG”:PP2_SUBTYPE_SSL_KEY_ALG、“SSL_SIG_ALG”:PP2_SUBTYPE_SSL_SIG_ALG、“SSL_VERSION”:PP2_SUBTYPE_SSL_VERSION、“UNIQUE_ID”:PP2_TYPE_UNIQUE_ID。接收到的值必须小于或等于 1024 字节。这样做是为了防止潜在的 DoS 攻击。小于或等于 256 字节的值将能够进行内存池化。因此,为了获得最佳性能,请尝试将发送值的长度限制在 256 字节以内。请注意,与 fc_pp_authority 和 fc_pp_unique_id 不同,fc_pp_tlv 能够迭代所请求 TLV 的所有出现次数,以防存在重复的 TLV ID。迭代顺序与 PROXY 协议标头中的位置匹配。但是,应尽量避免依赖重复项,因为 TLV 通常被假定为唯一。通常,发现重复的 TLV ID 表示 PROXY 协议标头发送方存在错误。
fc_rcvd_proxy : boolean
如果客户端使用 PROXY 协议头启动连接,则返回 true。
fc_reordering : integer
返回内核为客户端连接测量的重排序计数器。如果服务器连接未建立,连接不是 TCP,或者操作系统不支持 TCP_INFO(例如 Linux 内核 2.4 之前的版本),则样本获取失败。
fc_retrans : integer
返回内核为客户端连接测量的重传计数器。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
fc_rtt(<unit>) : integer
返回内核为客户端连接测量的往返时间(RTT)。<unit> 是可选的,默认单位是毫秒。<unit> 可以设置为“ms”表示毫秒,或“us”表示微秒。如果服务器连接未建立,连接不是 TCP,或者操作系统不支持 TCP_INFO(例如 Linux 内核 2.4 之前的版本),则样本获取失败。
fc_rttvar(<unit>) : integer
返回内核为客户端连接测量的往返时间(RTT)方差。<unit> 是可选的,默认单位是毫秒。<unit> 可以设置为“ms”表示毫秒,或“us”表示微秒。如果服务器连接未建立,连接不是 TCP,或者操作系统不支持 TCP_INFO(例如 Linux 内核 2.4 之前的版本),则样本获取失败。
fc_sacked : integer
返回内核为客户端连接测量的 sacked 计数器。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
fc_src : ip
这是客户端上的连接的原始源 IP 地址。只有“tcp-request connection”规则可能更改此地址。有关详细信息,请参阅“src”。
fc_src_is_local : boolean
如果传入连接的源地址是本地系统地址,则返回 true;如果地址不存在于系统中,则返回 false。有关详细信息,请参阅“src_is_local”。
fc_src_port : integer
返回客户端上的连接的 TCP 源端口的整数值。只有“tcp-request connection”规则可能更改此地址。有关详细信息,请参阅“src-port”。
fc_unacked : integer
返回内核为客户端连接测量的未确认计数器。如果服务器连接未建立,如果连接不是 TCP,或者如果操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。
fe_defbe : string
返回前端的默认后端名称的字符串。它可以在前端用于检查哪个后端将默认处理请求。
fe_id : 整数
返回一个包含当前前端 ID 的整数。它可以在后端使用,以检查它是从哪个前端调用的,或将通过同一前端进入的所有用户粘滞到同一台服务器。
fe_name : string
返回当前前端名称的字符串。它可以在后端用于检查它是由哪个前端调用的,或者将来自同一前端的所有用户粘性到同一服务器。
返回当前前端的客户端超时配置值(以毫秒为单位)。此超时可以通过“set-timeout”规则覆盖。
res.timer.data : integer
这是响应负载直到发送到客户端的最后一个字节的总传输时间。在 HTTP 中,它发生在最后一个响应头(Tr)之后。这相当于日志格式中的 %Td,以毫秒(ms)为单位报告。有关更多信息,请参见第 8.4 节“计时事件”。
sc_bytes_in_rate(<ctr>[,<table>]) : 整数
sc0_bytes_in_rate([<table>]) : 整数
sc1_bytes_in_rate([<table>]) : 整数
sc2_bytes_in_rate([<table>]) : 整数
返回当前跟踪的计数器中客户端到服务器的平均字节速率,以表中配置的时间段内的字节量来衡量。另请参阅 src_bytes_in_rate。
sc_bytes_out_rate(<ctr>[,<table>]) : 整数
sc0_bytes_out_rate([<table>]) : 整数
sc1_bytes_out_rate([<table>]) : 整数
sc2_bytes_out_rate([<table>]) : 整数
返回当前跟踪的计数器中服务器到客户端的平均字节速率,以表中配置的时间段内的字节量来衡量。另请参阅 src_bytes_out_rate。
sc_clr_gpc(<idx>,<ctr>[,<table>]) : integer
清除当前代理的粘滞表(stick table)中与指定跟踪计数器 ID <ctr> 关联的数组中索引为 <idx> 的通用计数器(General Purpose Counter),并返回其先前的值。<idx> 是一个介于 0 到 99 之间的整数,<ctr> 是一个介于 0 到 2 之间的整数。在第一次调用之前,存储的值为零,因此第一次调用将始终返回零。此获取仅适用于 'gpc' 数组的数据类型(而不适用于旧的 'gpc0' 或 'gpc1' 数据类型)。
sc_clr_gpc0(<ctr>[,<table>]) : 整数
sc0_clr_gpc0([<table>]) : 整数
sc1_clr_gpc0([<table>]) : 整数
sc2_clr_gpc0([<table>]) : 整数
清除与当前跟踪的计数器相关联的第一个通用计数器,并返回其先前的值。在第一次调用之前,存储的值为零,因此第一次调用将始终返回零。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证时标记连接
示例
# 如果连续 5 个请求的速率持续高于每秒 10 个会话,则阻止, # 并在流量减慢时立即重置计数器。 acl abuse sc0_http_req_rate gt 10 acl kill sc0_inc_gpc0 gt 5 acl save sc0_clr_gpc0 ge 0 tcp-request connection accept if !abuse save tcp-request connection reject if abuse kill
sc_clr_gpc1(<ctr>[,<table>]) : integer
sc0_clr_gpc1([<table>]) : integer
sc1_clr_gpc1([<table>]) : integer
sc2_clr_gpc1([<table>]) : integer
清除与当前跟踪计数器关联的第二个通用计数器,并返回其先前的值。在第一次调用之前,存储的值为零,因此第一次调用将始终返回零。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证后标记连接。
sc_conn_cnt(<ctr>[,<table>]) : 整数
sc0_conn_cnt([<table>]) : 整数
sc1_conn_cnt([<table>]) : 整数
sc2_conn_cnt([<table>]) : 整数
返回当前跟踪的计数器所统计的传入连接的总数。另请参阅 src_conn_cnt。
sc_conn_cur(<ctr>[,<table>]) : 整数
sc0_conn_cur([<table>]) : 整数
sc1_conn_cur([<table>]) : 整数
sc2_conn_cur([<table>]) : 整数
返回跟踪相同跟踪计数器的当前并发连接数。此数字在跟踪开始时自动递增,在跟踪停止时自动递减。另请参阅 src_conn_cur。
sc_conn_rate(<ctr>[,<table>]) : 整数
sc0_conn_rate([<table>]) : 整数
sc1_conn_rate([<table>]) : 整数
sc2_conn_rate([<table>]) : 整数
返回当前跟踪的计数器中的平均连接速率,以表中配置的时间段内的连接数量来衡量。另请参阅 src_conn_rate。
sc_get_gpc(<idx>,<ctr>[,<table>]) : integer
返回 GPC 数组中索引为 <idx> 的通用目的计数器的值,该计数器与当前代理的 stick-table 中 ID 为 <ctr> 的跟踪计数器相关联,或者与指定的 stick-table <table> 相关联。<idx> 是一个介于 0 和 99 之间的整数,<ctr> 是一个介于 0 和 2 之间的整数。如果在此索引处没有存储 gpc,则返回零。此获取仅适用于“gpc”数组数据类型(而不适用于旧的“gpc0”或“gpc1”数据类型)。另请参阅 src_get_gpc 和 sc_inc_gpc。
sc_get_gpc0(<ctr>[,<table>]) : 整数
sc0_get_gpc0([<table>]) : 整数
sc1_get_gpc0([<table>]) : 整数
sc2_get_gpc0([<table>]) : 整数
返回与当前跟踪的计数器关联的第一个通用计数器的值。另请参阅 src_get_gpc0 和 sc/sc0/sc1/sc2_inc_gpc0。
sc_get_gpc1(<ctr>[,<table>]) : integer
sc0_get_gpc1([<table>]) : integer
sc1_get_gpc1([<table>]) : integer
sc2_get_gpc1([<table>]) : integer
返回与当前跟踪的计数器关联的第二个通用目的计数器的值。另请参阅 src_get_gpc1 和 sc/sc0/sc1/sc2_inc_gpc1。
sc_get_gpt(<idx>,<ctr>[,<table>]) : integer
返回与 ID 为 <ctr> 的跟踪计数器以及当前代理的 stick-table 或指定的 stick-table <table> 关联的数组中索引为 <idx> 的第一个通用目的标签的值。<idx> 是一个介于 0 和 99 之间的整数,<ctr> 是一个介于 0 和 2 之间的整数。如果在此索引处没有存储 GPT,则返回零。此获取仅适用于“gpt”数组数据类型(而不适用于旧的“gpt0”数据类型)。另请参阅 src_get_gpt。
sc_get_gpt0(<ctr>[,<table>]) : 整数
sc0_get_gpt0([<table>]) : 整数
sc1_get_gpt0([<table>]) : 整数
sc2_get_gpt0([<table>]) : 整数
返回与当前跟踪的计数器关联的第一个通用标签(General Purpose Tag)的值。另请参阅 src_get_gpt0。
sc_gpc_rate(<idx>,<ctr>[,<table>]) : integer
返回与指定 ID <ctr> 的跟踪计数器关联的数组中索引为 <idx> 的通用计数器的平均增量率,该计数器来自当前代理的 stick-table 或指定的 stick-table <table>。它报告 gpc 计数器在配置周期内的增量频率。<idx> 是一个介于 0 到 99 之间的整数,<ctr> 是一个介于 0 到 2 之间的整数。请注意,'gpc_rate' 计数器数组必须存储在 stick-table 中才能返回值,因为 'gpc' 只包含事件计数。此获取仅适用于 'gpc_rate' 数组数据类型(而不适用于旧的 'gpc0_rate' 和 'gpc1_rate' 数据类型)。另请参阅 src_gpc_rate、sc_get_gpc 和 sc_inc_gpc。
sc_gpc0_rate(<ctr>[,<table>]) : 整数
sc0_gpc0_rate([<table>]) : 整数
sc1_gpc0_rate([<table>]) : 整数
sc2_gpc0_rate([<table>]) : 整数
返回与当前跟踪的计数器关联的第一个通用计数器的平均增量速率。它报告在配置的时间段内 gpc0 计数器递增的频率。另请参阅 src_gpc0_rate、sc/sc0/sc1/sc2_get_gpc0 和 sc/sc0/sc1/sc2_inc_gpc0。请注意,必须在粘性表中存储“gpc0_rate”计数器才能返回值,因为“gpc0”仅保存事件计数。
sc_gpc1_rate(<ctr>[,<table>]) : integer
sc0_gpc1_rate([<table>]) : integer
sc1_gpc1_rate([<table>]) : integer
sc2_gpc1_rate([<table>]) : integer
返回与当前跟踪计数器关联的第二个通用计数器的平均增量速率。它报告了在配置的时间段内 gpc1 计数器被增量的频率。另请参阅 src_gpcA_rate、sc/sc0/sc1/sc2_get_gpc1 和 sc/sc0/sc1/sc2_inc_gpc1。请注意,“gpc1_rate”计数器必须存储在粘滞表中才能返回一个值,因为“gpc1”只保存事件计数。
sc_http_err_cnt(<ctr>[,<table>]) : 整数
sc0_http_err_cnt([<table>]) : 整数
sc1_http_err_cnt([<table>]) : 整数
sc2_http_err_cnt([<table>]) : 整数
返回当前跟踪计数器中的 HTTP 错误总数。这包括请求错误和 4xx 错误响应。另请参阅 src_http_err_cnt。
sc_http_err_rate(<ctr>[,<table>]) : 整数
sc0_http_err_rate([<table>]) : 整数
sc1_http_err_rate([<table>]) : 整数
sc2_http_err_rate([<table>]) : 整数
返回当前跟踪的计数器中 HTTP 错误的平均速率,以表中配置的时间段内的错误数量来衡量。这包括请求错误和 4xx 错误响应。另请参阅 src_http_err_rate。
sc_http_fail_cnt(<ctr>[,<table>]) : integer
sc0_http_fail_cnt([<table>]) : integer
sc1_http_fail_cnt([<table>]) : integer
sc2_http_fail_cnt([<table>]) : integer
返回当前跟踪计数器中的 HTTP 响应失败总数。这包括响应错误和除 501 和 505 之外的 5xx 状态码。另请参阅 src_http_fail_cnt。
sc_http_fail_rate(<ctr>[,<table>]) : integer
sc0_http_fail_rate([<table>]) : integer
sc1_http_fail_rate([<table>]) : integer
sc2_http_fail_rate([<table>]) : integer
返回当前跟踪计数器中的 HTTP 响应失败的平均速率,以配置周期内的失败次数衡量。这包括响应错误和除 501 和 505 之外的 5xx 状态码。另请参阅 src_http_fail_rate。
sc_http_req_cnt(<ctr>[,<table>]) : 整数
sc0_http_req_cnt([<table>]) : 整数
sc1_http_req_cnt([<table>]) : 整数
sc2_http_req_cnt([<table>]) : 整数
返回当前跟踪计数器的累计 HTTP 请求数。这包括所有开始的请求,无论有效与否。另请参阅 src_http_req_cnt。
sc_http_req_rate(<ctr>[,<table>]) : 整数
sc0_http_req_rate([<table>]) : 整数
sc1_http_req_rate([<table>]) : 整数
sc2_http_req_rate([<table>]) : 整数
返回当前跟踪的计数器中 HTTP 请求的平均速率,以表中配置的时间段内的请求数量来衡量。这包括每个已启动的请求,无论其有效与否。另请参阅 src_http_req_rate。
sc_inc_gpc(<idx>,<ctr>[,<table>]) : integer
递增当前代理的粘滞表或指定的粘滞表 <table> 中与指定跟踪计数器 ID <ctr> 关联的数组中索引为 <idx> 的通用计数器,并返回其新值。<idx> 是一个介于 0 到 99 之间的整数,<ctr> 是一个介于 0 到 2 之间的整数。在第一次调用之前,存储的值为零,因此第一次调用会将其增加到 1 并返回 1。此获取仅适用于 'gpc' 数组的数据类型(而不适用于旧的 'gpc0' 或 'gpc1' 数据类型)。
sc_inc_gpc0(<ctr>[,<table>]) : 整数
sc0_inc_gpc0([<table>]) : 整数
sc1_inc_gpc0([<table>]) : 整数
sc2_inc_gpc0([<table>]) : 整数
递增与当前跟踪的计数器相关联的第一个通用计数器,并返回其新值。在第一次调用之前,存储的值为零,因此第一次调用将将其增加到 1 并返回 1。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证时标记连接
示例
acl abuse sc0_http_req_rate gt 10 acl kill sc0_inc_gpc0 gt 0 tcp-request connection reject if abuse kill
sc_inc_gpc1(<ctr>[,<table>]) : integer
sc0_inc_gpc1([<table>]) : integer
sc1_inc_gpc1([<table>]) : integer
sc2_inc_gpc1([<table>]) : integer
递增与当前跟踪计数器关联的第二个通用计数器,并返回其新值。在第一次调用之前,存储的值为零,因此第一次调用会将其增加到 1 并返回 1。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证后标记连接。
sc_kbytes_in(<ctr>[,<table>]) : 整数
sc0_kbytes_in([<table>]) : 整数
sc1_kbytes_in([<table>]) : 整数
sc2_kbytes_in([<table>]) : 整数
返回当前跟踪的计数器中客户端到服务器的总数据量,以千字节为单位。该测试目前在 32 位整数上执行,这将值限制为 4 TB。另请参阅 src_kbytes_in。
sc_kbytes_out(<ctr>[,<table>]) : 整数
sc0_kbytes_out([<table>]) : 整数
sc1_kbytes_out([<table>]) : 整数
sc2_kbytes_out([<table>]) : 整数
返回当前跟踪的计数器中服务器到客户端的总数据量,以千字节为单位。该测试目前在 32 位整数上执行,这将值限制为 4 TB。另请参阅 src_kbytes_out。
sc_sess_cnt(<ctr>[,<table>]) : 整数
sc0_sess_cnt([<table>]) : 整数
sc1_sess_cnt([<table>]) : 整数
sc2_sess_cnt([<table>]) : 整数
返回从当前跟踪计数器中转换为会话的传入连接总数,这意味着它们被“tcp-request connection”规则接受。后端可能会计算比连接更多的会话,因为每个连接都可能导致许多后端会话,如果通过与客户端的连接执行了某些 HTTP keep-alive。另请参阅 src_sess_cnt。
sc_sess_rate(<ctr>[,<table>]) : 整数
sc0_sess_rate([<table>]) : 整数
sc1_sess_rate([<table>]) : 整数
sc2_sess_rate([<table>]) : 整数
返回当前跟踪的计数器中的平均会话速率,以表中配置的时间段内的会话数量来衡量。会话是通过早期“tcp-request connection”规则的连接。一个后端可能会计算比连接更多的会话,因为如果通过与客户端的连接执行了 HTTP 保持连接(keep-alive),每个连接可能会导致多个后端会话。另请参阅 src_sess_rate。
sc_tracked(<ctr>[,<table>]) : 布尔值
sc0_tracked([<table>]) : 布尔值
sc1_tracked([<table>]) : 布尔值
sc2_tracked([<table>]) : 布尔值
如果指定的会话计数器当前正被当前会话跟踪,则返回 true。这在决定是否要在传递给服务器的头中设置某些值时很有用。
sc_trackers(<ctr>[,<table>]) : 整数
sc0_trackers([<table>]) : 整数
sc1_trackers([<table>]) : 整数
sc2_trackers([<table>]) : 整数
返回跟踪相同跟踪计数器的当前并发连接数。此数字在跟踪开始时自动递增,在跟踪停止时自动递减。它与 sc0_conn_cur 的不同之处在于,它不依赖于任何存储的信息,而是依赖于表的引用计数(即在 CLI 上通过“show table”返回的“use”值)。这有时可能更适合于第 7 层跟踪。例如,它可以用来告诉服务器来自给定地址的并发连接数。
so_id : 整数
返回一个包含当前侦听套接字 ID 的整数。它在涉及多个“bind”行的前端中非常有用,或者可以将所有来自同一套接字的用户粘性地绑定到同一台服务器。
so_name : string
返回一个包含当前侦听套接字名称的字符串,该名称在“bind”行中使用 name 定义。它可以与 so_id 具有相同的目的,但使用字符串而不是整数。
src : ip
这是会话客户端的源 IP 地址。任何 tcp/http 规则都可能更改此地址。它的类型是 IP,适用于 IPv4 和 IPv6 表。在 IPv6 表上,IPv4 地址根据 RFC 4291 映射到其 IPv6 等效项。请注意,使用的是 TCP 级别的源地址,而不是代理后面的客户端地址。但是,如果使用了“accept-proxy”或“accept-netscaler-cip”绑定指令,则对于除“tcp-request connection”之外的所有规则集,它可能是另一个 PROXY 协议兼容组件后面的客户端地址,该规则集查看真实地址。当传入连接通过涉及连接跟踪的地址转换或重定向时,将报告重定向之前的原始目标地址。在 Linux 系统上,如果设置了 nf_conntrack_tcp_loose sysctl,源和目标可能很少出现反转,因为延迟响应可能会重新打开超时连接并切换被认为是源和目标的地址。
示例
# 在请求中添加一个带有源地址国家的 HTTP 头 http-request set-header X-Country %[src,map_ip(geoip.lst)]
src_bytes_in_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,来自传入连接源地址的平均字节速率,以表中配置的时间段内的字节量来衡量。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_bytes_in_rate。
src_bytes_out_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,发往传入连接源地址的平均字节速率,以表中配置的时间段内的字节量来衡量。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_bytes_out_rate。
src_clr_gpc(<idx>,[<table>]) : integer
清除当前代理的 stick-table 或指定的 stick-table <table> 中与传入连接的源地址关联的数组中索引为 <idx> 的通用计数器,并返回其先前的值。<idx> 是一个介于 0 到 99 之间的整数。如果未找到该地址,则会创建一个条目并返回 0。此获取仅适用于 'gpc' 数组数据类型(而不适用于旧的 'gpc0' 和 'gpc1' 数据类型)。另请参阅 sc_clr_gpc。
src_clr_gpc0([<table>]) : 整数
清除与当前代理的 stick-table 或指定 stick-table 中传入连接源地址相关联的第一个通用计数器,并返回其先前的值。如果找不到该地址,则创建条目并返回 0。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证时标记连接
示例
# 如果连续 5 个请求的速率持续高于每秒 10 个会话,则阻止, # 并在流量减慢时立即重置计数器。 acl abuse src_http_req_rate gt 10 acl kill src_inc_gpc0 gt 5 acl save src_clr_gpc0 ge 0 tcp-request connection accept if !abuse save tcp-request connection reject if abuse kill
src_clr_gpc1([<table>]) : integer
清除当前代理的 stick-table 或指定 stick-table 中与传入连接的源地址关联的第二个通用计数器,并返回其先前的值。如果未找到该地址,则会创建一个条目并返回 0。这通常用作表达式中的第二个 ACL,以便在验证第一个 ACL 时标记连接。
src_conn_cnt([<table>]) : 整数
返回当前代理的 stick-table 或指定 stick-table 中与传入连接的源地址关联的已建立连接的总数。如果未找到该地址,则返回零。另请参阅 sc/sc0/sc1/sc2_conn_cnt。
src_conn_cur([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,从当前传入连接的源地址发起的当前并发连接数。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_conn_cur。
src_conn_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,来自传入连接源地址的平均连接速率,以表中配置的时间段内的连接数量来衡量。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_conn_rate。
src_get_gpc(<idx>,[<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table <table> 中与传入连接的源地址关联的数组中索引为 <idx> 的通用计数器的值。<idx> 是一个介于 0 到 99 之间的整数。如果未找到该地址或在此索引处没有存储 gpc,则返回零。此获取仅适用于 'gpc' 数组数据类型(而不适用于旧的 'gpc0' 和 'gpc1' 数据类型)。另请参阅 sc_get_gpc 和 src_inc_gpc。
src_get_gpc0([<table>]) : 整数
返回与当前代理的粘性表或指定粘性表中传入连接的源地址关联的第一个通用计数器的值。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_get_gpc0 和 src_inc_gpc0。
src_get_gpc1([<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table 中与传入连接的源地址关联的第二个通用计数器的值。如果未找到该地址,则返回零。另请参阅 sc/sc0/sc1/sc2_get_gpc1 和 src_inc_gpc1。
src_get_gpt(<idx>[,<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table <table> 中与传入连接的源地址关联的数组中索引为 <idx> 的第一个通用标记的值。<idx> 是一个介于 0 到 99 之间的整数。如果未找到该地址或未存储 GPT,则返回零。另请参阅 sc_get_gpt 示例获取关键字。
src_get_gpt0([<table>]) : 整数
返回与当前代理的粘性表或指定粘性表中传入连接的源地址关联的第一个通用标签的值。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_get_gpt0。
src_gpc_rate(<idx>[,<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table <table> 中与传入连接的源地址关联的数组中索引为 <idx> 的通用计数器的平均增量率。它报告 gpc 计数器在配置周期内的增量频率。<idx> 是一个介于 0 到 99 之间的整数。请注意,'gpc_rate' 计数器必须存储在 stick-table 中才能返回值,因为 'gpc' 只包含事件计数。此获取仅适用于 'gpc_rate' 数组数据类型(而不适用于旧的 'gpc0_rate' 和 'gpc1_rate' 数据类型)。另请参阅 sc_gpc_rate、src_get_gpc 和 sc_inc_gpc。
src_gpc0_rate([<table>]) : 整数
返回与当前代理的粘性表或指定粘性表中传入连接的源地址关联的第一个通用计数器的平均增量速率。它报告在配置的时间段内 gpc0 计数器递增的频率。另请参阅 sc/sc0/sc1/sc2_gpc0_rate、src_get_gpc0 和 sc/sc0/sc1/sc2_inc_gpc0。请注意,必须在粘性表中存储“gpc0_rate”计数器才能返回值,因为“gpc0”仅保存事件计数。
src_gpc1_rate([<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table 中与传入连接的源地址关联的第二个通用计数器的平均增量率。它报告 gpc1 计数器在配置周期内的增量频率。另请参阅 sc/sc0/sc1/sc2_gpc1_rate、src_get_gpc1 和 sc/sc0/sc1/sc2_inc_gpc1。请注意,“gpc1_rate”计数器必须存储在 stick-table 中才能返回值,因为“gpc1”只包含事件计数。
src_http_err_cnt([<table>]) : 整数
返回当前代理的 stick-table 或指定 stick-table 中传入连接的源地址的 HTTP 错误总数。这包括请求错误和 4xx 错误响应。另请参阅 sc/sc0/sc1/sc2_http_err_cnt。如果未找到该地址,则返回零。
src_http_err_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,来自传入连接源地址的 HTTP 错误的平均速率,以表中配置的时间段内的错误数量来衡量。这包括请求错误和 4xx 错误响应。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_http_err_rate。
src_http_fail_cnt([<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table 中由传入连接的源地址触发的 HTTP 响应失败总数。这包括响应错误和除 501 和 505 之外的 5xx 状态码。另请参阅 sc/sc0/sc1/sc2_http_fail_cnt。如果未找到该地址,则返回零。
src_http_fail_rate([<table>]) : integer
返回当前代理的 stick-table 或指定 stick-table 中由传入连接的源地址触发的 HTTP 响应失败的平均速率,以配置周期内的失败次数衡量。这包括响应错误和除 501 和 505 之外的 5xx 状态码。如果未找到该地址,则返回零。另请参阅 sc/sc0/sc1/sc2_http_fail_rate。
src_http_req_cnt([<table>]) : 整数
返回当前代理的 stick-table 或指定 stick-table 中传入连接的源地址的 HTTP 请求总数。这包括每个已启动的请求,无论是否有效。如果未找到该地址,则返回零。另请参阅 sc/sc0/sc1/sc2_http_req_cnt。
src_http_req_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,来自传入连接源地址的 HTTP 请求的平均速率,以表中配置的时间段内的请求数量来衡量。这包括每个已启动的请求,无论其有效与否。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_http_req_rate。
src_inc_gpc(<idx>,[<table>]) : integer
递增当前代理的 stick-table 或指定 stick-table <table> 中与传入连接的源地址关联的数组中索引为 <idx> 的通用计数器,并返回其新值。<idx> 是一个介于 0 到 99 之间的整数。如果未找到该地址,则会创建一个条目并返回 1。此获取仅适用于 'gpc' 数组数据类型(而不适用于旧的 'gpc0' 和 'gpc1' 数据类型)。另请参阅 sc_inc_gpc。
src_inc_gpc0([<table>]) : 整数
递增与当前代理的 stick-table 或指定 stick-table 中传入连接源地址相关联的第一个通用计数器,并返回其新值。如果找不到该地址,则创建条目并返回 1。另请参阅 sc0/sc2/sc2_inc_gpc0。这通常用作表达式中的第二个 ACL,以便在第一个 ACL 被验证时标记连接
示例
acl abuse src_http_req_rate gt 10 acl kill src_inc_gpc0 gt 0 tcp-request connection reject if abuse kill
src_inc_gpc1([<table>]) : integer
递增当前代理的 stick-table 或指定 stick-table 中与传入连接的源地址关联的第二个通用计数器,并返回其新值。如果未找到该地址,则会创建一个条目并返回 1。另请参阅 sc0/sc2/sc2_inc_gpc1。这通常用作表达式中的第二个 ACL,以便在验证第一个 ACL 时标记连接。
src_is_local : boolean
如果入站连接的源地址是本地的,则返回 true,如果地址不存在于系统中(意味着它来自远程计算机),则返回 false。请注意,UNIX 地址被视为本地的。这有助于根据客户端的来源应用某些访问限制(例如,对远程计算机要求身份验证或 https)。请注意,此检查涉及一些系统调用,因此最好每个连接只执行一次。
src_kbytes_in([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,从传入连接源地址接收的总数据量,以千字节为单位。如果找不到地址,则返回零。该测试目前在 32 位整数上执行,这将值限制为 4 TB。另请参阅 sc/sc0/sc1/sc2_kbytes_in。
src_kbytes_out([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,发送到传入连接源地址的总数据量,以千字节为单位。如果找不到地址,则返回零。该测试目前在 32 位整数上执行,这将值限制为 4 TB。另请参阅 sc/sc0/sc1/sc2_kbytes_out。
src_port : 整数
返回一个整数值,对应于客户端侧连接的 TCP 源端口,这是客户端连接的端口。任何 tcp/http 规则都可能更改此地址。此函数的使用非常有限,因为现代协议如今对源端口不太关心。
src_sess_cnt([<table>]) : 整数
返回当前代理的 stick-table 或指定 stick-table 中传入连接的源 IPv4 地址建立的连接总数,这些连接已转换为会话,这意味着它们已被“tcp-request”规则接受。如果未找到该地址,则返回零。另请参阅 sc/sc0/sc1/sc2_sess_cnt。
src_sess_rate([<table>]) : 整数
返回当前代理的粘性表或指定粘性表中,来自传入连接源地址的平均会话速率,以表中配置的时间段内的会话数量来衡量。会话是通过早期“tcp-request”规则的连接。如果找不到地址,则返回零。另请参阅 sc/sc0/sc1/sc2_sess_rate。
src_updt_conn_cnt([<table>]) : 整数
在当前代理的粘滞表或指定的粘滞表中,为传入连接的源地址创建或更新关联的条目。此表必须配置为存储 "conn_cnt" 数据类型,否则匹配将被忽略。当前计数会加一,并且到期计时器会刷新。更新后的计数将被返回,因此此匹配不会返回零。这曾被用来根据源地址拒绝滥用服务的用户。注意:建议改用 "tcp-request" 规则中功能更完整的 "track-sc*" 操作。
示例
# 此前端限制每个源地址的传入 SSH 连接为每 10 秒 3 次, # 并拒绝超出的连接,直到观察到 10 秒的静默期。最多跟踪 20 个地址。 listen ssh bind :22 mode tcp maxconn 100 stick-table type ip size 20 expire 10s store conn_cnt tcp-request content reject if { src_updt_conn_cnt gt 3 } server local 127.0.0.1:22
srv_id : integer
返回一个整数,包含处理响应时服务器的 ID。虽然它几乎只用于 ACL,但也可用于日志记录或调试。它也可以在 tcp-check 或 http-check 规则集中使用。
srv_name : string
返回一个字符串,包含处理响应时服务器的名称。虽然它几乎只用于 ACL,但也可用于日志记录或调试。它也可以在 tcp-check 或 http-check 规则集中使用。
返回此流在尝试连接到服务器时经历的连接重试次数。在连接完全建立之前,此值可能会发生变化。对于 HTTP 连接,L7 重试可能会影响该值。

7.3.4. 在第 5 层获取样本

第 5 层通常只描述会话层,在 HAProxy 中,一旦所有连接握手完成,并且在内容可用之前,它最接近会话层。此处描述的获取方法可用于低至“tcp-request content”的规则集,除非它们需要一些未来的信息。这些通常包括 SSL 协商的结果。本节中示例获取方法及其相应类型的摘要。
关键字输出类型
51d.all(<prop>[,<prop>*])字符串
ssl_bc布尔
ssl_bc_alg_keysize整数
ssl_bc_alpn字符串
ssl_bc_cipher字符串
ssl_bc_client_random二进制
ssl_bc_curve字符串
ssl_bc_err整数
ssl_bc_err_str字符串
ssl_bc_is_resumed布尔
ssl_bc_npn字符串
ssl_bc_protocol字符串
ssl_bc_unique_id二进制
ssl_bc_server_random二进制
ssl_bc_session_id二进制
ssl_bc_session_key二进制
ssl_bc_use_keysize整数
ssl_c_ca_err整数
ssl_c_ca_err_depth整数
ssl_c_chain_der二进制
关键字输出类型
ssl_c_der二进制
ssl_c_err整数
ssl_c_i_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_c_key_alg字符串
ssl_c_notafter字符串
ssl_c_notbefore字符串
ssl_c_r_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_c_s_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_c_serial二进制
ssl_c_sha1二进制
ssl_c_sig_alg字符串
ssl_c_used布尔
ssl_c_verify整数
ssl_c_version整数
ssl_f_der二进制
ssl_f_i_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_f_key_alg字符串
ssl_f_notafter字符串
ssl_f_notbefore字符串
ssl_f_s_dn([<entry>[,<occ>[,<format>]]])字符串
关键字输出类型
ssl_f_serial二进制
ssl_f_sha1二进制
ssl_f_sig_alg字符串
ssl_f_version整数
ssl_fc布尔
ssl_fc_alg_keysize整数
ssl_fc_alpn字符串
ssl_fc_cipher字符串
ssl_fc_cipherlist_bin([<filter_option>])二进制
ssl_fc_cipherlist_hex([<filter_option>])字符串
ssl_fc_cipherlist_str([<filter_option>])字符串
ssl_fc_cipherlist_xxh整数
ssl_fc_curve字符串
ssl_fc_ecformats_bin二进制
ssl_fc_eclist_bin([<filter_option>])二进制
ssl_fc_extlist_bin([<filter_option>])二进制
ssl_fc_client_random二进制
ssl_fc_client_early_traffic_secret字符串
ssl_fc_client_handshake_traffic_secret字符串
ssl_fc_client_traffic_secret_0字符串
关键字输出类型
ssl_fc_exporter_secret字符串
ssl_fc_early_exporter_secret字符串
ssl_fc_err整数
ssl_fc_err_str字符串
ssl_fc_has_crt布尔
ssl_fc_has_early布尔
ssl_fc_has_sni布尔
ssl_fc_is_resumed布尔
ssl_fc_npn字符串
ssl_fc_protocol字符串
ssl_fc_protocol_hello_id整数
ssl_fc_unique_id二进制
ssl_fc_server_handshake_traffic_secret字符串
ssl_fc_server_traffic_secret_0字符串
ssl_fc_server_random二进制
ssl_fc_session_id二进制
ssl_fc_session_key二进制
ssl_fc_sni字符串
ssl_fc_use_keysize整数
ssl_s_der二进制
关键字输出类型
ssl_s_chain_der二进制
ssl_s_key_alg字符串
ssl_s_notafter字符串
ssl_s_notbefore字符串
ssl_s_i_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_s_s_dn([<entry>[,<occ>[,<format>]]])字符串
ssl_s_serial二进制
ssl_s_sha1二进制
ssl_s_sig_alg字符串
ssl_s_version整数
txn.timer.user整数
详细列表
51d.all(<prop>[,<prop>*]) : string
以字符串形式返回请求的属性值,值之间用“51degrees-property-separator”指定的定界符分隔。设备通过请求中的所有重要 HTTP 头部来识别。该函数最多可以传递五个属性名称,如果找不到属性名称,则返回“NoData”。
示例
# 此处将头部 "X-51D-DeviceTypeMobileTablet" 添加到请求中 # 包含使用请求中的所有相关头部请求的三个属性。 frontend http-in bind *:8081 default_backend servers http-request set-header X-51D-DeviceTypeMobileTablet \ %[51d.all(DeviceType,IsMobile,IsTablet)]
ssl_bc : boolean
当后端连接是通过 SSL/TLS 传输层建立并已本地解密时,返回 true。这意味着出站连接是使用“ssl”选项与服务器建立的。它可以用于 tcp-check 或 http-check 规则集。
返回出站连接通过 SSL/TLS 传输层建立时支持的对称密码(cipher)密钥大小(以位为单位)。它可以用于 tcp-check 或 http-check 规则集。
ssl_bc_alpn : string
此项从通过 TLS 传输层建立的出站连接中提取应用层协议协商(ALPN)字段。结果是包含与服务器协商的协议名称的字符串。SSL 库必须在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。请注意,除非在 "server" 行上使用 "alpn" 关键字指定了协议列表,否则不会播发 TLS ALPN 扩展。此外,没有任何强制要求服务器从该列表中选择协议,服务器可以选择任何其他协议。TLS ALPN 扩展旨在取代 TLS NPN 扩展。另请参阅 "ssl_bc_npn"。它可用于 tcp-check 或 http-check 规则集。
ssl_bc_cipher : string
返回通过 SSL/TLS 传输层建立的出站连接所使用的密码(cipher)的名称。它可以用于 tcp-check 或 http-check 规则集。
当入站连接通过 SSL/TLS 传输层建立时,返回后端连接的客户端随机数(client random)。它对于解密使用临时密码(ephemeral ciphers)发送的流量很有用。这需要 OpenSSL >= 1.1.0,或 BoringSSL。它可以用于 tcp-check 或 http-check 规则集。
ssl_bc_curve : string
返回通过 SSL/TLS 传输层建立连接时使用的密钥协议的曲线名称。这需要 OpenSSL >= 3.0.0。
ssl_bc_err : integer
当出站连接通过 SSL/TLS 传输层建立时,返回后端端最后一个错误堆栈的第一个错误的 ID。它可能引发握手错误以及连接生命周期中发生的其他读写错误。为了获得此错误代码的文本描述,您可以使用“ssl_bc_err_str”示例获取,或使用“openssl errstr”命令(该命令以十六进制表示形式的错误代码作为参数)。请参考您的 SSL 库文档以查找错误代码的完整列表。
当出站连接通过 SSL/TLS 传输层建立时,返回后端角度的连接上发生的最后一个错误堆栈的第一个错误的字符串表示。另请参阅“ssl_fc_err”。
当后端连接通过 SSL/TLS 传输层建立,并且新创建的 SSL 会话是通过缓存会话或 TLS 票据恢复的,则返回 true。它可以用于 tcp-check 或 http-check 规则集。
ssl_bc_npn : string
此项从通过 TLS 传输层建立的出站连接中提取下一协议协商(NPN)字段。结果是包含与服务器协商的协议名称的字符串。SSL 库必须在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。请注意,除非在 "server" 行上使用 "npn" 关键字指定了协议列表,否则不会播发 TLS NPN 扩展。此外,没有任何强制要求服务器从该列表中选择协议,服务器可以选择任何其他协议。请注意,TLS NPN 扩展已被 ALPN 取代。它可用于 tcp-check 或 http-check 规则集。
返回通过 SSL/TLS 传输层建立的出站连接所使用的协议的名称。它可以用于 tcp-check 或 http-check 规则集。
当出站连接通过 SSL/TLS 传输层建立时,返回 RFC 5929 第 3 节定义的 TLS 唯一 ID。可以使用转换器将唯一 ID 编码为 base64:“ssl_bc_unique_id,base64”。它可以用于 tcp-check 或 http-check 规则集。
当入站连接通过 SSL/TLS 传输层建立时,返回后端连接的服务器随机数(server random)。它对于解密使用临时密码(ephemeral ciphers)发送的流量很有用。这需要 OpenSSL >= 1.1.0,或 BoringSSL。它可以用于 tcp-check 或 http-check 规则集。
当出站连接通过 SSL/TLS 传输层建立时,返回后端连接的 SSL ID。如果想要知道会话是否被重用,它对于日志记录很有用。它可以用于 tcp-check 或 http-check 规则集。
当出站连接通过 SSL/TLS 传输层建立时,返回后端连接的 SSL 会话主密钥。它对于解密使用临时密码(ephemeral ciphers)发送的流量很有用。这需要 OpenSSL >= 1.1.0,或 BoringSSL。它可以用于 tcp-check 或 http-check 规则集。
返回出站连接通过 SSL/TLS 传输层建立时使用的对称密码(cipher)密钥大小(以位为单位)。它可以用于 tcp-check 或 http-check 规则集。
ssl_c_ca_err : integer
当传入连接通过 SSL/TLS 传输层建立时,如果在验证深度 > 0 的客户端证书期间检测到第一个错误,则返回该错误的 ID;如果在此验证过程中未遇到错误,则返回 0。请参考您的 SSL 库文档以查找完整的错误代码列表。
当传入连接通过 SSL/TLS 传输层建立时,如果在验证客户端证书期间检测到第一个错误,则返回该错误在 CA 链中的深度。如果未遇到错误,则返回 0。
当入站连接通过 SSL/TLS 传输层建立时,返回客户端提供的 DER 格式的链证书。当用于 ACL 时,可以以十六进制形式传递要匹配的值。可以使用任何接受 ASN.1 DER 数据的库来解析结果。它目前不支持恢复的会话。
ssl_c_der : binary
当传入连接通过 SSL/TLS 传输层建立时,返回由客户端提供的 DER 格式证书。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
ssl_c_err : integer
当传入连接通过 SSL/TLS 传输层建立时,如果在深度为 0 的验证期间检测到第一个错误,则返回该错误的 ID;如果在此验证过程中未遇到错误,则返回 0。请参考您的 SSL 库文档以查找完整的错误代码列表。
ssl_c_i_dn([<entry>[,<occ>[,<format>]]]) : string
当入站连接通过 SSL/TLS 传输层建立时,在未指定 <entry> 时,返回客户端提供的证书颁发者的完整区分名(Distinguished Name, DN),或者返回从 DN 开始的第一个给定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 的开头/结尾开始的第 n 个给定条目的值。例如,“ssl_c_i_dn(OU,2)”表示第二个组织单位,而“ssl_c_i_dn(CN)”则检索通用名称。<format> 参数允许您获取适合不同协议使用的 DN。目前支持 LDAP v3 的 rfc2253。如果您只想修改格式,可以指定一个空字符串和零作为前两个参数。例如:ssl_c_i_dn(,0,rfc2253)
ssl_c_key_alg : string
当传入连接通过 SSL/TLS 传输层建立时,返回用于生成客户端证书密钥的算法名称。
当传入连接通过 SSL/TLS 传输层建立时,返回客户端证书中显示的结束日期,格式为 YYMMDDhhmmss[Z] 字符串。
当传入连接通过 SSL/TLS 传输层建立时,返回客户端证书中显示的开始日期,格式为 YYMMDDhhmmss[Z] 字符串。
ssl_c_r_dn([<entry>[,<occ>[,<format>]]]) : string
当入站连接通过 SSL/TLS 传输层建立,并且使用配置的 ca-file 成功验证时,在未指定 <entry> 时,返回客户端提供的证书的根 CA 的完整区分名(Distinguished Name, DN),或者返回从 DN 开始的第一个给定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 的开头/结尾开始的第 n 个给定条目的值。例如,“ssl_c_r_dn(OU,2)”表示第二个组织单位,而“ssl_c_r_dn(CN)”则检索通用名称。<format> 参数允许您获取适合不同协议使用的 DN。目前支持 LDAP v3 的 rfc2253。如果您只想修改格式,可以指定一个空字符串和零作为前两个参数。例如:ssl_c_r_dn(,0,rfc2253)
ssl_c_s_dn([<entry>[,<occ>[,<format>]]]) : string
当入站连接通过 SSL/TLS 传输层建立时,在未指定 <entry> 时,返回客户端提供的证书主题的完整区分名(Distinguished Name, DN),或者返回从 DN 开始的第一个给定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 的开头/结尾开始的第 n 个给定条目的值。例如,“ssl_c_s_dn(OU,2)”表示第二个组织单位,而“ssl_c_s_dn(CN)”则检索通用名称。<format> 参数允许您获取适合不同协议使用的 DN。目前支持 LDAP v3 的 rfc2253。如果您只想修改格式,可以指定一个空字符串和零作为前两个参数。例如:ssl_c_s_dn(,0,rfc2253)
ssl_c_serial : binary
当传入连接通过 SSL/TLS 传输层建立时,返回客户端证书的序列号。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
ssl_c_sha1 : binary
当传入连接通过 SSL/TLS 传输层建立时,返回客户端证书的 SHA-1 指纹。这可用于将客户端粘滞到某个服务器,或将此信息传递给服务器。请注意,输出是二进制格式,因此如果要将该签名传递给服务器,您需要将其编码为十六进制或 base64,如下例所示:
示例
http-request set-header X-SSL-Client-SHA1 %[ssl_c_sha1,hex]
ssl_c_sig_alg : string
当传入连接通过 SSL/TLS 传输层建立时,返回用于签署客户端证书的算法名称。
ssl_c_used : boolean
如果当前 SSL 会话使用了客户端证书,则返回 true,即使当前连接使用的是 SSL 会话恢复。另请参阅 "ssl_fc_has_crt"。
ssl_c_verify : integer
当传入连接通过 SSL/TLS 传输层建立时,返回验证结果的错误 ID;如果未遇到错误,则返回零。有关完整的错误代码列表,请参考您的 SSL 库文档。
ssl_c_version : integer
当传入连接通过 SSL/TLS 传输层建立时,返回客户端证书的版本。
ssl_f_der : binary
当传入连接通过 SSL/TLS 传输层建立时,返回前端提供的 DER 格式证书。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
ssl_f_i_dn([<entry>[,<occ>[,<format>]]]) : string
当入站连接通过 SSL/TLS 传输层建立时,在未指定 <entry> 时,返回前端提供的证书颁发者的完整区分名(Distinguished Name, DN),或者返回从 DN 开始的第一个给定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 的开头/结尾开始的第 n 个给定条目的值。例如,“ssl_f_i_dn(OU,2)”表示第二个组织单位,而“ssl_f_i_dn(CN)”则检索通用名称。<format> 参数允许您获取适合不同协议使用的 DN。目前支持 LDAP v3 的 rfc2253。如果您只想修改格式,可以指定一个空字符串和零作为前两个参数。例如:ssl_f_i_dn(,0,rfc2253)
ssl_f_key_alg : string
当传入连接通过 SSL/TLS 传输层建立时,返回用于生成前端证书密钥的算法名称。
当传入连接通过 SSL/TLS 传输层建立时,返回前端证书中显示的结束日期,格式为 YYMMDDhhmmss[Z] 字符串。
当传入连接通过 SSL/TLS 传输层建立时,返回前端证书中显示的开始日期,格式为 YYMMDDhhmmss[Z] 字符串。
ssl_f_s_dn([<entry>[,<occ>[,<format>]]]) : string
当入站连接通过 SSL/TLS 传输层建立时,在未指定 <entry> 时,返回前端提供的证书主题的完整区分名(Distinguished Name, DN),或者返回从 DN 开始的第一个给定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 的开头/结尾开始的第 n 个给定条目的值。例如,“ssl_f_s_dn(OU,2)”表示第二个组织单位,而“ssl_f_s_dn(CN)”则检索通用名称。<format> 参数允许您获取适合不同协议使用的 DN。目前支持 LDAP v3 的 rfc2253。如果您只想修改格式,可以指定一个空字符串和零作为前两个参数。例如:ssl_f_s_dn(,0,rfc2253)
ssl_f_serial : binary
当传入连接通过 SSL/TLS 传输层建立时,返回前端证书的序列号。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
ssl_f_sha1 : binary
当传入连接通过 SSL/TLS 传输层建立时,返回前端证书的 SHA-1 指纹。这可用于了解使用 SNI 选择了哪个证书。
ssl_f_sig_alg : string
当传入连接通过 SSL/TLS 传输层建立时,返回用于签署前端证书的算法名称。
ssl_f_version : integer
当传入连接通过 SSL/TLS 传输层建立时,返回前端证书的版本。
ssl_fc : boolean
当前端连接通过 SSL/TLS 传输层建立并由本地解密时,返回 true。这意味着它匹配了使用 "bind" 行声明的套接字,并且该行具有 "ssl" 选项。
示例
# 当客户端通过 SSL 连接时,向服务器传递 "X-Proto: https" listen http-https bind :80 bind :443 ssl crt /etc/haproxy.pem http-request add-header X-Proto https if { ssl_fc }
当传入连接通过 SSL/TLS 传输层建立时,返回支持的对称加密密钥大小(以位为单位)。
ssl_fc_alpn : string
此项从通过 TLS 传输层建立并由 HAProxy 本地解密的入站连接中提取应用层协议协商(ALPN)字段。结果是包含客户端播发的协议名称的字符串。SSL 库必须在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。请注意,除非在 "bind" 行上使用 "alpn" 关键字指定了协议列表,否则不会播发 TLS ALPN 扩展。此外,没有任何强制要求客户端从该列表中选择协议,客户端可以请求任何其他协议。TLS ALPN 扩展旨在取代 TLS NPN 扩展。另请参阅 "ssl_fc_npn"。
ssl_fc_cipher : string
当传入连接通过 SSL/TLS 传输层建立时,返回所使用的加密套件的名称。
ssl_fc_cipherlist_bin([<filter_option>]) : binary
返回客户端 hello 密码列表的二进制形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。设置 <filter_option> 允许过滤返回的数据。可接受的值:0:返回完整的密码列表(默认)1:从输出中排除 GREASE(RFC8701)值
示例
http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\ %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\ %[ssl_fc_extlist_bin(1),be2dec(-,2)],\ %[ssl_fc_eclist_bin(1),be2dec(-,2)],\ %[ssl_fc_ecformats_bin,be2dec(-,1)] acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \ -f /path/to/file/with/malware-ja3.lst http-request set-header X-Malware True if is_malware http-request set-header X-Malware False if !is_malware
ssl_fc_cipherlist_hex([<filter_option>]) : string
以十六进制编码的形式返回客户端 hello 密码列表的二进制形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。设置 <filter_option> 允许过滤返回的数据。可接受的值:0:返回完整的密码列表(默认)1:从输出中排除 GREASE(RFC8701)值
ssl_fc_cipherlist_str([<filter_option>]) : string
返回客户端 hello 密码列表的已解码文本形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。设置 <filter_option> 允许过滤返回的数据。可接受的值:0:返回完整的密码列表(默认)1:从输出中排除 GREASE(RFC8701)值请注意,此示例获取仅适用于 OpenSSL >= 1.0.2。如果未启用该函数,此示例获取将返回哈希值,如“ssl_fc_cipherlist_xxh”。
返回密码列表的 xxh64 哈希值。此哈希值仅在“tune.ssl.capture-buffer-size”的值大于 0 时才有效,但哈希值考虑了密码列表的所有数据。
ssl_fc_curve : string
当入站连接通过 SSL/TLS 传输层建立时,返回密钥协议(key agreement)中使用的曲线的名称。这需要 OpenSSL >= 3.0.0。
返回客户端 hello 支持的椭圆曲线点格式(elliptic curve point formats)的二进制形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。
示例
http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\ %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\ %[ssl_fc_extlist_bin(1),be2dec(-,2)],\ %[ssl_fc_eclist_bin(1),be2dec(-,2)],\ %[ssl_fc_ecformats_bin,be2dec(-,1)] acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \ -f /path/to/file/with/malware-ja3.lst http-request set-header X-Malware True if is_malware http-request set-header X-Malware False if !is_malware
ssl_fc_eclist_bin([<filter_option>]) : binary
返回客户端 hello 支持的椭圆曲线(elliptic curves)的二进制形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。设置 <filter_option> 允许过滤返回的数据。可接受的值:0:返回支持的椭圆曲线的完整列表(默认)1:从输出中排除 GREASE(RFC8701)值
示例
http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\ %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\ %[ssl_fc_extlist_bin(1),be2dec(-,2)],\ %[ssl_fc_eclist_bin(1),be2dec(-,2)],\ %[ssl_fc_ecformats_bin,be2dec(-,1)] acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \ -f /path/to/file/with/malware-ja3.lst http-request set-header X-Malware True if is_malware http-request set-header X-Malware False if !is_malware
ssl_fc_extlist_bin([<filter_option>]) : binary
返回客户端 hello 扩展列表(extension list)的二进制形式。最大返回值的长度受由“tune.ssl.capture-buffer-size”设置控制的共享捕获缓冲区大小的限制。设置 <filter_option> 允许过滤返回的数据。可接受的值:0:返回完整的扩展列表(默认)1:从输出中排除 GREASE(RFC8701)值
示例
http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\ %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\ %[ssl_fc_extlist_bin(1),be2dec(-,2)],\ %[ssl_fc_eclist_bin(1),be2dec(-,2)],\ %[ssl_fc_ecformats_bin,be2dec(-,1)] acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \ -f /path/to/file/with/malware-ja3.lst http-request set-header X-Malware True if is_malware http-request set-header X-Malware False if !is_malware
当入站连接通过 SSL/TLS 传输层建立时,返回前端连接的客户端随机数(client random)。它对于解密使用临时密码(ephemeral ciphers)发送的流量很有用。这需要 OpenSSL >= 1.1.0,或 BoringSSL。
当通过 TLS 1.3 传输层建立入站连接时,返回 CLIENT_EARLY_TRAFFIC_SECRET 作为十六进制字符串,用于前端连接。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调用于生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志记录必须通过全局部分的“tune.ssl.keylog on”进行激活。另请参阅“tune.ssl.keylog”。
当通过 TLS 1.3 传输层建立入站连接时,返回 CLIENT_HANDSHAKE_TRAFFIC_SECRET 作为十六进制字符串,用于前端连接。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调用于生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志记录必须通过全局部分的“tune.ssl.keylog on”进行激活。另请参阅“tune.ssl.keylog”。
当通过 TLS 1.3 传输层建立入站连接时,返回 CLIENT_TRAFFIC_SECRET_0 作为十六进制字符串,用于前端连接。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调用于生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志记录必须通过全局部分的“tune.ssl.keylog on”进行激活。另请参阅“tune.ssl.keylog”。
当通过 TLS 1.3 传输层建立入站连接时,返回 EXPORTER_SECRET 作为十六进制字符串,用于前端连接。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调用于生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志记录必须通过全局部分的“tune.ssl.keylog on”进行激活。另请参阅“tune.ssl.keylog”。
当通过 TLS 1.3 传输层建立入站连接时,返回 EARLY_EXPORTER_SECRET 作为十六进制字符串,用于前端连接。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调用于生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志记录必须通过全局部分的“tune.ssl.keylog on”进行激活。另请参阅“tune.ssl.keylog”。
ssl_fc_err : integer
当入站连接通过 SSL/TLS 传输层建立时,返回前端端最后一个错误堆栈的第一个错误的 ID,如果没有遇到错误则返回 0。它可用于识别与握手相关的错误(除了验证错误,例如密码不匹配),以及连接生命周期中发生的其他读写错误。客户端证书验证过程中发生的任何错误都不会通过此获取返回,而是通过现有的“ssl_c_err”、“ssl_c_ca_err”和“ssl_c_ca_err_depth”获取返回。为了获得此错误代码的文本描述,您可以使用“ssl_fc_err_str”示例获取,或使用“openssl errstr”命令(该命令以十六进制表示形式的错误代码作为参数)。请参考您的 SSL 库文档以查找错误代码的完整列表。
当入站连接通过 SSL/TLS 传输层建立时,返回前端端发生的最后一个错误堆栈的第一个错误的字符串表示。在客户端证书验证过程中发生的任何错误都不会通过此获取返回。另请参阅“ssl_fc_err”。
ssl_fc_has_crt : boolean
如果传入的 SSL/TLS 传输层连接中存在客户端证书,则返回 true。在 'verify' 语句设置为 'optional' 时很有用。注意:在使用会话 ID 或 TLS 票据进行 SSL 会话恢复时,当前连接中不存在客户端证书,但可以从缓存或票据中检索。因此,如果您想检查当前 SSL 会话是否使用了客户端证书,请优先使用 "ssl_c_used"。
如果发送了早期数据,并且握手尚未发生,则返回 true。由于它具有安全隐患,因此能够拒绝这些数据或等到握手发生后再处理它们非常有用。
ssl_fc_has_sni : boolean
这会检查入站连接是否通过 SSL/TLS 传输层建立,以及是否包含服务器名称指示(Server Name Indication, SNI)TLS 扩展。当入站连接提供 TLS SNI 字段时,返回 true。这需要 SSL 库已构建为支持 TLS 扩展(请检查 haproxy -vv)。
如果通过 SSL/TLS 传输层传入的连接上,SSL/TLS 会话已通过使用 SSL 会话缓存或 TLS 票据得到恢复,则返回 true。
ssl_fc_npn : string
此项从通过 TLS 传输层建立并由 HAProxy 本地解密的入站连接中提取下一协议协商(NPN)字段。结果是包含客户端播发的协议名称的字符串。SSL 库必须在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。请注意,除非在 "bind" 行上使用 "npn" 关键字指定了协议列表,否则不会播发 TLS NPN 扩展。此外,没有任何强制要求客户端从该列表中选择协议,客户端可以请求任何其他协议。请注意,TLS NPN 扩展已被 ALPN 取代。
当传入连接通过 SSL/TLS 传输层建立时,返回所使用的协议的名称。
客户端在会话期间希望通过 TLS 协议进行通信的版本,如客户端 hello 消息所示。此值仅在 "tune.ssl.capture-buffer-size" 的值大于 0 时才返回。
示例
http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\ %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\ %[ssl_fc_extlist_bin(1),be2dec(-,2)],\ %[ssl_fc_eclist_bin(1),be2dec(-,2)],\ %[ssl_fc_ecformats_bin,be2dec(-,1)] acl is_malware req.fhdr(x-ssl-ja3),digest(md5),hex \ -f /path/to/file/with/malware-ja3.lst http-request set-header X-Malware True if is_malware http-request set-header X-Malware False if !is_malware
当连接通过 SSL/TLS 传输层建立时,返回 RFC5929 第 3 节中定义的 TLS 唯一 ID。可以使用转换器 "ssl_fc_unique_id,base64" 将唯一 ID 编码为 base64。
当传入连接通过 TLS 1.3 传输层建立时,以十六进制字符串形式返回前端连接的 SERVER_HANDSHAKE_TRAFFIC_SECRET。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调函数转储以生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志必须在全局部分使用 "tune.ssl.keylog on" 激活。另请参阅 "tune.ssl.keylog"
当传入连接通过 TLS 1.3 传输层建立时,以十六进制字符串形式返回前端连接的 SERVER_TRAFFIC_SECRET_0。需要 OpenSSL >= 1.1.1。这是 OpenSSL keylog 回调函数转储以生成 SSLKEYLOGFILE 的密钥之一。SSL 密钥日志必须在全局部分使用 "tune.ssl.keylog on" 激活。另请参阅 "tune.ssl.keylog"
在连接通过 SSL/TLS 传输层建立时,返回前端连接的服务器随机数。这对于解密使用临时密码发送的流量非常有用。这需要 OpenSSL >= 1.1.0 或 BoringSSL。
当传入连接通过 SSL/TLS 传输层建立时,返回前端连接的 SSL ID。这对于将给定客户端粘滞到某个服务器很有用。需要注意的是,某些浏览器每隔几分钟就会刷新其会话 ID。
在连接通过 SSL/TLS 传输层建立时,返回前端连接的 SSL 会话主密钥。这对于解密使用临时密码发送的流量非常有用。这需要 OpenSSL >= 1.1.0 或 BoringSSL。
ssl_fc_sni : string
此项从通过 SSL/TLS 传输层建立并由 HAProxy 本地解密的入站连接中提取服务器名称指示(SNI)TLS 扩展字段。结果(如果存在)通常是匹配 HTTPS 主机名(253 个字符或更少)的字符串。SSL 库必须在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。此抓取与上面的 "req.ssl_sni" 不同,因为它适用于 HAProxy 正在解密的连接,而不是盲目转发的 SSL 内容。另请参阅下面的 "ssl_fc_sni_end" 和 "ssl_fc_sni_reg"。这要求 SSL 库在构建时启用了对 TLS 扩展的支持(检查 haproxy -vv)。注意!除了在非常特定的条件下,通常不应使用此字段替代 HTTP "Host" 标头字段。例如,当将 HTTPS 连接转发到服务器时,SNI 字段必须使用 "req.hdr(host)" 从 HTTP Host 标头字段设置,而不是从前端 SNI 值设置。原因是 SNI 仅用于选择服务器端将呈现的证书,并且客户端被允许发送具有不同 Host 值的请求,只要它们匹配证书中的名称即可。因此,"ssl_fc_sni" 通常不应作为 "sni" 服务器关键字的参数使用,除非后端在 TCP 模式下工作。ACL 衍生:ssl_fc_sni_end:后缀匹配 ssl_fc_sni_reg:正则表达式匹配
当传入连接通过 SSL/TLS 传输层建立时,返回实际使用的对称加密密钥大小(以位为单位)。
ssl_s_der : binary
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的 DER 格式的证书。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的 DER 格式的链证书。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。可以使用任何接受 ASN.1 DER 数据的库来解析结果。它目前不支持恢复的会话。
ssl_s_key_alg : string
当出站连接通过 SSL/TLS 传输层建立时,返回用于生成服务器呈现的证书密钥的算法名称。
当出站连接通过 SSL/TLS 传输层建立时,以 YYMMDDhhmmss[Z] 格式的字符串返回服务器呈现的到期日期。
当出站连接通过 SSL/TLS 传输层建立时,以 YYMMDDhhmmss[Z] 格式的字符串返回服务器呈现的开始日期。
ssl_s_i_dn([<entry>[,<occ>[,<format>]]]) : string
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的证书颁发者的完整专有名称,如果没有指定 <entry>,或者返回从 DN 开始找到的第一个指定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 开始/结束的第 n 个指定条目的值。例如,“ssl_s_i_dn(OU,2)”返回第二个组织单元,“ssl_s_i_dn(CN)”返回通用名称。<format> 参数允许您获取适合不同协议使用的 DN 格式。目前支持 rfc2253 用于 LDAP v3。如果您只想修改格式,您可以指定一个空字符串和零作为前两个参数。示例:ssl_s_i_dn(,0,rfc2253)
ssl_s_s_dn([<entry>[,<occ>[,<format>]]]) : string
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的证书主体的完整专有名称,如果没有指定 <entry>,或者返回从 DN 开始找到的第一个指定条目的值。如果指定了正数/负数的出现次数作为可选的第二个参数,则返回从 DN 开始/结束的第 n 个指定条目的值。例如,“ssl_s_s_dn(OU,2)”返回第二个组织单元,“ssl_s_s_dn(CN)”返回通用名称。<format> 参数允许您获取适合不同协议使用的 DN 格式。目前支持 rfc2253 用于 LDAP v3。如果您只想修改格式,您可以指定一个空字符串和零作为前两个参数。示例:ssl_s_s_dn(,0,rfc2253)
ssl_s_serial : binary
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的证书序列号。当用于 ACL 时,用于匹配的值可以以十六进制形式传递。
ssl_s_sha1 : binary
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的证书的 SHA-1 指纹。这可以用来知道使用 SNI 选择的证书。
ssl_s_sig_alg : string
当出站连接通过 SSL/TLS 传输层建立时,返回用于签名服务器呈现的证书的算法名称。
ssl_s_version : integer
当出站连接通过 SSL/TLS 传输层建立时,返回服务器呈现的证书的版本。
txn.timer.user : integer
从客户端看到的总估计时间,从代理接受它到双方都关闭,不包括空闲时间。这相当于日志格式中的 %Tu,并以毫秒 (ms) 为单位报告。有关更多详细信息,请参阅第 8.4 节“计时事件”。

7.3.5. 从缓冲区内容(第 6 层)获取样本

从缓冲区内容中抓取样本与上面先前的样本抓取有所不同,因为样本数据是短暂的。这些数据只能在可用时使用,转发后就会丢失。因此,在请求期间从缓冲区内容中抓取的样本无法在响应中使用。即使在抓取数据时,它们也可能发生变化。有时需要设置一些延迟或结合多种样本抓取方法来确保预期数据完整且可用,例如通过 TCP 请求内容检查。有关该主题的更多详细信息,请参阅 "tcp-request content" 关键字。警告:如果从 HTTP 代理中使用,则会忽略以下样本抓取。它们只处理缓冲区中的原始内容。HTTP 代理使用结构化内容。因此,这些数据的原始表示没有意义。如果 ACL 依赖于以下某个样本抓取,则会发出警告。但无法检测所有无效用法(例如在 log-format 字符串或样本表达式中)。因此请谨慎使用。本节中样本抓取方法及其相应类型的摘要
关键字输出类型
bs.id整数
distcc_body(<token>[,<occ>])二进制
distcc_param(<token>[,<occ>])整数
fs.id整数
payload(<offset>,<length>)二进制
payload_lv(<offset1>,<length>[,<offset2>])二进制
req.len整数
req_len整数
req.payload(<offset>,<length>)二进制
req.payload_lv(<offset1>,<length>[,<offset2>])二进制
req.proto_http布尔
req_proto_http布尔
req.rdp_cookie([<name>])字符串
rdp_cookie([<name>])字符串
req.rdp_cookie_cnt([name])整数
rdp_cookie_cnt([name])整数
req.ssl_alpn字符串
req.ssl_ec_ext布尔
req.ssl_hello_type整数
req_ssl_hello_type整数
req.ssl_sni字符串
req_ssl_sni字符串
req.ssl_st_ext整数
req.ssl_ver整数
req_ssl_ver整数
res.len整数
res.payload(<offset>,<length>)二进制
res.payload_lv(<offset1>,<length>[,<offset2>])二进制
res.ssl_hello_type整数
rep_ssl_hello_type整数
详细列表
bs.id : 整数
返回服务器端的复用器(multiplexer)流 ID。由复用器负责返回适当的信息。
distcc_body(<token>[,<occ>]) : binary
解析 distcc 消息并返回与 token <token> 的 occurrence #<occ> 关联的正文。Occurrence 从 1 开始,如果未指定,则任何 occurrence 都可能匹配,但实际上目前只检查第一个。这可以用于提取通过 HAProxy 构建的文件中的文件名或参数。有关支持的 token 的完整列表,请参阅 distcc 的协议文档。
distcc_param(<token>[,<occ>]) : integer
解析 distcc 消息并返回与 token <token> 的 occurrence #<occ> 关联的参数。Occurrence 从 1 开始,如果未指定,则任何 occurrence 都可能匹配,但实际上目前只检查第一个。这可以用于提取某些信息,例如协议版本、文件大小或通过 HAProxy 构建的文件中的参数。另一个用例是在连接到服务器之前等待预处理文件内容,以避免保持空闲连接。有关支持的 token 的完整列表,请参阅 distcc 的协议文档。
示例
# 等待预处理文件上传最多 20 秒 tcp-request inspect-delay 20s tcp-request content accept if { distcc_param(DOTI) -m found } # 将大文件发送到大型服务器场 use_backend big_farm if { distcc_param(DOTI) gt 1000000 }
fs.id : 整数
返回客户端的复用器(multiplexer)流 ID。由复用器负责返回适当的信息。例如,在原始 TCP 上,总是返回 0,因为没有流。
payload(<offset>,<length>) : binary (已弃用)
这是 "req.payload" 在请求上下文(例如,“stick on”、“stick match”)中的别名,在响应上下文(例如“stick store response”)中是 "res.payload" 的别名。
payload_lv(<offset1>,<length>[,<offset2>]) : binary (已弃用)
这是 "req.payload_lv" 在请求上下文(例如,“stick on”、“stick match”)中的别名,在响应上下文(例如“stick store response”)中是 "res.payload_lv" 的别名。
req.len : integer
req_len : integer (已弃用)
返回请求缓冲区中存在的字节数。这主要用于 ACL。重要的是要理解,只要缓冲区在变化,此测试就不会返回 false。这意味着等于零的检查几乎总是在会话开始时立即匹配,而对更多数据的测试将等待数据进入,直到 HAProxy 确定不再有数据进来时才返回 false。此测试旨在与 TCP 请求内容检查一起使用。
req.payload(<offset>,<length>) : binary
这会从请求缓冲区中提取 <length> 字节的二进制块,从字节 <offset> 开始。作为特殊情况,如果 <length> 参数为零,则提取从 <offset> 到末尾的整个缓冲区。这可以与 ACL 一起使用,以检查缓冲区中任何位置是否存在某些内容。ACL 派生:req.payload(<offset>,<length>):十六进制二进制匹配
req.payload_lv(<offset1>,<length>[,<offset2>]) : binary
这会提取一个二进制块,其大小由 <offset1> 指定 <length> 字节,如果指定了 <offset2>,则从该位置开始,否则紧跟在请求缓冲区中的长度之后。<offset2> 参数如果以 '+' 或 '-' 符号开头,也支持相对偏移。ACL 派生:req.payload_lv(<offset1>,<length>[,<offset2>]):十六进制二进制匹配
示例
请参考 "stick store-response" 关键字中的示例。
req.proto_http : boolean
req_proto_http : boolean (已弃用)
当请求缓冲区中的数据看起来像 HTTP 并且能被正确解析时,返回 true。它与通用的 HTTP 请求解析器相同,因此应该不会有意外。在请求完成、失败或超时之前,此测试不会匹配。此测试可用于在 TCP 日志中报告协议,但最大的用途是阻止 TCP 请求分析,直到缓冲区中出现完整的 HTTP 请求,例如为了跟踪某个头部。
示例
# 按 "base"(Host+URL 的拼接)跟踪请求计数 tcp-request inspect-delay 10s tcp-request content reject if !HTTP tcp-request content track-sc0 base table req-rate
req.rdp_cookie([<name>]) : string
rdp_cookie([<name>]) : string (已弃用)
当请求缓冲区看起来像 RDP 协议时,提取 RDP cookie <name>,或者在未指定时提取任何 cookie。解析器仅检查第一个 cookie,如 RDP 协议规范所示。cookie 名称不区分大小写。通常使用 "MSTS" cookie 名称,因为它可能包含连接到服务器的客户端用户名(如果客户端配置正确)。"MSTSHASH" cookie 也经常用于会话粘性到服务器。这与 "balance rdp-cookie" 不同,因为可以使用任何平衡算法,因此客户端到后端服务器的分布与 RDP cookie 的哈希值无关。设想使用 "balance roundrobin" 或 "balance leastconn" 等平衡算法将导致客户端到后端服务器的分布比 "balance rdp-cookie" 的哈希值更均匀。ACL 派生:req.rdp_cookie([<name>]):精确字符串匹配
示例
listen tse-farm bind 0.0.0.0:3389 # 在请求中等待 RDP cookie 最多 5 秒 tcp-request inspect-delay 5s tcp-request content accept if RDP_COOKIE # 应用 RDP cookie 持久性 persist rdp-cookie # 基于 mstshash cookie 进行持久化 # 仅在不使用 balance rdp-cookie 时 # 才有意义 stick-table type string size 204800 stick on req.rdp_cookie(mstshash) server srv1 1.1.1.1:3389 server srv1 1.1.1.2:3389
req.rdp_cookie_cnt([name]) : integer
rdp_cookie_cnt([name]) : integer (已弃用)
尝试将请求缓冲区解析为 RDP 协议,然后返回一个整数,表示找到的 RDP cookie 的数量。如果提供了可选的 cookie 名称,则只考虑匹配该名称的 cookie。这主要用于 ACL。ACL 派生:req.rdp_cookie_cnt([<name>]):整数匹配
req.ssl_alpn : string
返回一个字符串,其中包含客户端在 SSL ClientHello 消息中发送的应用层协议协商(ALPN)TLS 扩展(RFC7301)的值。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。这对于 ACL 非常有用,可以根据 TLS 客户端的 ALPN 首选项进行路由决策,如下面的示例所示。另请参阅 "ssl_fc_alpn"。
示例
# 等待客户端 hello 最多 5 秒 tcp-request inspect-delay 5s tcp-request content accept if { req.ssl_hello_type 1 } use_backend bk_acme if { req.ssl_alpn acme-tls/1 } default_backend bk_default
req.ssl_ec_ext : boolean
返回一个布尔值,用于标识客户端是否在 SSL ClientHello 消息中发送了 RFC4492 第 5.1 节中定义的“支持的椭圆曲线扩展”。这可用于向兼容 ECC 的客户端提供 EC 证书,并对所有其他客户端使用 RSA,在同一 IP 地址上。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。
req_ssl_hello_type : integer (已弃用)
如果缓冲区包含可解析为完整 SSL(v3 或更高版本)客户端 hello 消息的数据,则返回一个整数值,其中包含请求缓冲区中找到的 SSL hello 消息的类型。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。这主要用于 ACL 中,以检测是否存在包含可用于粘性会话的 SSL 会话 ID 的 SSL hello 消息。
req.ssl_sni : string
req_ssl_sni : string (已弃用)
如果缓冲区包含可解析为完整 SSL(v3 或更高版本)客户端 hello 消息的数据,则返回一个字符串,其中包含通过请求缓冲区传递的 TLS 流中客户端发送的服务器名称 TLS 扩展的值。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。这仅适用于实际隐式基于 TLS 的协议,如 HTTPS (443)、IMAPS (993)、SMTPS (465),但不适用于显式基于 TLS 的协议,如 SMTP (25/587) 或 IMAP (143)。SNI 通常包含客户端尝试连接的主机名(对于新版浏览器)。当客户端使用 SSL/TLS 时,SNI 对于允许或拒绝访问某些主机非常有用。此测试旨在与 TCP 请求内容检查一起使用。如果需要内容切换,建议首先等待完整的客户端 hello(类型 1),如下面的示例所示。另请参阅 "ssl_fc_sni"。ACL 衍生:req.ssl_sni:精确字符串匹配
示例
# 等待客户端 hello 最多 5 秒 tcp-request inspect-delay 5s tcp-request content accept if { req.ssl_hello_type 1 } use_backend bk_allow if { req.ssl_sni -f allowed_sites } default_backend bk_sorry_page
req.ssl_st_ext : integer
如果客户端未发送 SessionTicket TLS 扩展(RFC5077),则返回 0。如果客户端发送了 SessionTicket TLS 扩展,则返回 1。如果客户端还发送了非零长度的 TLS SessionTicket,则返回 2。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。例如,这可用于检测客户端是否发送了 SessionTicket,并相应地进行粘性处理,如果没有 SessionTicket,则基于 SessionID 进行粘性处理,或者不进行粘性处理,因为在使用 SessionTickets 时没有服务器端状态。
req.ssl_ver : integer
req_ssl_ver : integer (已弃用)
返回一个整数值,其中包含请求缓冲区中存在的流的 SSL/TLS 协议版本。支持 SSLv2 hello 消息和 SSLv3 消息。TLSv1 被宣布为 SSL 版本 3.1。该值由主版本乘以 65536,加上次版本组成。请注意,这仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "bind" 行。ACL 版本的测试匹配格式为 MAJOR.MINOR(例如 3.1)的十进制表示法。此抓取主要用于 ACL。ACL 衍生:req.ssl_ver:十进制匹配
res.len : integer
返回响应缓冲区中存在的字节数的整数值。这主要用于 ACL。重要的是要理解,只要缓冲区在变化,此测试就不会返回 false。这意味着等于零的检查几乎总是在流开始时立即匹配,而对更多数据的测试将等待数据进入,直到 HAProxy 确定不再有数据进来时才返回 false。此测试旨在与 TCP 响应内容检查一起使用。但也可用于基于 tcp-check 的 expect 规则。
res.payload(<offset>,<length>) : binary
这会从响应缓冲区中提取 <length> 字节的二进制块,从字节 <offset> 开始。作为特殊情况,如果 <length> 参数为零,则提取从 <offset> 到末尾的整个缓冲区。这可以与 ACL 一起使用,以检查缓冲区中任何位置是否存在某些内容。它也可用于基于 tcp-check 的 expect 规则。
res.payload_lv(<offset1>,<length>[,<offset2>]) : binary
这会提取一个二进制块,其大小由 <offset1> 指定 <length> 字节,如果指定了 <offset2>,则从该位置开始,否则紧跟在响应缓冲区中的长度之后。<offset2> 参数如果以 '+' 或 '-' 符号开头,也支持相对偏移。它也可用于基于 tcp-check 的 expect 规则。
示例
请参考 "stick store-response" 关键字中的示例。
rep_ssl_hello_type : integer (已弃用)
如果响应缓冲区包含可解析为完整 SSL(v3 或更高版本)hello 消息的数据,则返回一个整数值,其中包含响应缓冲区中找到的 SSL hello 消息的类型。请注意,这仅适用于响应缓冲区中的原始内容,不适用于通过 SSL 数据层解密的内容,因此这不适用于带有 "ssl" 选项的 "server" 行。这主要用于 ACL 中,以检测是否存在包含可用于粘性会话的 SSL hello 消息。

7.3.6. 获取 HTTP 样本 (第 7 层)

可以从 HTTP 内容、请求和响应中抓取样本。此应用层也称为第 7 层。只有当从其各自的请求或响应缓冲区解析出完整的 HTTP 请求或响应时,才能抓取此部分中的数据。对于所有 HTTP 特定规则以及以 "mode http" 运行的部分,情况总是如此。使用 TCP 内容检查时,可能需要支持检查延迟,以便先让请求或响应进来。这些抓取可能比第 4 层的抓取需要更多的 CPU 资源,但由于请求和响应已建立索引,所以不会多很多。注意:对于来自 tcp-request content 规则的 HTTP 处理,一切都将像来自 HTTP 代理一样正常工作。但是,对于 TCP 代理,如果没有 HTTP 升级,它仅适用于 HTTP/1 内容。对于 HTTP/2 内容,只有序言可见。因此,只能依赖 "req.proto_http"、"req.ver" 以及最终的 "method" 样本抓取。所有其他 L7 样本抓取都将失败。在 HTTP 升级之后,它们将以与 HTTP 代理相同的方式工作。本节中样本抓取方法及其相应类型的摘要
关键字输出类型
base字符串
base32整数
base32+src二进制
baseq字符串
capture.req.hdr(<idx>)字符串
capture.req.method字符串
capture.req.uri字符串
capture.req.ver字符串
capture.res.hdr(<idx>)字符串
capture.res.ver字符串
req.body二进制
req.body_param([<name>[,i]])字符串
req.body_len整数
req.body_size整数
req.cook([<name>])字符串
cook([<name>])字符串
req.cook_cnt([<name>])整数
cook_cnt([<name>])整数
req.cook_val([<name>])整数
cook_val([<name>])整数
关键字输出类型
req.cook_names([<delim>])字符串
cookie([<name>])字符串
hdr([<name>[,<occ>]])字符串
request_date([<unit>])整数
req.fhdr(<name>[,<occ>])字符串
req.fhdr_cnt([<name>])整数
req.hdr([<name>[,<occ>]])字符串
req.hdr_cnt([<name>])整数
hdr_cnt([<header>])整数
req.hdr_ip([<name>[,<occ>]])ip
hdr_ip([<name>[,<occ>]])ip
req.hdr_val([<name>[,<occ>]])整数
hdr_val([<name>[,<occ>]])整数
req.hdrs字符串
req.hdrs_bin二进制
req.timer.hdr整数
req.timer.idle整数
req.timer.queue整数
req.timer.tq整数
res.timer.hdr整数
关键字输出类型
http_auth(<userlist>)布尔
http_auth_bearer([<header>])字符串
http_auth_group(<userlist>)字符串
http_auth_pass字符串
http_auth_type字符串
http_auth_user字符串
http_first_req布尔
method整数
path字符串
pathq字符串
query字符串
req.hdr_names([<delim>])字符串
req.ver字符串
req_ver字符串
res.body二进制
res.body_len整数
res.body_size整数
res.cache_hit布尔
res.cache_name字符串
res.comp布尔
关键字输出类型
res.comp_algo字符串
res.cook([<name>])字符串
scook([<name>])字符串
res.cook_cnt([<name>])整数
scook_cnt([<name>])整数
res.cook_val([<name>])整数
scook_val([<name>])整数
res.cook_names([<delim>])字符串
res.fhdr([<name>[,<occ>]])字符串
res.fhdr_cnt([<name>])整数
res.hdr([<name>[,<occ>]])字符串
shdr([<name>[,<occ>]])字符串
res.hdr_cnt([<name>])整数
shdr_cnt([<name>])整数
res.hdr_ip([<name>[,<occ>]])ip
shdr_ip([<name>[,<occ>]])ip
res.hdr_names([<delim>])字符串
res.hdr_val([<name>[,<occ>]])整数
shdr_val([<name>[,<occ>]])整数
res.hdrs字符串
关键字输出类型
res.hdrs_bin二进制
res.ver字符串
resp_ver字符串
server_status整数
set-cookie([<name>])字符串
status整数
txn.status整数
txn.timer.total整数
unique-id字符串
url字符串
url_ipip
url_port整数
urlp([<name>[,<delim>[,i]]])字符串
url_param([<name>[,<delim>[,i]]])字符串
urlp_val([<name>[,<delim>[,i]]])整数
url32整数
url32+src二进制
详细列表
base : string
此函数返回第一个 Host 头部和请求路径部分的拼接,路径部分从第一个斜杠开始,到问号之前结束。在虚拟托管环境中,这对于检测 URL 滥用以及提高共享缓存效率很有用。将其与有限大小的粘滞表一起使用,还可以收集有关按主机/路径最常请求对象的数据。通过 ACL,它可以实现涉及主机和路径的简单内容切换规则,例如 "www.example.com/favicon.ico"。另请参阅 "path" 和 "uri"。ACL 派生词:base:精确字符串匹配 base_beg:前缀匹配 base_dir:子目录匹配 base_dom:域名匹配 base_end:后缀匹配 base_len:长度匹配 base_reg:正则表达式匹配 base_sub:子串匹配
base32 : integer
此函数返回上面 "base" 获取方法返回值的 32 位哈希值。这对于在高流量网站上跟踪每个 URL 的活动很有用,而无需存储所有 URL。相反,存储一个更短的哈希值,可以节省大量内存。输出类型是无符号整数。使用的哈希函数是 SDBM,输出具有完全雪崩效应。技术上,base32 完全等同于 "base,sdbm(1)"。
base32+src : binary
此函数返回上面 base32 获取结果和下面 src 获取结果的拼接。结果类型为 binary,大小为 8 或 20 字节,具体取决于源地址族。这可用于跟踪每个 IP、每个 URL 的计数器。
baseq : string
这会返回第一个 Host 标头与请求的路径部分(包含查询字符串)的连接,路径从第一个斜杠开始。使用此项而不是“base”可以正确标识目标资源,用于统计或缓存用例。另请参阅“path”、“pathq”和“base”。
capture.req.hdr(<idx>) : string
此函数提取由 "capture request header" 捕获的头部内容,idx 是 capture 关键字在配置中的位置。
此函数提取 HTTP 请求的 METHOD。它可以在请求和响应中使用。与 "method" 不同,因为它被分配了内存,所以可以在请求和响应中使用。
capture.req.uri : string
此函数提取请求的 HTTP 版本,并返回 "HTTP/1.0" 或 "HTTP/1.1"。与 "req.ver" 不同,因为它依赖于一个持久性标志,所以可以在请求、响应和日志中使用。
capture.res.hdr(<idx>) : string
此函数提取由 "capture response header" 捕获的头部内容,idx 是 capture 关键字在配置中的位置。第一个条目的索引为 0。
此函数提取响应的 HTTP 版本,并返回 "HTTP/1.0" 或 "HTTP/1.1"。与 "res.ver" 不同,因为它依赖于一个持久性标志,所以可以在日志中使用。
req.body : binary
这会返回 HTTP 请求的可用正文作为数据块。建议使用 "option http-buffer-request" 来确保尽可能等待请求的正文。
req.body_param([<name>[,i]]) : string
此获取假定 POST 请求的正文是 url 编码的。用户可以检查“content-type”是否包含值“application/x-www-form-urlencoded”。这会提取正文中参数 <name> 的第一次出现,该参数在 '&' 之前结束。参数名称区分大小写,除非添加 "i" 作为第二个参数。如果未给出名称,则任何参数都将匹配,并返回第一个。结果是对应于请求正文中参数 <name> 值的字符串(不执行 URL 解码)。请注意,此获取的 ACL 版本会迭代多个参数,如果未给出名称,则会迭代并报告所有参数值。
req.body_len : integer
这会返回 HTTP 请求可用正文的长度(以字节为单位)。如果正文大于缓冲区,则其长度可能小于广告长度。建议使用 "option http-buffer-request" 来确保尽可能等待请求的正文。
req.body_size : integer
这会返回 HTTP 请求正文的广告长度(以字节为单位)。它将代表广告的 Content-Length 标头,或在分块编码情况下可用数据的大小。
req.cook([<name>]) : string
cook([<name>]) : string (已弃用)
这会从请求的“Cookie”头行中提取Cookie名称<name>的最后一个出现项,并将其值作为字符串返回。如果未指定名称,则返回第一个cookie值。当与ACL一起使用时,会评估所有匹配的cookie。根据Cookie头规范(RFC6265)的要求,忽略名称和值周围的空格。Cookie名称区分大小写。空Cookie是有效的,因此如果存在,空Cookie可能会返回空值。使用“found”匹配来检测存在。使用res.cook()变体来处理服务器发送的响应Cookie。ACL派生:req.cook([<name>]):精确字符串匹配req.cook_beg([<name>]):前缀匹配req.cook_dir([<name>]):子目录匹配req.cook_dom([<name>]):域匹配req.cook_end([<name>]):后缀匹配req.cook_len([<name>]):长度匹配req.cook_reg([<name>]):正则表达式匹配req.cook_sub([<name>]):子字符串匹配
req.cook_cnt([<name>]) : integer
cook_cnt([<name>]) : integer (已弃用)
返回一个整数值,表示名为 <name> 的 cookie 在请求中出现的次数;如果未指定 <name>,则表示所有 cookie 的数量。
req.cook_val([<name>]) : integer
cook_val([<name>]) : integer (已弃用)
此函数从请求的 "Cookie" 头部行中提取名为 <name> 的 cookie 的最后一次出现,并将其值转换为整数返回。如果未指定名称,则返回第一个 cookie 的值。在 ACL 中使用时,将遍历所有匹配的名称,直到找到一个匹配的值。
req.cook_names([<delim>]) : string
在规则求值时,此函数会创建一个字符串,该字符串由请求(Cookie 标头)中出现的所有 cookie 名称连接而成。默认分隔符是逗号 (','),但可以作为可选参数 <delim> 覆盖。在这种情况下,只考虑 <delim> 的第一个字符。
cookie([<name>]) : string (已弃用)
从请求的“Cookie”标头行中提取 cookie 名称 <name> 的最后一次出现,或从响应的“Set-Cookie”标头中提取,并返回其值作为字符串。典型的用途是让共享相同配置文件的多个客户端使用相同的服务器。这可以与“appsession”通过“request-learn”语句所做的类似,但支持多对同步和跨重启的状态保持。如果未指定名称,则返回第一个 cookie 值。此获取不应再使用,应替换为 req.cook() 或 res.cook(),因为它根据使用它的上下文含糊地使用方向。
hdr([<name>[,<occ>]]) : string
在请求上使用时,此函数等同于 req.hdr();在响应上使用时,等同于 res.hdr()。有关更多详细信息,请参考这些各自的获取。如果不确定获取方向,请使用明确的函数。请注意,与 hdr() 样本获取方法相反,hdr_* ACL 关键字明确地应用于请求头部。
request_date([<unit>]) : integer
这表示 HAProxy 收到 HTTP 请求第一个字节的确切日期(log-format 标签 %tr)。它是根据 accept_date + 握手时间 (%Th) + 空闲时间 (%Ti) 计算得出的。返回自纪元以来的秒数。<unit> 是可选的,可以设置为 "s" 表示秒(默认行为),"ms" 表示毫秒或 "us" 表示微秒。如果设置了 unit,则返回值是一个整数,反映自纪元以来的秒数、毫秒数或微秒数。当需要小于一秒的时间分辨率时非常有用。
req.fhdr(<name>[,<occ>]) : string
返回 HTTP 请求中标头 <name> 的最后一次出现的完整值。它与 req.hdr() 的区别在于,它会返回值中存在的任何逗号,而不会将它们用作分隔符。这有时对 User-Agent 等标头很有用。从 ACL 使用时,会迭代所有出现直到找到匹配。可选地,可以通过位置编号指定特定的出现次数。正数表示从第一次出现开始的位置,1 是第一个。负数表示相对于最后一个的位置,-1 是最后一个。一个典型的用途是与 X-Forwarded-For 标头(在转换为 IP 后)相关联。
req.fhdr_cnt([<name>]) : integer
返回请求标头字段名称 <name> 的出现次数的整数值,如果未指定 <name>,则返回总标头字段数。与 req.fhdr() 不同,它不会在逗号处分割标头。ACL 中,它可以用于检测特定标头的存在、不存在或滥用,以及通过拒绝包含多个特定标头的请求来阻止请求伪装攻击。有关标头匹配的更多信息,请参阅 req.hdr()。
req.hdr([<name>[,<occ>]]) : string
此项返回 HTTP 请求中标头 <name> 的最后一个逗号分隔值。抓取将任何逗号视为不同值的分隔符。如果您需要处理定义为值列表的标头(例如 Accept 或 X-Forwarded-For),这将非常有用。如果需要完整的行标头,请改用 req.fhdr()。请仔细检查 RFC 7231 以了解某些标头应如何解析。此外,其中一些不区分大小写(例如 Connection)。当从 ACL 使用时,会迭代所有出现次数,直到找到匹配项。或者,可以指定特定出现次数的位置编号。正值表示从第一次出现的位置开始,1 是第一次出现。负值表示相对于最后一次出现的位置,-1 是最后一次出现。典型的用法是与 X-Forwarded-For 标头(一旦转换为 IP)关联,并与 IP stick-table 关联。ACL 衍生:hdr([<name>[,<occ>]]):精确字符串匹配 hdr_beg([<name>[,<occ>]]):前缀匹配 hdr_dir([<name>[,<occ>]]):子目录匹配 hdr_dom([<name>[,<occ>]]):域匹配 hdr_end([<name>[,<occ>]]):后缀匹配 hdr_len([<name>[,<occ>]]):长度匹配 hdr_reg([<name>[,<occ>]]):正则表达式匹配 hdr_sub([<name>[,<occ>]]):子字符串匹配
req.hdr_cnt([<name>]) : integer
hdr_cnt([<header>]) : integer (已弃用)
返回请求标头字段名称 <name> 的出现次数的整数值,如果未指定 <name>,则返回所有标头字段值。与 req.hdr() 一样,它计算标头值中每个逗号分隔的部分。如果需要计算完整的行标头,则应改用 req.fhdr_cnt()。使用 ACL,它可以用于检测特定标头的存在、不存在或滥用,以及通过拒绝包含多个特定标头的请求来阻止请求伪装攻击。有关更多信息,请参阅 req.hdr()。
req.hdr_ip([<name>[,<occ>]]) : ip
hdr_ip([<name>[,<occ>]]) : ip (已弃用)
提取 HTTP 请求中最后一个标头 <name> 的值,将其转换为 IPv4 或 IPv6 地址,并返回该地址。与 ACL 一起使用时,会检查所有出现;如果省略 <name>,则检查每个标头的所有值。解析器严格遵循 RFC7239 中描述的格式,并扩展支持 IPv4 地址后面可选地跟着一个冒号 (':') 和一个有效的十进制端口号(0 到 65535),该端口号将被静默删除。所有其他格式将不匹配并导致地址被忽略。<occ> 参数的处理方式与 req.hdr() 相同。典型的用法是 X-Forwarded-For 和 X-Client-IP 标头。
req.hdr_val([<name>[,<occ>]]) : integer
hdr_val([<name>[,<occ>]]) : integer (已弃用)
提取 HTTP 请求中最后一个标头 <name> 的值,并将其转换为整数值。与 ACL 一起使用时,会检查所有出现;如果省略 <name>,则检查每个标头的所有值。<occ> 参数的处理方式与 req.hdr() 相同。典型的用法是 X-Forwarded-For 标头。
req.hdrs : string
以字符串形式返回当前请求标头,包括分隔标头和请求正文的最后空行。最后空行可用于检测截断的标头块。此样本获取对于某些 SPOE 标头分析器和高级日志记录非常有用。
req.hdrs_bin : binary
以预解析的二进制形式返回当前请求标头。这对于使用 SPOE 进行部分处理非常有用。每个字符串由长度后面跟着长度指示的字节数描述。长度使用 SPOE 文档中详细的可变整数编码表示。列表的末尾由一对空标头名称和值(长度均为 0)标记。*(<str:header-name><str:header-value>)<empty string><empty string> int:参考 SPOE 文档的编码 str:<int:length><bytes>
req.timer.hdr : integer
获取客户端请求的总时间(仅限 HTTP 模式)。这是从接收到第一个字节到代理接收到标记 HTTP 标头结束的空行之间经过的时间。以毫秒 (ms) 为单位报告,相当于日志格式中的 %TR。有关更多详细信息,请参阅第 8.4 节“计时事件”。
req.timer.idle : integer
这是 HTTP 请求之前的空闲时间(仅限 HTTP 模式)。此计时器在握手结束和 HTTP 请求的第一个字节之间进行计数。以毫秒为单位报告,相当于日志格式中的 %Ti。有关更多详细信息,请参阅第 8.4 节“计时事件”。
req.timer.queue : integer
在队列中等待连接槽的总时间。以毫秒为单位报告,相当于日志格式中的 %Tw。有关更多详细信息,请参阅第 8.4 节“计时事件”。
req.timer.tq : integer
从接受日期或自上一个响应的最后一个字节发出以来,获取客户端请求的总时间。以毫秒为单位报告,相当于日志格式中的 %Tq。有关更多详细信息,请参阅第 8.4 节“计时事件”。
res.timer.hdr : integer
这是从建立到服务器的 TCP 连接到服务器发送其完整响应标头之间经过的时间。以毫秒为单位报告,相当于日志格式中的 %Tr。有关更多详细信息,请参阅第 8.4 节“计时事件”。
http_auth(<userlist>) : boolean
返回一个布尔值,指示从客户端收到的身份验证数据是否与指定用户列表中存储的用户名和密码匹配。此获取函数在 ACL 之外并不真正有用。目前仅支持 http 基本身份验证。
http_auth_bearer([<header>]) : string
返回客户端在使用 Bearer 方案(例如,发送 JSON Web Tokens)的授权数据中找到的客户端提供的 token。不对客户端发送的数据执行任何检查。如果提供了特定的 <header>,它将解析该标头而不是 Authorization 标头。
http_auth_group(<userlist>) : string
如果从客户端收到的身份验证数据中的用户名和密码根据指定用户列表均有效,则返回一个对应于该用户名的字符串。其主要目的是在 ACL 中使用,然后检查该用户是否属于列表中的任何组。此获取函数在 ACL 之外并不真正有用。目前仅支持 http 基本身份验证。ACL 派生词:http_auth_group(<userlist>) : group ... 当从请求中提取的用户(其密码根据指定用户列表有效)属于至少一个组时返回 true。
返回用户在从客户端接收到的身份验证数据中找到的密码,该数据在 Authorization 标头中提供。此样本获取不执行任何检查。仅支持 Basic 身份验证。
返回用户在从客户端接收到的身份验证数据中找到的身份验证方法,该数据在 Authorization 标头中提供。此样本获取不执行任何检查。仅支持 Basic 身份验证。
返回用户在从客户端接收到的身份验证数据中找到的用户名,该数据在 Authorization 标头中提供。此样本获取不执行任何检查。仅支持 Basic 身份验证。
http_first_req : boolean
当正在处理的请求是连接的第一个请求时返回 true。这可用于添加或删除在请求不是第一个时某些请求中可能缺少的头部,或帮助在日志中对请求进行分组。
method : integer + string
返回一个对应于 HTTP 请求中方法的整数值。例如,"GET" 等于 1(检查源代码以确定匹配关系)。值 9 表示“其他方法”,并可能转换为从流中提取的字符串。这不应直接用作样本,它仅用于 ACL,ACL 会透明地将方法从模式转换为这些整数 + 字符串值。一些预定义的 ACL 已经检查了最常见的方法。ACL 派生词:method:不区分大小写的方法匹配
示例
# 只接受 GET 和 HEAD 请求 acl valid_method method GET HEAD http-request deny if ! valid_method
path : string
此项提取请求的 URL 路径,该路径从第一个斜杠开始,到问号之前结束(不包括主机部分)。典型的用法是具有预取功能的缓存,以及需要从数据库聚合多个信息并将其保存在缓存中的门户网站。请注意,对于出站缓存,使用 "url" 会更明智。对于 ACL,通常使用衍生形式来匹配精确的文件名(例如 "/login.php")或目录部分。另请参阅 "url" 和 "base" 抓取方法。请注意,HTTP 标准严格禁止 URI 中的任何片段引用(路径后面的 '#'),并将被拒绝。但是,如果接收请求的前端具有 "option accept-invalid-http-request",则将接受此片段部分,并且它也会出现在路径中。ACL 衍生:path:精确字符串匹配 path_beg:前缀匹配 path_dir:子目录匹配 path_dom:域匹配 path_end:后缀匹配 path_len:长度匹配 path_reg:正则表达式匹配 path_sub:子字符串匹配
pathq : string
这会提取带有查询字符串的请求 URL 路径,从第一个斜杠开始。这个示例提取非常方便,总是能获取相对 URI,排除 scheme 和 authority 部分(如果存在)。事实上,虽然这是 HTTP/1.1 请求目标的常见表示,但在 HTTP/2 中,通常使用绝对 URI。这个示例提取在两种情况下都会返回相同的结果。请注意,URI 中的任何片段引用(路径后的“#”)严格禁止由 HTTP 标准,并将被拒绝。但是,如果接收请求的前端具有“option accept-invalid-http-request”选项,则该片段部分将被接受,并也会出现在路径中。
query : string
此函数提取请求的查询字符串,它从第一个问号之后开始。如果没有问号,此获取不返回任何内容。如果存在问号但后面没有任何内容,则返回一个空字符串。这意味着可以使用 "found" 匹配方法轻松地知道是否存在查询字符串。此获取是 "path" 的补充,后者在问号之前停止。
req.hdr_names([<delim>]) : string
此函数构建一个字符串,该字符串由规则评估时请求中出现的所有头部名称拼接而成。默认分隔符是逗号 (','),但可以通过可选参数 <delim> 进行覆盖。在这种情况下,只考虑 <delim> 的第一个字符。
req.ver : string
req_ver : string (已弃用)
返回 HTTP 请求中的版本字符串,例如 "1.1"。这对于 ACL 可能很有用。对于日志,请使用 "%HV" 日志变量。一些预定义的 ACL 已经检查了版本 1.0 和 1.1。常见值为 "1.0"、"1.1"、"2.0" 或 "3.0"。对于 http/2 和 http/3,该值不是从请求行中的 HTTP 版本中提取的,而是由协商的协议版本确定的。ACL 衍生:req.ver:精确字符串匹配
res.body : binary
这会返回 HTTP 响应的可用正文作为数据块。与请求端不同,没有指令可以等待响应的正文。此样本获取在健康检查上下文中非常有用(且可用)。它可用于基于 tcp-check 的 expect 规则。
res.body_len : integer
这会返回 HTTP 响应可用正文的长度(以字节为单位)。与请求端不同,没有指令可以等待响应的正文。此样本获取在健康检查上下文中非常有用(且可用)。它可用于基于 tcp-check 的 expect 规则。
res.body_size : integer
这会返回 HTTP 响应正文的广告长度(以字节为单位)。它将代表广告的 Content-Length 标头,或在分块编码情况下可用数据的大小。与请求端不同,没有指令可以等待响应正文。此样本获取在健康检查上下文中非常有用(且可用)。它可用于基于 tcp-check 的 expect 规则。
res.cache_hit : boolean
如果响应是由 HTTP 缓存条目构建的,则返回布尔值“true”,否则返回布尔值“false”。
返回用于构建 HTTP 响应的 HTTP 缓存名称的字符串(如果 res.cache_hit 为 true),否则返回空字符串。
res.comp : boolean
如果响应已被 HAProxy 压缩,则返回布尔值 "true",否则返回布尔值 "false"。这可用于在日志中添加信息。
res.comp_algo : string
如果响应被 HAProxy 压缩,则返回一个包含所用算法名称的字符串,例如:“deflate”。这可用于在日志中添加一些信息。
res.cook([<name>]) : string
scook([<name>]) : string (已弃用)
从响应的“Set-Cookie”标头行中提取 cookie 名称 <name> 的最后一次出现,并返回其值。如果未指定名称,则返回第一个 cookie 值。它可用于基于 tcp-check 的 expect 规则。ACL 派生:res.scook([<name>]:精确字符串匹配
res.cook_cnt([<name>]) : integer
scook_cnt([<name>]) : integer (已弃用)
返回响应中 cookie <name> 的出现次数的整数值,如果未指定 <name>,则返回所有 cookie。这在与 ACL 结合以检测可疑响应时非常有用。它可用于基于 tcp-check 的 expect 规则。
res.cook_val([<name>]) : integer
scook_val([<name>]) : integer (已弃用)
从响应的“Set-Cookie”标头行中提取 cookie 名称 <name> 的最后一次出现,并将其值转换为整数返回。如果未指定名称,则返回第一个 cookie 值。它可用于基于 tcp-check 的 expect 规则。
res.cook_names([<delim>]) : string
在规则求值时,此函数会创建一个字符串,该字符串由响应(Set-Cookie 标头)中出现的所有 cookie 名称连接而成。默认分隔符是逗号 (','),但可以作为可选参数 <delim> 覆盖。在这种情况下,只考虑 <delim> 的第一个字符。它可用于基于 tcp-check 的 expect 规则。
res.fhdr([<name>[,<occ>]]) : string
此获取器的工作方式类似于 req.fhdr() 获取器,区别在于它作用于 HTTP 响应中的标头。与 req.fhdr() 一样,res.fhdr() 获取器返回完整值。如果标头定义为列表,则应使用 res.hdr()。此获取器有时对 Date 或 Expires 等标头很有用。它可用于基于 tcp-check 的 expect 规则。
res.fhdr_cnt([<name>]) : integer
此获取器的工作方式类似于 req.fhdr_cnt() 获取器,区别在于它作用于 HTTP 响应中的标头。与 req.fhdr_cnt() 一样,res.fhdr_cnt() 获取器作用于完整值。如果标头定义为列表,则应使用 res.hdr_cnt()。它可用于基于 tcp-check 的 expect 规则。
res.hdr([<name>[,<occ>]]) : string
shdr([<name>[,<occ>]]) : string (已弃用)
此获取的工作方式类似于req.hdr()获取,但不同之处在于它作用于HTTP响应中的报头。与req.hdr()一样,res.hdr()获取将逗号视为分隔符。如果不需要这样做,则应使用res.fhdr()。它可用于基于tcp-check的expect规则。ACL派生:res.hdr([<name>[,<occ>]]):精确字符串匹配res.hdr_beg([<name>[,<occ>]]):前缀匹配res.hdr_dir([<name>[,<occ>]]):子目录匹配res.hdr_dom([<name>[,<occ>]]):域匹配res.hdr_end([<name>[,<occ>]]):后缀匹配res.hdr_len([<name>[,<occ>]]):长度匹配res.hdr_reg([<name>[,<occ>]]):正则表达式匹配res.hdr_sub([<name>[,<occ>]]):子字符串匹配
res.hdr_cnt([<name>]) : integer
shdr_cnt([<name>]) : integer (已弃用)
此获取器的工作方式类似于 req.hdr_cnt() 获取器,区别在于它作用于 HTTP 响应中的标头。与 req.hdr_cnt() 一样,res.hdr_cnt() 获取器将逗号视为分隔符。如果不需要,应使用 res.fhdr_cnt()。它可用于基于 tcp-check 的 expect 规则。
res.hdr_ip([<name>[,<occ>]]) : ip
shdr_ip([<name>[,<occ>]]) : ip (已弃用)
此获取器的工作方式类似于 req.hdr_ip() 获取器,区别在于它作用于 HTTP 响应中的标头。这有助于将某些数据学习到粘滞表中。它可用于基于 tcp-check 的 expect 规则。
res.hdr_names([<delim>]) : string
在规则求值时,此函数会创建一个字符串,该字符串由响应中出现的名称相同的标头连接而成。默认分隔符是逗号 (','),但可以作为可选参数 <delim> 覆盖。在这种情况下,只考虑 <delim> 的第一个字符。它可用于基于 tcp-check 的 expect 规则。
res.hdr_val([<name>[,<occ>]]) : integer
shdr_val([<name>[,<occ>]]) : integer (已弃用)
此获取器的工作方式类似于 req.hdr_val() 获取器,区别在于它作用于 HTTP 响应中的标头。这有助于将某些数据学习到粘滞表中。它可用于基于 tcp-check 的 expect 规则。
res.hdrs : string
以字符串形式返回当前响应标头,包括分隔标头和请求正文的最后空行。最后空行可用于检测截断的标头块。此样本获取对于某些 SPOE 标头分析器和高级日志记录非常有用。它也可用于基于 tcp-check 的 expect 规则。
res.hdrs_bin : binary
以预解析的二进制形式返回当前响应标头。这对于使用 SPOE 进行部分处理非常有用。它可用于基于 tcp-check 的 expect 规则。每个字符串由长度后面跟着长度指示的字节数描述。长度使用 SPOE 文档中详细的可变整数编码表示。列表的末尾由一对空标头名称和值(长度均为 0)标记。*(<str:header-name><str:header-value>)<empty string><empty string> int:参考 SPOE 文档的编码 str:<int:length><bytes>
res.ver : string
resp_ver : string (已弃用)
返回 HTTP 响应中的版本字符串,例如“1.1”。这在日志中很有用,但主要用于 ACL。它可用于基于 tcp-check 的 expect 规则。ACL 派生:resp.ver:精确字符串匹配
server_status : integer
返回一个整数,其中包含从服务器收到的 HTTP 状态代码。如果没有从服务器收到响应,则样本获取失败。
set-cookie([<name>]) : string (已弃用)
从响应的“Set-Cookie”标头行中提取 cookie 名称 <name> 的最后一次出现,并使用相应的值进行匹配。这可以与“appsession”的默认选项所做的相媲美,但支持多对同步和跨重启的状态保持。此获取函数已弃用,已被“res.cook”获取器取代。此关键字很快就会消失。
status : integer
返回一个整数,其中包含 HTTP 响应中的 HTTP 状态代码,例如 302。它主要用于 ACL 和整数范围,例如,如果响应不是 3xx,则删除任何 Location 标头。如果状态代码未更改,则将是客户端收到的状态代码(例如,通过 'set-status' 操作)。它可用于基于 tcp-check 的 expect 规则。
txn.status : integer
以整数形式返回事务的 HTTP 状态代码,如日志中所示。
txn.timer.total : integer
HTTP 请求的总活动时间,从代理接收到请求标头的第一个字节到响应正文的最后一个字节发出之间。这相当于日志格式中的 %Ta,并以毫秒 (ms) 为单位报告。有关更多信息,请参阅第 8.4 节“计时事件”。
unique-id : string
返回附加到请求的唯一 ID。必须设置“unique-id-format”指令。如果未设置,则 unique-id 样本获取将失败。请注意,unique-id 通常与 HTTP 请求一起使用,但是此样本获取也可以与其他协议一起使用。显然,如果它与 HTTP 以外的协议一起使用,unique-id-format 指令不应包含 HTTP 部分。另请参阅:unique-id-format 和 unique-id-header
url : string
此项提取请求中呈现的 URL。典型的用法是具有预取功能的缓存,以及需要从数据库聚合多个信息并将其保存在缓存中的门户网站。对于 ACL,使用 "path" 优于使用 "url",因为客户端可能会发送一个完整的 URL,就像代理通常所做的那样。唯一真正的用途是匹配 "path" 中不匹配的 "*",并且已经有一个预定义的 ACL。另请参阅 "path" 和 "base"。请注意,HTTP 标准严格禁止 URI 中的任何片段引用(路径后面的 '#'),并将被拒绝。但是,如果接收请求的前端具有 "option accept-invalid-http-request",则将接受此片段部分,并且它也会出现在 url 中。ACL 衍生:url:精确字符串匹配 url_beg:前缀匹配 url_dir:子目录匹配 url_dom:域匹配 url_end:后缀匹配 url_len:长度匹配 url_reg:正则表达式匹配 url_sub:子字符串匹配
url_ip : ip
当主机部分以IP地址形式呈现时,这会从请求的URL中提取IP地址。其用途非常有限。例如,监控系统可能会将此字段用作源IP的替代项,以测试给定源地址将遵循的路径,或为给定源地址强制写入表项。它可以与“http-request set-dst”结合使用,以模拟旧的“option http_proxy”。
url_port : integer
这会从请求的URL中提取端口部分。请注意,如果请求中未指定端口,则假定端口为80。
urlp([<name>[,<delim>[,i]]]) : string
url_param([<name>[,<delim>[,i]]]) : string
此项提取查询字符串中参数 <name> 的第一次出现,该参数在 '?' 或 <delim> 之后开始,在 '&'、';' 或 <delim> 之前结束。参数名称区分大小写,除非将 "i" 添加为第三个参数。如果未给出名称,则任何参数都将匹配,并返回第一个参数。结果是一个字符串,对应于请求中呈现的参数 <name> 的值(未执行 URL 解码)。这可用于基于客户端 ID 的会话粘性,以提取作为 URL 参数传递的应用程序 cookie,或在 ACL 中应用某些检查。请注意,此抓取的 ACL 版本会迭代多个参数,如果未给出名称,则会迭代报告所有参数值。ACL 衍生:urlp(<name>[,<delim>]):精确字符串匹配 urlp_beg(<name>[,<delim>]):前缀匹配 urlp_dir(<name>[,<delim>]):子目录匹配 urlp_dom(<name>[,<delim>]):域匹配 urlp_end(<name>[,<delim>]):后缀匹配 urlp_len(<name>[,<delim>]):长度匹配 urlp_reg(<name>[,<delim>]):正则表达式匹配 urlp_sub(<name>[,<delim>]):子字符串匹配
示例
# 匹配 http://example.com/foo?PHPSESSIONID=some_id stick on urlp(PHPSESSIONID) # 匹配 http://example.com/foo;JSESSIONID=some_id stick on urlp(JSESSIONID,;)
urlp_val([<name>[,<delim>[,i]]]) : integer
参见上面的 "urlp"。此函数提取请求中的 URL 参数 <name> 并将其转换为整数值。例如,这可用于基于用户 ID 的会话粘性,或与 ACL 一起匹配页码或价格。
url32 : integer
此函数返回一个 32 位哈希值,该值由连接第一个 Host 标头和整个 URL(包括参数,而不仅仅是请求的路径部分,如上面的 "base32" 提取)得到。这对于跟踪每个 URL 的活动很有用。存储一个较短的哈希值可以节省大量内存。输出类型是无符号整数。
url32+src : binary
此函数返回 "url32" 提取和 "src" 提取的连接结果。结果类型为 binary,大小为 8 或 20 字节,具体取决于源地址族。这可用于跟踪每个 IP、每个 URL 的计数器。

7.3.7. 为开发人员提取样本

这组样本fetch方法保留给开发人员,除非在调试目的下按开发人员的要求,否则绝不能在生产环境中使用。此外,在向后兼容性方面不会采取任何特殊措施。无法保证以下样本fetch方法永远不会更改、重命名或删除。因此,如果您使用其中一个,请务必小心。为避免任何歧义,这些样本fetch方法被放置在专用的“internal”作用域中,例如“internal.strm.is_htx”。本节中的样本fetch方法及其各自类型的摘要。
关键字输出类型
internal.htx.data整数
internal.htx.free整数
internal.htx.free_data整数
internal.htx.has_eom布尔
internal.htx.nbblks整数
internal.htx.size整数
internal.htx.used整数
internal.htx_blk.size(<idx>)整数
internal.htx_blk.type(<idx>)字符串
internal.htx_blk.data(<idx>)二进制
internal.htx_blk.hdrname(<idx>)字符串
internal.htx_blk.hdrval(<idx>)字符串
internal.htx_blk.start_line(<idx>)字符串
internal.strm.is_htx布尔
详细列表
返回与通道关联的HTX消息中数据使用的字节数。通道的选择取决于样本方向。
返回与通道关联的HTX消息中的可用空间(大小-已用)的字节数。通道的选择取决于样本方向。
返回与通道关联的HTX消息中数据使用的可用空间的字节数。通道的选择取决于样本方向。
如果与通道关联的HTX消息包含消息结束标志(EOM),则返回true。否则,返回false。通道的选择取决于样本方向。
返回与通道关联的HTX消息中存在的块的数量。通道的选择取决于样本方向。
返回与通道关联的HTX消息的总字节大小。通道的选择取决于样本方向。
返回与通道关联的HTX消息中使用的总大小(数据+元数据)的字节数。通道的选择取决于样本方向。
internal.htx_blk.size(<idx>) : integer
返回与通道关联的HTX消息中位置<idx>处的块的大小,如果不存在则返回0。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
internal.htx_blk.type(<idx>) : string
返回与通道关联的HTX消息中位置<idx>处的块的类型,如果不存在则返回“HTX_BLK_UNUSED”。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
internal.htx_blk.data(<idx>) : binary
返回与通道关联的HTX消息中位置<idx>处的DATA块的值,如果不存在或不是DATA块,则返回空字符串。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
internal.htx_blk.hdrname(<idx>) : string
返回与通道关联的HTX消息中位置<idx>处的HEADER块的头部名称,如果不存在或不是HEADER块,则返回空字符串。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
internal.htx_blk.hdrval(<idx>) : string
返回与通道关联的HTX消息中位置<idx>处的HEADER块的头部值,如果不存在或不是HEADER块,则返回空字符串。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
返回与通道关联的HTX消息中位置<idx>处的REQ_SL或RES_SL块的值,如果不存在或不是SL块,则返回空字符串。通道的选择取决于样本方向。<idx>可以是任何正整数或以下特殊值之一:* head:最先插入的块* tail:最新插入的块* first:进行(重新)分析的第一个块
如果当前流是HTX流,则返回true。这意味着通道缓冲区中的数据使用内部HTX表示法存储。否则,返回false。

7.4. 预定义的 ACL

一些预定义的 ACL 是硬编码的,因此不必在每个需要它们的前端中声明。它们的名称都使用大写字母,以避免混淆。下面提供了它们的等效项。
ACL 名称等同于Usage
FALSEalways_false从不匹配
HTTPreq.proto_http匹配如果协议是有效的HTTP
HTTP_1.0req.ver 1.0匹配如果HTTP请求版本是1.0
HTTP_1.1req.ver 1.1匹配如果HTTP请求版本是1.1
HTTP_2.0req.ver 2.0匹配如果HTTP请求版本是2.0
HTTP_3.0req.ver 3.0匹配如果HTTP请求版本是3.0
HTTP_CONTENTreq.hdr_val(content-length) gt 0匹配HTTP请求中存在的content-length
HTTP_URL_ABSurl_reg ^[^/:]*://匹配带协议方案的绝对 URL
HTTP_URL_SLASHurl_beg /匹配以 "/" 开头的 URL
HTTP_URL_STARurl *匹配等于 "*" 的 URL
LOCALHOSTsrc 127.0.0.1/8 ::1匹配来自本地主机的连接
METH_CONNECTmethod CONNECT匹配 HTTP CONNECT 方法
METH_DELETEmethod DELETE匹配HTTP DELETE方法
METH_GETmethod GET HEAD匹配 HTTP GET 或 HEAD 方法
METH_HEADmethod HEAD匹配 HTTP HEAD 方法
METH_OPTIONSmethod OPTIONS匹配 HTTP OPTIONS 方法
METH_POSTmethod POST匹配 HTTP POST 方法
METH_PUTmethod PUT匹配HTTP PUT方法
METH_TRACEmethod TRACE匹配 HTTP TRACE 方法
RDP_COOKIEreq.rdp_cookie_cnt gt 0匹配请求缓冲区中是否存在RDP cookie
REQ_CONTENTreq.len gt 0匹配请求缓冲区中的数据
TRUEalways_true总是匹配
WAIT_ENDwait_end等待内容分析结束
HAProxy 的一个强项无疑在于其精确的日志。它可能提供了此类产品可用的最精细的信息级别,这对于故障排除复杂环境非常重要。日志中提供的标准信息包括客户端端口、TCP/HTTP 状态计时器、终止时的精确流状态和精确终止原因、有关将流量导向服务器的决策信息,当然还有捕获任意标头的能力。为了提高管理员的反应能力,它提供了有关遇到的问题(内部和外部)的高度透明度,并且可以将日志同时发送到具有不同级别过滤器的不同源: - 全局进程级日志(系统错误、启动/停止等) - 每个实例的系统和内部错误(资源不足、错误等) - 每个实例的外部问题(服务器启动/关闭、最大连接数) - 每个实例的活动(客户端连接),无论是在建立时还是在终止时。 - 每个请求的日志级别控制,例如 http-request set-log-level silent if sensitive_request 将不同级别的日志分发到不同的日志服务器的能力允许多个生产团队进行交互并尽快修复他们的问题。例如,系统团队可能会监控系统范围的错误,而应用程序团队可能会实时监控其服务器的启动/关闭,而安全团队可能会延迟一小时分析活动日志。

8.1. 日志级别

可以记录 TCP 和 HTTP 连接,其中包含日期、时间、源 IP 地址、目标地址、连接持续时间、响应时间、HTTP 请求、HTTP 返回代码、传输的字节数、流结束条件,甚至交换的 cookie 值等信息。例如,跟踪特定用户的问题。所有消息最多可以发送到两个 syslog 服务器。有关日志设施的更多信息,请查看 第 4.2 节 中的 "log" 关键字。

8.2. 日志格式

HAProxy 支持 5 种日志格式。其中一些字段在这些格式之间是通用的,并将在以下部分中详细说明。其中一些可能会根据配置略有不同,因为某些选项具有特定的指标。支持的格式如下: - 默认格式,非常基本且很少使用。它仅提供有关传入连接在接受时非常基本的信息:源 IP:port、目标 IP:port 和前端名称。此模式最终将消失,因此不会进行详细描述。 - TCP 格式,更高级。当在前端设置 "option tcplog" 时启用此格式。HAProxy 通常会等待连接终止后再记录日志。此格式提供更丰富的信息,例如计时器、连接计数、队列大小等。此格式推荐用于纯 TCP 代理。 - HTTP 格式,这是 HTTP 代理最高级的格式。当在前端设置 "option httplog" 时启用此格式。它提供与 TCP 格式相同的信息以及一些 HTTP 特定字段,例如请求、状态代码以及标头和 cookie 的捕获。此格式推荐用于 HTTP 代理。 - CLF HTTP 格式,相当于 HTTP 格式,但字段排列顺序与 CLF 格式相同。在此模式下,所有计时器、捕获、标志等都以与标准 HTTP 格式中相同的顺序出现在公共字段之后,每个字段一个。 - 自定义日志格式,允许您创建自己的日志行。接下来的部分将深入详细介绍这些格式中的每一种。格式规范将以 "field" 为基础进行。除非另有说明,否则字段是由任意数量的空格分隔的一段文本。由于 syslog 服务器可能会在行首插入字段,因此始终假定第一个字段是包含进程名称和标识符的字段。注意:由于日志行可能很长,下面的部分中的日志示例可能会分成多行。示例日志行将以 3 个闭合角括号 ('>>>') 作为前缀,并且每次日志分成多行时,每个非最后一行都将以反斜杠 ('\') 结尾,下一行将缩进两个字符开始。

8.2.1. 默认日志格式

当没有设置特定选项时,使用此格式。日志在连接被接受后立即发出。需要注意的是,这目前是唯一记录请求目标 IP 和端口的格式。
示例
listen www mode http log global server srv1 127.0.0.1:8000 >>> Feb 6 12:12:09 localhost \ haproxy[14385]: Connect from 10.0.1.2:33312 to 10.0.3.31:8012 \ (www/HTTP)
字段格式 从上面的示例中提取 1 process_name '[' pid ']:' haproxy[14385]: 2 'Connect from' Connect from 3 source_ip ':' source_port 10.0.1.2:33312 4 'to' to 5 destination_ip ':' destination_port 10.0.3.31:8012 6 '(' frontend_name '/' mode ')' (www/HTTP) 详细字段描述: - "source_ip" 是发起连接的客户端的 IP 地址。 - "source_port" 是发起连接的客户端的 TCP 端口。 - "destination_ip" 是客户端连接到的 IP 地址。 - "destination_port" 是客户端连接到的 TCP 端口。 - "frontend_name" 是接收和处理连接的前端(或侦听器)的名称。 - "mode" 是前端运行的模式(TCP 或 HTTP)。对于 UNIX 套接字,源地址和目标地址标记为 "unix:",端口反映接受连接的套接字的内部 ID(与统计信息中报告的 ID 相同)。建议新安装不要使用此已弃用的格式,因为它最终将消失。

8.2.2. TCP 日志格式

当在前端中指定 "option tcplog" 时使用 TCP 格式,并且是纯 TCP 代理的推荐格式。它提供了许多宝贵的故障排除信息。由于此格式包含计时器和字节计数,因此日志通常在会话结束时发出。如果指定了 "option logasap",它可以更早发出,这对于远程终端等具有长会话的大多数环境很有意义。与 "monitor" 规则匹配的会话永远不会记录。还可以通过在前端指定 "option dontlognull" 来不记录客户端和服务器之间未交换数据的会话。如果前端中指定了 "option dontlog-normal",则不会记录成功的连接。TCP 日志格式在内部声明为基于以下精确字符串的自定义日志格式,如果需要,也可以将其用作扩展格式的基础。此外,可以使用 HAPROXY_TCP_LOG_FMT 变量代替。请参阅 第 8.2.6 节 "Custom log format" 以了解如何使用: # strict equivalent of "option tcplog" log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts \ %ac/%fc/%bc/%sc/%rc %sq/%bq" # or using the HAPROXY_TCP_LOG_FMT variable log-format "${HAPROXY_TCP_LOG_FMT}" 少数字段可能会根据某些配置选项略有不同,这些字段在字段名称后标有星号 ('*')。
示例
frontend fnt mode tcp option tcplog log global default_backend bck backend bck server srv1 127.0.0.1:8000 >>> Feb 6 12:12:56 localhost \ haproxy[14387]: 10.0.1.2:33313 [06/Feb/2009:12:12:51.443] fnt \ bck/srv1 0/0/5007 212 -- 0/0/0/0/3 0/0
字段格式 从上面的示例中提取 1 process_name '[' pid ']:' haproxy[14387]: 2 client_ip ':' client_port 10.0.1.2:33313 3 '[' accept_date ']' [06/Feb/2009:12:12:51.443] 4 frontend_name fnt 5 backend_name '/' server_name bck/srv1 6 Tw '/' Tc '/' Tt* 0/0/5007 7 bytes_read* 212 8 termination_state -- 9 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 0/0/0/0/3 10 srv_queue '/' backend_queue 0/0 详细字段描述: - "client_ip" 是发起 TCP 连接到 HAProxy 的客户端的 IP 地址。如果连接是在 UNIX 套接字上接受的,则 IP 地址将替换为单词 "unix"。请注意,当连接是在配置了 "accept-proxy" 且正确使用了 PROXY 协议的套接字上接受,或者配置了 "accept-netscaler-cip" 且正确使用了 NetScaler 客户端 IP 插入协议时,日志将反映转发的连接信息。 - "client_port" 是发起连接的客户端的 TCP 端口。如果连接是在 UNIX 套接字上接受的,则端口将替换为接受套接字的 ID,该 ID 也报告在 stats 界面中。 - "accept_date" 是 HAProxy 收到连接的确切日期(这可能与网络上观察到的日期略有不同,如果系统积压中存在一些排队)。这通常是可能出现在任何上游防火墙日志中的同一日期。在 HTTP 模式下使用时,accept_date 字段将重置为连接准备好接收新请求的第一个时刻(HTTP/1 的前一个响应结束,HTTP/2 的前一个请求之后立即)。 - "frontend_name" 是接收和处理连接的前端(或侦听器)的名称。 - "backend_name" 是选择用于管理与服务器连接的后端(或侦听器)的名称。如果未应用任何切换规则,这将与前端相同,这对于 TCP 应用程序很常见。 - "server_name" 是连接发送到的最后一个服务器的名称,如果发生连接错误并进行了重新调度,则可能与第一个服务器不同。请注意,此服务器属于处理请求的后端。如果在到达服务器之前连接中止,则会显示 "<NOSRV>" 而不是服务器名称。 - "Tw" 是在各种队列中等待的总时间(以毫秒为单位)。如果在到达队列之前连接中止,则可能为 "-1"。有关更多详细信息,请参阅下面的“计时器”。 - "Tc" 是等待与最终服务器建立连接的总时间(以毫秒为单位),包括重试。如果在建立连接之前请求中止,则可能为 "-1"。有关更多详细信息,请参阅下面的“计时器”。 - "Tt" 是从接受到最后关闭经过的总时间(以毫秒为单位)。它涵盖所有可能的处理。有一个例外,如果指定了 "option logasap",则时间计数在发出日志时停止。在这种情况下,值前面会加上 '+' 号,表示最终值会更大。有关更多详细信息,请参阅下面的“计时器”。 - "bytes_read" 是在发出日志时从服务器传输到客户端的总字节数。如果指定了 "option logasap",则此值前面会加上 '+' 号,表示最终值可能会更大。请注意,此值是一个 64 位计数器,因此日志分析工具必须能够处理它而不会溢出。 - "termination_state" 是会话结束时会话所处的状态。这表示会话状态、哪一侧导致会话结束发生以及原因(超时、错误等)。正常标志应为 "--",表示会话由任一端关闭,缓冲区中没有剩余数据。有关更多详细信息,请参阅下面的“断开连接时的流状态”。 - "actconn" 是记录会话时进程上的并发连接总数。检测何时达到每个进程的系统限制非常有用。例如,如果发生多个连接错误时 actconn 接近 512,则系统将进程限制为最多使用 1024 个文件描述符,并且所有文件描述符都被使用,这种情况的可能性很高。请参阅 第 3 节 “全局参数”以了解如何调整系统。 - "feconn" 是记录会话时前端上的并发连接总数。它可用于估计维持高负载所需的资源量,并检测何时达到前端的 "maxconn"。最常见的是,当此值急剧增加时,是由于后端服务器拥塞,但有时也可能是由拒绝服务攻击引起的。 - "beconn" 是记录会话时后端处理的并发连接总数。它包括服务器上处于活动状态的并发连接总数以及队列中等待连接的数量。它可用于估计支持给定应用程序高负载所需的额外服务器数量。最常见的是,当此值急剧增加时,是由于后端服务器拥塞,但有时也可能是由拒绝服务攻击引起的。 - "srv_conn" 是记录会话时服务器上仍处于活动状态的并发连接总数。它永远不会超过服务器配置的 "maxconn" 参数。如果此值经常接近或等于服务器的 "maxconn",则意味着涉及大量的流量调节,这意味着要么服务器的 maxconn 值太低,要么没有足够的服务器来以最佳响应时间处理负载。当只有一个服务器的 "srv_conn" 很高时,通常意味着此服务器存在一些问题,导致连接处理时间比其他服务器长。 - "retries" 是此会话尝试连接到服务器时经历的连接重试次数。通常必须为零,除非在尝试连接的同一时刻服务器正在停止。频繁的重试通常表示 HAProxy 和服务器之间的网络问题,或者服务器上配置错误的系统积压阻止新连接排队。此字段可以选择性地以 '+' 号为前缀,表示会话在达到初始服务器上的最大重试次数后经历了重新调度。在这种情况下,日志中出现的服务器名称是连接重新调度到的服务器,而不是第一个服务器,尽管在哈希的情况下两者有时可能相同。因此,作为一般经验法则,当重试计数前面有 '+' 时,此计数不应归因于记录的服务器。 - "srv_queue" 是在此请求之前在服务器队列中处理的请求总数。当请求未通过服务器队列时,它为零。它使得可以通过将队列中花费的时间除以队列中的请求数来估计近似的服务器响应时间。值得注意的是,如果会话经历重新调度并经过两个服务器队列,则它们的位置将是累积的。除非发生重新调度,否则请求不应同时通过服务器队列和后端队列。 - "backend_queue" 是在此请求之前在后端全局队列中处理的请求总数。当请求未通过全局队列时,它为零。它使得可以通过将平均队列长度除以服务器的 "maxconn" 参数来轻松转换为缺少服务器的数量。值得注意的是,如果流经历重新调度,它可能会两次通过后端的队列,然后两个位置将是累积的。除非发生重新调度,否则请求不应同时通过服务器队列和后端队列。

8.2.3. HTTP 日志格式

HTTP 格式是最完整且最适合 HTTP 代理的格式。当在前端中指定 "option httplog" 时启用此格式。它提供了与 TCP 格式相同级别的信息以及特定于 HTTP 协议的附加功能。就像 TCP 格式一样,日志通常在流结束时发出,除非指定了 "option logasap",这通常仅对下载站点有意义。与 "monitor" 规则匹配的流永远不会记录。还可以通过在前端指定 "option dontlognull" 来不记录客户端未发送数据的流。如果前端中指定了 "option dontlog-normal",则不会记录成功的连接。HTTP 日志格式在内部声明为基于以下精确字符串的自定义日志格式,如果需要,也可以将其用作扩展格式的基础。此外,可以使用 HAPROXY_HTTP_LOG_FMT 变量代替。请参阅 第 8.2.6 节 "Custom log format" 以了解如何使用: # strict equivalent of "option httplog" log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC \ %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" # or using the HAPROXY_HTTP_LOG_FMT variable log-format "${HAPROXY_HTTP_LOG_FMT}" CLF 日志格式在内部声明为基于此精确字符串的自定义日志格式: # strict equivalent of "option httplog clf" log-format "%{+Q}o %{-Q}ci - - [%trg] %r %ST %B \"\" \"\" %cp \ %ms %ft %b %s %TR %Tw %Tc %Tr %Ta %tsc %ac %fc \ %bc %sc %rc %sq %bq %CC %CS %hrl %hsl" 大多数字段与 TCP 日志共享,有些不同。少数字段可能会根据某些配置选项略有不同。这些字段在字段名称后标有星号 ('*')。
示例
frontend http-in mode http option httplog log global default_backend bck backend static server srv1 127.0.0.1:8000 >>> Feb 6 12:14:14 localhost \ haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] http-in \ static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \ {} "GET /index.html HTTP/1.1"
字段格式 从上面的示例中提取 1 process_name '[' pid ']:' haproxy[14389]: 2 client_ip ':' client_port 10.0.1.2:33317 3 '[' request_date ']' [06/Feb/2009:12:14:14.655] 4 frontend_name http-in 5 backend_name '/' server_name static/srv1 6 TR '/' Tw '/' Tc '/' Tr '/' Ta* 10/0/30/69/109 7 status_code 200 8 bytes_read* 2750 9 captured_request_cookie - 10 captured_response_cookie - 11 termination_state ---- 12 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 1/1/1/1/0 13 srv_queue '/' backend_queue 0/0 14 '{' captured_request_headers* '}' {haproxy.1wt.eu} 15 '{' captured_response_headers* '}' {} 16 '"' http_request '"' "GET /index.html HTTP/1.1" 详细字段描述: - "client_ip" 是发起 TCP 连接到 HAProxy 的客户端的 IP 地址。如果连接是在 UNIX 套接字上接受的,则 IP 地址将替换为单词 "unix"。请注意,当连接是在配置了 "accept-proxy" 且正确使用了 PROXY 协议的套接字上接受,或者配置了 "accept-netscaler-cip" 且正确使用了 NetScaler 客户端 IP 插入协议时,日志将反映转发的连接信息。 - "client_port" 是发起连接的客户端的 TCP 端口。如果连接是在 UNIX 套接字上接受的,则端口将替换为接受套接字的 ID,该 ID 也报告在 stats 界面中。 - "request_date" 是 HAProxy 收到 HTTP 请求第一个字节的确切日期(log field %tr)。 - "frontend_name" 是接收和处理连接的前端(或侦听器)的名称。 - "backend_name" 是选择用于管理与服务器连接的后端(或侦听器)的名称。如果未应用任何切换规则,这将与前端相同。 - "server_name" 是连接发送到的最后一个服务器的名称,如果发生连接错误并进行了重新调度,则可能与第一个服务器不同。请注意,此服务器属于处理请求的后端。如果在到达服务器之前请求中止,则会显示 "<NOSRV>" 而不是服务器名称。如果请求被 stats 子系统拦截,则会显示 "<STATS>"。 - "TR" 是在收到第一个字节后等待客户端发送完整 HTTP 请求(不计算正文)的总时间(以毫秒为单位)。如果在收到完整请求之前连接中止或收到了错误的请求,则可能为 "-1"。它应该总是很小,因为请求通常适合单个数据包。这里时间过长通常表示客户端和 HAProxy 之间的网络问题或手动输入请求。有关更多详细信息,请参阅 第 8.4 节 “计时事件”。 - "Tw" 是在各种队列中等待的总时间(以毫秒为单位)。如果在到达队列之前连接中止,则可能为 "-1"。有关更多详细信息,请参阅 第 8.4 节 “计时事件”。 - "Tc" 是等待与最终服务器建立连接的总时间(以毫秒为单位),包括重试。如果在建立连接之前请求中止,则可能为 "-1"。有关更多详细信息,请参阅 第 8.4 节 “计时事件”。 - "Tr" 是等待服务器发送完整 HTTP 响应(不计算数据)的总时间(以毫秒为单位)。如果在收到完整响应之前请求中止,则可能为 "-1"。它通常匹配服务器处理请求的时间,尽管它可能会受到客户端发送到服务器的数据量的影响。这里 "GET" 请求时间过长通常表示服务器过载。有关更多详细信息,请参阅 第 8.4 节 “计时事件”。 - "Ta" 是请求在 HAProxy 中保持活动状态的时间,即从收到请求的第一个字节到发送响应的最后一个字节经过的总时间(以毫秒为单位)。它涵盖所有可能的处理,除了握手(请参阅 Th)和空闲时间(请参阅 Ti)。有一个例外,如果指定了 "option logasap",则时间计数在发出日志时停止。在这种情况下,值前面会加上 '+' 号,表示最终值会更大。有关更多详细信息,请参阅 第 8.4 节 “计时事件”。 - "status_code" 是返回给客户端的 HTTP 状态代码。此状态通常由服务器设置,但当无法访问服务器或 HAProxy 阻止其响应时,也可能由 HAProxy 设置。 - "bytes_read" 是在发出日志时传输到客户端的总字节数。这包括 HTTP 标头。如果指定了 "option logasap",则此值前面会加上 '+' 号,表示最终值可能会更大。请注意,此值是一个 64 位计数器,因此日志分析工具必须能够处理它而不会溢出。 - "captured_request_cookie" 是一个可选的 "name=value" 条目,表示客户端在请求中带有此 cookie。cookie 名称及其最大长度由前端配置中的 "capture cookie" 语句定义。当未设置选项时,该字段为单个短划线 ('-')。只能捕获一个 cookie,通常用于跟踪客户端和服务器之间交换的会话 ID,以检测由于应用程序错误导致的客户端之间的会话交叉。有关更多详细信息,请参阅下面的“捕获 HTTP 标头和 cookie”部分。 - "captured_response_cookie" 是一个可选的 "name=value" 条目,表示服务器已返回一个 cookie 及其响应。cookie 名称及其最大长度由前端配置中的 "capture cookie" 语句定义。当未设置选项时,该字段为单个短划线 ('-')。只能捕获一个 cookie,通常用于跟踪客户端和服务器之间交换的会话 ID,以检测由于应用程序错误导致的客户端之间的会话交叉。有关更多详细信息,请参阅下面的“捕获 HTTP 标头和 cookie”部分。 - "termination_state" 是流结束时流所处的状态。这表示流状态、哪一侧导致流结束发生以及原因(超时、错误等),就像在 TCP 日志中一样,以及最后两个字符中的 cookie 上的持久性操作信息。正常标志应以 "--" 开头,表示流由任一端关闭,缓冲区中没有剩余数据。有关更多详细信息,请参阅下面的“断开连接时的流状态”。 - "actconn" 是记录流时进程上的并发连接总数。检测何时达到每个进程的系统限制非常有用。例如,如果发生多个连接错误时 actconn 接近 512 或 1024,则系统将进程限制为最多使用 1024 个文件描述符,并且所有文件描述符都被使用,这种情况的可能性很高。请参阅 第 3 节 “全局参数”以了解如何调整系统。 - "feconn" 是记录流时前端上的并发连接总数。它可用于估计维持高负载所需的资源量,并检测何时达到前端的 "maxconn"。最常见的是,当此值急剧增加时,是由于后端服务器拥塞,但有时也可能是由拒绝服务攻击引起的。 - "beconn" 是记录流时后端处理的并发连接总数。它包括服务器上处于活动状态的并发连接总数以及队列中等待连接的数量。它可用于估计支持给定应用程序高负载所需的额外服务器数量。最常见的是,当此值急剧增加时,是由于后端服务器拥塞,但有时也可能是由拒绝服务攻击引起的。 - "srv_conn" 是记录流时服务器上仍处于活动状态的并发连接总数。它永远不会超过服务器配置的 "maxconn" 参数。如果此值经常接近或等于服务器的 "maxconn",则意味着涉及大量的流量调节,这意味着要么服务器的 maxconn 值太低,要么没有足够的服务器来以最佳响应时间处理负载。当只有一个服务器的 "srv_conn" 很高时,通常意味着此服务器存在一些问题,导致请求处理时间比其他服务器长。 - "retries" 是此流尝试连接到服务器时经历的连接重试次数。通常必须为零,除非在尝试连接的同一时刻服务器正在停止。频繁的重试通常表示 HAProxy 和服务器之间的网络问题,或者服务器上配置错误的系统积压阻止新连接排队。此字段可以选择性地以 '+' 号为前缀,表示流在达到初始服务器上的最大重试次数后经历了重新调度。在这种情况下,日志中出现的服务器名称是连接重新调度到的服务器,而不是第一个服务器,尽管在哈希的情况下两者有时可能相同。因此,作为一般经验法则,当重试计数前面有 '+' 时,此计数不应归因于记录的服务器。 - "srv_queue" 是在此请求之前在服务器队列中处理的请求总数。当请求未通过服务器队列时,它为零。它使得可以通过将队列中花费的时间除以队列中的请求数来估计近似的服务器响应时间。值得注意的是,如果流经历重新调度并经过两个服务器队列,则它们的位置将是累积的。除非发生重新调度,否则请求不应同时通过服务器队列和后端队列。 - "backend_queue" 是在此请求之前在后端全局队列中处理的请求总数。当请求未通过全局队列时,它为零。它使得可以通过将平均队列长度除以服务器的 "maxconn" 参数来轻松转换为缺少服务器的数量。值得注意的是,如果流经历重新调度,它可能会两次通过后端的队列,然后两个位置将是累积的。除非发生重新调度,否则请求不应同时通过服务器队列和后端队列。 - "captured_request_headers" 是由于前端中存在 "capture request header" 语句而在请求中捕获的标头列表。可以捕获多个标头,它们将由竖线 ('|') 分隔。当未启用捕获时,花括号不会出现,导致其余字段发生偏移。重要的是要注意此字段可能包含空格,并且使用它需要比不使用时更智能的日志解析器。有关更多详细信息,请参阅下面的“捕获 HTTP 标头和 cookie”部分。 - "captured_response_headers" 是由于前端中存在 "capture response header" 语句而在响应中捕获的标头列表。可以捕获多个标头,它们将由竖线 ('|') 分隔。当未启用捕获时,花括号不会出现,导致其余字段发生偏移。重要的是要注意此字段可能包含空格,并且使用它需要比不使用时更智能的日志解析器。有关更多详细信息,请参阅下面的“捕获 HTTP 标头和 cookie”部分。 - "http_request" 是完整的 HTTP 请求行,包括方法、请求和 HTTP 版本字符串。不可打印字符经过编码(请参阅下面的“不可打印字符”部分)。这始终是最后一个字段,并且始终由引号分隔,并且是唯一可以包含引号的字段。如果将新字段添加到日志格式中,它们将在此字段之前添加。如果请求太大且不适合标准 syslog 缓冲区(1024 个字符),则此字段可能会被截断。这就是此字段必须始终保持最后一个的原因。

8.2.4. HTTPS日志格式

HTTPS 格式最适合 HTTP over SSL 连接。它是 HTTP 格式的扩展(请参阅 第 8.2.3 节),其中添加了 SSL 相关信息。当在前端中指定 "option httpslog" 时启用此格式。就像 TCP 和 HTTP 格式一样,日志通常在流结束时发出,除非指定了 "option logasap"。与 "monitor" 规则匹配的流永远不会记录。还可以通过在前端指定 "option dontlognull" 来不记录客户端未发送数据的流。如果前端中指定了 "option dontlog-normal",则不会记录成功的连接。HTTPS 日志格式在内部声明为基于以下精确字符串的自定义日志格式,如果需要,也可以将其用作扩展格式的基础。此外,可以使用 HAPROXY_HTTPS_LOG_FMT 变量代替。请参阅 第 8.2.6 节 "Custom log format" 以了解如何使用: # strict equivalent of "option httpslog" log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC \ %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r \ %[fc_err]/%[ssl_fc_err,hex]/%[ssl_c_err]/\ %[ssl_c_ca_err]/%[ssl_fc_is_resumed] %[ssl_fc_sni]/%sslv/%sslc" # or using the HAPROXY_HTTPS_LOG_FMT variable log-format "${HAPROXY_HTTPS_LOG_FMT}" 此格式基本上是 HTTP 格式(请参阅 第 8.2.3 节),并附加了新字段。新字段(第 17 行和第 18 行)将在此处详细说明。对于 HTTP 字段,请参阅 HTTP 部分。
示例
frontend https-in mode http option httpslog log global bind *:443 ssl crt mycerts/srv.pem ... default_backend bck backend static server srv1 127.0.0.1:8000 ssl crt mycerts/clt.pem ... >>> Feb 6 12:14:14 localhost \ haproxy[14389]: 10.0.1.2:33317 [06/Feb/2009:12:14:14.655] https-in \ static/srv1 10/0/30/69/109 200 2750 - - ---- 1/1/1/1/0 0/0 {1wt.eu} \ {} "GET /index.html HTTP/1.1" 0/0/0/0/0 \ 1wt.eu/TLSv1.3/TLS_AES_256_GCM_SHA384
字段格式 从上面的示例中提取 1 process_name '[' pid ']:' haproxy[14389]: 2 client_ip ':' client_port 10.0.1.2:33317 3 '[' request_date ']' [06/Feb/2009:12:14:14.655] 4 frontend_name https-in 5 backend_name '/' server_name static/srv1 6 TR '/' Tw '/' Tc '/' Tr '/' Ta* 10/0/30/69/109 7 status_code 200 8 bytes_read* 2750 9 captured_request_cookie - 10 captured_response_cookie - 11 termination_state ---- 12 actconn '/' feconn '/' beconn '/' srv_conn '/' retries* 1/1/1/1/0 13 srv_queue '/' backend_queue 0/0 14 '{' captured_request_headers* '}' {haproxy.1wt.eu} 15 '{' captured_response_headers* '}' {} 16 '"' http_request '"' "GET /index.html HTTP/1.1" 17 fc_err '/' ssl_fc_err '/' ssl_c_err '/' ssl_c_ca_err '/' ssl_fc_is_resumed 0/0/0/0/0 18 ssl_fc_sni '/' ssl_version '/' ssl_ciphers 1wt.eu/TLSv1.3/TLS_AES_256_GCM_SHA384 详细字段描述: - "fc_err" 是前端侧连接的状态。它对应于 "fc_err" 样本抓取。有关更多信息,请参阅 "fc_err" 和 "fc_err_str" 样本抓取函数。 - "ssl_fc_err" 是从前端的角度来看连接上引发的第一个 SSL 错误堆栈的最后一个错误。例如,它可用于检测 SSL 握手错误。如果一切顺利,它将为 0。有关更多信息,请参阅 "ssl_fc_err" 样本抓取的描述。 - "ssl_c_err" 是客户端证书验证过程的状态。如果是非忽略的错误代码,则握手可能会成功,同时具有非 null 验证错误代码。请参阅 "ssl_c_err" 样本抓取和 "crt-ignore-err" 选项。 - "ssl_c_ca_err" 是客户端证书链验证过程的状态。如果是非忽略的错误代码,则握手可能会成功,同时具有非 null 验证错误代码。请参阅 "ssl_c_ca_err" 样本抓取和 "ca-ignore-err" 选项。 - "ssl_fc_is_resumed" 如果传入的 TLS 会话已通过有状态缓存或无状态票证恢复,则为 true。请不要忘记 TLS 会话可以由多个请求共享。 - "ssl_fc_sni" 是客户端为了选择要使用的证书而呈现的 SNI(服务器名称指示)。对于连接的第一个请求,它通常与主机名匹配。此字段的缺失可能表示客户端未发送 SNI,并将导致 haproxy 使用默认证书,或者在严格 SNI 的情况下拒绝连接。 - "ssl_version" 是前端的 SSL 版本。 - "ssl_ciphers" 是用于连接的 SSL 密码。

8.2.5. 错误日志格式

When an incoming connection fails due to an SSL handshake or an invalid PROXY protocol header, HAProxy will log the event using a shorter, fixed line format, unless a dedicated error log format is defined through an "error-log-format" line. By default, logs are emitted at the LOG_INFO level, unless the option "log-separate-errors" is set in the backend, in which case the LOG_ERR level will be used. Connections on which no data are exchanged (e.g. probes) are not logged if the "dontlognull" option is set. The default format looks like this : >>> Dec 3 18:27:14 localhost \ haproxy[6103]: 127.0.0.1:56059 [03/Dec/2012:17:35:10.380] frt/f1: \ Connection error during SSL handshake Field Format Extract from the example above 1 process_name '[' pid ']:' haproxy[6103]: 2 client_ip ':' client_port 127.0.0.1:56059 3 '[' accept_date ']' [03/Dec/2012:17:35:10.380] 4 frontend_name "/" bind_name ":" frt/f1: 5 message Connection error during SSL handshake These fields just provide minimal information to help debugging connection failures. By using the "error-log-format" directive, the legacy log format described above will not be used anymore, and all error log lines will follow the defined format. An example of reasonably complete error-log-format follows, it will report the source address and port, the connection accept() date, the frontend name, the number of active connections on the process and on thit frontend, haproxy's internal error identifier on the front connection, the hexadecimal OpenSSL error number (that can be copy-pasted to "openssl errstr" for full decoding), the client certificate extraction status (0 indicates no error), the client certificate validation status using the CA (0 indicates no error), a boolean indicating if the connection is new or was resumed, the optional server name indication (SNI) provided by the client, the SSL version name and the SSL ciphers used on the connection, if any. Note that backend connection errors are never reported here since in order for a backend connection to fail, it would have passed through a successful stream, hence will be available as regular traffic log (see option httplog or option httpslog). # detailed frontend connection error log error-log-format "%ci:%cp [%tr] %ft %ac/%fc %[fc_err]/\ %[ssl_fc_err,hex]/%[ssl_c_err]/%[ssl_c_ca_err]/%[ssl_fc_is_resumed] \ %[ssl_fc_sni]/%sslv/%sslc"

8.2.6. 自定义日志格式

When the default log formats are not sufficient, it is possible to define new ones in very fine details. As creating a log-format from scratch is not always a trivial task, it is strongly recommended to first have a look at the existing formats ("option tcplog", "option httplog", "option httpslog"), pick the one looking the closest to the expectation, copy its "log-format" equivalent string and adjust it. HAProxy understands some log format variables. % precedes log format variables. Variables can take arguments using braces ('{}'), and multiple arguments are separated by commas within the braces. Flags may be added or removed by prefixing them with a '+' or '-' sign. Special variable "%o" may be used to propagate its flags to all other variables on the same format string. This is particularly handy with quoted ("Q") and escaped ("E") string formats. If a variable is named between square brackets ('[' .. ']') then it is used as a sample expression rule (see section 7.3). This it useful to add some less common information such as the client's SSL certificate's DN, or to log the key that would be used to store an entry into a stick table. Note: spaces must be escaped. In configuration directives "log-format", "log-format-sd" and "unique-id-format", spaces are considered as delimiters and are merged. In order to emit a verbatim '%', it must be preceded by another '%' resulting in '%%'. Note: when using the RFC5424 syslog message format, the characters '"', '\' and ']' inside PARAM-VALUE should be escaped with '\' as prefix (see https://tools.ietf.org/html/rfc5424#section-6.3.3 for more details). In such cases, the use of the flag "E" should be considered. Flags are : * Q: quote a string * X: hexadecimal representation (IPs, Ports, %Ts, %rt, %pid) * E: escape characters '"', '\' and ']' in a string with '\' as prefix (intended purpose is for the RFC5424 structured-data log formats)
示例
log-format %T\ %t\ Some\ Text log-format %{+Q}o\ %t\ %s\ %{-Q}r log-format-sd %{+Q,+E}o\ [exampleSDID@1234\ header=%[capture.req.hdr(0)]]
Please refer to the table below for currently defined variables : +---+------+------------------------------------------------------+---------+ | R | var | field name (8.2.2 and 8.2.3 for description) | type | | | | sample fetch alternative | | +===+======+======================================================+=========+ | | %o | special variable, apply flags on all next var | | +---+------+------------------------------------------------------+---------+ | date formats | +---+------+------------------------------------------------------+---------+ | | %T | Accept date UTC + timezone | | | | | %[accept_date,utime("%d/%b/%Y:%H:%M:%S %z")] | date | +---+------+------------------------------------------------------+---------+ | | %Tl | Accept date local + timezone | | | | | %[accept_date,ltime("%d/%b/%Y:%H:%M:%S %z")] | date | +---+------+------------------------------------------------------+---------+ | | %Ts | Accept date as a UNIX timestamp | numeric | +---+------+------------------------------------------------------+---------+ | | %t | Accept date local (with millisecond resolution) | | | | | %[accept_date(ms),ms_ltime("%d/%b/%Y:%H:%M:%S.%3N")] | date | +---+------+------------------------------------------------------+---------+ | | %ms | Accept date milliseconds | | | | | %[accept_date(ms),ms_utime("%3N") | numeric | +---+------+------------------------------------------------------+---------+ | H | %tr | Request date local (with millisecond resolution) | | | | | %[request_date(ms),ms_ltime("%d/%b/%Y:%H:%M:%S.%3N")]| date | +---+------+------------------------------------------------------+---------+ | H | %trg | Request date UTC + timezone | | | | | %[request_date,utime("%d/%b/%Y:%H:%M:%S %z")] | date | +---+------+------------------------------------------------------+---------+ | H | %trl | Request date local + timezone | | | | | %[request_date,ltime("%d/%b/%Y:%H:%M:%S %z")] | date | +---+------+------------------------------------------------------+---------+ | Timing events | +---+------+------------------------------------------------------+---------+ | H | %Ta | Active time of the request (from TR to end) | | | | | %[txn.timer.total] | numeric | +---+------+------------------------------------------------------+---------+ | | %Tc | Tc | | | | | %[bc.timer.connect] | numeric | +---+------+------------------------------------------------------+---------+ | | %Td | Td = Tt - (Tq + Tw + Tc + Tr) | | | | | %[res.timer.data] | numeric | +---+------+------------------------------------------------------+---------+ | | %Th | connection handshake time (SSL, PROXY proto) | | | | | %[fc.timer.handshake] | numeric | +---+------+------------------------------------------------------+---------+ | H | %Ti | idle time before the HTTP request | | | | | %[req.timer.idle] | numeric | +---+------+------------------------------------------------------+---------+ | H | %Tq | Th + Ti + TR | | | | | %[req.timer.tq] | numeric | +---+------+------------------------------------------------------+---------+ | H | %TR | time to receive the full request from 1st byte | | | | | %[req.timer.hdr] | numeric | +---+------+------------------------------------------------------+---------+ | H | %Tr | Tr (response time) | | | | | %[res.timer.hdr] | numeric | +---+------+------------------------------------------------------+---------+ | | %Tt | Tt | | | | | %[fc.timer.total] | numeric | +---+------+------------------------------------------------------+---------+ | | %Tu | Tu | | | | | %[txn.timer.user] | numeric | +---+------+------------------------------------------------------+---------+ | | %Tw | Tw | | | | | %[req.timer.queue] | numeric | +---+------+------------------------------------------------------+---------+ | Others | +---+------+------------------------------------------------------+---------+ | | %B | bytes_read (from server to client) | numeric | | | | %[bytes_out] | | +---+------+------------------------------------------------------+---------+ | H | %CC | captured_request_cookie | string | +---+------+------------------------------------------------------+---------+ | H | %CS | captured_response_cookie | string | +---+------+------------------------------------------------------+---------+ | | %H | hostname | string | +---+------+------------------------------------------------------+---------+ | H | %HM | HTTP method (ex: POST) | string | +---+------+------------------------------------------------------+---------+ | H | %HP | HTTP request URI without query string | string | +---+------+------------------------------------------------------+---------+ | H | %HPO | HTTP path only (without host nor query string) | string | +---+------+------------------------------------------------------+---------+ | H | %HQ | HTTP request URI query string (ex: ?bar=baz) | string | | | | ?%[query] | | +---+------+------------------------------------------------------+---------+ | H | %HU | HTTP request URI (ex: /foo?bar=baz) | string | +---+------+------------------------------------------------------+---------+ | H | %HV | HTTP version (ex: HTTP/1.0) | string | | | | HTTP/%[req.ver] | | +---+------+------------------------------------------------------+---------+ | | %ID | unique-id | string | | | | %[unique-id] | | +---+------+------------------------------------------------------+---------+ | | %ST | status_code | numeric | | | | %[txn.status] | | +---+------+------------------------------------------------------+---------+ | | %U | bytes_uploaded (from client to server) | numeric | | | | %[bytes_in] | | +---+------+------------------------------------------------------+---------+ | | %ac | actconn | | | | | %[act_conn] | numeric | +---+------+------------------------------------------------------+---------+ | | %b | backend_name | | | | | %[be_name] | string | +---+------+------------------------------------------------------+---------+ | | %bc | beconn (backend concurrent connections) | numeric | +---+------+------------------------------------------------------+---------+ | | %bi | backend_source_ip (connecting address) | | | | | %[bc_src] | IP | +---+------+------------------------------------------------------+---------+ | | %bp | backend_source_port (connecting address) | | | | | %[bc_src_port] | numeric | +---+------+------------------------------------------------------+---------+ | | %bq | backend_queue | numeric | +---+------+------------------------------------------------------+---------+ | | %ci | client_ip (accepted address) | | | | | %[src] | IP | +---+------+------------------------------------------------------+---------+ | | %cp | client_port (accepted address) | | | | | %[src_port] | numeric | +---+------+------------------------------------------------------+---------+ | | %f | frontend_name | string | +---+------+------------------------------------------------------+---------+ | | %fc | feconn (frontend concurrent connections) | numeric | +---+------+------------------------------------------------------+---------+ | | %fi | frontend_ip (accepting address) | | | | | %[dst] | IP | +---+------+------------------------------------------------------+---------+ | | %fp | frontend_port (accepting address) | | | | | %[dst_port] | numeric | +---+------+------------------------------------------------------+---------+ | | %ft | frontend_name_transport ('~' suffix for SSL) | string | +---+------+------------------------------------------------------+---------+ | | %lc | frontend_log_counter | numeric | +---+------+------------------------------------------------------+---------+ | | %hr | captured_request_headers default style | string | +---+------+------------------------------------------------------+---------+ | | %hrl | captured_request_headers CLF style | string | | | | | list | +---+------+------------------------------------------------------+---------+ | | %hs | captured_response_headers default style | string | +---+------+------------------------------------------------------+---------+ | | %hsl | captured_response_headers CLF style | string | | | | | list | +---+------+------------------------------------------------------+---------+ | | %pid | PID | | | | | %[pid] | numeric | +---+------+------------------------------------------------------+---------+ | H | %r | http_request | string | +---+------+------------------------------------------------------+---------+ | | %rc | retries | numeric | | | | %[txn.conn_retries] | | +---+------+------------------------------------------------------+---------+ | | %rt | request_counter (HTTP req or TCP session) | numeric | | | | %[txn.id32] | | +---+------+------------------------------------------------------+---------+ | | %s | server_name | string | +---+------+------------------------------------------------------+---------+ | | %sc | srv_conn (server concurrent connections) | numeric | +---+------+------------------------------------------------------+---------+ | | %si | server_IP (target address) | | | | | %[bc_dst] | IP | +---+------+------------------------------------------------------+---------+ | | %sp | server_port (target address) | | | | | %[bc_dst_port] | numeric | +---+------+------------------------------------------------------+---------+ | | %sq | srv_queue | numeric | +---+------+------------------------------------------------------+---------+ | S | %sslc| ssl_ciphers (ex: AES-SHA) | | | | | %[ssl_fc_cipher] | string | +---+------+------------------------------------------------------+---------+ | S | %sslv| ssl_version (ex: TLSv1) | | | | | %[ssl_fc_protocol] | string | +---+------+------------------------------------------------------+---------+ | | %ts | termination_state | string | | | | %[txn.sess_term_state] | | +---+------+------------------------------------------------------+---------+ | H | %tsc | termination_state with cookie status | string | +---+------+------------------------------------------------------+---------+ R = Restrictions : H = mode http only ; S = SSL only

8.3. 高级日志记录选项

一些高级日志记录选项经常被寻找,但仅通过查看各种选项不容易找到。这里是几个可以实现更好日志记录的选项的入口点。有关其用法的更多信息,请参考关键字参考。

8.3.1. 禁用外部测试的日志记录

It is quite common to have some monitoring tools perform health checks on HAProxy. Sometimes it will be a layer 3 load-balancer such as LVS or any commercial load-balancer, and sometimes it will simply be a more complete monitoring system such as Nagios. When the tests are very frequent, users often ask how to disable logging for those checks. There are three possibilities : - if connections come from everywhere and are just TCP probes, it is often desired to simply disable logging of connections without data exchange, by setting "option dontlognull" in the frontend. It also disables logging of port scans, which may or may not be desired. - it is possible to use the "http-request set-log-level silent" action using a variety of conditions (source networks, paths, user-agents, etc). - if the tests are performed on a known URI, use "monitor-uri" to declare this URI as dedicated to monitoring. Any host sending this request will only get the result of a health-check, and the request will not be logged.

8.3.2. 在等待流终止之前进行日志记录

在连接结束时进行日志记录的问题在于,您无法了解在非常长的流(例如远程终端会话或大文件下载)期间发生了什么。通过在前端指定“option logasap”可以解决此问题。HAProxy 将尽快记录,就在数据传输开始之前。这意味着在 TCP 的情况下,它仍将记录到服务器的连接状态,在 HTTP 的情况下,它将在处理服务器头信息后进行记录。在这种情况下,报告的字节数是发送到客户端的头字节数。为了避免与正常日志混淆,总时间字段和字节数前面会加上“+”号,表示实际数字肯定更大。

8.3.3. 发生错误时提高日志级别

有时,将正常流量与错误日志分开会更方便,例如,为了简化从日志文件中监控错误。当使用 "log-separate-errors" 选项时,遇到错误、超时、重试、重新分派或 HTTP 状态码为 5xx 的连接,其 syslog 级别将从 "info" 提高到 "err"。这将帮助 syslog 守护进程将日志存储在一个单独的文件中。将错误也保留在正常流量文件中非常重要,这样日志顺序就不会改变。如果您已经配置了 syslog 守护进程将所有高于 "notice" 的日志存储在 "admin" 文件中,您也应该小心,因为 "err" 级别高于 "notice"。

8.3.4. 禁用成功连接的日志记录

虽然这乍听起来可能很奇怪,但一些大型站点必须处理每秒数千条日志,并且在长时间保持其完整性或在其中检测错误方面遇到困难。如果在前端设置了 "dontlog-normal" 选项,所有正常的连接都不会被记录。在这方面,正常连接定义为没有任何错误、超时、重试或重新分派的连接。在 HTTP 中,状态码也会被检查,状态为 5xx 的响应不被认为是正常的,也会被记录。当然,这样做是强烈不鼓励的,因为它会从日志中删除大部分有用的信息。只有在没有其他选择的情况下才这样做。

8.4. 计时事件

Timers provide a great help in troubleshooting network problems. All values are reported in milliseconds (ms). These timers should be used in conjunction with the stream termination flags. In TCP mode with "option tcplog" set on the frontend, 3 control points are reported under the form "Tw/Tc/Tt", and in HTTP mode, 5 control points are reported under the form "TR/Tw/Tc/Tr/Ta". In addition, three other measures are provided, "Th", "Ti", and "Tq". Timings events in HTTP mode: first request 2nd request |<-------------------------------->|<-------------- ... t tr t tr ... ---|----|----|----|----|----|----|----|----|-- : Th Ti TR Tw Tc Tr Td : Ti ... :<---- Tq ---->: : :<-------------- Tt -------------->: :<-- -----Tu--------------->: :<--------- Ta --------->: Timings events in TCP mode: TCP session |<----------------->| t t ---|----|----|----|----|--- | Th Tw Tc Td | |<------ Tt ------->| - Th: total time to accept tcp connection and execute handshakes for low level protocols. Currently, these protocols are proxy-protocol and SSL. This may only happen once during the whole connection's lifetime. A large time here may indicate that the client only pre-established the connection without speaking, that it is experiencing network issues preventing it from completing a handshake in a reasonable time (e.g. MTU issues), or that an SSL handshake was very expensive to compute. Please note that this time is reported only before the first request, so it is safe to average it over all request to calculate the amortized value. The second and subsequent request will always report zero here. This timer is named %Th as a log-format tag, and fc.timer.handshake as a sample fetch. - Ti: is the idle time before the HTTP request (HTTP mode only). This timer counts between the end of the handshakes and the first byte of the HTTP request. When dealing with a second request in keep-alive mode, it starts to count after the end of the transmission the previous response. When a multiplexed protocol such as HTTP/2 is used, it starts to count immediately after the previous request. Some browsers pre-establish connections to a server in order to reduce the latency of a future request, and keep them pending until they need it. This delay will be reported as the idle time. A value of -1 indicates that nothing was received on the connection. This timer is named %Ti as a log-format tag, and req.timer.idle as a sample fetch. - TR: total time to get the client request (HTTP mode only). It's the time elapsed between the first bytes received and the moment the proxy received the empty line marking the end of the HTTP headers. The value "-1" indicates that the end of headers has never been seen. This happens when the client closes prematurely or times out. This time is usually very short since most requests fit in a single packet. A large time may indicate a request typed by hand during a test. This timer is named %TR as a log-format tag, and req.timer.hdr as a sample fetch. - Tq: total time to get the client request from the accept date or since the emission of the last byte of the previous response (HTTP mode only). It's exactly equal to Th + Ti + TR unless any of them is -1, in which case it returns -1 as well. This timer used to be very useful before the arrival of HTTP keep-alive and browsers' pre-connect feature. It's recommended to drop it in favor of TR nowadays, as the idle time adds a lot of noise to the reports. This timer is named %Tq as a log-format tag, and req.timer.tq as a sample fetch. - Tw: total time spent in the queues waiting for a connection slot. It accounts for backend queue as well as the server queues, and depends on the queue size, and the time needed for the server to complete previous requests. The value "-1" means that the request was killed before reaching the queue, which is generally what happens with invalid or denied requests. This timer is named %Tw as a log-format tag, and req.timer.queue as a sample fetch. - Tc: total time to establish the TCP connection to the server. It's the time elapsed between the moment the proxy sent the connection request, and the moment it was acknowledged by the server, or between the TCP SYN packet and the matching SYN/ACK packet in return. The value "-1" means that the connection never established. This timer is named %Tc as a log-format tag, and bc.timer.connect as a sample fetch. - Tr: server response time (HTTP mode only). It's the time elapsed between the moment the TCP connection was established to the server and the moment the server sent its complete response headers. It purely shows its request processing time, without the network overhead due to the data transmission. It is worth noting that when the client has data to send to the server, for instance during a POST request, the time already runs, and this can distort apparent response time. For this reason, it's generally wise not to trust too much this field for POST requests initiated from clients behind an untrusted network. A value of "-1" here means that the last response header (empty line) was never seen, most likely because the server timeout stroke before the server managed to process the request or because the server returned an invalid response. This timer is named %Tr as a log-format tag, and res.timer.hdr as a sample fetch. - Td: this is the total transfer time of the response payload till the last byte sent to the client. In HTTP it starts after the last response header (after Tr). The data sent are not guaranteed to be received by the client, they can be stuck in either the kernel or the network. This timer is named %Td as a log-format tag, and res.timer.data as a sample fetch. - Ta: total active time for the HTTP request, between the moment the proxy received the first byte of the request header and the emission of the last byte of the response body. The exception is when the "logasap" option is specified. In this case, it only equals (TR+Tw+Tc+Tr), and is prefixed with a '+' sign. From this field, we can deduce "Td", the data transmission time, by subtracting other timers when valid : Td = Ta - (TR + Tw + Tc + Tr) Timers with "-1" values have to be excluded from this equation. Note that "Ta" can never be negative. This timer is named %Ta as a log-format tag, and txn.timer.total as a sample fetch. - Tt: total stream duration time, between the moment the proxy accepted it and the moment both ends were closed. The exception is when the "logasap" option is specified. In this case, it only equals (Th+Ti+TR+Tw+Tc+Tr), and is prefixed with a '+' sign. From this field, we can deduce "Td", the data transmission time, by subtracting other timers when valid : Td = Tt - (Th + Ti + TR + Tw + Tc + Tr) Timers with "-1" values have to be excluded from this equation. In TCP mode, "Ti", "Tq" and "Tr" have to be excluded too. Note that "Tt" can never be negative and that for HTTP, Tt is simply equal to (Th+Ti+Ta). This timer is named %Tt as a log-format tag, and fc.timer.total as a sample fetch. - Tu: total estimated time as seen from client, between the moment the proxy accepted it and the moment both ends were closed, without idle time. This is useful to roughly measure end-to-end time as a user would see it, without idle time pollution from keep-alive time between requests. This timer in only an estimation of time seen by user as it assumes network latency is the same in both directions. The exception is when the "logasap" option is specified. In this case, it only equals (Th+TR+Tw+Tc+Tr), and is prefixed with a '+' sign. This timer is named %Tu as a log-format tag, and txn.timer.user as a sample fetch. These timers provide precious indications on trouble causes. Since the TCP protocol defines retransmit delays of 3, 6, 12... seconds, we know for sure that timers close to multiples of 3s are nearly always related to lost packets due to network problems (wires, negotiation, congestion). Moreover, if "Ta" or "Tt" is close to a timeout value specified in the configuration, it often means that a stream has been aborted on timeout. Most common cases : - If "Th" or "Ti" are close to 3000, a packet has probably been lost between the client and the proxy. This is very rare on local networks but might happen when clients are on far remote networks and send large requests. It may happen that values larger than usual appear here without any network cause. Sometimes, during an attack or just after a resource starvation has ended, HAProxy may accept thousands of connections in a few milliseconds. The time spent accepting these connections will inevitably slightly delay processing of other connections, and it can happen that request times in the order of a few tens of milliseconds are measured after a few thousands of new connections have been accepted at once. Using one of the keep-alive modes may display larger idle times since "Ti" measures the time spent waiting for additional requests. - If "Tc" is close to 3000, a packet has probably been lost between the server and the proxy during the server connection phase. This value should always be very low, such as 1 ms on local networks and less than a few tens of ms on remote networks. - If "Tr" is nearly always lower than 3000 except some rare values which seem to be the average majored by 3000, there are probably some packets lost between the proxy and the server. - If "Ta" is large even for small byte counts, it generally is because neither the client nor the server decides to close the connection while HAProxy is running in tunnel mode and both have agreed on a keep-alive connection mode. In order to solve this issue, it will be needed to specify one of the HTTP options to manipulate keep-alive or close options on either the frontend or the backend. Having the smallest possible 'Ta' or 'Tt' is important when connection regulation is used with the "maxconn" option on the servers, since no new connection will be sent to the server until another one is released. Other noticeable HTTP log cases ('xx' means any value to be ignored) : TR/Tw/Tc/Tr/+Ta The "option logasap" is present on the frontend and the log was emitted before the data phase. All the timers are valid except "Ta" which is shorter than reality. -1/xx/xx/xx/Ta The client was not able to send a complete request in time or it aborted too early. Check the stream termination flags then "timeout http-request" and "timeout client" settings. TR/-1/xx/xx/Ta It was not possible to process the request, maybe because servers were out of order, because the request was invalid or forbidden by ACL rules. Check the stream termination flags. TR/Tw/-1/xx/Ta The connection could not establish on the server. Either it actively refused it or it timed out after Ta-(TR+Tw) ms. Check the stream termination flags, then check the "timeout connect" setting. Note that the tarpit action might return similar-looking patterns, with "Tw" equal to the time the client connection was maintained open. TR/Tw/Tc/-1/Ta The server has accepted the connection but did not return a complete response in time, or it closed its connection unexpectedly after Ta-(TR+Tw+Tc) ms. Check the stream termination flags, then check the "timeout server" setting.

8.5. 断开连接时的流状态

TCP and HTTP logs provide a stream termination indicator in the "termination_state" field, just before the number of active connections. It is 2-characters long in TCP mode, and is extended to 4 characters in HTTP mode, each of which has a special meaning : - On the first character, a code reporting the first event which caused the stream to terminate : C : the TCP session was unexpectedly aborted by the client. S : the TCP session was unexpectedly aborted by the server, or the server explicitly refused it. P : the stream or session was prematurely aborted by the proxy, because of a connection limit enforcement, because a DENY filter was matched, because of a security check which detected and blocked a dangerous error in server response which might have caused information leak (e.g. cacheable cookie). L : the stream was locally processed by HAProxy. R : a resource on the proxy has been exhausted (memory, sockets, source ports, ...). Usually, this happens during the connection phase, and system logs should contain a copy of the precise error. If this happens, it must be considered as a very serious anomaly which should be fixed as soon as possible by any means. I : an internal error was identified by the proxy during a self-check. This should NEVER happen, and you are encouraged to report any log containing this, because this would almost certainly be a bug. It would be wise to preventively restart the process after such an event too, in case it would be caused by memory corruption. D : the stream was killed by HAProxy because the server was detected as down and was configured to kill all connections when going down. U : the stream was killed by HAProxy on this backup server because an active server was detected as up and was configured to kill all backup connections when going up. K : the stream was actively killed by an admin operating on HAProxy. c : the client-side timeout expired while waiting for the client to send or receive data. s : the server-side timeout expired while waiting for the server to send or receive data. - : normal stream completion, both the client and the server closed with nothing left in the buffers. - on the second character, the TCP or HTTP stream state when it was closed : R : the proxy was waiting for a complete, valid REQUEST from the client (HTTP mode only). Nothing was sent to any server. Q : the proxy was waiting in the QUEUE for a connection slot. This can only happen when servers have a 'maxconn' parameter set. It can also happen in the global queue after a redispatch consecutive to a failed attempt to connect to a dying server. If no redispatch is reported, then no connection attempt was made to any server. C : the proxy was waiting for the CONNECTION to establish on the server. The server might at most have noticed a connection attempt. H : the proxy was waiting for complete, valid response HEADERS from the server (HTTP only). D : the stream was in the DATA phase. L : the proxy was still transmitting LAST data to the client while the server had already finished. This one is very rare as it can only happen when the client dies while receiving the last packets. T : the request was tarpitted. It has been held open with the client during the whole "timeout tarpit" duration or until the client closed, both of which will be reported in the "Tw" timer. - : normal stream completion after end of data transfer. - the third character tells whether the persistence cookie was provided by the client (only in HTTP mode) : N : the client provided NO cookie. This is usually the case for new visitors, so counting the number of occurrences of this flag in the logs generally indicate a valid trend for the site frequentation. I : the client provided an INVALID cookie matching no known server. This might be caused by a recent configuration change, mixed cookies between HTTP/HTTPS sites, persistence conditionally ignored, or an attack. D : the client provided a cookie designating a server which was DOWN, so either "option persist" was used and the client was sent to this server, or it was not set and the client was redispatched to another server. V : the client provided a VALID cookie, and was sent to the associated server. E : the client provided a valid cookie, but with a last date which was older than what is allowed by the "maxidle" cookie parameter, so the cookie is consider EXPIRED and is ignored. The request will be redispatched just as if there was no cookie. O : the client provided a valid cookie, but with a first date which was older than what is allowed by the "maxlife" cookie parameter, so the cookie is consider too OLD and is ignored. The request will be redispatched just as if there was no cookie. U : a cookie was present but was not used to select the server because some other server selection mechanism was used instead (typically a "use-server" rule). - : does not apply (no cookie set in configuration). - the last character reports what operations were performed on the persistence cookie returned by the server (only in HTTP mode) : N : NO cookie was provided by the server, and none was inserted either. I : no cookie was provided by the server, and the proxy INSERTED one. Note that in "cookie insert" mode, if the server provides a cookie, it will still be overwritten and reported as "I" here. U : the proxy UPDATED the last date in the cookie that was presented by the client. This can only happen in insert mode with "maxidle". It happens every time there is activity at a different date than the date indicated in the cookie. If any other change happens, such as a redispatch, then the cookie will be marked as inserted instead. P : a cookie was PROVIDED by the server and transmitted as-is. R : the cookie provided by the server was REWRITTEN by the proxy, which happens in "cookie rewrite" or "cookie prefix" modes. D : the cookie provided by the server was DELETED by the proxy. - : does not apply (no cookie set in configuration). The combination of the two first flags gives a lot of information about what was happening when the stream or session terminated, and why it did terminate. It can be helpful to detect server saturation, network troubles, local system resource starvation, attacks, etc... The most common termination flags combinations are indicated below. They are alphabetically sorted, with the lowercase set just after the upper case for easier finding and understanding. Flags Reason -- Normal termination. CC The client aborted before the connection could be established to the server. This can happen when HAProxy tries to connect to a recently dead (or unchecked) server, and the client aborts while HAProxy is waiting for the server to respond or for "timeout connect" to expire. CD The client unexpectedly aborted during data transfer. This can be caused by a browser crash, by an intermediate equipment between the client and HAProxy which decided to actively break the connection, by network routing issues between the client and HAProxy, or by a keep-alive stream between the server and the client terminated first by the client. cD The client did not send nor acknowledge any data for as long as the "timeout client" delay. This is often caused by network failures on the client side, or the client simply leaving the net uncleanly. CH The client aborted while waiting for the server to start responding. It might be the server taking too long to respond or the client clicking the 'Stop' button too fast. cH The "timeout client" stroke while waiting for client data during a POST request. This is sometimes caused by too large TCP MSS values for PPPoE networks which cannot transport full-sized packets. It can also happen when client timeout is smaller than server timeout and the server takes too long to respond. CQ The client aborted while its stream was queued, waiting for a server with enough empty slots to accept it. It might be that either all the servers were saturated or that the assigned server was taking too long a time to respond. CR The client aborted before sending a full HTTP request. Most likely the request was typed by hand using a telnet client, and aborted too early. The HTTP status code is likely a 400 here. Sometimes this might also be caused by an IDS killing the connection between HAProxy and the client. "option http-ignore-probes" can be used to ignore connections without any data transfer. cR The "timeout http-request" stroke before the client sent a full HTTP request. This is sometimes caused by too large TCP MSS values on the client side for PPPoE networks which cannot transport full-sized packets, or by clients sending requests by hand and not typing fast enough, or forgetting to enter the empty line at the end of the request. The HTTP status code is likely a 408 here. Note: recently, some browsers started to implement a "pre-connect" feature consisting in speculatively connecting to some recently visited web sites just in case the user would like to visit them. This results in many connections being established to web sites, which end up in 408 Request Timeout if the timeout strikes first, or 400 Bad Request when the browser decides to close them first. These ones pollute the log and feed the error counters. Some versions of some browsers have even been reported to display the error code. It is possible to work around the undesirable effects of this behavior by adding "option http-ignore-probes" in the frontend, resulting in connections with zero data transfer to be totally ignored. This will definitely hide the errors of people experiencing connectivity issues though. CT The client aborted while its stream was tarpitted. It is important to check if this happens on valid requests, in order to be sure that no wrong tarpit rules have been written. If a lot of them happen, it might make sense to lower the "timeout tarpit" value to something closer to the average reported "Tw" timer, in order not to consume resources for just a few attackers. LC The request was intercepted and locally handled by HAProxy. The request was not sent to the server. It only happens with a redirect because of a "redir" parameter on the server line. LR The request was intercepted and locally handled by HAProxy. The request was not sent to the server. Generally it means a redirect was returned, an HTTP return statement was processed or the request was handled by an applet (stats, cache, Prometheus exported, lua applet...). LH The response was intercepted and locally handled by HAProxy. Generally it means a redirect was returned or an HTTP return statement was processed. SC The server or an equipment between it and HAProxy explicitly refused the TCP connection (the proxy received a TCP RST or an ICMP message in return). Under some circumstances, it can also be the network stack telling the proxy that the server is unreachable (e.g. no route, or no ARP response on local network). When this happens in HTTP mode, the status code is likely a 502 or 503 here. sC The "timeout connect" stroke before a connection to the server could complete. When this happens in HTTP mode, the status code is likely a 503 or 504 here. SD The connection to the server died with an error during the data transfer. This usually means that HAProxy has received an RST from the server or an ICMP message from an intermediate equipment while exchanging data with the server. This can be caused by a server crash or by a network issue on an intermediate equipment. sD The server did not send nor acknowledge any data for as long as the "timeout server" setting during the data phase. This is often caused by too short timeouts on L4 equipment before the server (firewalls, load-balancers, ...), as well as keep-alive sessions maintained between the client and the server expiring first on HAProxy. SH The server aborted before sending its full HTTP response headers, or it crashed while processing the request. Since a server aborting at this moment is very rare, it would be wise to inspect its logs to control whether it crashed and why. The logged request may indicate a small set of faulty requests, demonstrating bugs in the application. Sometimes this might also be caused by an IDS killing the connection between HAProxy and the server. sH The "timeout server" stroke before the server could return its response headers. This is the most common anomaly, indicating too long transactions, probably caused by server or database saturation. The immediate workaround consists in increasing the "timeout server" setting, but it is important to keep in mind that the user experience will suffer from these long response times. The only long term solution is to fix the application. sQ The stream spent too much time in queue and has been expired. See the "timeout queue" and "timeout connect" settings to find out how to fix this if it happens too often. If it often happens massively in short periods, it may indicate general problems on the affected servers due to I/O or database congestion, or saturation caused by external attacks. PC The proxy refused to establish a connection to the server because the process's socket limit has been reached while attempting to connect. The global "maxconn" parameter may be increased in the configuration so that it does not happen anymore. This status is very rare and might happen when the global "ulimit-n" parameter is forced by hand. PD The proxy blocked an incorrectly formatted chunked encoded message in a request or a response, after the server has emitted its headers. In most cases, this will indicate an invalid message from the server to the client. HAProxy supports chunk sizes of up to 2GB - 1 (2147483647 bytes). Any larger size will be considered as an error. PH The proxy blocked the server's response, because it was invalid, incomplete, dangerous (cache control), or matched a security filter. In any case, an HTTP 502 error is sent to the client. One possible cause for this error is an invalid syntax in an HTTP header name containing unauthorized characters. It is also possible but quite rare, that the proxy blocked a chunked-encoding request from the client due to an invalid syntax, before the server responded. In this case, an HTTP 400 error is sent to the client and reported in the logs. Finally, it may be due to an HTTP header rewrite failure on the response. In this case, an HTTP 500 error is sent (see "tune.maxrewrite" and "http-response strict-mode" for more inforomation). PR The proxy blocked the client's HTTP request, either because of an invalid HTTP syntax, in which case it returned an HTTP 400 error to the client, or because a deny filter matched, in which case it returned an HTTP 403 error. It may also be due to an HTTP header rewrite failure on the request. In this case, an HTTP 500 error is sent (see "tune.maxrewrite" and "http-request strict-mode" for more inforomation). PT The proxy blocked the client's request and has tarpitted its connection before returning it a 500 server error. Nothing was sent to the server. The connection was maintained open for as long as reported by the "Tw" timer field. RC A local resource has been exhausted (memory, sockets, source ports) preventing the connection to the server from establishing. The error logs will tell precisely what was missing. This is very rare and can only be solved by proper system tuning. The combination of the two last flags gives a lot of information about how persistence was handled by the client, the server and by HAProxy. This is very important to troubleshoot disconnections, when users complain they have to re-authenticate. The commonly encountered flags are : -- Persistence cookie is not enabled. NN No cookie was provided by the client, none was inserted in the response. For instance, this can be in insert mode with "postonly" set on a GET request. II A cookie designating an invalid server was provided by the client, a valid one was inserted in the response. This typically happens when a "server" entry is removed from the configuration, since its cookie value can be presented by a client when no other server knows it. NI No cookie was provided by the client, one was inserted in the response. This typically happens for first requests from every user in "insert" mode, which makes it an easy way to count real users. VN A cookie was provided by the client, none was inserted in the response. This happens for most responses for which the client has already got a cookie. VU A cookie was provided by the client, with a last visit date which is not completely up-to-date, so an updated cookie was provided in response. This can also happen if there was no date at all, or if there was a date but the "maxidle" parameter was not set, so that the cookie can be switched to unlimited time. EI A cookie was provided by the client, with a last visit date which is too old for the "maxidle" parameter, so the cookie was ignored and a new cookie was inserted in the response. OI A cookie was provided by the client, with a first visit date which is too old for the "maxlife" parameter, so the cookie was ignored and a new cookie was inserted in the response. DI The server designated by the cookie was down, a new server was selected and a new cookie was emitted in the response. VI The server designated by the cookie was not marked dead but could not be reached. A redispatch happened and selected another one, which was then advertised in the response.

8.6. 不可打印字符

为了在查阅日志时避免给日志分析工具或终端带来麻烦,不可打印的字符不会按原样发送到日志文件中,而是会转换为其 ASCII 码的两位十六进制表示,并以字符“#”为前缀。唯一可以不经转义直接记录的字符范围是 32 到 126(含)。显然,转义字符“#”本身也会被编码以避免任何歧义(“#23”)。字符“"”也是如此,它会变成“#22”,以及在记录头时,“{”、“|”和“}”也是如此。请注意,空格字符(' ')在头中不被编码,这可能会给依赖空格计数来定位字段的工具带来问题。一个包含空格的典型头是“User-Agent”。最后,据观察,一些 syslog 守护进程(如 syslog-ng)会用反斜杠('\')来转义引号('\"')。可以安全地执行反向操作,因为日志中其他任何地方都不会出现引号。

8.7. 捕获 HTTP cookie

Cookie 捕获简化了对完整用户会话的跟踪。这可以通过在前端使用“capture cookie”语句来实现。更多详情请参考第 4.2 节。只能捕获一个 cookie,并且同一个 cookie 将同时在请求(“Cookie:”头)和响应(“Set-Cookie:”头)中进行检查。相应的值将报告在 HTTP 日志的“captured_request_cookie”和“captured_response_cookie”位置(请参阅关于 HTTP 日志格式的第 8.2.3 节)。当任一 cookie 未被看到时,一个破折号('-')将取代该值。这样,就很容易检测到用户何时切换到新会话,例如,因为服务器将为其重新分配一个新的 cookie。也可以检测服务器是否意外地向客户端设置了错误的 cookie,从而导致会话交叉。
示例
# 捕获第一个名称以“ASPSESSION”开头的 cookie capture cookie ASPSESSION len 32 # 捕获第一个名称正好是“vgnvisitor”的 cookie capture cookie vgnvisitor= len 32

8.8. 捕获 HTTP 头

Header captures are useful to track unique request identifiers set by an upper proxy, virtual host names, user-agents, POST content-length, referrers, etc. In the response, one can search for information about the response length, how the server asked the cache to behave, or an object location during a redirection. Header captures are performed using the "capture request header" and "capture response header" statements in the frontend. Please consult their definition in section 4.2 for more details. It is possible to include both request headers and response headers at the same time. Non-existent headers are logged as empty strings, and if one header appears more than once, only its last occurrence will be logged. Request headers are grouped within braces '{' and '}' in the same order as they were declared, and delimited with a vertical bar '|' without any space. Response headers follow the same representation, but are displayed after a space following the request headers block. These blocks are displayed just before the HTTP request in the logs. As a special case, it is possible to specify an HTTP header capture in a TCP frontend. The purpose is to enable logging of headers which will be parsed in an HTTP backend if the request is then switched to this HTTP backend.
示例
    # This instance chains to the outgoing proxy listen proxy-out mode http option httplog option logasap log global server cache1 192.168.1.1:3128 # log the name of the virtual server capture request header Host len 20 # log the amount of data uploaded during a POST capture request header Content-Length len 10 # log the beginning of the referrer capture request header Referer len 20 # server name (useful for outgoing proxies only) capture response header Server len 20 # logging the content-length is useful with "option logasap" capture response header Content-Length len 10 # log the expected cache behavior on the response capture response header Cache-Control len 8 # the Via header will report the next proxy's name capture response header Via len 20 # log the URL location during a redirection capture response header Location len 20 >>> Aug 9 20:26:09 localhost \ haproxy[2022]: 127.0.0.1:34014 [09/Aug/2004:20:26:09] proxy-out \ proxy-out/cache1 0/0/0/162/+162 200 +350 - - ---- 0/0/0/0/0 0/0 \ {fr.adserver.yahoo.co||http://fr.f416.mail.} {|864|private||} \ "GET http://fr.adserver.yahoo.com/" >>> Aug 9 20:30:46 localhost \ haproxy[2022]: 127.0.0.1:34020 [09/Aug/2004:20:30:46] proxy-out \ proxy-out/cache1 0/0/0/182/+182 200 +279 - - ---- 0/0/0/0/0 0/0 \ {w.ods.org||} {Formilux/0.1.8|3495|||} \ "GET http://trafic.1wt.eu/ HTTP/1.1" >>> Aug 9 20:30:46 localhost \ haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46] proxy-out \ proxy-out/cache1 0/0/2/126/+128 301 +223 - - ---- 0/0/0/0/0 0/0 \ {www.sytadin.equipement.gouv.fr||http://trafic.1wt.eu/} \ {Apache|230|||http://www.sytadin.} \ "GET http://www.sytadin.equipement.gouv.fr/ HTTP/1.1"

8.9. 日志示例

These are real-world examples of logs accompanied with an explanation. Some of them have been made up by hand. The syslog part has been removed for better reading. Their sole purpose is to explain how to decipher them. >>> haproxy[674]: 127.0.0.1:33318 [15/Oct/2003:08:31:57.130] px-http \ px-http/srv1 6559/0/7/147/6723 200 243 - - ---- 5/3/3/1/0 0/0 \ "HEAD / HTTP/1.0" => long request (6.5s) entered by hand through 'telnet'. The server replied in 147 ms, and the session ended normally ('----') >>> haproxy[674]: 127.0.0.1:33319 [15/Oct/2003:08:31:57.149] px-http \ px-http/srv1 6559/1230/7/147/6870 200 243 - - ---- 324/239/239/99/0 \ 0/9 "HEAD / HTTP/1.0" => Idem, but the request was queued in the global queue behind 9 other requests, and waited there for 1230 ms. >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.654] px-http \ px-http/srv1 9/0/7/14/+30 200 +243 - - ---- 3/3/3/1/0 0/0 \ "GET /image.iso HTTP/1.0" => request for a long data transfer. The "logasap" option was specified, so the log was produced just before transferring data. The server replied in 14 ms, 243 bytes of headers were sent to the client, and total time from accept to first data byte is 30 ms. >>> haproxy[674]: 127.0.0.1:33320 [15/Oct/2003:08:32:17.925] px-http \ px-http/srv1 9/0/7/14/30 502 243 - - PH-- 3/2/2/0/0 0/0 \ "GET /cgi-bin/bug.cgi? HTTP/1.0" => the proxy blocked a server response either because of an "http-response deny" rule, or because the response was improperly formatted and not HTTP-compliant, or because it blocked sensitive information which risked being cached. In this case, the response is replaced with a "502 bad gateway". The flags ("PH--") tell us that it was HAProxy who decided to return the 502 and not the server. >>> haproxy[18113]: 127.0.0.1:34548 [15/Oct/2003:15:18:55.798] px-http \ px-http/<NOSRV> -1/-1/-1/-1/8490 -1 0 - - CR-- 2/2/2/0/0 0/0 "" => the client never completed its request and aborted itself ("C---") after 8.5s, while the proxy was waiting for the request headers ("-R--"). Nothing was sent to any server. >>> haproxy[18113]: 127.0.0.1:34549 [15/Oct/2003:15:19:06.103] px-http \ px-http/<NOSRV> -1/-1/-1/-1/50001 408 0 - - cR-- 2/2/2/0/0 0/0 "" => The client never completed its request, which was aborted by the time-out ("c---") after 50s, while the proxy was waiting for the request headers ("-R--"). Nothing was sent to any server, but the proxy could send a 408 return code to the client. >>> haproxy[18989]: 127.0.0.1:34550 [15/Oct/2003:15:24:28.312] px-tcp \ px-tcp/srv1 0/0/5007 0 cD 0/0/0/0/0 0/0 => This log was produced with "option tcplog". The client timed out after 5 seconds ("c----"). >>> haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31.462] px-http \ px-http/srv1 3183/-1/-1/-1/11215 503 0 - - SC-- 205/202/202/115/3 \ 0/0 "HEAD / HTTP/1.0" => The request took 3s to complete (probably a network problem), and the connection to the server failed ('SC--') after 4 attempts of 2 seconds (config says 'retries 3'), and no redispatch (otherwise we would have seen "/+3"). Status code 503 was returned to the client. There were 115 connections on this server, 202 connections on this proxy, and 205 on the global process. It is possible that the server refused the connection because of too many already established.
此处列出了官方支持的过滤器及其接受的参数。根据编译选项,其中一些过滤器可能不可用。可用过滤器的列表将在 haproxy -vv 中报告。

9.1. 跟踪

filter trace [name <name>] [random-forwarding] [hexdump]
参数
<name> 是一个任意名称,将在消息中报告。如果未提供名称,则使用“TRACE”。 <quiet> 会抑制跟踪消息。 <random-forwarding> 启用对解析数据的随机转发。默认情况下,此过滤器转发所有先前解析的数据。使用此参数,它仅转发解析数据的随机量。 <hexdump> 将所有转发的数据转储到服务器和客户端。
此过滤器可用作开发新过滤器的基础。它定义了所有回调,并在标准错误流(stderr)上打印一条包含所有回调有用信息的消息。调试其他过滤器活动或 HAProxy 本身活动时可能很有用。使用 <;random-parsing> 和/或 <;random-forwarding> 参数是通过在处理中增加延迟来测试解析客户端和服务器之间交换数据的过滤器行为的好方法。

9.2. HTTP 压缩

HTTP compression has been moved to a filter in HAProxy 1.7. "compression" keyword must still be used to enable and configure HTTP compression. And when no other filter is used, it is enough. When used with the cache or the fcgi-app enabled, it is also enough. In this case, the compression is always done after the response is stored in the cache. But it is mandatory to explicitly use a filter line to enable HTTP compression when at least one filter other than the cache or the fcgi-app is used for the same listener/frontend/backend. This is important to know the filters evaluation order.

9.3. Stream Processing Offload Engine (SPOE)

filter spoe [engine <name>] config <file>
参数
<name> is the engine name that will be used to find the right scope in the configuration file. If not provided, all the file will be parsed. <file> is the path of the engine configuration file. This file can contain configuration of several engines. In this case, each part must be placed in its own scope.
The Stream Processing Offload Engine (SPOE) is a filter communicating with external components. It allows the offload of some specifics processing on the streams in tiered applications. These external components and information exchanged with them are configured in dedicated files, for the main part. It also requires dedicated backends, defined in HAProxy configuration. SPOE communicates with external components using an in-house binary protocol, the Stream Processing Offload Protocol (SPOP). For all information about the SPOE configuration and the SPOP specification, see "doc/SPOE.txt".

9.4. Cache

参数
<name> is name of the cache section this filter will use.
The cache uses a filter to store cacheable responses. The HTTP rules "cache-store" and "cache-use" must be used to define how and when to use a cache. By default the corresponding filter is implicitly defined. And when no other filters than fcgi-app or compression are used, it is enough. In such case, the compression filter is always evaluated after the cache filter. But it is mandatory to explicitly use a filter line to use a cache when at least one filter other than the compression or the fcgi-app is used for the same listener/frontend/backend. This is important to know the filters evaluation order.

9.5. Fcgi-app

参数
<name> is name of the fcgi-app section this filter will use.
The FastCGI application uses a filter to evaluate all custom parameters on the request path, and to process the headers on the response path. the <name> must reference an existing fcgi-app section. The directive "use-fcgi-app" should be used to define the application to use. By default the corresponding filter is implicitly defined. And when no other filters than cache or compression are used, it is enough. But it is mandatory to explicitly use a filter line to a fcgi-app when at least one filter other than the compression or the cache is used for the same backend. This is important to know the filters evaluation order.

9.6. OpenTracing

OpenTracing过滤器增加了对 HAProxy 中分布式跟踪的原生支持。通过向 Datadog、Jaeger、Lightstep 和 Zipkin 追踪器等受支持的追踪器发送符合 OpenTracing 标准的请求来启用此功能。请注意:追踪器列表不分先后,按字母顺序排列。此功能仅在 HAProxy 使用 USE_OT=1 构建时启用。OpenTracing 过滤器的激活通过在 HAProxy 配置中显式指定来实现。如果未这样做,OpenTracing 过滤器将不会参与 HAProxy 的任何工作。
filter opentracing [id <id>] config <file>
参数
<id> 是 OpenTracing 过滤器的 ID,用于在配置文件中查找正确的范围。如果未指定过滤器 ID,则默认使用 'ot-filter'。如果在配置文件中未指定范围,则适用于所有已定义的 OpenTracing 过滤器。<file> 是 OpenTracing 配置文件路径。同一文件可以同时包含多个 OpenTracing 过滤器的配置。在这种情况下,我们不需要定义范围,因此相同的配置适用于所有过滤器,或者每个过滤器必须定义自己的范围。
有关该过滤器操作、配置和使用的更详细文档,请参见 addons/ot 目录。

9.7. 带宽限制

filter bwlim-in <name> default-limit <size> default-period <time> [min-size <sz>]
filter bwlim-out <name> default-limit <size> default-period <time> [min-size <sz>]
filter bwlim-in <name> limit <size> key <pattern> [table <table>] [min-size <sz>]
filter bwlim-out <name> limit <size> key <pattern> [table <table>] [min-size <sz>]
参数
<name> is the filter name that will be used by 'set-bandwidth-limit' actions to reference a specific bandwidth limitation filter. <size> is max number of bytes that can be forwarded over the period. The value must be specified for per-stream and shared bandwidth limitation filters. It follows the HAProxy size format and is expressed in bytes. <pattern> is a sample expression rule as described in section 7.3. It describes what elements will be analyzed, extracted, combined, and used to select which table entry to update the counters. It must be specified for shared bandwidth limitation filters only. <table> is an optional table to be used instead of the default one, which is the stick-table declared in the current proxy. It can be specified for shared bandwidth limitation filters only. <time> is the default time period used to evaluate the bandwidth limitation rate. It can be specified for per-stream bandwidth limitation filters only. It follows the HAProxy time format and is expressed in milliseconds. <min-size> is the optional minimum number of bytes forwarded at a time by a stream excluding the last packet that may be smaller. This value can be specified for per-stream and shared bandwidth limitation filters. It follows the HAProxy size format and is expressed in bytes.
Bandwidth limitation filters should be used to restrict the data forwarding speed at the stream level. By extension, such filters limit the network bandwidth consumed by a resource. Several bandwidth limitation filters can be used. For instance, it is possible to define a limit per source address to be sure a client will never consume all the network bandwidth, thereby penalizing other clients, and another one per stream to be able to fairly handle several connections for a given client. The definition order of these filters is important. If several bandwidth filters are enabled on a stream, the filtering will be applied in their definition order. It is also important to understand the definition order of the other filters have an influence. For instance, depending on the HTTP compression filter is defined before or after a bandwidth limitation filter, the limit will be applied on the compressed payload or not. The same is true for the cache filter. There are two kinds of bandwidth limitation filters. The first one enforces a default limit and is applied per stream. The second one uses a stickiness table to enforce a limit equally divided between all streams sharing the same entry in the table. In addition, for a given filter, depending on the filter keyword used, the limitation can be applied on incoming data, received from the client and forwarded to a server, or on outgoing data, received from a server and sent to the client. To apply a limit on incoming data, "bwlim-in" keyword must be used. To apply it on outgoing data, "bwlim-out" keyword must be used. In both cases, the bandwidth limitation is applied on forwarded data, at the stream level. The bandwidth limitation is applied at the stream level and not at the connection level. For multiplexed protocols (H2, H3 and FastCGI), the streams of the same connection may have different limits. For a per-stream bandwidth limitation filter, default period and limit must be defined. As their names suggest, they are the default values used to setup the bandwidth limitation rate for a stream. However, for this kind of filter and only this one, it is possible to redefine these values using sample expressions when the filter is enabled with a TCP/HTTP "set-bandwidth-limit" action. For a shared bandwidth limitation filter, depending on whether it is applied on incoming or outgoing data, the stickiness table used must store the corresponding bytes rate information. "bytes_in_rate(<period>)" counter must be stored to limit incoming data and "bytes_out_rate(<period>)" counter must be used to limit outgoing data. Finally, it is possible to set the minimum number of bytes that a bandwidth limitation filter can forward at a time for a given stream. It should be used to not forward too small amount of data, to reduce the CPU usage. It must carefully be defined. Too small, a value can increase the CPU usage. Too high, it can increase the latency. It is also highly linked to the defined bandwidth limit. If it is too close to the bandwidth limit, some pauses may be experienced to not exceed the limit because too many bytes will be consumed at a time. It is highly dependent on the filter configuration. A good idea is to start with something around 2 TCP MSS, typically 2896 bytes, and tune it after some experimentations.
示例
frontend http bind *:80 mode http # If this filter is enabled, the stream will share the download limit # of 10m/s with all other streams with the same source address. filter bwlim-out limit-by-src key src table limit-by-src limit 10m # If this filter is enabled, the stream will be limited to download at 1m/s, # independently of all other streams. filter bwlim-out limit-by-strm default-limit 1m default-period 1s # Limit all streams to 1m/s (the default limit) and those accessing the # internal API to 100k/s. Limit each source address to 10m/s. The shared # limit is applied first. Both are limiting the download rate. http-request set-bandwidth-limit limit-by-strm http-request set-bandwidth-limit limit-by-strm limit 100k if { path_beg /internal } http-request set-bandwidth-limit limit-by-src ... backend limit-by-src # The stickiness table used by <limit-by-src> filter stick-table type ip size 1m expire 3600s store bytes_out_rate(1s)
HAProxy is able to send HTTP requests to Responder FastCGI applications. This feature was added in HAProxy 2.1. To do so, servers must be configured to use the FastCGI protocol (using the keyword "proto fcgi" on the server line) and a FastCGI application must be configured and used by the backend managing these servers (using the keyword "use-fcgi-app" into the proxy section). Several FastCGI applications may be defined, but only one can be used at a time by a backend. HAProxy implements all features of the FastCGI specification for Responder application. Especially it is able to multiplex several requests on a simple connection.

10.1. 设置

10.1.1. Fcgi-app 部分

fcgi-app <name>
声明一个名为 <name> 的 FastCGI 应用程序。要使其有效,至少必须定义 document root。
acl <aclname> <criterion> [flags] [operator] <value> ...
声明或完成访问列表。有关 ACL 用法的详细信息,请参见 第 4.2 节第 7 节中的“acl”关键字。为 FastCGI 应用程序定义的 ACL 是私有的。其他任何应用程序或代理都无法使用它们。同样,任何其他部分中定义的 ACL 也不适用于 FastCGI 应用程序。但是,预定义的 ACL 是可用的。
docroot <path> 定义远程主机上的文档根目录。<path> 将用于构建 FastCGI 参数 SCRIPT_FILENAME 和 PATH_TRANSLATED 的默认值。这是一个强制性设置。
index <script-name>
定义将在以斜杠 ("/") 结尾的 URI 之后附加的脚本名称,用于设置 FastCGI 参数 SCRIPT_NAME 的默认值。这是一个可选设置。
示例
index index.php
log-stderr <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]
启用 FastCGI 应用程序报告的 STDERR 消息的日志记录。有关详细信息,请参见 第 4.2 节中的“log”关键字。这是一个可选设置。默认情况下,STDERR 消息会被忽略。
pass-header <name> [ { if | unless } <condition> ]
指定将传递到 FastCGI 应用程序的请求头名称。它可能可选地跟一个基于 ACL 的条件,在这种情况下,只有当条件为真时才会对其进行评估。大多数请求头已经可供 FastCGI 应用程序使用,并带有“HTTP_”前缀。因此,此指令仅用于传递故意省略的头。当前,“Authorization”、“Proxy-Authorization”以及 hop-by-hop 头都会被省略。请注意,“Content-type”和“Content-length”头永远不会传递给 FastCGI 应用程序,因为它们已经被转换为参数。
path-info <regex>
定义一个正则表达式,用于从 URL 解码的路径中提取脚本名称和 path-info。因此,<regex> 可能有两个捕获:第一个捕获脚本名称,第二个捕获 path-info。第一个是强制性的,第二个是可选的。这样,就可以从路径中提取脚本名称而忽略 path-info。这是一个可选设置。如果未定义,则不会对路径进行匹配。并且 FastCGI 参数 PATH_INFO 和 PATH_TRANSLATED 不会被填充。出于安全原因,当定义此正则表达式时,URL 解码后的路径中禁止使用换行符和空字符。限制的原因是,由于 HAProxy 中正则表达式的执行方式存在限制,否则匹配将始终失败。因此,如果 URL 解码的路径中找到这两个字符中的任何一个,将向客户端返回错误。此处应用了最小惊讶原则。
示例
path-info ^(/.+\.php)(/.*)?$ # both script-name and path-info may be set path-info ^(/.+\.php) # the path-info is ignored
启用或禁用对连接管理变量的检索。HAProxy 能够在连接建立时发送记录 FCGI_GET_VALUES 来检索以下变量的值:* FCGI_MAX_REQS 此应用程序将接受的最大并发请求数。* FCGI_MPXS_CONNS 如果此应用程序不复用连接,则为 "0";否则为 "1"。某些 FastCGI 应用程序不支持此功能。其他一些应用程序在发送响应后会立即关闭连接。因此,默认情况下,此选项处于禁用状态。请注意,FastCGI 应用程序接受的最大并发请求数是一个连接变量。它只限制每个连接的流数。如果必须限制应用程序的全局负载,则必须设置服务器参数 "maxconn" 和 "pool-max-conn"。此外,如果应用程序不支持连接复用,则最大并发请求数会自动设置为 1。
指示 FastCGI 应用程序在发送响应后是否保持连接打开。如果禁用,FastCGI 应用程序将在响应此请求后关闭连接。默认情况下,此选项处于启用状态。
定义此应用程序将接受的最大并发请求数。如果连接建立期间检索到 FCGI_MAX_REQS 变量,此选项可能会被覆盖。此外,如果应用程序不支持连接多路复用,则将忽略此选项。默认设置为 1。
启用或禁用连接多路复用的支持。如果连接建立期间检索到 FCGI_MPXS_CONNS 变量,此选项可能会被覆盖。默认情况下禁用。
set-param <name> <fmt> [ { if | unless } <condition> ]
设置应传递给此应用程序的 FastCGI 参数。其值由 <fmt> 定义,必须遵循日志格式规则(请参阅第 8.2.6 节“自定义日志格式”)。它可选择性地后跟一个基于 ACL 的条件,在这种情况下,只有当条件为真时才会被评估。通过此指令,可以覆盖默认 FastCGI 参数的值。如果值评估为空字符串,则忽略该规则。这些指令按其声明顺序评估。
示例
# PHP only, required if PHP was built with --enable-force-cgi-redirect set-param REDIRECT_STATUS 200 set-param PHP_AUTH_DIGEST %[req.hdr(Authorization)]

10.1.2. 代理部分

定义要用于后端的 FastCGI 应用程序。
参数
<name> 是要使用的 FastCGI 应用程序的名称。
此关键字仅适用于具有后端功能且至少有一个 FastCGI 服务器的 HTTP 代理。但是,FastCGI 服务器可以与 HTTP 服务器混合。但除非有充分理由,否则不建议这样做(有关详细信息,请参见第 10.3 节的限制)。每个后端一次只能定义一个应用程序。请注意,一旦为后端引用了 FastCGI 应用程序,根据配置,即使请求未发送到 FastCGI 服务器,也可能会执行某些处理。将参数设置或将头传递到应用程序的规则会被评估。

10.1.3. 示例

frontend front-http mode http bind *:80 bind *: use_backend back-dynamic if { path_reg ^/.+\.php(/.*)?$ } default_backend back-static backend back-static mode http server www A.B.C.D:80 backend back-dynamic mode http use-fcgi-app php-fpm server php-fpm A.B.C.D:9000 proto fcgi fcgi-app php-fpm log-stderr global option keep-conn docroot /var/www/my-app index index.php path-info ^(/.+\.php)(/.*)?$

10.2. 默认参数

Responder FastCGI 应用程序具有与 CGI/1.1 程序相同的目的。在 CGI/1.1 规范 (RFC3875) 中,必须向脚本传递几个变量。因此 HAProxy 设置了它们以及 FastCGI 应用程序常用的一些其他变量。所有这些变量都可以被覆盖,但要小心。+-------------------+-----------------------------------------------------+ | AUTH_TYPE | 标识 HAProxy 用于验证用户的机制(如果有)。 | | | 具体来说,只支持 BASIC 身份验证机制。 | | | | +-------------------+-----------------------------------------------------+ | CONTENT_LENGTH | 包含附加到请求的消息体的大小。这意味着 | | | 只有大小已知的请求才被视为有效并发送到 | | | 应用程序。 | | | | +-------------------+-----------------------------------------------------+ | CONTENT_TYPE | 包含附加到请求的消息体的类型。它可能未设置。 | | | | +-------------------+-----------------------------------------------------+ | DOCUMENT_ROOT | 包含远程主机上应执行脚本的文档根目录, | | | 如应用程序配置中所定义。 | | | | +-------------------+-----------------------------------------------------+ | GATEWAY_INTERFACE | 包含 HAProxy 用于与 FastCGI 应用程序通信的 | | | CGI 方言。具体来说,它设置为 "CGI/1.1"。 | | | | +-------------------+-----------------------------------------------------+ | PATH_INFO | 包含 URI 路径层次结构中标识脚本本身的 | | | 部分之后的部分。要设置,必须定义指令 | | | "path-info"。 | | | | +-------------------+-----------------------------------------------------+ | PATH_TRANSLATED | 如果设置了 PATH_INFO,它是其翻译版本。 | | | 它是 DOCUMENT_ROOT 和 PATH_INFO 的串联。 | | | 如果未设置 PATH_INFO,则此参数也不会设置。 | | | | +-------------------+-----------------------------------------------------+ | QUERY_STRING | 包含请求的查询字符串。它可能未设置。 | | | | +-------------------+-----------------------------------------------------+ | REMOTE_ADDR | 包含发送请求的客户端的网络地址。 | | | | +-------------------+-----------------------------------------------------+ | REMOTE_USER | 包含客户端作为用户身份验证的一部分提供的 | | | 用户标识字符串。 | | | | +-------------------+-----------------------------------------------------+ | REQUEST_METHOD | 包含脚本应用于处理请求的方法。 | | | | +-------------------+-----------------------------------------------------+ | REQUEST_URI | 包含请求的 URI。 | | | | +-------------------+-----------------------------------------------------+ | SCRIPT_FILENAME | 包含脚本的绝对路径名。它是 DOCUMENT_ROOT 和 | | | SCRIPT_NAME 的串联。 | | | | +-------------------+-----------------------------------------------------+ | SCRIPT_NAME | 包含脚本的名称。如果定义了指令 "path-info", | | | 它是 URI 路径层次结构的**第一部分**,以脚本 | | | 名称结尾。否则,它是**整个** URI 路径。 | | | | +-------------------+-----------------------------------------------------+ | SERVER_NAME | 包含客户端请求所针对的服务器主机的名称。 | | | 如果定义了 "Host" 标头,则它是该标头的值。 | | | 否则,它是客户端连接上的目标地址。 | | | | +-------------------+-----------------------------------------------------+ | SERVER_PORT | 包含客户端连接上的目标 TCP 端口,即客户端 | | | 连接到的端口。 | | | | +-------------------+-----------------------------------------------------+ | SERVER_PROTOCOL | 包含请求的协议。 | | | | +-------------------+-----------------------------------------------------+ | SERVER_SOFTWARE | 包含字符串 "HAProxy" 后跟当前的 HAProxy 版本。 | | | | +-------------------+-----------------------------------------------------+ | HTTPS | 如果脚本是通过 HTTPS 协议查询的,则设置为 | | | 非空值 ("on")。 | | | | +-------------------+-----------------------------------------------------+

10.3. 限制

当前的实现有一些限制。第一个是关于某些请求标头对 FastCGI 应用程序隐藏的方式。这发生在后端侧的标头分析期间,在连接建立之前。在此阶段,HAProxy 知道后端正在使用 FastCGI 应用程序,但它不知道请求是否会路由到 FastCGI 服务器。但为了隐藏请求标头,它只是将它们从 HTX 消息中删除。因此,如果请求最终路由到 HTTP 服务器,它永远不会看到这些标头。因此,不建议在同一后端混合使用 FastCGI 服务器和 HTTP 服务器。类似地,规则 "set-param" 和 "pass-header" 在请求标头分析期间进行评估。因此,即使请求最终转发到 HTTP 服务器,也会始终执行评估。关于规则 "set-param",当应用规则时,会将一个伪标头添加到 HTX 消息中。因此,与 HTTP 标头重写相同的方式,如果缓冲区已满,它可能会失败。规则 "set-param" 将与 "http-request" 规则竞争。最后,所有 FastCGI 参数和 HTTP 标头都发送到一个唯一的记录 FCGI_PARAM 中。此记录的编码必须一次完成,否则会返回处理错误。这意味着记录 FCGI_PARAM 编码后不得超过缓冲区的大小。但是,此处没有要遵守的保留。
几个语句,如 "bind"、"server"、"nameserver" 和 "log" 需要一个地址。此地址可以是主机名、IPv4 地址、IPv6 地址或 '*'。'*' 等于特殊地址 "0.0.0.0",可用于 "bind" 或 "dgram-bind" 的情况,用于侦听系统上的所有 IPv4。IPv6 等效项是 '::'。根据语句的不同,IP 地址后面跟着一个端口或端口范围。这对于 'bind' 语句是强制性的,对于 'server' 是可选的。此地址也可以以斜杠 '/' 开头。它被视为 "unix" 系列,'/' 和后面的字符必须是路径。默认套接字类型或传输方法 "datagram" 或 "stream" 取决于显示地址的配置语句。实际上,'bind' 和 'server' 默认使用 "stream" 套接字类型,而 'log'、'nameserver' 或 'dgram-bind' 默认使用 "datagram"。可选地,可以使用前缀来强制指定地址族和/或套接字类型和传输方法。

11.1. 地址族前缀

'abns@<name>' 后面跟着 <name> 是一个抽象命名空间(仅限 Linux)。'fd@<n>' 后面跟着地址是一个从父进程继承的文件描述符 <n>。fd 必须已绑定,并且可能已或未在侦听。'ip@<address>[:port1[-port2]]' 后面跟着 <address> 根据语法被视为 IPv4 或 IPv6 地址。根据使用此地址的语句,可以或必须指定端口或端口范围。'ipv4@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv4 地址。根据使用此地址的语句,可以或必须指定端口或端口范围。'ipv6@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv6 地址。根据使用此地址的语句,可以或必须指定端口或端口范围。'sockpair@<n>' 后面跟着地址是已连接的 unix 套接字或 socketpair 的文件描述符。在连接期间,发起者创建一对连接的套接字,并将其中一个通过 FD 传递给另一端。侦听器等待从 unix 套接字接收 FD,并将其用作 accept() 的 FD。应谨慎使用。'unix@<path>' 后面跟着字符串被视为 UNIX 套接字 <path>。此前缀对于声明不以斜杠 '/' 开头的 UNIX 套接字路径很有用。

11.2. 套接字类型前缀

前面的 "地址族前缀" 也可以作为前缀来强制指定套接字类型和传输方法。默认值取决于使用此地址的语句,但在某些情况下,用户可能希望强制将其设置为不同的值。对于 "log" 语句就是这种情况,其中默认值是通过 UDP 的 syslog,但我们可以强制使用通过 TCP 的 syslog。这些前缀是为内部目的设计的,用户应该改为使用下一节 "11.3 协议前缀" 的别名。但是,这些有时很方便,例如与通过其文件描述符编号已知的继承套接字结合使用,在这种情况下,地址族是 "fd",并且必须声明套接字类型。如果用户需要其中一个前缀来执行他们期望的操作,因为他们无法使用协议前缀配置相同的功能,则应向维护人员报告。'stream+<family>@<address>' 强制套接字类型和传输方法为 "stream"'dgram+<family>@<address>' 强制套接字类型和传输方法为 "datagram"。'quic+<family>@<address>' 强制套接字类型为 "datagram",传输方法为 "stream"。

11.3. 协议前缀

'quic4@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv4 地址,但套接字类型强制为 "datagram",传输方法强制为 "stream"。根据使用此地址的语句,可以或必须指定 UDP 端口或端口范围。它等效于 "quic+ipv4@"。'quic6@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv6 地址,但套接字类型强制为 "datagram",传输方法强制为 "stream"。根据使用此地址的语句,可以或必须指定 UDP 端口或端口范围。它等效于 "quic+ipv6@"。'tcp@<address>[:port1[-port2]]' 后面跟着 <address> 根据语法被视为 IPv4 或 IPv6 地址,但套接字类型和传输方法强制为 "stream"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'stream+ip@' 的别名。'tcp4@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv4 地址,但套接字类型和传输方法强制为 "stream"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'stream+ipv4@' 的别名。'tcp6@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv6 地址,但套接字类型和传输方法强制为 "stream"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'stream+ipv4@' 的别名。'udp@<address>[:port1[-port2]]' 后面跟着 <address> 根据语法被视为 IPv4 或 IPv6 地址,但套接字类型和传输方法强制为 "datagram"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'dgram+ip@' 的别名。'udp4@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv4 地址,但套接字类型和传输方法强制为 "datagram"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'dgram+ipv4@' 的别名。'udp6@<address>[:port1[-port2]]' 后面跟着 <address> 始终被视为 IPv6 地址,但套接字类型和传输方法强制为 "datagram"。根据使用此地址的语句,可以或必须指定端口或端口范围。它被视为 'dgram+ipv4@' 的别名。'uxdg@<path>' 后面跟着字符串被视为 unix 套接字 <path>,但传输方法强制为 "datagram"。它被视为 'dgram+unix@' 的别名。'uxst@<path>' 后面跟着字符串被视为 unix 套接字 <path>,但传输方法强制为 "stream"。它被视为 'stream+unix@' 的别名。在未来的版本中,可以使用其他前缀来指定 QUIC 等协议,这些协议基于 "datagram" 类型的套接字提供流传输。


HAProxy 2.9.15 – 配置手册
, 2025/03/21