跳转到主要内容

7. ACL 与样本提取

ACL 匹配、条件、转换器、样本提取和预定义 ACL

HAProxy 可从请求或响应流、客户端或服务器信息、表格、环境信息等来源提取数据。提取此类数据的动作称为获取样本。获取后,这些样本可用于多种用途,例如作为粘性表的键,但最常见的用法是将其与称为模式的预定义常量数据进行匹配。

7.1. ACL 基础

访问控制列表(ACL)用于声明一种命名的匹配方法,以将任意信息与预先定义的模式列表进行比较。ACL 可视为大多数编程语言中函数的实际等价物,其声明使得该方法可在后续需要时被调用。ACL 的评估结果仅返回匹配或不匹配,这与许多编程语言中的布尔值类似。与编程语言中的函数不同,ACL 可以针对同一名称多次重载,以定义额外的匹配方法。在此情况下,所有 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 时,某些类型会自动关联默认匹配方法,具体如下表所示:

   +---------------------+-----------------+
   | Sample or converter | Default         |
   |    output type      | matching method |
   +---------------------+-----------------+
   | boolean             | bool            |
   +---------------------+-----------------+
   | integer             | int             |
   +---------------------+-----------------+
   | ip                  | ip              |
   +---------------------+-----------------+
   | string              | str             |
   +---------------------+-----------------+
   | binary              | none, use "-m"  |
   +---------------------+-----------------+

请注意,若要匹配二进制样本,必须指定匹配方法,详见下文。

ACL 引擎可将这些类型与以下类型的模式进行匹配:

  • 布尔值
  • 整数或整数范围
  • IP 地址 / 网络
  • 字符串(精确匹配、子串、后缀、前缀、子目录、域名)
  • 正则表达式
  • 十六进制块

以下 ACL 标志当前受支持:

-i: ignore case during matching of all subsequent patterns.
-f: load patterns from a list.
-m: use a specific pattern matching method
-n: forbid the DNS resolutions
-M: load the file pointed by -f like a map.
-u: force the unique id of the ACL
--: force end of flags. Useful when a string looks like one of the flags.

“-f” 标志后跟的名称必须符合第 2.7 节中关于映射和 ACL 名称格式的描述。如果需从多个列表加载模式,可以传递多个“-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” 并后接模式匹配方法名称时,该方法将取代条件的默认匹配方法。这使得能够以最初未计划的方式进行内容匹配,或与返回字符串的样本提取方法配合使用。匹配方法还会影响模式的解析方式,因此不得与带有匹配后缀(_beg、_end、_sub…)的样本提取操作一同使用。此外,禁止指定多个 “-m” 模式匹配方法。

“-n” 标志禁止 DNS 解析。该标志与 IP 文件加载配合使用。默认情况下,若解析器无法解析 IP 地址,会认为被解析的字符串可能为域名并尝试进行 DNS 解析。标志 “-n” 可禁用此解析行为。该选项有助于检测格式错误的 IP 列表。请注意,若 DNS 服务器不可达,HAProxy 配置解析过程可能持续数分钟,等待超时。在此期间不会显示任何错误消息。标志 “-n” 可禁用此行为。此外,在运行时,该功能对于动态 ACL 修改将被禁用。

然而,存在一些限制。并非所有匹配方法均可与所有样本提取方法配合使用。 此外,若将 “-m” 与 “-f” 一同使用,必须将 “-m” 置于首位。模式匹配方法必须为以下之一:

  • “found”: 仅检查请求的样本是否存在于流中,而不与任何模式进行比较。建议不要传递任何模式,以避免混淆。此匹配方法特别适用于检测特定内容(如头、Cookie 等)是否存在,即使其为空,也无需与任何内容比较或计数。

  • “bool” : 将值作为布尔类型进行检查。仅可应用于返回布尔值或整数值的 fetch 操作,且不接受任何模式。值为零或 false 时不匹配,其余所有值均匹配。

  • int:将值匹配为整数。可用于整数和布尔值样本。布尔值 false 对应整数 0,true 对应整数 1。

  • “ip” : 以 IPv4 或 IPv6 地址形式匹配值。仅与 IP 地址样本兼容,因此为隐含项,无需显式指定。

  • “bin” : 将内容与表示二进制序列的十六进制字符串进行匹配。此选项可用于二进制或字符串样本。

  • “len” : 以整数形式匹配样本的长度。可与二进制或字符串样本配合使用。

  • “str” : 精确匹配:将内容与字符串进行匹配。此选项可用于二进制或字符串样本。

  • “sub” : 子串匹配:检查内容中是否包含至少一个提供的字符串模式。此模式可用于二进制或字符串样本。

  • “reg” : 正则表达式匹配:将内容与一组正则表达式进行匹配。此选项可用于二进制或字符串样本。

  • “beg” : 前缀匹配:检查内容是否以提供的字符串模式开头。此模式可用于二进制或字符串样本。

  • “end” : 后缀匹配:检查内容是否以提供的字符串模式结尾。此模式可用于二进制或字符串样本。

  • “dir” : subdir 匹配:检查内容中以斜杠分隔的部分是否与提供的某个字符串模式完全匹配。此功能可用于二进制或字符串样本。

  • “dom” : 域名匹配:检查内容中以点分隔的部分是否与提供的某个字符串模式完全匹配。此模式可用于二进制或字符串样本。

例如,要快速检测 HTTP 请求中是否存在 Cookie “JSESSIONID”,可以执行:

acl jsess_present req.cook(JSESSIONID) -m found

为在缓冲区的前 500 字节数据上应用正则表达式,可使用以下 ACL:

acl script_tag req.payload(0,500) -m reg -i <script>

在正则表达式库在使用 “-i” 时性能显著降低的系统上,可在匹配前将样本转换为小写,例如:

acl script_tag req.payload(0,500),lower -m reg <script>

所有 ACL 特定条件均隐含一个默认匹配方法。大多数情况下,这些条件通过将原始样本提取方法名称与匹配方法拼接而成。例如,“hdr_beg” 对使用 “hdr” 样本提取方法获取的样本应用 “beg” 匹配。该匹配方法仅在关键字单独使用、未附加任何转换器时可用。若在该 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” 时自动生效。

                           +-------------------------------------------------+
                           |                Input sample type                |
    +----------------------+---------+---------+---------+---------+---------+
    |     pattern type     | 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”的 fetch 方法默认使用布尔匹配。使用布尔匹配时,获取的值将原样返回,即布尔值“true”始终匹配,布尔值“false”从不匹配。

布尔匹配也可通过在返回整数值的 fetch 方法中使用 “-m bool” 强制执行。此时,整数值 0 被转换为布尔值 “false”,其余所有值均被转换为 “true”。

7.1.2. 匹配整数

整数匹配默认适用于整数获取方法。也可通过使用 “-m int” 强制对布尔值获取进行整数匹配。此时,“false” 将被转换为整数 0,“true” 将被转换为整数 1。

整数匹配还支持整数范围和运算符。请注意,整数匹配仅适用于正值。范围以冒号分隔的下界和上界表示,两者均可省略。

例如,“1024:65535” 是表示非特权端口范围的有效范围,而 “1024:” 也同样有效。“0:1023” 是表示特权端口的有效表示方式,而 “:1023” 也同样适用。

作为特例,某些 ACL 函数支持小数形式的数值,这些数值实际上是由两个整数通过英文句点分隔构成。例如,在某些版本检查中会用到此类格式。所有整数属性均适用于此类小数,包括范围和运算符。

为便于使用,也支持比较运算符。请注意,将运算符与范围结合使用意义不大,强烈不建议这样做。同理,对一组值执行顺序比较也不合理。

整数匹配可用的运算符如下:

eq: true if the tested value equals at least one value
ge: true if the tested value is greater than or equal to at least one value
gt: true if the tested value is greater than at least one value
le: true if the tested value is less than or equal to at least one value
lt: true if the tested value is less than at least one value

例如,以下 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. 匹配字符串

字符串匹配适用于字符串或二进制获取方法,共有六种不同形式:

  • 精确匹配(-m str):提取的字符串必须与模式完全匹配;

  • 子串匹配(-m sub):在提取的字符串中查找模式,若其中任意一个模式被找到,则 ACL 匹配成功;

  • 前缀匹配(-m beg):模式与提取字符串的开头进行比较,只要其中任意一个匹配,ACL 即视为匹配。

  • 后缀匹配(-m 结尾):模式与提取字符串的末尾进行比较,只要其中任意一个匹配,ACL 即匹配。

  • subdir match (-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 设计。模式中的前导和尾随分隔符会被忽略。只要任一模式匹配即判定为匹配。例如在字符串 “http://www1.dc-eu.example.com:80/blah ” 中,“http”、“www1”、".www1"、“dc-eu”、“example”、“com”、“80”、“dc-eu.example”、“blah”、":www1:"、“dc-eu.example:80” 均可匹配,但 “eu” 和 “dc” 不匹配。使用该方式匹配域名后缀以实现过滤或路由通常并非良策,因为路由可能轻易被欺骗,例如在另一个域名前添加匹配前缀即可绕过规则。

字符串匹配适用于原样传递的字面量字符串,唯一例外是反斜杠("\"),可用于转义空格等字符。 若在第一个字符串前传递 “-i” 标志,则匹配时将忽略大小写。 要匹配字符串 “-i”,可将其置于第二个位置,或在第一个字符串前传递 “–” 标志。 同理,匹配字符串 “–” 时也适用相同规则。

对于可能包含空字节(0x00)的二进制获取操作,不得使用字符串匹配,因为比较会在遇到第一个空字节时停止。应首先使用 hex 转换器将二进制获取结果转换为十六进制字符串。

示例:

# matches if the string <tag> is present in the binary sample
acl tag_found req.payload(0,0),hex -m sub 3C7461673E

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

与字符串匹配类似,正则表达式匹配会原样处理传入的字面量字符串,唯一例外是反斜杠("\"),可用于转义空格等字符。若在第一个正则表达式前传递 “-i” 标志,则匹配时将忽略大小写。要匹配字符串 “-i”,可将其置于第二个位置,或在第一个字符串前传递 “–” 标志。同理,匹配字符串 “–” 也遵循相同原则。

7.1.5. 匹配任意数据块

可以将某些提取的样本与二进制块进行匹配,该二进制块可能无法安全地表示为字符串。为此,当匹配方法设置为 binary 时,模式必须以偶数个十六进制数字的形式传递。每两个数字组成一个字节。十六进制数字可使用大写或小写。

示例:

# match "Hello\n" in the input stream (\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 地址表示法支持常规形式以及简写形式,后者可省略所有为 0 的字节:

    +------------------+------------------+------------------+
    |   Example 1      |     Example 2    |     Example 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,匹配在 IPv4 环境下使用模式的掩码进行,前提是 IPv6 地址符合 2002:IPV4::、::IPV4 或 ::ffff: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” 语句之后,表示在何种情况下触发动作。

例如,阻止对 “*” URL 发起的 HTTP 请求(方法非 “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 表达式,可在无需声明的情况下动态构建。它们必须用大括号括起,大括号前后均需留一个空格(因为大括号必须被视为独立的词)。示例:

The following rule:

    acl missing_cl req.hdr_cnt(Content-length) eq 0
    http-request deny if METH_POST missing_cl

Can also be written that way:

    http-request deny if METH_POST { req.hdr_cnt(Content-length) eq 0 }

通常不建议使用此结构,因为以这种方式编写配置时更容易引入错误。然而,对于仅匹配单一源 IP 地址等非常简单的规则,使用它们可能比声明带有随机名称的 ACL 更为合理。另一个合适的使用示例是:

With named ACLs:

     acl site_dead nbsrv(dynamic) lt 2
     acl site_dead nbsrv(static)  lt 2
     monitor fail  if site_dead

With anonymous ACLs:

     monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }

请参阅 第 4.2 节 ,以获取关于 “http-request deny” 和 “use_backend” 关键字的详细说明。

7.3. 获取样本

历史上,样本提取方法仅用于通过 ACL 匹配模式来检索数据。随着粘性表(stick-tables)的引入,一类新的样本提取方法被创建,通常与对应的 ACL 语法保持一致。这些样本提取方法也被称为“提取操作”。截至目前,ACL 与提取操作已实现统一。所有 ACL 提取方法均已作为提取方法提供,ACL 也可使用任意样本提取方法。

本节详细说明所有可用的样本提取方法及其输出类型。部分样本提取方法拥有已弃用的别名,用于保持与现有配置的兼容性。这些别名已被明确标记为已弃用,新配置中不应使用。

当可用时,也会标明 ACL 衍生项及其对应的匹配方法。这些项均具有明确的默认模式匹配方法,因此无需(尽管允许)传递 “-m” 选项来指定样本如何通过 ACL 进行匹配。

如上文样本类型与匹配兼容性矩阵所示,在 ACL 中使用通用样本提取方法时,除非样本类型为 boolean、integer、IPv4 或 IPv6,否则必须指定 “-m” 选项。当同一关键字同时作为 ACL 关键字和标准样本提取方法存在时,ACL 引擎默认将自动选择仅适用于 ACL 的版本。

部分关键字支持一个或多个必选参数,以及一个或多个可选参数。这些参数具有严格的类型,并在配置解析时进行检查,以确保不会因错误参数(例如未解析的后端名称)而运行。获取函数的参数用圆括号括起,并以逗号分隔。当某个参数为可选时,将在其下方用方括号(’[’ 和 ‘]’)标明。当所有参数均为可选时,圆括号可省略。

因此,标准样本提取方法的语法如下之一:

  • name
  • name(arg1)
  • name(arg1, arg2)

7.3.1. 转换器

样本提取方法可与转换器结合使用,以在提取的样本上应用转换(也称为“转换器”)。这些组合构成了所谓的“样本表达式”,其结果为一个“样本”。最初,这一功能仅由“stick on”和“stick store-request”指令支持,现已扩展至所有可使用样本的场景(ACL、日志格式、唯一 ID 格式、添加头、…)。

这些转换以一系列特定关键字的形式列出,紧跟在样本提取方法之后。 这些关键字也可以直接附加在 fetch 关键字的参数之后,以逗号分隔。 这些关键字还可能支持某些参数(例如,网络掩码),参数必须用括号括起传递。

某些类型的转换器为位运算和算术运算符,支持对整数执行基本操作。支持部分位运算(and、or、xor、cpl),以及部分算术运算(add、sub、mul、div、mod、neg)。还提供了一些比较器(odd、even、not、bool),可实现无需编写 ACL 即报告匹配结果。

以下关键字受支持:

   keyword                                         input type   output type
------------------------------------------------+-------------+----------------
51d.single(prop[,prop*])                           string       string
add(value)                                         integer      integer
add_item(delim[,var[,suff]])                       string       string
aes_cbc_dec(bits,nonce,key[,<aad>])                binary       binary
aes_cbc_enc(bits,nonce,key[,<aad>])                binary       binary
aes_gcm_dec(bits,nonce,key,aead_tag[,aad])         binary       binary
aes_gcm_enc(bits,nonce,key,aead_tag[,aad])         binary       binary
and(value)                                         integer      integer
b64dec                                             string       binary
base2                                              binary       string
base64                                             binary       string
be2dec(separator,chunk_size[,truncate])            binary       string
le2dec(separator,chunk_size[,truncate])            binary       string
be2hex([separator[,chunk_size[,truncate]]])        binary       string
bool                                               integer      boolean
bytes(offset[,length])                             binary       binary
capture-req(id)                                    string       string
capture-res(id)                                    string       string
concat([start[,var[,end]]])                        string       string
cpl                                                integer      integer
crc32([avalanche])                                 binary       integer
crc32c([avalanche])                                binary       integer
cut_crlf                                           string       string
da-csv-conv(prop[,prop*])                          string       string
date                                               string       integer
debug([prefix][,destination])                       any          same
-- keyword -------------------------------------+- input type + output type -
digest(algorithm)                                  binary       binary
div(value)                                         integer      integer
djb2([avalanche])                                  binary       integer
eth.data                                           binary       binary
eth.dst                                            binary       binary
eth.hdr                                            binary       binary
eth.proto                                          binary       integer
eth.src                                            binary       binary
eth.vlan                                           binary       integer
even                                               integer      boolean
fe_exists                                          string       boolean
field(index,delimiters[,count])                    string       string
fix_is_valid                                       binary       boolean
fix_tag_value(tag)                                 binary       binary
has_ctl([mask])                                    binary       boolean
hex                                                binary       string
hex2i                                              binary       integer
hmac(algorithm,key)                                binary       binary
host_only                                          string       string
htonl                                              integer      integer
http_date([offset[,unit]])                         integer      string
iif(true,false)                                    boolean      string
in_table([table])                                  any          boolean
ip.data                                            binary       binary
ip.df                                              binary       integer
ip.dst                                             binary       address
ip.fp                                              binary       binary
ip.hdr                                             binary       binary
ip.proto                                           binary       integer
ip.src                                             binary       address
ip.tos                                             binary       integer
ip.ttl                                             binary       integer
ip.ver                                             binary       integer
ipmask(mask4[,mask6])                              address      address
json([input-code])                                 string       string
json_query(json_path[,output_type])                string       _outtype_
jwt_decrypt_jwk(<jwk>)                             string       binary
jwt_decrypt_cert(<cert>)                           string       binary
jwt_decrypt_secret(<secret>)                       string       binary
jwt_header_query([json_path[,output_type]])        string       string
jwt_payload_query([json_path[,output_type]])       string       string
-- keyword -------------------------------------+- input type + output type -
jwt_verify(alg,key)                                string       integer
jwt_verify_cert(alg,cert)                          string       integer
language(value[,default])                          string       string
length                                             string       integer
lower                                              string       string
ltime(format[,offset])                             integer      string
ltrim(chars)                                       string       string
map(map_name[,default_value])                      string       string
map_match(map_name[,default_value])                _match_      string
map_match_output(map_name[,default_value])         _match_      _output_
mod(value)                                         integer      integer
mqtt_field_value(pkt_type,fieldname_or_prop_ID)    binary       binary
mqtt_is_valid                                      binary       boolean
ms_ltime(format[,offset])                          integer      string
ms_utime(format[,offset])                          integer      string
mul(value)                                         integer      integer
nbsrv                                              string       integer
neg                                                integer      integer
not                                                integer      boolean
odd                                                integer      boolean
or(value)                                          integer      integer
-- keyword -------------------------------------+- input type + output type -
param(name[,delim])                                string       string
port_only                                          string       integer
protobuf(field_number[,field_type])                binary       binary
regsub(regex,subst[,flags])                        string       string
reverse                                            string       string
reverse_dom                                        string       string
rfc7239_field(field)                               string       string
rfc7239_is_valid                                   string       boolean
rfc7239_n2nn                                       string       address / str
rfc7239_n2np                                       string       integer / str
rfc7239_nn                                         address/str  string
rfc7239_np                                         integer/str  string
rtrim(chars)                                       string       string
sdbm([avalanche])                                  binary       integer
secure_memcmp(var)                                 string       boolean
set-var(var[,cond...])                              any          same
sha1                                               binary       binary
sha2([bits])                                       binary       binary
srv_is_up                                          string       boolean
srv_queue                                          string       integer
strcmp(var)                                        string       boolean
sub(value)                                         integer      integer
table_bytes_in_rate([table])                       any          integer
table_bytes_out_rate([table])                      any          integer
table_clr_gpc(idx[,table])                         any          integer
table_clr_gpc0([table])                            any          integer
table_clr_gpc1([table])                            any          integer
table_conn_cnt([table])                            any          integer
-- keyword -------------------------------------+- input type + output type -
table_conn_cur([table])                            any          integer
table_conn_rate([table])                           any          integer
table_expire([table[,default_value]])              any          integer
table_glitch_cnt([table])                          any          integer
table_glitch_rate([table])                         any          integer
table_gpc(idx[,table])                             any          integer
table_gpc0([table])                                any          integer
table_gpc0_rate([table])                           any          integer
table_gpc1([table])                                any          integer
table_gpc1_rate([table])                           any          integer
table_gpc_rate(idx[,table])                        any          integer
table_gpt(idx[,table])                             any          integer
table_gpt0([table])                                any          integer
table_http_err_cnt([table])                        any          integer
table_http_err_rate([table])                       any          integer
table_http_fail_cnt([table])                       any          integer
table_http_fail_rate([table])                      any          integer
table_http_req_cnt([table])                        any          integer
table_http_req_rate([table])                       any          integer
table_idle([table[,default_value]])                any          integer
table_inc_gpc(idx[,table])                         any          integer
table_inc_gpc0([table])                            any          integer
table_inc_gpc1([table])                            any          integer
table_kbytes_in([table])                           any          integer
-- keyword -------------------------------------+- input type + output type -
table_kbytes_out([table])                          any          integer
table_server_id([table])                           any          integer
table_sess_cnt([table])                            any          integer
table_sess_rate([table])                           any          integer
table_trackers([table])                            any          integer
tcp.dst                                            binary       integer
tcp.flags                                          binary       integer
tcp.options.mss                                    binary       integer
tcp.options.sack                                   binary       integer
tcp.options.tsopt                                  binary       integer
tcp.options.tsval                                  binary       integer
tcp.options.wscale                                 binary       integer
tcp.options.wsopt                                  binary       integer
tcp.options_list                                   binary       binary
tcp.seq                                            binary       integer
tcp.src                                            binary       integer
tcp.win                                            binary       integer
ub64dec                                            string       string
ub64enc                                            string       string
ungrpc(field_number[,field_type])                  binary       binary / int
unset-var(var)                                      any          same
upper                                              string       string
url_dec([in_form])                                 string       string
url_enc([enc_type])                                string       string
us_ltime(format[,offset])                          integer      string
us_utime(format[,offset])                          integer      string
utime(format[,offset])                             integer      string
when(condition)                                     any          same
word(index,delimiters[,count])                     string       string
wt6([avalanche])                                   binary       integer
x509_v_err_str                                     integer      string
xor(value)                                         integer      integer
-- keyword -------------------------------------+- input type + output type -
xxh3([seed])                                       binary       integer
xxh32([seed])                                      binary       integer
xxh64([seed])                                      binary       integer

转换器关键字的详细列表如下:

51d.single(<prop>[,<prop>*])

51d.single(<prop>[,<prop>*])

以字符串形式返回所请求属性的值,各值之间使用“51degrees-property-separator”指定的分隔符分隔。设备通过传递给转换器的 User-Agent 头进行识别。该函数最多可传入五个属性名,若某属性名无法找到,则返回值为 “NoData”。

示例:

# Here the header "X-51D-DeviceTypeMobileTablet" is added to the request,
# containing values for the three properties requested by using the
# User-Agent passed to the converter.
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>)

add(<value>)

将 <value> 加到类型为有符号整数的输入值上,并以有符号整数形式返回结果。<value> 可以是数值或变量名。有关变量的详细信息,请参阅 第 2.8 节 。

add_item(<delim>[,<var>[,<suff>]])

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_cbc_dec(<bits>,<nonce>,<key>[,<aad>])

aes_cbc_dec(<bits>,<nonce>,<key>[,<aad>])

使用 AES128-CBC、AES192-CBC 或 AES256-CBC 算法解密原始字节输入,具体算法取决于 <bits> 参数。所有其他参数必须为 Base64 编码格式,返回结果为原始字节格式。<aad> 参数为可选。若 <aad> 验证失败,转换器不返回任何数据。<nonce>、<key> 和 <aad> 可为字符串或变量。该转换器要求至少使用 OpenSSL 1.0.1。

示例:

http-response set-header X-Decrypted-Text %[var(txn.enc),\
  aes_cbc_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==)]

aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])

aes_cbc_enc(<bits>,<nonce>,<key>[,<aad>])

使用 AES128-CBC、AES192-CBC 或 AES256-CBC 算法对原始字节输入进行加密,具体算法取决于 <bits> 参数。<nonce>、<key> 和 <aad> 参数必须为 Base64 编码。<aad> 参数为可选。返回结果为原始字节格式。<nonce>、<key> 和 <aad> 可为字符串或变量。此转换器要求至少使用 OpenSSL 1.0.1。

示例:

http-response set-header X-Encrypted-Text %[var(txn.plain),\
  aes_cbc_enc(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==)]

aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

aes_gcm_dec(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

使用 AES128-GCM、AES192-GCM 或 AES256-GCM 算法解密原始字节输入,具体算法由 <bits> 参数决定。所有其他参数必须以 Base64 编码,返回结果为原始字节格式。若 <aead_tag> 或 <aad> 验证失败,转换器将不返回任何数据。<aad> 参数为可选。<nonce>、<key>、<aead_tag> 和 <aad> 可为字符串或变量。该转换器要求至少使用 OpenSSL 1.0.1。

示例:

http-response set-header X-Decrypted-Text %[var(txn.enc),\
  aes_gcm_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]

aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

aes_gcm_enc(<bits>,<nonce>,<key>,<aead_tag>[,<aad>])

使用 AES128-GCM、AES192-GCM 或 AES256-GCM 算法对原始字节输入进行加密,具体取决于 <bits> 参数。<nonce>、<key> 和 <aad> 参数必须为 Base64 编码。参数 <aead_tag> 必须为变量。AEAD 标签将以 Base64 编码形式存储于该变量中。<aad> 参数为可选。返回结果为原始字节格式。<nonce>、<key> 和 <aad> 可为字符串或变量。此转换器要求至少使用 OpenSSL 1.0.1。

示例:

http-response set-header X-Encrypted-Text %[var(txn.plain),\
  aes_gcm_enc(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]

and(<value>)

and(<value>)

对 <value> 与输入的有符号整数类型值执行按位“与”运算,并将结果以有符号整数形式返回。<value> 可以是数值或变量名。有关变量的详细信息,请参阅 第 2.8 节 。

b64dec

b64dec

将 base64 编码的输入字符串转换(解码)为其二进制表示。该操作与 base64() 执行相反。对于 base64url(“URL 和文件名安全字母表” (RFC 4648)) 变体,请参见 “ub64dec”。

base2

base2

将二进制输入样本转换为二进制字符串,每个输入字节对应八个二进制数字。该功能用于在原生表示形式不支持前缀匹配的类型上执行最长前缀匹配,例如 IP 前缀。

base64

base64

将二进制输入样本转换为 base64 字符串。该功能用于以可可靠传输的方式记录或传输二进制内容(例如,SSL ID 可以复制到头中)。有关 base64url(“URL 和文件名安全字母表”(RFC 4648))变体,请参见 “ub64enc”。

be2dec(<separator>,<chunk_size>[,<truncate>])

be2dec(<separator>,<chunk_size>[,<truncate>])

将大端字节序的二进制输入样本转换为字符串,每 <chunk_size> 个输入字节对应一个无符号整数。若指定,每 <chunk_size> 个二进制输入字节之间插入 <separator>。<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

le2dec(<separator>,<chunk_size>[,<truncate>])

le2dec(<separator>,<chunk_size>[,<truncate>])

将小端格式的二进制输入样本转换为字符串,每 <chunk_size> 个输入字节对应一个无符号整数。若指定,每 <chunk_size> 个二进制输入字节之间插入 <separator>。<truncate> 标志表示二进制输入是否在 <chunk_size> 边界处截断。<chunk_size> 的最大值受 long long int 大小限制(8 字节)。

示例:

bin(01020304050607),le2dec(:,2)   # 513:1284:2055:7
bin(01020304050607),le2dec(-,2,1) # 513-1284-2055
bin(01020304050607),le2dec(,2,1)  # 51312842055
bin(7f000001),le2dec(.,1)         # 127.0.0.1

be2hex([<separator>[,<chunk_size>[,<truncate>]]])

be2hex([<separator>[,<chunk_size>[,<truncate>]]])

将大端字节序的二进制输入样本转换为每输入字节对应两个十六进制数字的十六进制字符串。该功能用于以可可靠传输的方式记录或传输某些二进制输入数据的十六进制转储(例如,可将 SSL ID 复制到头中)。若指定,每 <chunk_size> 个二进制输入字节插入一次 <separator>。<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

bool

bool

如果输入值为有符号整数类型且非空,则返回布尔值 TRUE,否则返回 FALSE。与 and() 配合使用时,可用于对输入值进行位测试,报告真或假(例如,验证标志是否存在)。

bytes(<offset>[,<length>])

bytes(<offset>[,<length>])

从输入的二进制样本中提取部分字节。结果为一个二进制样本,起始于原始样本的指定偏移量(以字节为单位),并可选地在指定长度处截断。<offset> 和 <length> 可以是数值或变量名。若 <offset> 或 <length> 无效,则转换器返回空样本。无效的 <offset> 指负值或大于输入样本长度的值。无效的 <length> 指负值。

示例:

http-request set-var(txn.input) req.hdr(input) # let's say input is "012345"

http-response set-header bytes_0 "%[var(txn.input),bytes(0)]"  # outputs "012345"
http-response set-header bytes_1_3 "%[var(txn.input),bytes(1,3)]"  # outputs "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)]"  # outputs "123"

capture-req(<id>)

capture-req(<id>)

捕获请求槽 <id> 中的字符串条目,并原样返回该条目。若槽不存在,捕获将静默失败。

另请参阅:“declare capture”、“http-request capture”、“http-response capture”、“capture.req.hdr” 和 “capture.res.hdr”(样本提取)。

capture-res(<id>)

capture-res(<id>)

捕获响应槽 <id> 中的字符串条目,并原样返回该条目。若槽不存在,捕获操作将静默失败。

另请参阅:“declare capture”、“http-request capture”、“http-response capture”、“capture.req.hdr” 和 “capture.res.hdr”(样本提取)。

concat([<start>[,<var>[,<end>]]])

concat([<start>[,<var>[,<end>]]])

将当前样本之后最多 3 个字段拼接为字符串。第一个字段 <start> 为常量字符串,将在现有样本之后立即追加。若未使用,可省略。第二个字段 <var> 为变量名,将查找该变量,将其内容转换为字符串,并立即追加至 <first> 部分之后。若变量未找到,则不追加任何内容。该字段也可省略。第三个字段 <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])"  ## does the same
http-request set-header x-hap-sig %[var(txn.sig)]

cpl

cpl

对类型为有符号整数的输入值执行按位取反(翻转所有位)操作,并将结果以有符号整数形式返回。

crc32([<avalanche>])

crc32([<avalanche>])

使用 CRC32 哈希函数将二进制输入样本哈希为无符号 32 位整数。 可选地,若可选参数 <avalanche> 等于 1,则可对输出应用完整的雪崩哈希函数。 该转换器使用与各种基于哈希的负载均衡算法相同的函数,因此将提供完全相同的结果。 其设计目的是为了与其他希望对某些输入键计算 CRC32 的软件保持兼容,因此遵循以太网、Gzip、PNG 等中常见的实现方式。 相比其他算法,该方法速度较慢,但可能提供更优或至少更不可预测的分布效果。 不得用于安全目的,因为 32 位哈希极易被破解。 另请参见 “djb2”、“sdbm”、“wt6”、“crc32c” 以及 “hash-type” 指令。

crc32c([<avalanche>])

crc32c([<avalanche>])

使用 CRC32C 哈希函数将二进制输入样本哈希为无符号 32 位整数。 可选地,如果可选参数 <avalanche> 等于 1,则可对输出应用完整的雪崩哈希函数。 该转换器使用 RFC4960 附录 B [8] 中所述的相同函数。 此功能用于与其他希望对某些输入键计算 CRC32C 的软件保持兼容性。 该算法速度较慢,且不得用于安全目的,因为 32 位哈希极易被破解。 另请参阅 “djb2”、“sdbm”、“wt6”、“crc32” 以及 “hash-type” 指令。

cut_crlf

cut_crlf

在首个回车符(’\r’)或换行符(’\n’)处截断输入样本的字符串表示形式。仅更新字符串长度。

da-csv-conv(<prop>[,<prop>*])

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)]

date

date

此转换器用于从 HTTP 头中转换日期。它可以是 IMF 日期、ASCTIME 日期或 RFC850 日期。转换结果将输出为 UNIX 时间戳。

示例:

http-request return lf-string "%[str('Sun, 06 Nov 1994 08:49:37 GMT'),date]\n" content-type text/plain

debug([<prefix][,<destination>])

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>)

digest(<algorithm>)

将二进制输入样本转换为消息摘要。结果为二进制样本。<algorithm> 必须为 OpenSSL 消息摘要名称(例如 sha256)。

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

div(<value>)

div(<value>)

将类型为有符号整数的输入值除以 <value>,并将结果以有符号整数形式返回。若 <value> 为 null,则返回最大无符号整数(通常为 2^63-1)。<value> 可为数值或变量名。有关变量的详细信息,请参见 第 2.8 节 。

djb2([<avalanche>])

djb2([<avalanche>])

使用 DJB2 哈希函数将二进制输入样本哈希为无符号 32 位整数。 可选地,若可选参数 <avalanche> 等于 1,则可对输出应用完整的雪崩哈希函数。 该转换器使用与各种基于哈希的负载均衡算法相同的函数,因此将提供完全相同的结果。 其主要用途为调试,但也可用作粘性表条目以收集粗略统计信息。 不得用于安全目的,因为 32 位哈希极易被破解。 另请参见 “crc32”、“sdbm”、“wt6”、“crc32c” 以及 “hash-type” 指令。

eth.data

eth.data

此功能与表示二进制以太网帧的输入样本配合使用,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “2” 时返回。它跳过所有以太网头(包括可能的 VLAN)并返回从第 3 层协议(通常为 IPv4 或 IPv6)开始的二进制数据块。参见 “fc_saved_syn” 和 “tcp-ss”。

eth.dst

eth.dst

此功能与表示二进制以太网帧的样本配合使用,该样本由 “fc_saved_syn” 与设置为 “2” 的 “tcp-ss” 绑定选项共同返回。它返回对应于帧目标地址的以太网头的 6 字节内容,以二进制块形式输出。另请参见 “fc_saved_syn” 和 “tcp-ss”。

eth.hdr

eth.hdr

此功能与表示二进制以太网帧的输入样本配合使用,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “2” 时返回。它会裁剪以太网头之后的内容,但保留可能存在的 VLAN 信息,并将此头作为二进制数据块返回。参见 “fc_saved_syn” 和 “tcp-ss”。

eth.proto

eth.proto

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “2” 时返回。它将返回以太网头中在任何可选 VLAN 之后的协议号(也称为 EtherType),以整数值形式表示。通常情况下,该值应为 0x800(表示 IPv4)或 0x86DD(表示 IPv6)。另请参见 “fc_saved_syn” 和 “tcp-ss”。

eth.src

eth.src

此功能与表示二进制以太网帧的输入样本配合使用,该样本由 “fc_saved_syn” 返回,并配合设置 “tcp-ss” 绑定选项为 “2”。它返回对应于帧源地址的以太网头的 6 字节内容,以二进制块形式输出。另请参见 “fc_saved_syn” 和 “tcp-ss”。

eth.vlan

eth.vlan

此功能与表示二进制以太网帧的输入样本配合使用,该样本由 “fc_saved_syn” 与设置为 “2” 的 “tcp-ss” 绑定选项共同生成。它返回以太网头中找到的最后一个 VLAN ID,以整数值形式输出。参见 “fc_saved_syn” 和 “tcp-ss”。

even

even

如果输入值为有符号整数类型且为偶数,则返回布尔值 TRUE;否则返回 FALSE。其功能等价于 “not,and(1),bool”。

field(<index>,<delimiters>[,<count>])

field(<index>,<delimiters>[,<count>])

使用给定的分隔符切分输入字符串,并提取指定索引处的子串。正索引从开头计数,负索引从结尾计数。索引从 1 或 -1 开始;分隔符为格式化字符列表。可以指定要提取的字段数 <count>(默认值:1)。值 0 表示提取所有剩余字段。

示例:

str(f1_f2_f3__f5),field(4,_)    # <empty>
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

fe_exists

fe_exists

接收前端名称作为输入值,若当前配置中存在同名前端,则返回布尔值 TRUE,否则返回 FALSE。可在需要验证动态名称对应的前端是否存在时使用,例如映射查找或响应外部检查。

示例:

http-request deny unless { var(txn.fe_name),fe_exists }

fix_is_valid

fix_is_valid

解析二进制负载,并对 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_value(<tag>)

fix_tag_value(<tag>)

解析一个 FIX(Financial Information eXchange)消息,并从标签 <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 tag ID is 35, so both lines below will return the same content
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)

has_ctl([mask])

has_ctl([mask])

按照 mask 参数的定义,检查输入的二进制样本中是否包含控制字符。掩码是一个 33 位数字(可使用十进制,或以 0x 为前缀的十六进制):其中每一位分别对应 0x00 至 0x1F 范围内的一个字符,第 32 位用于匹配 DEL 字符(0x7F)。未指定掩码时,转换器使用 0x1FFFFFDFF,匹配除 TAB(0x09)以外的所有控制字符;TAB 常用于 HTTP 头。特殊掩码 any 等于 0x1FFFFFFFF,会匹配包括 TAB 在内的全部控制字符。特殊掩码 http 等于 0x2401,仅匹配 HTTP 头值中禁止出现的 CR(0x0D)、LF(0x0A)和 NUL(0x00)。

示例:

# reject presence of DEL, CR, LF, NUL characters in the referer header
http-request deny if { req.fhdr(referer),has_ctl(0x100002401) }
# reject presence of any control char but tab in any HTTP header value
http-request deny if { req.hdr(),has_ctl }

hex

hex

将二进制输入样本转换为十六进制字符串,每个输入字节对应两个十六进制数字。该功能用于以可可靠传输的方式记录或传输某些二进制输入数据的十六进制转储(例如,可将 SSL ID 复制到头中)。

hex2i

hex2i

将包含每输入字节两个十六进制数字的十六进制字符串转换为整数。如果输入值无法转换,则返回零。

hmac(<algorithm>,<key>)

hmac(<algorithm>,<key>)

使用指定密钥将二进制输入样本转换为消息认证码。结果为二进制样本。<algorithm> 必须为已注册的 OpenSSL 消息摘要名称之一(例如 sha256)。<key> 参数必须以 Base64 编码,可以为字符串或变量。

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

host_only

host_only

将包含 Host 头值的字符串转换为不带端口的形式。输入必须符合 Host 头值的格式(rfc9110#section-7.2)。该函数支持以下格式的输入:hostname、hostname:80、127.0.0.1、127.0.0.1:80、[::1]、[::1]:80。

此转换器还会将字符串转换为小写。

另请参见:“port_only” 转换器,该转换器将返回端口。

htonl

htonl

将输入的整数值转换为以网络字节序表示的 32 位二进制形式。 由于样本提取操作自身使用有符号 64 位整数,因此使用此转换器时,输入的整数值会首先被转换为无符号 32 位整数。

http_date([<offset[,<unit>]])

http_date([<offset[,<unit>]])

将一个表示自纪元以来日期的整数转换为适合在 HTTP 头字段中使用的字符串格式。若指定偏移值,则在转换前将其加到日期上。此功能特别适用于在响应中生成 Date 头字段、Expires 值(当偏移值为正时),或 Last-Modified 值(当偏移值为负时)。若指定单位值,则将时间戳视为“s”(秒,默认行为)、“ms”(毫秒)或“us”(微秒)自纪元以来的值。偏移值的单位与输入时间戳的单位一致。

iif(<true>,<false>)

iif(<true>,<false>)

输入值为真时返回 <true> 字符串,否则返回 <false> 字符串。

示例:

http-request set-header x-forwarded-proto %[ssl_fc,iif(https,http)]

in_table([<table>])

in_table([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。如果键在表中未找到,返回布尔值 false。否则返回布尔值 true。此功能可用于验证表中是否已存在某个特定键(例如,源 IP 地址或 Authorization 头是否已被记录)。

ip.data

ip.data

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。它跳过 IP 头以及任何可选选项或扩展,返回从传输协议(通常为 TCP 或 UDP)开始的二进制数据块。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.df

ip.df

此功能用于处理表示二进制以太网帧的输入样本,由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 输出所得。若 IP 头中的 DF(不分片)标志被设置,则返回整数值 1;否则返回 0。IPv6 无 DF 标志,且默认不分片,因此始终返回 1。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.dst

ip.dst

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。它从 IPv4/v6 头中返回目标地址。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.fp([<mode>])

ip.fp([<mode>])

此转换器用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设为 “1” 时返回,或由 “eth.data” 的输出提供。它检查 IP 头和 TCP 头的多个部分,以构建一种指纹,该指纹包含可用于区分多个看似相同的主机的不变部分。实际应用场景是,在共享 IP 地址的情况下,精确定位行为异常的主机,从而避免因仅一个主机异常而阻断所有合法用户。该转换器基于输入构建最小长度为 8 字节的二进制块。指纹字节的排列方式如下: - 字节 0:IP TOS 字段(参见 ip.tos) - 字节 1: - 位 7:IPv6(1)/ IPv4(0) - 位 6:ip.df - 位 5..4:0:ip.ttl ≤ 32;1:ip.ttl ≤ 64;2:ip.ttl ≤ 128;3:ip.ttl ≤ 255 - 位 3:IP 选项存在(1)/ 不存在(0) - 位 2:TCP 数据存在(1)/ 不存在(0) - 位 1:TCP.flags 中 CWR 位已设置(1)/ 已清除(0) - 位 0:TCP.flags 中 ECE 位已设置(1)/ 已清除(0) - 字节 2: - 位 7..4:TCP 头长度(以 4 字节为单位) - 位 3..0:TCP 窗口缩放值 + 1(1..15)/ 0(未通告 WS) - 字节 3..4:tcp.win - 字节 5..6:tcp.options.mss,若不存在则为零 - 字节 7:每种存在的 TCP 选项对应 1 位,其中选项 2 至 8 分别映射到位 0 至 6,位 7 表示选项 9 至 255 中是否存在任一选项

<mode> 参数允许向指纹中附加更多信息。默认情况下,当 <mode> 参数未设置或值为零时,指纹仅由上述 8 字节构成。若 <mode> 指定为其他值,则其对应以下各项的总和,相应组件将按以下顺序拼接到指纹中: - 1:接收的 TTL 值附加到指纹中(1 字节) - 2:由 “tcp.options_list” 返回的 TCP 选项类型列表,包含 0 至 40 字节的额外数据,附加到指纹中 - 4:源 IP 地址附加到指纹中,IPv4 增加 4 字节,IPv6 增加 16 字节

示例:使用基础指纹(FP)、TTL 和源地址生成长度为 13..25 字节的指纹(1+4=5):

frontend test
    mode http
    bind:4445 tcp-ss 1
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain lf-string &#92;
          "src=%[var(sess.syn),ip.src] fp=%[var(sess.syn),ip.fp(5),hex]&#92;n"

另请参见 “fc_saved_syn”、“tcp-ss”、“eth.data”、“ip.df”、“ip.ttl”、“tcp.win”、“tcp.options.mss” 及 “tcp.options_list”。

ip.hdr

ip.hdr

此功能用于处理表示二进制以太网帧的输入样本,由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。它返回一段二进制数据块,起始于 IP 头,终止于最后一个选项或扩展之后、传输层协议头之前。另请参见 “fc_saved_syn”、“tcp-ss” 以及 “eth.data”。

ip.proto

ip.proto

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。该功能返回传输层协议号,通常为 6(表示 TCP)或 17(表示 UDP)。另请参见 “fc_saved_syn”、“tcp-ss” 以及 “eth.data”。

ip.src

ip.src

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。它从 IPv4/v6 头中返回源地址。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.tos

ip.tos

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 输出所得。它返回一个整数,对应 IPv4 头中的服务类型(TOS)字段或 IPv6 头中的流量类别(TC)字段的值。请注意,在现代互联网中,该字段通常在高 6 位中包含 DSCP(区分服务代码点)值,而低 2 位可能未使用,或由 IP ECN 使用。请参阅 RFC2474 和 RFC8436 了解 DSCP 值,参阅 RFC3168 了解 IP ECN 字段。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.ttl

ip.ttl

此功能用于处理表示二进制以太网帧的样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。 该功能返回一个整数,对应 IPv4/IPv6 头中的 TTL(生存时间)或 HL(跳数限制)字段。该值通常预设为固定值,并在数据包经过每个路由器时递减。当已知初始值时,可借此推断客户端连接距离。请注意,大多数现代操作系统初始值均为 64。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ip.ver

ip.ver

此功能用于处理表示二进制以太网帧的输入样本,该样本由 “fc_saved_syn” 与 “tcp-ss” 绑定选项设置为 “1” 时返回,或由 “eth.data” 的输出提供。该功能返回 IP 头中的 IP 版本,通常为 4 或 6。请注意,此功能不会检查上层以太网帧中的协议号是否匹配,但由于预期使用的是有效数据包,因此操作系统应已验证该匹配关系。另请参见 “fc_saved_syn”、“tcp-ss” 和 “eth.data”。

ipmask(<mask4>[,<mask6>])

ipmask(<mask4>[,<mask6>])

对 IP 地址应用掩码,并使用结果进行查找和存储。此功能可用于使特定掩码范围内的所有主机共享相同的表项,从而使用同一台服务器。mask4 可以以点分十进制形式(例如 255.255.255.0)或 CIDR 形式(例如 24)传递。mask6 可以以四组形式(例如 ffff:ffff::)或 CIDR 形式(例如 64)传递。若未指定 mask6,出于向后兼容性考虑,IPv6 地址将无法转换。

json([<input-code>])

json([<input-code>])

转义输入字符串,并生成一个可直接用作 JSON 字符串的 ASCII 输出字符串。转换器会根据 <input-code> 参数尝试解码输入字符串。该参数可取值为 “ascii”、“utf8”、“utf8s”、“utf8p” 或 “utf8ps”。“ascii” 解码器始终不会失败。“utf8” 解码器可检测三种错误:

  • 无效的 UTF-8 序列(孤立的延续字节、延续字节数量错误等)
  • 无效的范围(解码后的值位于 UTF-8 禁止范围内)
  • 编码过长(该值使用的字节数多于必要数量)

UTF-8 JSON 编码在 UTF-8 字符大于 0xffff 时可能产生“值过长”错误,因为 JSON 字符串转义规范仅允许使用 4 位十六进制数字进行值编码。UTF-8 解码器存在 4 种变体,由两个后缀字母的组合指定:“p”表示“宽松模式”,“s”表示“静默忽略”。解码器的行为如下:

  • “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_path>[,<output_type>])

本文档中的 json_query 转换器支持 string、boolean、number 和 array 类型。浮点数将以字符串形式返回。通过指定 output_type 为 int,值将被转换为整数。数组将以字符串形式返回,以方括号开头和结尾,内容为 CSV 格式。根据数据类型,数组元素可能被引号包围。若数组元素为复杂类型,字符串中将包含每个元素的完整 JSON 表示形式,元素间以逗号分隔。JWT 的 roles 查询示例结果如下:

["manage-account","manage-account-links","view-profile"]

如果无法进行转换,json_query 转换器将失败。

<json_path> 必须是符合 https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/ 定义的有效 JSON 路径字符串

请注意:根据上下文和底层实现的不同,重复 JSON 键的提取行为未定义,可能返回输入内容中相同键的首个、末个或任意其他出现位置,且若键名以编码形式传入,可能无法始终匹配。简言之,该转换器不适用于内容净化。

示例:

# get a integer value from the request body
# "{"integer":4}" => 5
http-request set-var(txn.pay_int) req.body,json_query('$.integer','int'),add(1)

# get a key with '.' in the name
# {"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')

# get the value of the key 'iss' from a JWT Bearer token
http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec,json_query('$.iss')

jwt_decrypt_cert(<cert>)

jwt_decrypt_cert(<cert>)

按照 JSON Web 加密格式(参见 RFC 7516)对输入的 JSON Web Token 执行签名验证,并通过提供的证书解密返回其内容。<cert> 参数必须指向一个已加载的证书路径(可通过 “dump ssl cert” CLI 命令导出)。该证书必须显式将 “jwt” 选项设置为 “on”(参见 “jwt” crt-list 选项)。证书可直接提供,也可通过变量提供。目前仅支持使用紧凑序列化格式的令牌(由五个以点号分隔的 base64-url 编码字符串组成)。

此转换器可用于具有以下算法(JOSE 头中的 “alg” 字段)的令牌:RSA-OAEP、RSA-OAEP-256、ECDH-ES、ECDH-ES+A128KW、ECDH-ES+A192KW 或 ECDH-ES+A256KW。RSA1_5 算法已实现,但默认情况下已禁用,符合 RFC 8725 第 section 3.2 段的建议。如需启用,可借助 ‘jwt.decrypt_alg_list’ 全局选项重新激活。

支持的算法和加密算法(分别对应 JOSE 头中的 “alg” 和 “enc” 字段)可通过 ‘jwt.decrypt_alg_list’ 和 ‘jwt.decrypt_enc_list’ 全局选项进行修改。

JWE 令牌必须以 base64url 编码形式提供,输出将以“原始”形式返回。若在令牌解析、签名验证或内容解密过程中发生错误,将返回空字符串。

示例:

# Get a JWT from the authorization header, put its decrypted content in an
# HTTP header
http-request set-var(txn.bearer) http_auth_bearer
http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_cert("/foo/bar.pem")]

jwt_decrypt_jwk(<jwk>)

jwt_decrypt_jwk(<jwk>)

按照 JSON Web 加密格式(参见 RFC 7516)对输入的 JSON Web Token 执行签名验证,并通过提供的 JSON Web Key(RFC 7517)解密返回其内容。<jwk> 参数必须为类型为 ‘oct’、‘EC’ 或 ‘RSA’ 的有效 JWK(JSON 密钥中的 ‘kty’ 字段),可作为字符串提供,或通过变量传递。

目前仅支持管理使用紧凑序列化格式的令牌(由五个以点号分隔的 Base64-URL 编码字符串组成)。

此转换器可用于解码采用对称算法类型(JOSE 头中的 “alg” 字段)的令牌,支持的算法包括:A128KW、A192KW、A256KW、A128GCMKW、A192GCMKW、A256GCMKW 和 dir。在此情况下,预期提供的 JWK 类型为 ‘oct’。

该转换器在提供 ‘RSA’ JWK 时,会管理属于 RSA 系列(RSA-OAEP 或 RSA-OAEP-256)的算法(JOSE 头中的 “alg” 字段);在提供 ‘EC’ JWK 时,会管理属于 ECDH 系列(ECDH-ES、ECDH-ES+A128KW、ECDH-ES+A192KW 或 ECDH-ES+A256KW)的算法。RSA1_5 算法已实现,但默认处于禁用状态,符合 RFC 8725 第 3.2 节的建议。如需启用,可借助 ‘jwt.decrypt_alg_list’ 全局选项重新激活。

请注意,A128KW 和 A192KW 算法在 AWS-LC 上不可用,因此 A128KW、A192KW、ECDH-ES+A128KW 和 ECDH-ES+A192KW 算法将无法使用。

支持的算法和加密算法(分别对应 JOSE 头中的 “alg” 和 “enc” 字段)可通过 ‘jwt.decrypt_alg_list’ 和 ‘jwt.decrypt_enc_list’ 全局选项进行修改。

JWE 令牌必须以 base64url 编码形式提供,输出将以“原始”形式返回。若在令牌解析、签名验证或内容解密过程中发生错误,将返回空字符串。

由于配置中对引号、逗号和双引号的处理方式,JWK 的内容必须正确转义,才能使该转换器正常工作(详见 第 2.2 节 )。

示例:

 # Get a JWT from the authorization header, put its decrypted content in an
 # HTTP header
 http-request set-var(txn.bearer) http_auth_bearer
 http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_jwk(\'{\"kty\":\"oct\",\"k\":\"wAsgsg\"}\')

# or via a variable
 http-request set-var(txn.bearer) http_auth_bearer
 http-request set-var(txn.jwk) str(\'{\"kty\":\"oct\",\"k\":\"Q-NFLlghQ\"}\')
 http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_jwk(txn.jwk)

jwt_decrypt_secret(<secret>)

jwt_decrypt_secret(<secret>)

按照 JSON Web 加密格式(参见 RFC 7516)对输入的 JSON Web Token 执行签名验证,并通过提供的 base64 编码密钥解密其内容。密钥可作为字符串或通过变量提供。目前仅支持使用紧凑序列化格式的令牌(由五个以点号分隔的 base64-url 编码字符串组成)。

此转换器可用于具有以下算法(JOSE 头中的 “alg” 字段)的令牌:A128KW、A192KW、A256KW、A128GCMKW、A192GCMKW、A256GCMKW、dir。请注意,A128KW 和 A192KW 算法在 AWS-LC 上不可用,解密将无法正常工作。

JWE 令牌必须以 base64url 编码形式提供,输出将以“原始”形式返回。若在令牌解析、签名验证或内容解密过程中发生错误,将返回空字符串。

示例:

# Get a JWT from the authorization header, put its decrypted content in an
# HTTP header
http-request set-var(txn.bearer) http_auth_bearer
http-request set-header X-Decrypted %[var(txn.bearer),jwt_decrypt_secret("GawgguFyGrWKav7AX4VKUg")]

jwt_header_query([<json_path>[,<output_type>]])

jwt_header_query([<json_path>[,<output_type>]])

当输入包含 JSON Web Token (JWT) 时,若未提供参数,则返回该令牌解码后的头部(JWT 中第一个采用 base64-url 编码的部分);否则,对令牌解码后的头部执行 json_query 操作。有关 json_path 和 output_type 参数可接受值的详细信息,请参见 “json_query” 转换器。该转换器可用于 JWS 或 JWE 格式的令牌,只要它们采用紧凑序列化格式即可。

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

jwt_payload_query([<json_path>[,<output_type>]])

jwt_payload_query([<json_path>[,<output_type>]])

当输入为 JSON Web 签名(JWS)格式的 JSON Web 令牌(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) 执行签名验证。目前仅支持采用紧凑序列化格式(三个以点号分隔的 base64-url 编码字符串)的 JWS 令牌。该转换器仅验证令牌的签名,不执行 RFC7519 第 7.2 段所规定的完整 JWT 验证。例如,解码后的头和载荷内容是否为完全有效的 JSON,不作保证,且不对它们的内容进行任何检查。

  • <alg> 可以是字符串或变量名(参见“set-var”),其值为用于验证的算法名称。

    支持 RFC7518 第 3.1 节 中列出的算法:

   +--------------+---------------------------------------------------------+
   | "alg" Param  | Digital Signature or MAC Algorithm                      |
   | Value        |                                                         |
   +--------------+---------------------------------------------------------+
   | HS256        | HMAC using SHA-256                                      |
   | HS384        | HMAC using SHA-384                                      |
   | HS512        | HMAC using SHA-512                                      |
   | RS256        | RSASSA-PKCS1-v1_5 using SHA-256                         |
   | RS384        | RSASSA-PKCS1-v1_5 using SHA-384                         |
   | RS512        | RSASSA-PKCS1-v1_5 using SHA-512                         |
   | ES256        | ECDSA using P-256 and SHA-256                           |
   | ES384        | ECDSA using P-384 and SHA-384                           |
   | ES512        | ECDSA using P-521 and SHA-512                           |
   | PS256        | RSASSA-PSS using SHA-256 and MGF1 with SHA-256          |
   | PS384        | RSASSA-PSS using SHA-384 and MGF1 with SHA-384          |
   | PS512        | RSASSA-PSS using SHA-512 and MGF1 with SHA-512          |
   | none         | No digital signature or MAC performed                   |
   +--------------+---------------------------------------------------------+
  • <key> 可以是字符串或变量名(参见“set-var”),用于存储密钥或公钥路径。

仅在使用 HMAC 算法时,密钥才适用。

公钥必须采用 PKCS#1 格式(RSA 密钥,以 BEGIN RSA PUBLIC KEY 开头)或 SPKI 格式(主题公钥信息,以 BEGIN PUBLIC KEY 开头)。公钥必须在配置解析期间可用,且无法在运行时更新或加载。参见 “jwt_verify_cert” 转换器,用于基于完整 PEM 证书的 JWT 令牌验证。

所有可能用于验证 JWT 的公钥必须在初始化阶段已知,以便添加至专用缓存中,从而在运行时无需访问磁盘。

验证成功时返回 1,验证失败时返回 0,其他任何错误返回严格负值。由于所有非零错误返回值的存在,此转换器的返回结果不应转换为布尔值。有关可能返回值的完整列表,请参见下文。

可能的返回值如下:

  +----+----------------------------------------------------------------------+
  | ID | message                                                              |
  +----+----------------------------------------------------------------------+
  |  1 | "Verification success"                                               |
  |  0 | "Verification failure"                                               |
  | -1 | "Unknown algorithm (not mentioned in RFC7518)"                       |
  | -2 | "Unmanaged algorithm"                                                |
  | -3 | "Invalid token"                                                      |
  | -4 | "Out of memory"                                                      |
  | -5 | "Unknown pubkey/certificate"                                         |
  | -6 | "Internal error"                                                     |
  +----+----------------------------------------------------------------------+

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

示例:

# Get a JWT from the authorization header, extract the "alg" field of its
# JOSE header and use a public key to verify a signature
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/pubkey.pem") 1 }

jwt_verify_cert(<alg>,<cert>)

使用 <alg> 算法和 <cert> 参数,对输入的 JSON Web Token (JWT) 执行签名验证。目前仅支持采用紧凑序列化格式的 JWS 令牌(由三个以英文句点分隔的 base64-url 编码字符串组成)的处理。该转换器仅验证令牌的签名,不执行 RFC7519 第 7.2 段所规定的完整 JWT 验证。我们不保证解码后的头和载荷内容为完全有效的 JSON,且不对它们的具体内容进行任何检查。

  • <alg> 可以是字符串或变量名(参见“set-var”),其值为用于验证的算法名称。与 “jwt_verify” 转换器不同,该转换器仅期望第二个参数为证书,因此不应用于使用 HMAC 算法的令牌。

    支持 RFC7518 第 3.1 节 中列出的算法(HMAC 算法除外):

   +--------------+---------------------------------------------------------+
   | "alg" Param  | Digital Signature or MAC Algorithm                      |
   | Value        |                                                         |
   +--------------+---------------------------------------------------------+
   | RS256        | RSASSA-PKCS1-v1_5 using SHA-256                         |
   | RS384        | RSASSA-PKCS1-v1_5 using SHA-384                         |
   | RS512        | RSASSA-PKCS1-v1_5 using SHA-512                         |
   | ES256        | ECDSA using P-256 and SHA-256                           |
   | ES384        | ECDSA using P-384 and SHA-384                           |
   | ES512        | ECDSA using P-521 and SHA-512                           |
   | PS256        | RSASSA-PSS using SHA-256 and MGF1 with SHA-256          |
   | PS384        | RSASSA-PSS using SHA-384 and MGF1 with SHA-384          |
   | PS512        | RSASSA-PSS using SHA-512 and MGF1 with SHA-512          |
   | none         | No digital signature or MAC performed                   |
   +--------------+---------------------------------------------------------+
  • <key> 可以是字符串或变量名(参见“set-var”),其值为证书路径。

证书必须为标准的 PEM 格式证书(以 BEGIN CERTIFICATE 开头)。证书路径可直接传递给转换器,或通过变量引用。若使用变量,对应的证书可声明在 crt-store 中,或通过 stats socket 动态加载。若直接指定路径,且对应的证书尚未加载至内部证书存储,则将在配置解析期间加载该证书,因此证书文件必须已存在,否则将引发错误。

仅可使用显式定义为可用于 JWT 验证的证书。参见“jwt” crt-store 选项。

可以动态更新证书,并通过统计信息套接字添加新证书。 参见管理指南中的“set ssl cert”和“new ssl cert”。

验证成功时返回 1,验证失败时返回 0,其他任何错误返回严格负值。由于所有非零错误返回值的存在,此转换器的返回结果不应转换为布尔值。有关可能返回值的完整列表,请参见下文。

可能的返回值如下:

  +----+----------------------------------------------------------------------+
  | ID | message                                                              |
  +----+----------------------------------------------------------------------+
  |  1 | "Verification success"                                               |
  |  0 | "Verification failure"                                               |
  | -1 | "Unknown algorithm (not mentioned in RFC7518)"                       |
  | -2 | "Unmanaged algorithm"                                                |
  | -3 | "Invalid token"                                                      |
  | -4 | "Out of memory"                                                      |
  | -5 | "Unknown pubkey/certificate"                                         |
  | -6 | "Internal error"                                                     |
  | -7 | "Unavailable certificate" (see "jwt")                                |
  +----+----------------------------------------------------------------------+

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

示例:

# Get a JWT from the authorization header, extract the "alg" field of its
# JOSE header and use a public certificate to verify a signature
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_cert(txn.jwt_alg,"/path/to/cert.pem") 1 }

language(<value>[,<default>])

language(<value>[,<default>])

从 “accept-language” 头中提取的列表中,返回 q-factor 最高的值,使用 “req.fhdr” 进行解析。未指定 q-factor 的值,其 q-factor 默认为 1。q-factor 为 0 的值将被丢弃。仅考虑属于分号分隔的 <values> 列表中的值。参数 <value> 的语法为 “lang[;lang[;lang[;…]]]"。若无值匹配给定列表且提供了默认值,则返回默认值。请注意,语言名称后可跟连字符(’-’)分隔的变体。若变体存在于列表中,则进行匹配;若不存在,则仅检查基础语言。匹配区分大小写,输出字符串始终为参数中提供的值之一。参数顺序无关紧要,仅请求中值的顺序有效,当多个值具有相同 q-factor 时,优先使用其中第一个值。

示例:

# this configuration switches to the backend matching a
# given language based on the request:

acl es req.fhdr(accept-language),language(es;fr;en) -m str es
acl fr req.fhdr(accept-language),language(es;fr;en) -m str fr
acl en req.fhdr(accept-language),language(es;fr;en) -m str en
use_backend spanish if es
use_backend french  if fr
use_backend english if en
default_backend choose_your_language

length

length

获取字符串的长度。此指令只能置于字符串样本提取函数之后,或置于返回字符串类型的转换关键字之后。结果类型为整数。

lower

lower

将字符串样本转换为小写。此操作只能置于字符串样本提取函数之后,或置于返回字符串类型的转换关键字之后。结果类型为字符串。

ltime(<format>[,<offset>])

ltime(<format>[,<offset>])

将一个表示自纪元以来日期的整数转换为以本地时间表示的字符串,使用由 <format> 字符串定义的格式,该格式遵循 strftime(3) 的规范。此功能旨在允许在日志中使用任意日期格式。可选地,可在输入日期上应用一个以秒为单位的 <offset> 值(正或负)。有关操作系统支持的格式,请参阅 strftime() 手册页。另请参见 utime 转换器。

示例:

# Emit two colons, one with the local time and another with ip:port
# e.g.  20140710162350 127.0.0.1:57325
log-format %[date,ltime(%Y%m%d%H%M%S)]\ %ci:%cp

ltrim(<chars>)

ltrim(<chars>)

跳过输入样本的字符串表示形式开头的 <chars> 中的任意字符

map(<map_name>[,<default_value>])

map(<map_name>[,<default_value>])
map_<match_type>(<map_name>[,<default_value>])
map_<match_type>_<output_type>(<map_name>[,<default_value>])

使用 <match_type> 匹配方法在 <map_name> 中搜索输入值,并将关联值转换为 <output_type> 类型返回。若输入值在 <map_name> 中未找到,转换器返回 <default_value>。若 <default_value> 未设置,转换器将失败,并表现为无法获取输入值。若 <match_type> 未设置,其默认值为 “str”。同理,若 <output_type> 未设置,其默认值也为 “str”。为方便起见,“map” 关键字是 “map_str” 的别名,用于将字符串映射到另一字符串。<map_name> 必须遵循 2.7 节中关于映射和 ACL 名称格式的描述。

避免键之间发生重叠非常重要:IP 地址和字符串存储在树结构中,因此将采用匹配程度最细的首个结果。其他键存储在列表中,因此将采用首个匹配项。

以下数组按输入类型、匹配类型和输出类型排序,列出了所有可用映射函数的列表。

  input type | match method | output type str | output type int | output type ip | output type key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | str          | map_str         | map_str_int     | map_str_ip     | map_str_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | beg          | map_beg         | map_beg_int     | map_end_ip     | map_end_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | sub          | map_sub         | map_sub_int     | map_sub_ip     | map_sub_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | dir          | map_dir         | map_dir_int     | map_dir_ip     | map_dir_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | dom          | map_dom         | map_dom_int     | map_dom_ip     | map_dom_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | end          | map_end         | map_end_int     | map_end_ip     | map_end_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | reg          | map_reg         | map_reg_int     | map_reg_ip     | map_reg_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    str      | reg          | map_regm        | map_reg_int     | map_reg_ip     | map_reg_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    int      | int          | map_int         | map_int_int     | map_int_ip     | map_int_key
  -----------+--------------+-----------------+-----------------+----------------+----------------
    ip       | ip           | map_ip          | map_ip_int      | map_ip_ip      | map_ip_key
  -----------+--------------+-----------------+-----------------+----------------+----------------

名为 “map_regm” 的特殊映射会期望在正则表达式中匹配区域,并修改输出,将反向引用(如 “\1”)替换为对应的匹配文本。

输出类型 “key” 表示将返回匹配条目的键(即映射文件中找到的键),而非值。请注意,当使用 “key” 输出类型时,不支持可选的 <default_value> 参数。

<map_name> 中的文件每行包含一个键值对。以 ‘#’ 开头的行会被忽略,与空行处理方式相同。行首的制表符和空格将被去除。键为第一个“词”(非空格或制表符字符的连续序列),值为该词之后至行尾(不包括末尾的空格或制表符)的部分。

示例:

     # this is a comment and is ignored
        2.22.246.0/23    United Kingdom      \n
     <-><-----------><--><------------><---->
      |       |       |         |        `- trailing spaces ignored
      |       |       |         `---------- value
      |       |       `-------------------- middle spaces ignored
      |       `---------------------------- key
      `------------------------------------ leading spaces ignored

mod(<value>)

mod(<value>)

将类型为有符号整数的输入值除以 <value>,并以有符号整数形式返回余数。若 <value> 为 null,则返回零。<value> 可以是数值或变量名。有关变量的详细信息,请参见 第 2.8 节 。

mqtt_field_value(<packettype>,<fieldname_or_property_ID>)

mqtt_field_value(<packettype>,<fieldname_or_property_ID>)

返回在输入 MQTT 负载中找到的 <fieldname> 值,该负载类型为 <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,或任意属性 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 或任意属性 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 是客户端发送的第一个消息,CONNAK 是服务器发送的第一个响应。

示例:

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
# do the same as above
tcp-request content set-var(txn.username) \
        req.payload(0,0),mqtt_field_value(1,protocol_name) \
        if data_in_buffer

mqtt_is_valid

mqtt_is_valid

检查二进制输入是否为有效的 MQTT 数据包。返回布尔值。

由于当前 HAProxy 的设计限制,仅能解析客户端和服务器发送的首个消息。因此,该转换器仅可从 CONNECT 和 CONNACK 报文类型中提取数据。CONNECT 是客户端发送的第一个消息,CONNAK 是服务器发送的第一个响应。

仅支持 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>])

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” 转换器。

示例:

# Emit 3 colons, the local time, the timezone and another with ip:port
# e.g. 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>])

ms_utime(<format>[,<offset>])

这与 “utime” 类似,但输入单位为毫秒。它还支持受 date(1) 启发的 %N 转换说明符。将一个表示自纪元以来日期的整数转换为字符串,该字符串以 UTC 时间表示该日期,格式由 <format> 字符串定义,使用 strftime(3)。此功能旨在允许在日志中使用任意日期格式。可选地,可在输入日期上应用一个以毫秒为单位的 <offset> 值(正或负)。有关操作系统支持的格式,请参阅 strftime() 手册页。

%N 转换说明符可用于输出日期的纳秒部分,由于输入精度为毫秒级,因此其精度受限(取值范围为 000000000..999000000)。%N 可接受位于 % 与 N 之间的宽度参数。该参数可用于显示毫秒(%3N)或微秒(%6N)。默认及最大宽度为 9(%N 等价于 %9N)。

另请参阅 ltime 转换器,用于本地时间以及 “utime” 和 “us_utime” 转换器。

示例:

# Emit 3 colons, the UTC time, the timezone and another with ip:port
# e.g. 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>)

mul(<value>)

将类型为有符号整数的输入值乘以 <value>,并将结果以有符号整数形式返回。若发生溢出,将返回该符号所能表示的最大值,以避免操作结果发生环绕。<value> 可以是数值或变量名。有关变量的详细信息,请参见 第 2.8 节 。

nbsrv

nbsrv

接收类型为字符串的输入值,将其解释为后端名称,并返回该后端中可用服务器的数量。可在需要从动态名称查找后端的场景中使用,例如映射查找的结果。

neg

neg

取类型为有符号整数的输入值,计算其相反数,并返回余数作为有符号整数。0 为恒等值。该运算符用于反向减法:若需从常量中减去输入值,只需执行“neg,add(value)”操作。

not

not

如果输入值为非空的有符号整数类型,则返回布尔值 FALSE;否则返回 TRUE。与 and() 配合使用时,可用于对输入值进行位测试,报告真或假(例如,验证标志位的缺失)。

odd

odd

如果输入值为有符号整数类型且为奇数,则返回布尔值 TRUE;否则返回 FALSE。其功能等价于 “and(1),bool”。

or(<value>)

or(<value>)

对 <value> 与输入的有符号整数类型值执行按位“或”运算,并将结果以有符号整数形式返回。<value> 可以是数值或变量名。有关变量的详细信息,请参见 第 2.8 节 。

param(<name>[,<delim>])

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()

port_only

port_only

将包含 Host 头值的字符串转换为整数,通过返回其端口号实现。输入必须符合 Host 头值的格式(rfc9110#section-7.2)。支持的输入格式包括:主机名、主机名:80、127.0.0.1、127.0.0.1:80、[::1]、[::1]:80。

如果输入中未提供端口,则返回 0。

参见:“host_only” 转换器,该转换器将返回主机。

protobuf(<field_number>[,<field_type>])

protobuf(<field_number>[,<field_type>])

此操作以原始模式提取协议缓冲区消息字段,针对协议缓冲区消息的二进制样本表示,使用 <field_number> 作为字段编号(点号表示法)。若 <field_type> 不存在,则提取为整数样本;若该字段存在,则提取为整数样本(参见下方 “ungrpc”)。允许的类型列表如下:对于“varint”线缆类型 0,支持 “int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”;对于 64 位线缆类型 1,支持 “fixed64”、“sfixed64”、“double”;对于线缆类型 5,支持 “fixed32”、“sfixed32”、“float”。请注意,“string” 被视为长度限定类型,因此提取时无需任何 <field_type> 参数。关于协议缓冲区消息字段类型的更多信息,请参见 https://developers.google.com/protocol-buffers/docs/encoding 。

regsub(<regex>,<subst>[,<flags>])

regsub(<regex>,<subst>[,<flags>])

对输入字符串应用基于正则表达式的替换操作。其功能与广为人知的“sed”工具执行“s/<regex>/<subst>/”操作相同。默认情况下,它将在输入字符串中将与正则表达式 <regex> 匹配的最大部分的首个出现位置,替换为替换字符串 <subst>。可通过在第三个参数 <flags> 中添加标志“g”来替换所有匹配项。也可通过在 <flags> 中添加标志“i”使正则表达式不区分大小写。由于 <flags> 是一个字符串,因此由所有所需标志连接而成。因此,若同时需要“i”和“g”标志,使用“gi”或“ig”效果相同。此转换器的首次用途是将某些字符或字符序列替换为其他字符。

强烈建议使用保护引号包裹正则表达式部分,以提高清晰度,并避免正则表达式中的右括号与函数中的括号混淆。与 Bourne shell 类似,第一层引号用于在行上界定词组,第二层引号可用于参数。建议在外层使用单引号,因为单引号不会尝试解析反斜杠或美元符号。

示例:

# de-duplicate "/" in header "x-path".
# input:  x-path: /////a///b/c/xzxyz/
# output: x-path: /a/b/c/xzxyz/
http-request set-header x-path "%[hdr(x-path),regsub('/+','/','g')]"

# copy query string to x-query and drop all leading '?', ';' and '&'
http-request set-header x-query "%[query,regsub([?;&]*,'')]"

# capture groups and backreferences
# both lines do the same.
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)]

reverse

reverse

按字节反转输入字符串。

该转换器与编码无关,且反转的是字节而非字符;它不适用于反转以 UTF-8 编码的文本。

这可将原始字符串的后缀查找转换为反转字符串的前缀查找,从而可在大型映射上使用索引前缀匹配器,例如 “map_beg”。

示例:

"example.com" -> "moc.elpmaxe"
"ab cd" -> "dc ba"

# Given a map file where each key contains a reversed hostname:
#   moc.elpmaxe.ppa app1
#   moc.elpmaxe.bd  dbcluster
# Pick a backend based on the domain suffix of the Host header:
use_backend %[req.hdr(host),lower,reverse,map_beg(/etc/haproxy/hosts.map,default)]

reverse_dom

reverse_dom

将包含类似 FQDN 主机名的字符串转换为其反向标签形式。输入中的单个尾随句点会被忽略。空标签会导致转换器失败。

此转换器不会将其输入转换为小写,也不会去除任何端口。在需要时,应将其与现有的转换器(如 “lower” 或 “host_only”)结合使用。

尾随句点的处理策略有意交由调用方决定。这使得调用方能够自行决定是否匹配域名根(apex)或仅匹配子域名。

反向标签形式在大型域名映射中非常有用,因为它将域名后缀查找转换为前缀查找,从而可使用索引前缀匹配器(如 “map_beg”)。

示例:

"example.com" -> "com.example"
"mail.example.com" -> "com.example.mail"
"example.com." -> "com.example"

# match only subdomains of example.net, not the apex
acl example_net_sub req.hdr(Host),host_only,reverse_dom -m beg net.example.

# match only the apex
acl example_net_apex req.hdr(Host),host_only,reverse_dom -i net.example

# exact-or-subdomain prefix lookup using an explicit dotted form
http-request set-var(txn.rev_host) req.hdr(Host),host_only,reverse_dom,concat(.)
use_backend %[var(txn.rev_host),map_beg(/etc/haproxy/domains.map)]

rfc7239_field(<field>)

rfc7239_field(<field>)

从符合 RFC 7239 规范的头值输入中提取单个字段/参数。

支持的字段包括: - proto:取值为 ‘http’ 或 ‘https’ - host:符合 HTTP 规范的 host - for:RFC7239 中定义的 node - by:RFC7239 中定义的 node

更多信息请见此处:

https://www.rfc-editor.org/rfc/rfc7239.html#section-6

示例:

# extract host field from forwarded header and store it in req.fhost var
http-request set-var(req.fhost) req.hdr(forwarded),rfc7239_field(host)
#input: "proto=https;host=\"haproxy.org:80\""
#  output: "haproxy.org:80"

# extract for field from forwarded header and store it in req.ffor var
http-request set-var(req.ffor) req.hdr(forwarded),rfc7239_field(for)
#input: "proto=https;host=\"haproxy.org:80\";for=\"127.0.0.1:9999\""
#  output: "127.0.0.1:9999"

rfc7239_is_valid

rfc7239_is_valid

如果输入头符合 RFC 7239 规范,则返回 true,否则返回 false。

示例:

acl valid req.hdr(forwarded),rfc7239_is_valid
#input: "for=127.0.0.1;proto=http"
#  output: TRUE
#input: "proto=custom"
#  output: FALSE

rfc7239_n2nn

rfc7239_n2nn

将 RFC7239 节点(由 ‘for’ 或 ‘by’ 7239 头字段提供)转换为其对应的节点名称 最终形式:- IPv4 地址 - IPv6 地址 - ‘unknown’ - ‘_obfs’ 标识符

示例:

# extract 'for' field from forwarded header, extract nodename from
# resulting node identifier and store the result in req.fnn
http-request set-var(req.fnn) req.hdr(forwarded),rfc7239_field(for),rfc7239_n2nn
#input: "127.0.0.1:9999"
#  output: 127.0.0.1 (ipv4)
#input: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998"
#  output: ab:cd:ff:ff:ff:ff:ff:ff (ipv6)
#input: "_name:_port"
#  output: "_name" (string)

rfc7239_n2np

rfc7239_n2np

将 RFC7239 节点(由 ‘for’ 或 ‘by’ 7239 头字段提供)转换为其对应的节点端口 最终形式:无符号整数 - ‘_obfs’ 标识符

示例:

# extract 'by' field from forwarded header, extract node port from
# resulting node identifier and store the result in req.fnp
http-request set-var(req.fnp) req.hdr(forwarded),rfc7239_field(by),rfc7239_n2np
#input: "127.0.0.1:9999"
#  output: 9999 (integer)
#input: "[ab:cd:ff:ff:ff:ff:ff:ff]:9998"
#  output: 9998 (integer)
#input: "_name:_port"
#  output: "_port" (string)

rfc7239_nn

rfc7239_nn

将提供的地址或字符串输入转换为符合 RFC7239 规范的节点名称。可用于手动构建 ‘for’ 或 ‘by’ 7239 头字段。

当输入为字符串时,将自动在其前缀添加 ‘_’ 字符,以表示混淆标识符。字符串必须符合 RFC7239 字符集要求。若字符串为空,则将其转换为 “unknown” 标识符。

示例:

#input: ipv6(ab:cd:ff:ff:ff:ff:ff:ff)
#  output: "[ab:cd:ff:ff:ff:ff:ff:ff]"
#input: str(test)
#  output: "_test"
#input: str()
#  output: "unknown"

参见:“rfc7239_np”

rfc7239_np

rfc7239_np

将提供的无符号整数或字符串输入转换为符合 RFC7239 规范的节点端口。可用于手动构建 ‘for’ 或 ‘by’ 7239 头字段。

当输入为字符串时,将自动在其前缀添加 ‘_’ 字符,以表示混淆标识符。字符串必须符合 RFC7239 字符集要求,且不能为空。

示例:

#input: int(12)
#  output: "12"
#input: str(test)
#  output: "_test"

# build 'for' forwarded header field
http-request set-var-fmt(txn.test) "for=\"%[ipv6(::1),rfc7239_nn]:%[int(8080),rfc7239_np]\";"
#  output: "for=\"[::1]:8080\";"

# build RFC-compliant 7239 header:
http-request set-var-fmt(txn.forwarded) "for=\"%[ipv6(::1),rfc7239_nn]:%[str(8888),rfc7239_np]\";host=\"haproxy.org\";proto=http"
# check RFC-compliancy:
http-request set-var(txn.test) "var(txn.forwarded),debug(test,stderr),rfc7239_is_valid,debug(test,stderr)"
#  stderr output:
#    [debug] test: type=str <for="[::1]:_8888";host="haproxy.org";proto=http>
#    [debug] test: type=bool <1>

参见:“rfc7239_nn”

rtrim(<chars>)

rtrim(<chars>)

跳过输入样本的字符串表示形式末尾的 <chars> 中的任意字符。

sdbm([<avalanche>])

sdbm([<avalanche>])

使用 SDBM 哈希函数将二进制输入样本哈希为无符号 32 位整数。 可选地,若可选参数 <avalanche> 等于 1,则可对输出应用完整的雪崩哈希函数。 该转换器使用与各种基于哈希的负载均衡算法相同的函数,因此将提供完全相同的结果。 其主要用途为调试,但也可用作粘性表条目以收集粗略统计信息。 不得用于安全目的,因为 32 位哈希极易被破解。 另请参见 “crc32”、“djb2”、“wt6”、“crc32c” 以及 “hash-type” 指令。

secure_memcmp(<var>)

secure_memcmp(<var>)

将 <var> 的内容与输入值进行比较。两个值均被视为二进制字符串。 返回一个布尔值,指示两个二进制字符串是否匹配。

如果两个二进制字符串长度相同,则比较操作将在常量时间内完成。

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

示例:

http-request set-var(txn.token) hdr(token)
# Check whether the token sent by the client matches the secret token
# value, without leaking the contents using a timing attack.
acl token_given str(my_secret_token),secure_memcmp(txn.token)

set-var(<var>[,<cond>...])

set-var(<var>[,<cond>...])

设置一个变量,将其输入内容赋值,并在所有指定条件均为真时,将内容原样返回至输出(详见下文可能条件列表)。该变量将保留其值及关联的输入类型。有关变量的详细信息,请参见 第 2.8 节 。

可向转换器传递最多四个以下可能的条件:

  • ifexists / ifnotexists:
Checks if the variable already existed before the current set-var call.
A variable is usually created through a successful set-var call.
Note that variables of scope "proc" are created during configuration
parsing so the "ifexists" condition will always be true for them.
  • “ifempty”/“ifnotempty”:
Checks if the input is empty or not.
Scalar types are never empty so the ifempty condition will be false for
them regardless of the input's contents (integers, booleans, IPs ...).
  • ifset / ifnotset:
Checks if the variable was previously set or not, or if unset-var was
called on the variable.
A variable that does not exist yet is considered as not set. A "proc"
variable can exist while not being set since they are created during
configuration parsing.
  • ifgt / iflt:
Checks if the content of the variable is "greater than" or "less than"
the input. This check can only be performed if both the input and
the variable are of type integer. Otherwise, the check is considered as
true by default.

sha1

sha1

将二进制输入样本转换为 SHA-1 摘要。结果为长度为 20 字节的二进制样本。

sha2([<bits>])

sha2([<bits>])

将二进制输入样本转换为 SHA-2 系列摘要。结果为长度为 <bits>/8 字节的二进制样本。

<bits> 的有效值为 224、256、384 或 512,分别对应 SHA-<bits>。默认值为 256。

请注意,仅当 HAProxy 编译时包含 USE_OPENSSL 时,此转换器才可用。

srv_is_up

srv_is_up

接收类型为字符串的输入值,可以是服务器名称,也可以是 <backend>/<server> 格式,当指定的服务器当前处于 UP 状态时返回 true。可在需要从动态名称(例如 Cookie 值,如 req.cook(SRVID), srv_is_up)查询服务器状态并据此决定将请求转发至其他位置的场景中使用。使用前请注意,对不受控数据使用此转换器可能使外部观察者查询整个配置中任意服务器的状态,这在某些环境中可能不可接受。

srv_queue

srv_queue

接受类型为字符串的输入值,可以是服务器名称,也可以是 <backend>/<server> 格式, 返回该服务器上的队列流数量。可在需要根据动态名称查询队列流的场景中使用,例如从 Cookie 值(如 req.cook(SRVID), srv_queue)获取后, 决定是否中断持久性或将请求导向其他位置。使用前请注意,若在不受控数据上使用此转换器, 可能允许外部观察者查询整个配置中任意服务器的状态,这在某些环境中可能不可接受。

strcmp(<var>)

strcmp(<var>)

比较 <var> 与类型为字符串的输入值。返回结果为与 strcmp(3) 兼容的有符号整数:若两个字符串完全相同,则返回 0;若左侧字符串在字典序上小于右侧字符串,或左侧字符串较短,则返回小于 0 的值;否则返回大于 0 的值(即右侧字符串大于左侧字符串,或右侧字符串较短)。

如需以恒定时间比较两个二进制字符串,请参阅 secure_memcmp 转换器。

示例:

http-request set-var(txn.host) hdr(host)
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0

sub(<value>)

sub(<value>)

从类型为有符号整数的输入值中减去 <value>,并将结果以有符号整数形式返回。请注意:若需从常量中减去输入值,只需执行“neg,add(value)”操作。<value> 可以是数值或变量名。有关变量的详细信息,请参阅 第 2.8 节 。

table_bytes_in_rate([<table>])

table_bytes_in_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回输入样本在指定表中关联的客户端到服务器字节速率的平均值,单位为字节,该值基于表中配置的周期进行测量。另请参见 sc_bytes_in_rate 样本提取关键字。

table_bytes_out_rate([<table>])

table_bytes_out_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回输入样本在指定表中对应的平均服务器到客户端字节速率,单位为字节,该速率基于表中配置的周期进行测量。另请参见 sc_bytes_out_rate 样本提取关键字。

table_clr_gpc(<idx>[,<table>])

table_clr_gpc(<idx>[,<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。清除 gpc 数组中索引 <idx> 处的通用计数器,并返回其先前的值。<idx> 是介于 0 到 99 之间的整数。若未找到条目,则创建新条目并返回 0。此转换器仅适用于 ‘gpc’ 数组 data_type(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ data_type)。另请参见 sc_clr_gpc 样本提取关键字。

table_clr_gpc0([<table>])

table_clr_gpc0([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。清空第一个通用计数器 ‘0’ 并返回其先前的值。若未找到条目,则创建新条目并返回 0。通常作为表达式中的第二个 ACL 使用,以便在首个 ACL 验证通过时标记连接:

示例:

# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill  src,table_inc_gpc0 gt 5
acl save  src,table_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

另请参见 sc_clr_gpc0 样本提取关键字。

table_clr_gpc1([<table>])

table_clr_gpc1([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。清除第一个通用计数器 ‘1’ 并返回其先前值。若未找到条目,则创建新条目并返回 0。通常作为表达式中的第二个 ACL 使用,以便在首个 ACL 验证通过时标记连接。参见 sc_clr_gpc1 样本提取关键字。

table_conn_cnt([<table>])

table_conn_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的累计入站连接数。另请参见 sc_conn_cnt 样本提取关键字。

table_conn_cur([<table>])

table_conn_cur([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的当前并发连接数。另请参见 sc_conn_cur 样本提取关键字。

table_conn_rate([<table>])

table_conn_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回指定表中与输入样本关联的平均入站连接速率。参见 sc_conn_rate 样本提取关键字。

table_expire([<table>[,<default_value>]])

table_expire([<table>[,<default_value>]])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。如果键在表中未找到,转换器将失败,除非设置了 <default_value>:此时转换器将成功并返回 <default_value>。如果键被找到,转换器将返回输入样本在指定表中关联的键过期延迟。另请参见 table_idle 样本提取关键字。

table_glitch_cnt([<table>])

table_glitch_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回指定表中与输入样本关联的前端连接异常累计次数。另请参见 sc_glitch_cnt 样本提取关键字以及 fc_glitches,后者用于获取当前前端连接上测量到的值。

table_glitch_rate([<table>])

table_glitch_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的平均前端连接异常率。另请参见 sc_glitch_rate 样本提取关键字。

table_gpc(<idx>[,<table>])

table_gpc(<idx>[,<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键未在表中找到,返回整数值 0。否则,转换器返回指定 <table> 中与输入样本关联的数组在索引 <idx> 处的通用计数器(GPC)当前值。<idx> 为 0 至 99 之间的整数。若该索引处未存储 GPC,则同样返回整数值 0。此行为仅适用于 ‘gpc’ 数组 data_type(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ data_type)。另请参见 sc_get_gpc 样本提取关键字。

table_gpc0([<table>])

table_gpc0([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的第一个通用计数器的当前值。另请参见 sc_get_gpc0 样本提取关键字。

table_gpc0_rate([<table>])

table_gpc0_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回在指定表中与输入样本关联的 gpc0 计数器在配置周期内被递增的频率。参见 sc_get_gpc0_rate 样本提取关键字。

table_gpc1([<table>])

table_gpc1([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若在表中未找到该键,则返回整数值零。否则,转换器返回指定表中与输入样本关联的第二个通用计数器的当前值。另请参见 sc_get_gpc1 样本提取关键字。

table_gpc1_rate([<table>])

table_gpc1_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键在表中未找到,返回整数值零。否则,转换器返回在指定表中与输入样本关联的 gpc1 计数器在配置周期内被递增的频率。参见 sc_get_gpc1_rate 样本提取关键字。

table_gpc_rate(<idx>[,<table>])

table_gpc_rate(<idx>[,<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键未在表中找到,返回整数值 0。否则,转换器返回在配置周期内,与指定 stick-table <table> 中输入样本关联的数组中索引 <idx> 处的通用计数器(GPC)的增量频率。<idx> 为 0 至 99 之间的整数。若该索引处未存储 gpc_rate,则同样返回整数值 0。此行为仅适用于 ‘gpc_rate’ 数组 data_type(不适用于旧版 ‘gpc0_rate’ 及 ‘gpc1_rate’ data_type)。另请参阅 sc_gpc_rate 样本提取关键字。

table_gpt(<idx>[,<table>])

table_gpt(<idx>[,<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键在表中未找到,返回整数值 0。否则,转换器返回指定 <table> 中与输入样本关联的数组在索引 <idx> 处的通用标签(GPT)当前值。<idx> 是介于 0 到 99 之间的整数。若该索引处未存储 GPT,同样返回整数值 0。此行为仅适用于 ‘gpt’ 数组 data_type(不适用于旧版 ‘gpt0’ data-type)。另请参见 sc_get_gpt 样本提取关键字。

table_gpt0([<table>])

table_gpt0([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的第一个通用标签的当前值。另请参见 sc_get_gpt0 样本提取关键字。

table_http_err_cnt([<table>])

table_http_err_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的累计 HTTP 错误数量。另请参见 sc_http_err_cnt 样本提取关键字。

table_http_err_rate([<table>])

table_http_err_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,返回指定表中与输入样本关联的 HTTP 错误平均速率,单位为表中配置周期内的错误数量。参见 sc_http_err_rate 样本提取关键字。

table_http_fail_cnt([<table>])

table_http_fail_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的累计 HTTP 失败次数。另请参见 sc_http_fail_cnt 样本提取关键字。

table_http_fail_rate([<table>])

table_http_fail_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则返回指定表中与输入样本关联的 HTTP 失败平均速率,单位为表中配置周期内的失败次数。参见 sc_http_fail_rate 样本提取关键字。

table_http_req_cnt([<table>])

table_http_req_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回指定表中与输入样本关联的累计 HTTP 请求数量。另请参见 sc_http_req_cnt 样本提取关键字。

table_http_req_rate([<table>])

table_http_req_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则返回指定表中与输入样本关联的 HTTP 请求的平均速率,单位为请求数量,按表中配置的周期进行测量。另请参见 sc_http_req_rate 样本提取关键字。

table_idle([<table>[,<default_value>]])

table_idle([<table>[,<default_value>]])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。如果键在表中未找到,转换器将失败,除非设置了 <default_value>:此时转换器将成功并返回 <default_value>。如果找到键,转换器将返回指定表中与输入样本关联的键条目自上次更新以来保持空闲的时间。参见 table_expire 样本提取关键字。

table_inc_gpc(<idx>[,<table>])

table_inc_gpc(<idx>[,<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。将数组中索引 <idx> 处的通用计数器加 1,并返回其新值。<idx> 为 0 至 99 之间的整数。若未找到条目,则创建新条目并返回 1。此转换器仅适用于 ‘gpc’ 数组数据类型(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ 数据类型)。参见 sc_inc_gpc。

table_inc_gpc0([<table>])

table_inc_gpc0([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。递增通用计数器 ‘0’ 并返回其新值。若未找到条目,则创建条目并返回 1。参见 sc0/sc2/sc2_inc_gpc0。通常作为表达式中的第二个 ACL 使用,以便在第一个 ACL 验证通过时标记连接:

示例:

acl abuse src,table_req_rate gt 10
acl kill  src,table_inc_gpc0 gt 0
tcp-request connection reject if abuse kill

table_inc_gpc1([<table>])

table_inc_gpc1([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。递增通用计数器 ‘1’ 并返回其新值。若未找到条目,则创建新条目并返回 1。参见 sc0/sc2/sc2_inc_gpc1。通常作为表达式中的第二个 ACL 使用,以便在第一个 ACL 验证通过时标记连接。

table_kbytes_in([<table>])

table_kbytes_in([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的客户端到服务器数据的累计数量,单位为千字节。当前测试基于 32 位整数,因此数值上限为 4 太字节。另请参见 sc_kbytes_in 样本提取关键字。

table_kbytes_out([<table>])

table_kbytes_out([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的客户端数据累计量,单位为千字节。当前测试基于 32 位整数,因此数值上限为 4 太字节。另请参见 sc_kbytes_out 样本提取关键字。

table_server_id([<table>])

table_server_id([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本关联的服务器 ID。当连接到服务器成功时,通过“stick”规则将服务器 ID 与样本关联。服务器 ID 为零表示该键未关联任何服务器。

table_sess_cnt([<table>])

table_sess_cnt([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回指定表中与输入样本关联的累计入站会话数。请注意,此处的会话指由 “tcp-request connection” 规则集接受的入站连接。另请参见 sc_sess_cnt 样本提取关键字。

table_sess_rate([<table>])

table_sess_rate([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中进行查找。若键值在表中未找到,返回整数值 0。否则,转换器返回输入样本在指定表中关联的平均入站会话速率。请注意,此处的会话指被 “tcp-request connection” 规则集接受的入站连接。另请参见 sc_sess_rate 样本提取关键字。

table_trackers([<table>])

table_trackers([<table>])

使用输入样本在当前代理的 stick-table 或指定的 stick-table 中执行查找。若键值在表中未找到,返回整数值零。否则,转换器返回指定表中与输入样本相同键值所跟踪的当前并发连接数量。与 table_conn_cur 的区别在于,它不依赖于任何存储信息,而是基于表的引用计数(即 CLI 中 “show table” 命令返回的“use”值)。在某些情况下,此方法更适合用于第 7 层跟踪。可用于告知服务器来自特定地址的并发连接数量。另请参见 sc_trackers 样本提取关键字。

tcp.dst

tcp.dst

此功能与表示二进制 TCP 头的输入样本配合使用,该样本由 “ip.data” 返回。它返回一个整数,表示 TCP 头中的目标端口。另请参阅 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.flags

tcp.flags

此功能与表示二进制 TCP 头的输入样本配合使用,该样本由 “ip.data” 返回。它返回一个整数,表示来自该 TCP 头的 TCP 标志。从 FIN 到 CWR 的全部 8 个标志均被提取。每个标志均可通过 “and()” 转换器进行测试。请参阅 RFC9293 以获取每个标志的取值。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.options.mss

tcp.options.mss

此功能用于处理由 “ip.data” 返回的表示二进制 TCP 头的输入样本。它查找类型为“MSS”的 TCP 选项,若找到,则返回该选项中通告值对应的整数值,否则返回零。MSS 表示最大段大小,以字节为单位,指示对等节点可接收的最大段大小。另请参见 “fc_saved_syn”、“tcp-ss”以及 “ip.data”。

tcp.options.sack

tcp.options.sack

此功能用于处理表示二进制 TCP 头的输入样本,该样本由 “ip.data” 返回。它查找类型为“Sack-Permitted”的 TCP 选项,若找到则返回 1,否则返回 0。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.options.tsopt

tcp.options.tsopt

此功能用于处理表示二进制 TCP 头的输入样本,该样本由 “ip.data” 返回。它查找类型为“Timestamp”的 TCP 选项,若找到则返回 1,否则返回 0。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.options.tsval

tcp.options.tsval

此功能用于处理由 “ip.data” 返回的、表示二进制 TCP 头的输入样本。它查找类型为“Timestamp”的 TCP 选项,若找到则返回对等节点发出的时间戳值,否则不返回任何内容。请注意,时间戳为 32 位无符号值,无特定单位,仅由对等节点决定,且不同连接之间的时间戳应相互独立。另请参见 “fc_saved_syn”、“tcp-ss” 及 “ip.data”。

tcp.options.wscale

tcp.options.wscale

此函数用于处理表示二进制 TCP 头的输入样本,该样本由 “ip.data” 返回。它查找类型为“窗口缩放”的 TCP 选项,若找到则返回对等节点发出的窗口缩放值,否则返回零。请注意,虽然实际值通常不会超过 14,但并无技术限制阻止其发送更大数值。如需检测是否使用了窗口缩放选项,请使用 “tcp.options.wsopt”。另请参阅 “tcp-ss”、“fc_saved_syn”、“ip.data” 及 “tcp.options.wsopt”。

tcp.options.wsopt

tcp.options.wsopt

此功能用于处理表示二进制 TCP 头的输入样本,即 “ip.data” 返回的结果。它查找类型为“窗口缩放”的 TCP 选项,若找到则返回 1,否则返回 0。另请参见 “fc_saved_syn”、“tcp-ss”、“ip.data” “tcp.options.wscale”。

tcp.options_list

tcp.options_list

此功能与表示二进制 TCP 头的输入样本配合使用,该样本由 “ip.data” 返回。它按 TCP 头中出现的顺序,构建所有 TCP 选项类型的二进制序列。输出长度可在 0 到 60 字节之间(最坏情况)。不会发出选项结束标记。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.seq

tcp.seq

此功能用于处理表示二进制 TCP 头的输入样本,如 “ip.data” 所返回。它返回一个整数,表示对等节点在 TCP 头中使用的序列号。序列号为 32 位无符号值。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.src

tcp.src

此函数用于处理表示二进制 TCP 头的输入样本,该样本由 “ip.data” 返回。它返回一个整数,表示 TCP 头中的源端口。另请参见 “fc_saved_syn”、“tcp-ss” 和 “ip.data”。

tcp.win

tcp.win

此功能用于处理表示二进制 TCP 头的输入样本,即 “ip.data” 返回的结果。它返回一个整数,表示对等节点在 TCP 头中通告的窗口大小。该值以原始 16 位无符号整数形式提供,未应用窗口缩放因子。参见 “fc_saved_syn”、“tcp-ss” 及 “ip.data”。

ub64dec

ub64dec

此转换器是 b64dec 转换器的 base64url 变体。base64url 编码是 base64 编码的“URL 和文件名安全字母表”变体,也是 JWT(JSON Web Token)标准中所使用的编码方式。

示例:

# Decoding a JWT payload:
http-request set-var(txn.token_payload) req.hdr(Authorization),word(2,.),ub64dec

ub64enc

ub64enc

此转换器是 base64 转换器的 base64url 变体。

ungrpc(<field_number>[,<field_type>])

ungrpc(<field_number>[,<field_type>])

此操作以原始模式提取 gRPC 消息输入二进制样本表示中的 Protocol Buffers 消息字段,字段编号为 <field_number>(点号表示法),若 <field_type> 不存在,则以整数样本形式提取该字段;若该字段存在,则以整数样本形式提取。允许的类型列表如下:“int32”、“int64”、“uint32”、“uint64”、“sint32”、“sint64”、“bool”、“enum”对应“varint”线缆类型 0;“fixed64”、“sfixed64”、“double”对应 64 位线缆类型 1;“fixed32”、“sfixed32”、“float”对应线缆类型 5。请注意,“string”被视为长度限定类型,因此提取时无需提供 <field_type> 参数。有关 Protocol Buffers 消息字段类型的更多信息,请参见 https://developers.google.com/protocol-buffers/docs/encoding 。

示例:

// with such a protocol buffer .proto file content adapted from
// https://github.com/grpc/grpc/blob/master/examples/protos/route_guide.proto

message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

message PPoint {
  Point point = 59;
}

message Rectangle {
  // One corner of the rectangle.
  PPoint lo = 48;
  // The other corner of the rectangle.
  PPoint hi = 49;
}

假设一个请求体包含一个“Rectangle”对象值(两个 PPoint 协议缓冲区消息),可通过以下“ungrpc”指令提取四个协议缓冲区字段:

req.body,ungrpc(48.59.1,int32) # "latitude" of "lo" first PPoint
req.body,ungrpc(48.59.2,int32) # "longitude" of "lo" first PPoint
req.body,ungrpc(49.59.1,int32) # "latitude" of "hi" second PPoint
req.body,ungrpc(49.59.2,int32) # "longitude" of "hi" second PPoint

我们也可以将中间的 48.59 字段作为二进制样本提取,如下所示:

req.body,ungrpc(48.59)

由于 gRPC 消息始终由 gRPC 头后接 Protocol Buffers 消息组成,因此在前述示例中,可通过以下等效指令提取 “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>)

unset-var(<var>)

如果输入内容已定义,则取消设置变量。变量名称以表示其作用域的前缀开头。有关变量的详细信息,请参见 第 2.8 节 。

upper

upper

将字符串样本转换为大写形式。此操作只能置于字符串样本提取函数之后,或置于返回字符串类型的结果的转换关键字之后。结果类型为字符串。

url_dec([<in_form>])

url_dec([<in_form>])

将作为输入提供的 URL 编码字符串解码,并返回解码后的结果。输入和输出均为字符串类型。若 <in_form> 参数设置为非零整数值,则输入字符串被视为表单或查询字符串的一部分,加号字符(’+’)将被转换为空格(’ ‘)。否则,仅在问号字符(’?’)之后才执行此转换。

url_enc([<enc_type>])

url_enc([<enc_type>])

接收作为输入的字符串,并返回编码后的输出结果。输入和输出均为字符串类型。默认情况下,编码类型适用于 query 类型。目前不支持其他类型,但保留可选参数以备未来扩展。

us_ltime(<format>[,<offset>])

us_ltime(<format>[,<offset>])

这与 “ltime” 类似,但输入单位为微秒。它还支持受 date(1) 启发的 %N 转换说明符。将一个表示自纪元以来日期的整数转换为字符串,该字符串以本地时间格式表示该日期,格式由 <format> 字符串定义,使用 strftime(3)。此功能旨在允许在日志中使用任意日期格式。可选地,可在输入日期上应用一个以微秒为单位的 <offset> 值(正或负)。有关操作系统支持的格式,请参阅 strftime() 手册页。

%N 转换说明符可用于输出日期的纳秒部分,由于输入精度为微秒,因此精度受限(取值范围为 000000000..999999000)。%N 可以在 % 和 N 之间指定宽度参数。该功能可用于显示毫秒(%3N)或微秒(%6N)。默认及最大宽度为 9(%N 等价于 %9N)。

另请参阅“utime”转换器以处理 UTC 时间,以及“ltime”和 “ms_ltime” 转换器。

示例:

# Emit 3 colons, the local time, the timezone and another with ip:port
# e.g. 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>])

us_utime(<format>[,<offset>])

这与 “utime” 类似,但输入单位为微秒。它还支持受 date(1) 启发的 %N 转换说明符。将一个假设包含自纪元以来日期的整数转换为字符串,表示该日期在 UTC 时间下的格式,使用由 <format> 字符串定义的格式,该格式由 strftime(3) 解析。此功能旨在允许在日志中使用任意日期格式。可选地,可在输入日期上应用 <offset> 微秒(正或负)。请参阅 strftime() 手册页,了解操作系统支持的格式。

%N 转换说明符可用于输出日期的纳秒部分,由于输入精度为微秒,因此精度受限(取值范围为 000000000..999999000)。%N 可以在 % 和 N 之间指定宽度参数。该功能可用于显示毫秒(%3N)或微秒(%6N)。默认及最大宽度为 9(%N 等价于 %9N)。

另请参阅“ltime”转换器以处理本地时间,以及“utime”和 “ms_utime” 转换器。

示例:

# Emit 3 colons, the UTC time, the timezone and another with ip:port
# e.g. 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>])

utime(<format>[,<offset>])

将一个表示自纪元以来日期的整数转换为以 UTC 时间表示的字符串,使用由 <format> 字符串定义的格式,该格式遵循 strftime(3)。此功能旨在允许在日志中使用任意日期格式。可选地,可对输入的日期(正或负)应用 <offset> 秒的偏移量。有关操作系统支持的格式,请参阅 strftime() 手册页。另请参见 “ltime” 转换器以及 “ms_utime” 和 “us_utime”。

示例:

# Emit two colons, one with the UTC time and another with ip:port
# e.g.  20140710162350 127.0.0.1:57325
log-format %[date,utime(%Y%m%d%H%M%S)]\ %ci:%cp

when(<condition>[,<args>...])

when(<condition>[,<args>...])

评估条件,当条件为真时,将输入样本原样传递至输出,否则不返回任何内容。此功能专为在特定条件下生成极少数需要的数据而设计,例如在遇到错误时输出调试信息。

条件由以下列表中的关键字构成,可选择性地在前面加上感叹号(’!’)以否定该条件,并可选择性地在后面附加与该条件相关的特定参数:

- "error" returns true when an error was encountered during the processing
  of the request or stream. It uses the same rules as "dontlog-normal"
  (e.g. a successful redispatch counts as an error).

- "forwarded" returns true when the request was forwarded to a backend
  server

- "normal" returns true when no error happened (this is equivalent to
  "!error").

- "processed" returns true when the request was either forwarded to a
  backend server, or processed by an applet.

- "stopping" returns true if the process is currently stopping when the
  rule is evaluated

- "toapplet" returns true when the request was processed by an applet.

- "acl" returns true when the ACL designated by the next argument evaluates
  to true. Note that the ACL is evaluated inline by the converter, so that
  what it refers to must be valid in that context. A particular use case
  consists in evaluating if the total transfer time is too long or not
  before deciding to log detauls from abnormally long transfers.

请注意,无论何种情况都会评估内容,因此执行此操作并不能避免生成相关信息。其目的仅在于避免输出该信息。

例如,仅在处理过程中遇到错误时,才在日志中添加后端流的调试信息,或在停止时记录额外信息等。

示例:

# log "dbg={-}" when fine, or "dbg={... debug info ...}" on error:
log-format "$HAPROXY_HTTP_LOG_FMT dbg={%[bs.debug_str,when(!normal)]}"

Here, the "dbg" field in the log will only contain an dash ('-') to
indicate a missing content when the rule is not validated, and will emit a
whole debugging block when it is.

示例 # 当传输正常时记录 “dbg={-}",在慢速传输时记录 “dbg={… debug info …}” acl slow_xfer res.timer.data ge 10000 # 超过 10 秒视为慢速传输 log-format “$HAPROXY_HTTP_LOG_FMT \ fsdbg={%[fs.debug_str,when(acl,slow_xfer)]} \ bsdbg={%[bs.debug_str,when(acl,slow_xfer)]}”

示例 # 仅在建立真实连接时输出后端 src/port:log-format “$HAPROXY_HTTP_LOG_FMT \ src=[%[bc_src,when(forwarded)]:%[bc_src_port,when(forwarded)]]”

由于该表达式在不成立时会终止评估,因此也可用于阻止后续转换器被调用。例如,可仅在出现错误时调用 debug() 转换器,或仅在绝对必要时记录元素。

示例:

# emit the whole response headers list to stderr only on error and only
# when the output is a connection. We abuse a dummy variable here.
http-after-response set-var(res.test) \
              res.hdrs,when(error),when(forwarded),debug(hdrs,stderr)

另请参见:调试转换器

word(<index>,<delimiters>[,<count>])

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,_)    # <not found>
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([<avalanche>])

使用 WT6 哈希函数将二进制输入样本哈希为无符号 32 位整数。 可选地,若可选参数 <avalanche> 等于 1,则可对输出应用完整的雪崩哈希函数。 该转换器使用与各种基于哈希的负载均衡算法相同的函数,因此将提供完全相同的结果。 其主要用途为调试,但也可用作粘性表条目以收集粗略统计信息。 不得用于安全目的,因为 32 位哈希极易被破解。 另请参见 “crc32”、“djb2”、“sdbm”、“crc32c” 以及 “hash-type” 指令。

x509_v_err_str

x509_v_err_str

将数值转换为其对应的 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>)

xor(<value>)

对 <value> 与输入值(有符号整数类型)执行按位“异或”(XOR)运算,并将结果以有符号整数形式返回。<value> 可以是数值或变量名。有关变量的详细信息,请参见 第 2.8 节 。

xxh3([<seed>])

xxh3([<seed>])

使用 XXhash 哈希函数的 XXH3 64 位变体,将二进制输入样本哈希为有符号 64 位整数。该哈希支持种子值,其默认值为零,但可作为 <seed> 参数传入其他值。该哈希算法以性能优异且速度极快著称,可用于对 URL 和/或 URL 参数进行哈希,作为粘性表键值以收集统计信息,且碰撞率较低。请注意,由于该算法不被视为具有密码学安全性,因此使用时需谨慎。

xxh32([<seed>])

xxh32([<seed>])

使用 XXHash 的 32 位变体哈希函数,将二进制输入样本哈希为无符号 32 位整数。该哈希支持种子值,其默认值为零,但可作为 <seed> 参数传入其他值。该哈希算法以高效且性能优异著称,可用于对 URL 和/或 URL 参数进行哈希,作为粘性表键值以收集统计信息,碰撞率较低。请注意,该算法不被视为具有密码学安全性,使用时需谨慎。

xxh64([<seed>])

xxh64([<seed>])

使用 XXHash 哈希函数的 64 位变体,将二进制输入样本哈希为有符号 64 位整数。该哈希支持种子,其默认值为零,但可作为 <seed> 参数传入其他值。该哈希算法以性能优异且速度极快著称,可用于对 URL 和/或 URL 参数进行哈希,作为粘性表键以收集统计信息,且碰撞率较低。请注意,由于该算法不被视为具有密码学安全性,因此使用时需谨慎。

7.3.2. 从内部状态获取样本

本节介绍的第一组样本提取方法适用于与任何客户端信息均无关的内部信息。这些方法有时与“monitor fail”指令配合使用,用于向外部观察者报告内部状态。本节所述的样本提取方法可在任何位置使用。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                          output type
-------------------------------------------------+-------------
acl([!]<name>[,...])                               boolean
act_conn                                           integer
always_false                                       boolean
always_true                                        boolean
avg_queue([<backend>])                             integer
be_conn([<backend>])                               integer
be_conn_free([<backend>])                          integer
be_sess_rate([<backend>])                          integer
bin(<hex>)                                         bin
bool(<bool>)                                       bool
connslots([<backend>])                             integer
cpu_calls                                          integer
cpu_ns_avg                                         integer
cpu_ns_tot                                         integer
date([<offset>[,<unit>]])                          integer
date_us                                            integer
env(<name>)                                        string
fe_conn([<frontend>])                              integer
fe_req_rate([<frontend>])                          integer
fe_sess_rate([<frontend>])                         integer
hostname                                           string
int(<integer>)                                     signed
ipv4(<ipv4>)                                       ipv4
ipv6(<ipv6>)                                       ipv6
last_entity                                        string
last_rule_file                                     string
last_rule_line                                     integer
lat_ns_avg                                         integer
lat_ns_tot                                         integer
meth(<method>)                                     method
nbsrv([<backend>])                                 integer
pid                                                integer
prio_class                                         integer
prio_offset                                        integer
proc                                               integer
queue([<backend>])                                 integer
quic_enabled                                       boolean
rand([<range>])                                    integer
srv_conn([<backend>/]<server>)                     integer
srv_conn_free([<backend>/]<server>)                integer
srv_is_up([<backend>/]<server>)                    boolean
srv_iweight([<backend>/]<server>)                  integer
srv_queue([<backend>/]<server>)                    integer
srv_sess_rate([<backend>/]<server>)                integer
srv_uweight([<backend>/]<server>)                  integer
srv_weight([<backend>/]<server>)                   integer
stopping                                           boolean
str(<string>)                                      string
table_avl([<table>])                               integer
table_cnt([<table>])                               integer
term_events                                        string
thread                                             integer
txn.id32                                           integer
txn.sess_term_state                                string
uptime                                             integer
uuid([<version>])                                  string
var(<var-name>[,<default>])                        undefined
wait_end                                           boolean
waiting_entity                                     string
-------------------------------------------------+-------------

详细列表:

acl([!]<name>[,...]): boolean

acl([!]<name>[,...]): boolean

如果所有指定的 ACL 的评估结果均为真,则返回真;否则返回假。最多可提供 12 个 ACL,各以逗号分隔。每个命名的 ACL 可以用 “!” 前缀来反转结果。如果任意评估产生错误,则样本同样返回错误。请注意,HAProxy 不会对引用的 ACL 执行任何验证检查,例如,使用 HTTP 请求样本的 ACL 是否在响应上下文中被使用。此行为未来可能会更改。

act_conn: integer 返回进程当前活跃的并发连接总数。

always_false: boolean 始终返回布尔值“false”。在调整配置时,可将其用作 ACL 中另一个 ACL 的临时替代。

always_true:boolean 始终返回布尔值“true”。在调整配置时,可将其用作 ACL 中另一个 ACL 的临时替代。

avg_queue([<backend>]): integer

avg_queue([<backend>]): integer

返回指定后端的已排队连接总数除以活跃服务器数量。若未指定后端,则使用当前后端。此指标与“queue”非常相似,但考虑了服务器集群规模,以更准确地衡量新连接可能需要等待的处理时间。主要用途是配合 ACL,在确定新用户将遭遇服务质量下降时返回抱歉页面,或将其传递至后端服务器的头中,使后端服务器自行决定进入降级模式,或禁用部分功能以加快处理速度。请注意,若已无任何活跃服务器,将把已排队连接数的两倍作为测量值。这一估算合理,因为预计总有一台服务器会很快恢复,但若存在状态更优的其他后端,仍建议将新流量导向该后端。另请参见“queue”、“be_conn” 和 “be_sess_rate” 样本提取。

be_conn([<backend>]): integer

be_conn([<backend>]): integer

应用于后端当前已建立的连接数量,可能包含正在评估的连接。若未指定后端名称,则使用当前后端。也可用于检查其他后端。当名义后端已满时,可借此使用特定农场。另见 “fe_conn”、“queue”、“be_conn_free” 及 “be_sess_rate” 条件。

be_conn_free([<backend>]): integer

be_conn_free([<backend>]): integer

返回一个整数值,表示后端中可用服务器的可用连接总数。队列槽位不计入其中。除非所有其他服务器均处于宕机状态,否则不会包含备用服务器。若未指定后端名称,则使用当前后端。也可用于检查其他后端。当名义后端已满时,可借此使用特定农场。另请参见 “be_conn”、“connslots” 和 “srv_conn_free” 条件。

其他注意事项:如果任意服务器的 maxconn 或 maxqueue 为 0(表示无限制),则此 fetch 操作显然无意义,此时返回的值为 -1.

be_sess_rate([<backend>]): integer

be_sess_rate([<backend>]): integer

返回一个整数值,表示后端每秒创建的会话数量。该值可用于 ACL 中,当某个耗资源或不稳定的后端会话创建速率过高时,切换至备用后端;也可用于限制服务滥用(例如防止在线词典被过度访问)。此外,可通过 log-format 指令将此元素添加至日志中。

示例:

# Redirect to an error page if the dictionary is requested too often
backend dynamic
    mode http
    acl being_scanned be_sess_rate gt 100
    redirect location /denied.html if being_scanned

bin(<hex>): bin

bin(<hex>): bin

返回一个二进制链。输入为字符串的十六进制表示。

bool(<bool>): bool

bool(<bool>): bool

返回布尔值。<bool> 可以是 ’true’、‘false’、‘1’ 或 ‘0’。‘false’ 和 ‘0’ 表示相同含义。 ’true’ 和 ‘1’ 表示相同含义。

connslots([<backend>]): integer

connslots([<backend>]): integer

返回一个整数值,表示后端中仍可用的连接槽位数量,该值通过统计所有服务器的最大连接数与最大队列大小之和得出。此值通常仅用于 ACL。

此处的基本思路是能够测量仍可用的连接“槽位”数量(连接 + 队列),以便超出该数量的请求(预期用途;参见 “use_backend” 关键字)可被重定向至其他后端。

‘connslots’ = 可用服务器连接槽位数,加可用服务器队列槽位数。

请注意,尽管可以使用 “fe_conn”,但当流量指向单一 IP 地址并分发至多个后端(例如使用 ACL 实现基于名称的负载均衡)时,“connslots”尤为有用,此时可区分不同后端及其可用的“connslots”数量。此外,“nbsrv”仅统计实际处于 down 状态的服务器,而此获取方式更为精细,还会检查可用连接槽位数量。另请参见“queue”和 “avg_queue”。

其他注意事项:截至目前,代码尚未处理动态连接。 此外,若任意服务器的 maxconn 或 maxqueue 值为 0,则此获取操作显然无意义,此时返回的值将为 -1.

cpu_calls: integer 返回自分配以来,处理流或当前请求的任务调用次数。在 HTTP 持久连接情况下,同一连接上的每个新请求都会重置此数值。该值通常应保持较低且稳定(典型简单请求约为 2 次调用),但如果执行了某些处理操作(如压缩、缓存或分析),该值可能升高。此指标仅用于性能监控。

cpu_ns_avg: 整数 返回处理流或当前请求时,每次调用任务所花费的平均纳秒数。在 HTTP 持久连接情况下,每次新请求都会重置该值。该值表示每次调用处理请求或连接的整体开销。并无所谓的好或坏值,但调用所花费的时间会自动导致其他处理的延迟(参见下文的 lat_ns_avg),并可能影响其他连接的响应时间表现。某些操作如压缩、复杂的正则表达式匹配或繁重的 Lua 操作可能直接影响该值,将其记录在日志中将有助于识别需要修复以恢复良好性能的故障处理环节。请注意:该值等于 cpu_ns_tot 除以 cpu_calls。

cpu_ns_tot: 整数 返回每次调用任务处理流或当前请求所花费的总纳秒数。在 HTTP 持久连接情况下,每次新请求都会重置该数值。该值表示每次调用处理请求或连接的整体开销。并无所谓的好或坏数值,但调用所花费的时间会自动导致其他处理的延迟(参见下文的 lat_ns_avg),增加机器的 CPU 开销,并可能影响其他连接的响应时间感知。某些操作如压缩、复杂的正则表达式匹配或繁重的 Lua 操作可能直接影响该值,将其记录在日志中将有助于识别需要修复以恢复良好性能的故障处理环节。由于高 cpu_calls 计数(例如处理大量 HTTP 数据块)可能导致该值被人为抬高,因此通常更建议记录 cpu_ns_avg。

cpu_usage_grp: 整数 返回上一次轮询周期内测得的 CPU 使用率,取值范围为 0 至 100,该值为当前线程组中所有线程的平均值。可用于故障排查和日志记录。该测量值波动性极强,但在持续负载下仍能保持准确,因为每个线程均在处理数十至数百个请求的过程中进行测量。

cpu_usage_proc: 整数 返回上一次轮询周期内测得的 CPU 使用率,取值范围为 0 到 100,该值为所有运行线程的平均值。可用于故障排查和日志记录。该测量值波动极强,但在持续负载下仍保持准确,因为每个线程会基于数十至数百个请求进行测量。该值等于统计信息页面及 “show info” 命令中空闲比率所报告值的 100 减去该值。

cpu_usage_thr: integer 返回调用线程在上一次轮询周期内测得的 CPU 使用率,取值范围为 0 至 100,可用于故障排查和日志记录。该测量值波动极强,但在持续负载下仍保持准确,因其基于数十至数百个请求的测量结果。该值与判断是否因 CPU 使用率过高而启用连接终止,或是否禁用压缩的决策依据相同。另见 “tune.glitches.kill.cpu-usage” 和 “maxcompcpuusage”。

date([<offset>[,<unit>]]): integer

date([<offset>[,<unit>]]): integer

返回当前日期的纪元时间(自 01/01/1970 起的秒数)。

如果指定了偏移值,则在返回值前将其加到当前日期上。 这特别适用于计算相对日期,因为允许使用正负偏移值。 与 http_date 转换器结合使用时尤为有用。

<unit> 为可选配置,可设置为 “s” 表示秒(默认行为)、“ms” 表示毫秒或 “us” 表示微秒。若指定单位,返回值为自纪元以来的整数,单位为秒、毫秒或微秒,并包含偏移量。当需要小于秒级的时间分辨率时,该配置非常有用。

示例:

# set an expires header to now+1 hour in every response
http-response set-header Expires %[date(3600),http_date]

# set an expires header to now+1 hour in every response, with
# millisecond granularity
http-response set-header Expires %[date(3600000,ms),http_date(0,ms)]

date_us: integer 返回日期的微秒部分(“秒”部分由 date_sample 返回)。该样本与 date_sample 保持一致,因为其来自相同的 timeval 结构。

env(<name>): string

env(<name>): string

返回一个包含环境变量 <name> 值的字符串。请注意,环境变量是进程级的,仅在进程启动时采样。此功能可用于向下一跳服务器传递某些信息,或配合 ACL 在进程以特定方式启动时执行特定动作。

示例:

# Pass the Via header to next hop with the local hostname in it
http-request add-header Via 1.1\ %[env(HOSTNAME)]

# reject cookie-less requests when the STOP environment variable is set
http-request deny if !{ req.cook(SESSIONID) -m found } { env(STOP) -m found }

fe_conn([<frontend>]): integer

fe_conn([<frontend>]): integer

返回前端当前建立的连接数,可能包含正在评估的连接。若未指定前端名称,则使用当前前端。也可用于检查其他前端。可用于在强制阻断前返回抱歉页面,或在服务端组被认为已满时,使用特定后端处理新请求。该功能主要与 ACL 配合使用,也可用于将部分统计信息传递至服务器的 HTTP 头中。参见 “dst_conn”、“be_conn”、“fe_sess_rate” 获取操作。

fe_req_rate([<frontend>]): integer

fe_req_rate([<frontend>]): integer

返回一个整数值,表示发送至前端的每秒 HTTP 请求数。 在启用客户端持久连接的情况下,该数值可能与 “fe_sess_rate” 不同。

fe_sess_rate([<frontend>]): integer

fe_sess_rate([<frontend>]): integer

返回一个整数值,表示前端的会话创建速率,单位为每秒新建会话数。该值可用于 ACL 中,将传入会话速率限制在可接受范围内,以便在最早时刻防止服务被滥用,例如与其他第 4 层 ACL 结合使用,强制客户端在速率降至限制以下前等待。也可通过 log-format 指令将此元素添加至日志中。另请参见前端中使用的“rate-limit sessions”指令。

示例:

# This frontend limits incoming mails to 10/s with a max of 100
# concurrent connections. We accept any connection below 10/s, and
# force excess clients to wait for 100 ms. Since clients are limited to
# 100 max, there cannot be more than 10 incoming mails per second.
frontend mail
    bind:25
    mode tcp
    maxconn 100
    acl too_fast fe_sess_rate ge 10
    tcp-request inspect-delay 100ms
    tcp-request content accept if ! too_fast
    tcp-request content accept if WAIT_END

hostname: string 返回系统主机名。

int(<integer>): signed integer

int(<integer>): signed integer

返回一个有符号整数。

ipv4(<ipv4>): ipv4

ipv4(<ipv4>): ipv4

返回 IPv4 地址。

ipv6(<ipv6>): ipv6

ipv6(<ipv6>): ipv6

返回 IPv6 地址。

last_entity: string 该字段返回流分析过程中最后一个被评估的实体的身份。可能是最后一个匹配的规则,也可能是中断处理的过滤器。

最终规则是指终止规则集评估的规则(如“accept”、“deny”或“redirect”)。该机制适用于作用于“content”规则集的 TCP 请求和响应规则,以及“http-request”、“http-response”和“http-after-response”规则集中的 HTTP 规则。不支持旧版“redirect”规则集(相关信息未存储于此),也不支持“tcp-request connection”和“tcp-request session”规则集,因为相关信息存储在流级别,而这些规则执行时流尚不存在。此时,返回值等价于“last_rule_file:last_rule_line”。参见 “last_rule_file”、“last_rule_line”。

对于过滤器,其标识符按开发人员定义的方式返回。若未定义标识符,则返回对应唯一内部标识符的十六进制值。

此函数的主要目的是在日志中记录中断处理的最后一个实体,以协助排查问题。返回的实体信息可能会随时间变化,不得用于除调试以外的其他用途。

示例:

# Log the last entity, if any, and only if an error is reported
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[last_entity,when(error)]

last_rule_file: string 此函数返回在流分析过程中匹配到的最后一个最终规则所在的配置文件名称。最终规则是指终止规则集评估的规则(例如“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: 整数 返回在处理流的任务被唤醒至实际被调用之间所花费的平均纳秒数。在启用 HTTP 持久连接的情况下,每次新请求到达同一连接时该数值将被重置。该值表示当前请求因并行处理的其他请求而承受的整体延迟,是受“噪音邻居”影响导致感知性能下降的直接指标。为保持该值较低,可采取以下措施:使用 “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 持久连接的情况下,每次新请求到达时该数值将被重置。该值反映了当前请求因并行处理的其他请求而遭受的整体延迟,是受“噪音邻居”影响感知性能的直接指标。为保持该值较低,可采取以下措施:使用 “tune.runqueue-depth” 降低调度器运行队列深度;使用 “tune.maxpollevents” 减少单次处理的并发事件数量;通过在 “bind” 行或前端中使用 “nice” 选项降低流的 nice 值;启用低延迟调度模式 “tune.sched.low-latency”;或检查日志中是否存在其他处理耗时较长的请求(表现为 “cpu_ns_avg” 值较大),并调整或修复其处理逻辑。大缓冲区的压缩可能为问题根源,如复杂的正则表达式或过长的正则表达式列表。请注意:尽管直观上可能认为总延迟会增加传输时间,但实际情况几乎从不如此,因为当任务等待 CPU 时,网络缓冲区仍在持续填充,下一次调用将一次性处理更多数据。该值可能因 cpu_calls 计数过高而被人为抬高,例如在处理大量 HTTP 数据块时,因此通常更建议记录 lat_ns_avg,其作为性能指标更具参考价值。

meth(<method>): method

meth(<method>): method

返回一个方法。

nbsrv([<backend>]): integer

nbsrv([<backend>]): integer

返回一个整数值,表示当前后端或指定后端中可用服务器的数量。该功能主要用于 ACL,也可用于日志记录。通常在服务器数量过低、无法处理负载时,用于切换至备用后端。与“monitor fail”结合使用时,可用于报告故障。

pid: integer 返回当前进程的 PID。在大多数情况下,这是工作进程的 PID。

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” 所设置的值。

proc: integer 始终返回值 1(历史上会返回调用进程的编号)。

queue([<backend>]): integer

queue([<backend>]): integer

返回指定后端的排队连接总数,包括所有服务器队列中的连接。若未指定后端名称,则使用当前后端,也可检查其他后端。此功能在 ACL 中或向后端服务器传递统计信息时非常有用。当排队连接数超过已知阈值时,可采取相应动作,通常表明流量激增或服务器出现严重性能下降。一种可能的动作是拒绝新用户连接,但仍接受旧连接。另请参见 “avg_queue”、“be_conn” 和 “be_sess_rate” 获取操作。

quic_enabled: boolean 当编译时启用了对 QUIC 传输协议的支持,且未通过 “tune.quic.listen” 全局选项禁用 QUIC 监听器时,返回 true。参见 “tune.quic.listen” 全局选项。

rand([<range>]): integer

rand([<range>]): integer

返回一个介于 0 到 <range> 个可能值范围内的随机整数。若未指定范围,则默认为 2^32,生成的数值范围为 0 到 4294967295。该功能可用于传递某些用于路由决策的值,或仅用于调试目的。请注意,此随机数生成器不得用于安全用途。

srv_conn([<backend>/]<server>): integer

srv_conn([<backend>/]<server>): integer

返回一个整数值,表示指定服务器上当前建立的连接数量,可能包含正在评估的连接。如果省略 <backend>,则在当前后端中查找服务器。可用于在某台服务器满载时切换至特定农场,或向服务器通报我们对其当前活跃连接数的统计视图。另请参见 “fe_conn”、“be_conn”、“queue” 和 “srv_conn_free” 获取方法。

srv_conn_free([<backend>/]<server>): integer

srv_conn_free([<backend>/]<server>): integer

返回一个整数值,表示指定服务器上可用连接的数量,可能包含正在评估的连接。该值不包含队列槽位。若省略 <backend>,则在当前后端中查找服务器。可用于在某台服务器满载时切换至特定农场,或向服务器通报我们对其当前活跃连接数的观测值。另请参见 “be_conn_free” 和 “srv_conn” 获取方法。

其他注意事项和说明:如果服务器的 maxconn 为 0,则此获取操作显然无意义,此时返回的值为 -1.

srv_is_up([<backend>/]<server>): boolean

srv_is_up([<backend>/]<server>): boolean

当指定服务器处于运行状态时返回 true,处于关闭状态或维护模式时返回 false。若省略 <backend>,则在当前后端中查找服务器。该功能主要用于根据通过健康检查报告的外部状态采取动作(例如,某个地理站点的可用性)。另一种可能的用法更像一种技巧,即使用虚拟服务器作为布尔变量,可通过 CLI 启用或禁用,从而实现实时调整依赖于这些 ACL 的规则。

srv_iweight([<backend>/]<server>): integer

srv_iweight([<backend>/]<server>): integer

返回对应服务器初始权重的整数值。若省略 <backend>,则在当前后端中查找服务器。参见 “srv_weight” 和 “srv_uweight”。

srv_queue([<backend>/]<server>): integer

srv_queue([<backend>/]<server>): integer

返回一个整数值,表示指定服务器队列中当前挂起的连接数量。若省略 <backend>,则在当前后端中查找服务器。该指令可与 “use-server” 指令配合使用,当某服务器负载不重时,强制使用已知响应更快的服务器。另请参见 “srv_conn”、“avg_queue” 和 “queue” 样本提取方法。

srv_sess_rate([<backend>/]<server>): integer

srv_sess_rate([<backend>/]<server>): integer

返回指定服务器的会话创建速率对应的整数,单位为每秒新建会话数。若省略 <backend>,则在当前后端中查找服务器。该功能主要用于 ACL,但也可用于日志记录。当昂贵或脆弱的后端会话速率过高时,可用于切换至备用后端,或限制服务滥用(例如防止延迟请求导致服务器过载)。

示例:

# Redirect to a separate back
acl srv1_full srv_sess_rate(be1/srv1) gt 50
acl srv2_full srv_sess_rate(be1/srv2) gt 50
use_backend be2 if srv1_full or srv2_full

srv_uweight([<backend>/]<server>): integer

srv_uweight([<backend>/]<server>): integer

返回对应用户可见服务器权重的整数值。若省略 <backend>,则在当前后端中查找服务器。参见 “srv_weight” 和 “srv_iweight”。

srv_weight([<backend>/]<server>): integer

srv_weight([<backend>/]<server>): integer

返回当前(或生效)服务器的权重值,该值为整数。若省略 <backend>,则在当前后端中查找服务器。参见 “srv_iweight” 和 “srv_uweight”。

stopping: boolean 如果调用函数的进程当前正在停止,则返回 TRUE。此信息可用于日志记录,或在优雅关闭期间放松某些检查,或协助关闭特定连接。

str(<string>): string

str(<string>): string

返回一个字符串。

table_avl([<table>]): integer

table_avl([<table>]): integer

返回当前代理的 stick-table 中可用条目的总数,或指定 stick-table 中的可用条目总数。参见 “table_cnt”。

table_cnt([<table>]): integer

table_cnt([<table>]): integer

返回当前代理的 stick-table 中当前正在使用的条目总数,或指定 stick-table 中的条目总数。另请参见 “table_conn_cnt” 和 table_avl 以了解其他条目计数方法。

term_events: string 返回与流关联的所有实体(客户端和服务器端)已知的终止事件。返回包含七个元素的元组,内容如下:

- the termination events of the frontend connection
- the termination events of the frontend mux connection
- the termination events of the frontend stream endpoint descriptor
  (the mux stream or the applet)
- the termination events of the stream
- the termination events of the backend stream endpoint descriptor
  (the mux stream or the applet)
- the termination events of the backend mux connection
- the termination events of the backend connection

在每个级别上,前四个事件会被报告。若某一特定级别尚未报告任何事件,则返回空字符串。若不支持终止事件,则返回“-”。

仅可用于调试目的。确切格式未记录,因为其可能根据开发人员需求而变化。

tgroup: integer 返回一个整数值,表示调用该函数的线程组的位置,取值范围为 0 到 (global.thread-groups - 1)。此功能在日志记录和调试时非常有用。

thread: integer 返回一个整数值,表示调用函数的线程位置,取值范围为 0 到 (global.nbthread - 1)。该值在日志记录和调试时非常有用。

txn.id32: integer 返回内部事务 ID。该值为 32 位整数。因此,从绝对值上看,其值并非唯一,事务 ID 可能发生回绕。回绕周期取决于请求速率。实践中通常不会造成问题。如需真正的唯一 ID,请参见 “unique-id-format” 指令。

txn.sess_term_state: string 返回日志中报告的 TCP 或 HTTP 流终止状态。该值为 2 个字符的字符串,格式为“最终流状态 + 导致其终止的事件”。有关断开连接时流状态的可能事件列表,请参见 第 8.5 节 。返回样本提取评估时刻的当前值,该值可能发生变化。除非在 “http-after-response” 规则集中与 ACL 一起使用,或用于日志消息中,否则该值始终为 “–"。

示例:

# Return a 429-Too-Many-Requests if stream timed out in queue
http-after-response set-status 429 if { txn.sess_term_state  "sQ" }

uptime: integer 返回当前 HAProxy 工作进程的运行时间(单位:秒)。

uuid([<version>]): string

uuid([<version>]): string

按照 RFC 9562 标准返回一个 UUID。若未指定版本,则返回 UUID 版本 4(完全随机)。

版本 4 和 7 受支持。

var(<var-name>[,<default>]): undefined

var(<var-name>[,<default>]): undefined

返回存储类型的变量。如果该变量未设置,样本提取将失败,除非提供了默认值,此时将返回该默认值作为字符串。允许空字符串。有关变量的详细信息,请参见 第 2.8 节 。

dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string

dump_all_vars([<scope>][,<prefix>][,<delimiter>]): string

返回指定作用域中的所有变量列表,可选择按名称前缀进行过滤,并支持自定义分隔符。

输出格式:var1=value1<delim>var2=value2<delim>…

按类型进行值编码:

  • 字符串:使用引号包围并转义("、\、\r、\n、\b、\0)示例:txn.name=“John \“Doe\”
  • 二进制:以 x 开头的十六进制编码,不加引号 示例:txn.data=x48656c6c6f
  • 整数:不加引号的十进制数 示例:txn.count=42
  • 布尔值:不加引号的 “true” 或 “false” 示例:txn.active=true
  • 地址:不加引号的 IP 地址字符串 示例:txn.client=192.168.1.1
  • HTTP 方法:加引号的字符串 示例:req.method=“GET”

参数:

  • <scope>(可选):sess、txn、req、res 或 proc。若省略,则按此处所示顺序遍历所有这些作用域。

  • <prefix>(可选):过滤名称以指定前缀开头的变量(在移除作用域前缀后)。性能提示:使用前缀过滤时,仍会遍历作用域内的所有变量。请勿在涉及数千个变量的配置中使用。

  • <delimiter>(可选):用于分隔变量的字符串。默认值为“, ”(逗号加空格)。可自定义为任意字符串。请注意,若需在函数参数中传递逗号或空格,必须将其用单引号或双引号括起(若表达式本身已在引号内,请使用另一类引号)。

返回值:

  • 成功时:包含所有匹配变量的字符串
  • 失败时:若输出缓冲区太小,则返回空值(样本提取失败)。该函数不会截断输出;失败时将完全终止,以避免产生部分数据。

这在调试、日志记录或导出变量状态时尤为有用。

示例:

# Dump all transaction variables
http-request return string %[dump_all_vars(txn)]

# Dump only variables starting with "user"
http-request set-header X-User-Vars "%[dump_all_vars(txn,user)]"

# Dump all process variables
http-request return string %[dump_all_vars(proc)]

# Custom delimiter (semicolon)
http-request set-header X-Vars "%[dump_all_vars(txn,,; )]"

# Force the default delimiter (comma space)
http-request set-header X-Vars "%[dump_all_vars(txn,,', ')]"

# Prefix filter with custom delimiter
http-request set-header X-Session "%[dump_all_vars(sess,user,|)]"

wait_end: boolean 此获取操作在检查周期结束时返回 true,或不返回任何结果。仅在 ACL 中与内容分析配合使用,以避免过早得出错误结论。也可用于延迟某些动作,例如对特定地址的延迟拒绝。由于该获取操作要么停止规则评估,要么立即返回 true,建议将此 ACL 作为规则中的最后一个使用。请注意,默认 ACL “WAIT_END” 始终可直接使用,无需预先声明。此测试专为与 TCP 请求内容检查配合使用而设计。

示例:

# delay every incoming request by 2 seconds
tcp-request inspect-delay 2s
tcp-request content accept if WAIT_END

# don't immediately tell bad guys they are rejected
tcp-request inspect-delay 10s
acl goodguys src 10.0.0.0/24
acl badguys  src 10.0.1.0/24
tcp-request content accept if goodguys
tcp-request content reject if badguys WAIT_END
tcp-request content reject

waiting_entity: string 当发生错误或超时时,此字段返回正在等待继续处理的实体的身份。该实体可能是一个规则或过滤器。然而,此列表并非详尽无遗,所有可能实体的格式也未强制记录。

当实体为规则时,将返回其位置。位置信息为包含该规则的配置文件,后跟规则在该文件中的行号,两者以冒号分隔。

对于过滤器,其标识符按开发人员定义的方式返回。若未定义标识符,则返回对应唯一内部标识符的十六进制值。

此函数的主要目的是在遇到错误或超时并中断处理时,能够将阻塞流分析的实体记录到日志中,以协助排查问题。返回的实体信息可能会随时间变化,不得用于除调试以外的其他用途。

示例:

# Log the waiting entity, if any, and only if an error is reported
log-format "$HAPROXY_HTTP_LOG_FMT %{Q}[waiting_entity,when(error)]

7.3.3. 获取第 4 层样本

第 4 层通常仅描述传输层,HAProxy 中该层最接近连接,此时尚未提供任何内容。此处描述的获取方法可应用于最低至 “tcp-request connection” 规则集,除非它们需要未来信息。这些方法通常包括 TCP/IP 地址和端口,以及与入站连接相关的粘性表元素。若需从粘性计数器中获取值,可使用预定义的 “sc0_"、“sc1_” 或 “sc2_” 前缀显式指定计数器编号为 0、1 或 2。这三个预定义前缀仅在全局 “tune.stick-counters” 值不超过 3 时可用;否则,可使用 “sc_” 前缀并从 “sc_0” 到 “sc_N” 指定计数器编号,其中 N 为 (tune.stick-counters-1)。可选地,可通过 “sc*” 形式指定表,此时将查找当前跟踪键在该备用表中的值,而非当前正在跟踪的表。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                          output type
-------------------------------------------------+-------------
accept_date([<unit>])                              integer
bc.timer.connect                                   integer
bc_be_queue                                        integer
bc_dst                                             ip
bc_dst_port                                        integer
bc_err                                             integer
bc_err_name                                        string
bc_err_str                                         string
bc_glitches                                        integer
bc_http_major                                      integer
bc_nb_streams                                      integer
bc_reused                                          boolean
bc_rtt(<unit>)                                     integer
bc_rttvar(<unit>)                                  integer
bc_settings_streams_limit                          integer
bc_src                                             ip
bc_src_port                                        integer
bc_srv_queue                                       integer
be_id                                              integer
be_name                                            string
be_connect_timeout                                 integer
be_queue_timeout                                   integer
be_server_timeout                                  integer
be_tarpit_timeout                                  integer
be_tunnel_timeout                                  integer
bytes_in                                           integer
bytes_out                                          integer
cur_connect_timeout                                integer
cur_client_timeout                                 integer
cur_queue_timeout                                  integer
cur_server_timeout                                 integer
cur_tarpit_timeout                                 integer
cur_tunnel_timeout                                 integer
dst                                                ip
dst_conn                                           integer
dst_is_local                                       boolean
dst_port                                           integer
fc.timer.handshake                                 integer
fc.timer.total                                     integer
fc_dst                                             ip
fc_dst_is_local                                    boolean
fc_dst_port                                        integer
fc_err                                             integer
fc_err_name                                        string
fc_err_str                                         string
fc_fackets                                         integer
fc_glitches                                        integer
fc_http_major                                      integer
fc_lost                                            integer
fc_nb_streams                                      integer
fc_pp_authority                                    string
fc_pp_tlv(<id>)                                    string
fc_pp_unique_id                                    string
fc_rcvd_proxy                                      boolean
fc_reordering                                      integer
fc_retrans                                         integer
fc_rtt(<unit>)                                     integer
fc_rttvar(<unit>)                                  integer
fc_sacked                                          integer
fc_saved_syn                                       binary
fc_settings_streams_limit                          integer
fc_src                                             ip
fc_src_is_local                                    boolean
fc_src_port                                        integer
fc_unacked                                         integer
fe_tarpit_timeout                                  integer
fe_client_timeout                                  integer
fe_defbe                                           string
fe_id                                              integer
fe_name                                            string
req.bytes_in                                       integer
req.bytes_out                                      integer
res.bytes_in                                       integer
res.bytes_out                                      integer
res.timer.data                                     integer
sc0_bytes_in_rate([<table>])                       integer
sc0_bytes_out_rate([<table>])                      integer
sc0_clr_gpc0([<table>])                            integer
sc0_clr_gpc1([<table>])                            integer
sc0_conn_cnt([<table>])                            integer
sc0_conn_cur([<table>])                            integer
sc0_conn_rate([<table>])                           integer
sc0_get_gpc0([<table>])                            integer
sc0_get_gpc1([<table>])                            integer
sc0_get_gpt0([<table>])                            integer
sc0_glitch_cnt([<table>])                          integer
sc0_glitch_rate([<table>])                         integer
sc0_gpc0_rate([<table>])                           integer
sc0_gpc1_rate([<table>])                           integer
sc0_http_err_cnt([<table>])                        integer
sc0_http_err_rate([<table>])                       integer
sc0_http_fail_cnt([<table>])                       integer
sc0_http_fail_rate([<table>])                      integer
sc0_http_req_cnt([<table>])                        integer
sc0_http_req_rate([<table>])                       integer
sc0_inc_gpc0([<table>])                            integer
sc0_inc_gpc1([<table>])                            integer
sc0_kbytes_in([<table>])                           integer
sc0_kbytes_out([<table>])                          integer
sc0_key                                            any
sc0_sess_cnt([<table>])                            integer
sc0_sess_rate([<table>])                           integer
sc0_tracked([<table>])                             boolean
sc0_trackers([<table>])                            integer
sc1_bytes_in_rate([<table>])                       integer
sc1_bytes_out_rate([<table>])                      integer
sc1_clr_gpc0([<table>])                            integer
sc1_clr_gpc1([<table>])                            integer
sc1_conn_cnt([<table>])                            integer
sc1_conn_cur([<table>])                            integer
sc1_conn_rate([<table>])                           integer
sc1_get_gpc0([<table>])                            integer
sc1_get_gpc1([<table>])                            integer
sc1_get_gpt0([<table>])                            integer
sc1_glitch_cnt([<table>])                          integer
sc1_glitch_rate([<table>])                         integer
sc1_gpc0_rate([<table>])                           integer
sc1_gpc1_rate([<table>])                           integer
sc1_http_err_cnt([<table>])                        integer
sc1_http_err_rate([<table>])                       integer
sc1_http_fail_cnt([<table>])                       integer
sc1_http_fail_rate([<table>])                      integer
sc1_http_req_cnt([<table>])                        integer
sc1_http_req_rate([<table>])                       integer
sc1_inc_gpc0([<table>])                            integer
sc1_inc_gpc1([<table>])                            integer
sc1_kbytes_in([<table>])                           integer
sc1_kbytes_out([<table>])                          integer
sc1_key                                            any
sc1_sess_cnt([<table>])                            integer
sc1_sess_rate([<table>])                           integer
sc1_tracked([<table>])                             boolean
sc1_trackers([<table>])                            integer
sc2_bytes_in_rate([<table>])                       integer
sc2_bytes_out_rate([<table>])                      integer
sc2_clr_gpc0([<table>])                            integer
sc2_clr_gpc1([<table>])                            integer
sc2_conn_cnt([<table>])                            integer
sc2_conn_cur([<table>])                            integer
sc2_conn_rate([<table>])                           integer
sc2_get_gpc0([<table>])                            integer
sc2_get_gpc1([<table>])                            integer
sc2_get_gpt0([<table>])                            integer
sc2_glitch_cnt([<table>])                          integer
sc2_glitch_rate([<table>])                         integer
sc2_gpc0_rate([<table>])                           integer
sc2_gpc1_rate([<table>])                           integer
sc2_http_err_cnt([<table>])                        integer
sc2_http_err_rate([<table>])                       integer
sc2_http_fail_cnt([<table>])                       integer
sc2_http_fail_rate([<table>])                      integer
sc2_http_req_cnt([<table>])                        integer
sc2_http_req_rate([<table>])                       integer
sc2_inc_gpc0([<table>])                            integer
sc2_inc_gpc1([<table>])                            integer
sc2_kbytes_in([<table>])                           integer
sc2_kbytes_out([<table>])                          integer
sc2_key                                            any
sc2_sess_cnt([<table>])                            integer
sc2_sess_rate([<table>])                           integer
sc2_tracked([<table>])                             boolean
sc2_trackers([<table>])                            integer
sc_bytes_in_rate(<ctr>[,<table>])                  integer
sc_bytes_out_rate(<ctr>[,<table>])                 integer
sc_clr_gpc(<idx>,<ctr>[,<table>])                  integer
sc_clr_gpc0(<ctr>[,<table>])                       integer
sc_clr_gpc1(<ctr>[,<table>])                       integer
sc_conn_cnt(<ctr>[,<table>])                       integer
sc_conn_cur(<ctr>[,<table>])                       integer
sc_conn_rate(<ctr>[,<table>])                      integer
sc_get_gpc(<idx>,<ctr>[,<table>])                  integer
sc_get_gpc0(<ctr>[,<table>])                       integer
sc_get_gpc1(<ctr>[,<table>])                       integer
sc_get_gpt(<idx>,<ctr>[,<table>])                  integer
sc_get_gpt0(<ctr>[,<table>])                       integer
sc_glitch_cnt(<ctr>[,<table>])                     integer
sc_glitch_rate(<ctr>[,<table>])                    integer
sc_gpc0_rate(<ctr>[,<table>])                      integer
sc_gpc1_rate(<ctr>[,<table>])                      integer
sc_gpc_rate(<idx>,<ctr>[,<table>])                 integer
sc_http_err_cnt(<ctr>[,<table>])                   integer
sc_http_err_rate(<ctr>[,<table>])                  integer
sc_http_fail_cnt(<ctr>[,<table>])                  integer
sc_http_fail_rate(<ctr>[,<table>])                 integer
sc_http_req_cnt(<ctr>[,<table>])                   integer
sc_http_req_rate(<ctr>[,<table>])                  integer
sc_inc_gpc(<idx>,<ctr>[,<table>])                  integer
sc_inc_gpc0(<ctr>[,<table>])                       integer
sc_inc_gpc1(<ctr>[,<table>])                       integer
sc_kbytes_in(<ctr>[,<table>])                      integer
sc_kbytes_out(<ctr>[,<table>])                     integer
sc_key(<ctr>)                                      any
sc_sess_cnt(<ctr>[,<table>])                       integer
sc_sess_rate(<ctr>[,<table>])                      integer
sc_tracked(<ctr>[,<table>])                        boolean
sc_trackers(<ctr>[,<table>])                       integer
so_id                                              integer
so_name                                            string
src                                                ip
src_bytes_in_rate([<table>])                       integer
src_bytes_out_rate([<table>])                      integer
src_clr_gpc(<idx>[,<table>])                       integer
src_clr_gpc0([<table>])                            integer
src_clr_gpc1([<table>])                            integer
src_conn_cnt([<table>])                            integer
src_conn_cur([<table>])                            integer
src_conn_rate([<table>])                           integer
src_get_gpc(<idx>[,<table>])                       integer
src_get_gpc0([<table>])                            integer
src_get_gpc1([<table>])                            integer
src_get_gpt(<idx>[,<table>])                       integer
src_get_gpt0([<table>])                            integer
src_glitch_cnt([<table>])                          integer
src_glitch_rate([<table>])                         integer
src_gpc0_rate([<table>])                           integer
src_gpc1_rate([<table>])                           integer
src_gpc_rate(<idx>[,<table>])                      integer
src_http_err_cnt([<table>])                        integer
src_http_err_rate([<table>])                       integer
src_http_fail_cnt([<table>])                       integer
src_http_fail_rate([<table>])                      integer
src_http_req_cnt([<table>])                        integer
src_http_req_rate([<table>])                       integer
src_inc_gpc(<idx>[,<table>])                       integer
src_inc_gpc0([<table>])                            integer
src_inc_gpc1([<table>])                            integer
src_is_local                                       boolean
src_kbytes_in([<table>])                           integer
src_kbytes_out([<table>])                          integer
src_port                                           integer
src_sess_cnt([<table>])                            integer
src_sess_rate([<table>])                           integer
src_updt_conn_cnt([<table>])                       integer
srv_id                                             integer
srv_name                                           string
txn.conn_retries                                   integer
txn.redispatched                                   boolean
-------------------------------------------------+-------------

详细列表:

accept_date([<unit>]): integer

accept_date([<unit>]): integer

这是 HAProxy 接收到连接的确切时间(如果系统队列中存在延迟,该时间可能与网络上观察到的时间略有差异)。该时间通常与上游防火墙日志中出现的时间一致。在 HTTP 模式下,accept_date 字段将在连接首次准备好接收新请求时重置(HTTP/1 为上一个响应结束时,HTTP/2 为上一个请求结束后立即)。

返回自纪元以来的秒数。

<unit> 为可选配置,可设置为 “s” 表示秒(默认行为)、“ms” 表示毫秒或 “us” 表示微秒。若指定单位,返回值为整数,表示自纪元以来的秒、毫秒或微秒数。当需要小于秒级的时间分辨率时,该配置非常有用。

bc.timer.connect: integer 建立与服务器的 TCP 连接所花费的总时间。此值等同于日志格式中的 %Tc。单位为毫秒(ms)。更多信息请参见 Section 8.4 “Timing events”

bc_be_queue: 整数,表示在等待目标后端连接槽位时,从队列中取出的流数量。这等价于日志格式中的 %bq。

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” fetch。

bc_err_name: string 返回描述后端内部错误的名称,说明连接失败的原因。该字符串由单个单词组成,当无错误时为空。其对应于 “fc_err_str” 关键字所列表格中的“name”列。

bc_err_str: string 返回描述当前后端发生问题的错误消息,导致连接失败。请参见 “fc_err_str” fetch 以获取完整的错误码及其对应的错误消息列表。

bc_glitches: integer 返回后端连接上计数的协议异常数量。 这些异常通常涵盖协议违规行为,以及可能表明服务器伪造或行为异常的小型异常,这类问题可能在基础设施中引发问题(例如导致连接提前终止,或频繁触发 TLS 重协商)。这些异常也可能由响应过大无法容纳于单个缓冲区引起,从而导致 HTTP 502 错误。理想情况下,该数值应保持为零,尽管若其相对于总请求数量极低,通常也可接受。这些数值通常不应视为警报信号(尤其是数值较小时),但突然上升可能表明存在异常。并非所有协议多路复用器都会测量此指标,若需获取事件的更多详情,唯一方法是启用追踪以捕获所有通信过程。

bc_http_major: integer 返回后端连接的 HTTP 主版本编码,可能为 1(表示 HTTP/0.9 至 HTTP/1.1)或 2(表示 HTTP/2)。请注意,此值基于网络传输编码,而非请求头中所含的版本。

bc_nb_streams: integer 返回后端连接上打开的流的数量。

bc_reused: boolean 如果通过复用的后端连接完成传输,则返回 true。

bc_rtt(<unit>): integer

bc_rtt(<unit>): integer

返回内核测量的后端连接往返时间(RTT)。<unit> 为可选,默认单位为毫秒。<unit> 可设置为 “ms” 表示毫秒,或 “us” 表示微秒。若服务器连接未建立,或连接非 TCP,或操作系统不支持 TCP_INFO(例如 2.4 版本之前的 Linux 内核),则样本提取失败。

bc_rttvar(<unit>): integer

bc_rttvar(<unit>): integer

返回内核测量的后端连接往返时间(RTT)方差。<unit> 为可选,默认单位为毫秒。<unit> 可设置为 “ms” 表示毫秒,或 “us” 表示微秒。若服务器连接未建立,或连接非 TCP,或操作系统不支持 TCP_INFO(例如 Linux 内核版本低于 2.4),则样本提取失败。

bc_settings_streams_limit: 整数 返回后端连接上允许的最大流数。对于 TCP 和 HTTP/1.1 连接,该值始终为 1。对于其他协议,取决于与服务器协商的设置。

bc_src: ip 这是连接在服务器端的源 IP 地址,即 HAProxy 所连接的服务器地址。该字段类型为 IP,适用于 IPv4 和 IPv6 表。在 IPv6 表中,IPv4 地址根据 RFC 4291 映射为其对应的 IPv6 形式。

bc_src_port: integer 返回与连接在服务器端的 TCP 源端口对应的整数值,即 HAProxy 所连接的源端口。

bc_srv_queue: 整数,表示在等待目标服务器连接槽位时,从队列中取出的流数量。这等价于日志格式中的 %sq。

be_id: integer 返回一个整数,表示当前后端的 ID。可在前端的响应中使用,以检查是哪个后端处理了请求。若在前端中使用且未使用后端,则返回当前前端的 ID。该字段也可用于 tcp-check 或 http-check 规则集中。

be_connect_timeout: integer 返回当前后端的连接超时配置值,单位为毫秒。该超时可被“set-timeout”规则覆盖。详见 “cur_connect_timeout”。

be_name: string 返回一个包含当前后端名称的字符串。可在前端中用于响应,以检查是哪个后端处理了请求。若在前端中使用且未使用后端,则返回当前前端的名称。该函数也可用于 tcp-check 或 http-check 规则集中。

be_queue_timeout: integer 返回当前后端队列超时的配置值(单位:毫秒)。该超时可被“set-timeout”规则覆盖。详见 “cur_queue_timeout”。

be_server_timeout: integer 返回当前后端服务器超时的配置值(单位:毫秒)。该超时值可被“set-timeout”规则覆盖。详见 “cur_server_timeout”。

be_tarpit_timeout: integer 返回当前后端队列超时的配置值,单位为毫秒。该超时可被“set-timeout”规则覆盖。详见 “cur_tarpit_timeout”。

be_tunnel_timeout: integer 返回当前后端的隧道超时配置值(单位:毫秒)。该超时可被“set-timeout”规则覆盖。详见 “cur_tunnel_timeout”。

bytes_in: 整数 参见 “req.bytes_in”。

bytes_out: 整数 参见 “res.bytes_in”。

cur_connect_timeout: integer 返回当前流所应用的连接超时时间(单位:毫秒)。默认情况下,该值等于 be_connect_timeout,除非已应用“set-timeout”规则。参见 “be_connect_timeout”。

cur_client_timeout: integer 返回当前流所应用的客户端超时时间(单位:毫秒)。默认情况下,该值等于 fe_client_timeout,除非已应用“set-timeout”规则。参见 “fe_client_timeout”。

cur_queue_timeout: integer 返回当前流所应用的队列超时时间(单位:毫秒)。默认情况下,该值等于 be_queue_timeout,除非已应用“set-timeout”规则。参见 “be_queue_timeout”。

cur_server_timeout: integer 返回当前流所应用的服务器超时时间(单位:毫秒)。默认情况下,该值等于 be_server_timeout,除非已应用“set-timeout”规则。参见 “be_server_timeout”。

cur_tarpit_timeout: integer 返回当前流应用的 tarpit 超时时间(单位:毫秒)。默认情况下,该值等于 fe_tarpit_timeout 或 be_tarpit_timeout,除非已应用“set-timeout”规则。参见 “fe_tarpit_timeout” 和 “be_tarpit_timeout”。

cur_tunnel_timeout: integer 返回当前流所应用的隧道超时时间(单位:毫秒)。默认情况下,该值等于 be_tunnel_timeout,除非已应用“set-timeout”规则。参见 “be_tunnel_timeout”。

dst: ip 这是客户端侧连接的目标 IP 地址,即客户端所连接的地址。任何 tcp/http 规则均可修改此地址。在透明模式下运行时,该字段可能具有实用价值。其类型为 IP,适用于 IPv4 和 IPv6 表。在 IPv6 表中,IPv4 地址根据 RFC 4291 映射为对应的 IPv6 形式。当入站连接经过涉及连接跟踪的地址转换或重定向时,将报告重定向前的原始目标地址。在 Linux 系统上,若设置了 nf_conntrack_tcp_loose sysctl,源地址与目标地址偶尔可能出现颠倒,因为延迟响应可能重新打开已超时的连接,并导致源与目标角色被误判。

dst_conn: integer 返回一个整数值,表示当前在相同套接字上建立的连接数,包括正在评估的连接。该值通常用于 ACL,也可用于将信息传递至服务器的 HTTP 头或日志中。可用于在强制阻断前返回抱歉页面,或在套接字被认为已饱和时,使用特定后端处理新请求。此功能可为不同监听端口或地址分配不同的限制。参见 “fe_conn” 和 “be_conn” 获取。

dst_is_local:boolean 如果入站连接的目标地址是系统本地地址,则返回 true;如果该地址在系统上不存在,表示该连接在透明模式下被拦截,则返回 false。此判断可用于默认对转发流量应用某些规则,而对目标为机器真实地址的流量应用其他规则。例如,统计信息页面可仅在此地址上提供,或 SSH 访问可被本地重定向。请注意,该检查涉及若干系统调用,因此建议每个连接仅执行一次。

dst_port: integer 返回与客户端侧连接的目标 TCP 端口对应的整数值,即客户端所连接的端口。任何 TCP 或 HTTP 规则均可修改此端口。在透明模式下运行时,可用于为整个应用会话动态分配端口,将所有用户绑定至同一服务器,或通过 HTTP 头将目标端口信息传递给服务器。

fc.timer.handshake: 整数 接受 TCP 连接并完成低层协议握手的总时间。当前支持的协议包括 proxy-protocol 和 SSL。此指标等同于日志格式中的 %Th。单位为毫秒(ms)。更多信息请参见 Section 8.4 “Timing events”

fc.timer.total: 整数 代理从接收流到两端均关闭的总持续时间。这等同于日志格式中的 %Tt。单位为毫秒(ms)。更多信息请参见 第 8.4 节 “时间事件”

fc_dst: ip 这是客户端侧连接的原始目标 IP 地址。仅“tcp-request connection”规则可修改此地址。详情请参见“dst”。

fc_dst_is_local: 布尔类型 若入站连接的原始目标地址属于本机系统,则返回 true;若该地址在系统中不存在,则返回 false。详见 “dst_is_local”。

fc_dst_port: 整数 返回与客户端侧连接的原始目标 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: 整数 若连接不是 TCP 或 QUIC,样本提取失败。 对于 QUIC,返回客户端连接丢失的 QUIC 数据包数量。 对于 TCP,返回内核为客户端连接测量的丢失计数。 若服务器连接未建立,或操作系统不支持 TCP_INFO(例如 2.4 版本之前的 Linux 内核),样本提取失败。

fc_nb_streams: 整数 返回前端连接上打开的流的数量。

fc_pp_authority: 字符串 返回客户端在 PROXY 协议中发送的第一个 authority TLV,若存在。

fc_pp_tlv(<id>): string

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 ID 的情况下遍历所有匹配的 TLV。遍历顺序与 PROXY 协议头中的位置一致。然而,应尽量避免依赖重复的 TLV,因为 TLV 通常被视为唯一。通常情况下,发现重复的 TLV ID 表明 PROXY 协议头的发送方存在错误。

fc_pp_unique_id: string 返回客户端在 PROXY 协议中发送的第一个唯一 ID TLV,若有。

fc_rcvd_proxy: boolean 若客户端通过 PROXY 协议发起连接,则返回 true。

fc_reordering: 整数 若连接不是 TCP 或 QUIC,样本提取失败。对于 QUIC,返回客户端连接的 QUIC 重排序数据包数量。对于 TCP,返回内核测量的客户端连接的重排序计数器。若服务器连接未建立,或操作系统不支持 TCP_INFO(例如 2.4 版本之前的 Linux 内核),样本提取失败。

fc_retrans: integer 返回内核为客户端连接测量的重传次数。如果服务器连接未建立、连接不是 TCP 类型,或操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。

fc_rtt(<unit>): integer

fc_rtt(<unit>): integer

如果连接不是 TCP 或 QUIC,则样本提取失败。对于 QUIC,返回客户端连接的平滑往返时间。对于 TCP,返回内核测量的客户端连接的往返时间(RTT)。<unit> 为可选项,默认单位为毫秒。<unit> 可设置为 “ms” 表示毫秒,或 “us” 表示微秒。如果服务器连接未建立,或操作系统不支持 TCP_INFO(例如 Linux 内核版本早于 2.4),则样本提取失败。

fc_rttvar(<unit>): integer

fc_rttvar(<unit>): integer

如果连接不是 TCP 或 QUIC,则样本提取失败。对于 QUIC,返回客户端连接的平滑往返时间方差。对于 TCP,返回内核测量的客户端连接的往返时间(RTT)方差。<unit> 为可选参数,默认单位为毫秒。<unit> 可设置为 “ms” 表示毫秒,或 “us” 表示微秒。如果服务器连接未建立,或操作系统不支持 TCP_INFO(例如,2.4 版本之前的 Linux 内核),则样本提取失败。

fc_sacked: 整数 返回由内核测量的客户端连接的丢弃计数器值。如果服务器连接未建立、连接不是 TCP 类型,或操作系统不支持 TCP_INFO(例如,Linux 内核版本早于 2.4),则样本提取失败。

fc_saved_syn: binary 返回系统在建立入站连接过程中保存的 SYN 数据包副本。这要求“bind”行中包含“tcp-ss”选项,且运行的 Linux 内核版本不低于 4.3。当“tcp-ss”设置为 1 时,仅包含 IP 和 TCP 头。当“tcp-ss”设置为 2 时,IP 头之前还包含以太网头,可用于控制或记录源 MAC 地址或 VLAN 等信息。请注意,系统不保证一定会保存 SYN 数据包。例如,若使用 SYN Cookie 机制,SYN 数据包不会被保存,连接将在匹配的 ACK 数据包上建立。此外,系统不保证在首次读取后仍保留该副本。因此,强烈建议在“tcp-request connection”规则中将该样本复制到“sess”作用域的变量中,并仅使用该变量进行后续操作。值得注意的是,在环回接口上,系统会构造一个 14 字节的虚拟以太网头,其中源地址和目的地址均为零,仅协议字段被设置。在调试过程中,可方便地使用“hex”转换器将此类样本转换为十六进制格式。示例(字段手动分隔并注释如下):

frontend test
    mode http
    bind:::4445 tcp-ss 2
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain \
                 lf-string "%[var(sess.syn),hex]\n"

$ curl '0:4445'
000000000000 000000000000 0800 \  # MAC_DST MAC_SRC PROTO=IPv4
4500003C0A65400040063255       \  # IPv4 header, proto=6 (TCP)
7F000001 7F000001              \  # IP_SRC=127.0.0.1 IP_DST=127.0.0.1
E1F2 115D 01AF4E3E 00000000    \  # TCP_SPORT=57842 TCP_DPORT=4445, SEQ
A0 02 FFD7 FE300000            \  # OPT_LEN=20 TCP_FLAGS=SYN WIN=65495
0204FFD70402080A01C2A71A0000000001030307 # MSS=65495, TS, SACK, WSCALE 7

$ curl '[::1]:4445'
000000000000 000000000000 86DD   \ # MAC_DST MAC_SRC PROTO=IPv6
6008018F00280640                 \ # IPv6 header, proto=6 (TCP)
00000000000000000000000000000001 \ # SRC=::1
00000000000000000000000000000001 \ # DST=::1
9758 115D B5511F5D 00000000      \ # TCP_SPORT=38744 TCP_DPORT=4445, SEQ
A0 02 FFC4 00300000              \  # OPT_LEN=20 TCP_FLAGS=SYN WIN=65476
0204FFC40402080A9C231D680000000001030307 # MSS=65476, TS, SACK, WSCALE 7

“bytes()” 转换器有助于从数据包中提取特定字段。be2dec() 也允许读取数据块并以整数形式输出。如需更精确的提取,请参阅 “eth.XXX” 转换器。

IPv4 输入示例:

frontend test
    mode http
    bind:4445 tcp-ss 2
    tcp-request connection set-var(sess.syn) fc_saved_syn
    http-request return status 200 content-type text/plain lf-string \
                 "mac_dst=%[var(sess.syn),eth.dst,hex] \
                  mac_src=%[var(sess.syn),eth.src,hex] \
                  proto=%[var(sess.syn),eth.proto,bytes(6),be2hex(,2)] \
                  ipv4h=%[var(sess.syn),eth.data,bytes(0,12),hex] \
                  ipv4_src=%[var(sess.syn),eth.data,ip.src] \
                  ipv4_dst=%[var(sess.syn),eth.data,ip.dst] \
                  tcp_spt=%[var(sess.syn),eth.data,ip.data,tcp.src] \
                  tcp_dpt=%[var(sess.syn),eth.data,ip.data,tcp.dst] \
                  tcp_win=%[var(sess.syn),eth.data,ip.data,tcp.win] \
                  tcp_opt=%[var(sess.syn),eth.data,ip.data,bytes(20),hex]\n"

$ curl '0:4445'
mac_dst=000000000000 mac_src=000000000000 proto=0800 \
ipv4h=4500003CC9B7400040067302 ipv4_src=127.0.0.1 ipv4_dst=127.0.0.1 \
tcp_spt=43970 tcp_dpt=4445 tcp_win=65495 \
tcp_opt=0204FFD70402080A01DC0D410000000001030307

另请参见 “set-var” 动作,以及 “be2dec”、“bytes”、“hex”、“eth.XXX”、“ip.XXX” 和 “tcp.XXX” 转换器。

fc_settings_streams_limit: 整数 返回前端连接上允许的最大流数。对于 TCP 和 HTTP/1.1 连接,该值始终为 1。对于其他协议,取决于与客户端协商的设置。

fc_src: ip 这是连接在客户端一侧的原始源 IP 地址。仅“tcp-request connection”规则可修改此地址。详情参见“src”。

fc_src_is_local: 布尔值 用于判断传入连接的源地址是否为系统本地地址,若源地址在系统中不存在则返回 false。详情请参见 “src_is_local”。

fc_src_port: integer 返回与客户端侧连接的 TCP 源端口相对应的整数值。仅“tcp-request connection”规则可修改此地址。详情参见“src-port”。

fc_unacked: 整数 返回由内核测量的客户端连接的未确认(unacked)计数器值。 若服务器连接未建立、连接非 TCP 协议,或操作系统不支持 TCP_INFO(例如 2.4 版本之前的 Linux 内核),则样本提取失败。

fe_client_timeout: integer 返回当前前端客户端超时的配置值,单位为毫秒。该超时值可被“set-timeout”规则覆盖。

fe_defbe: string 返回一个字符串,其中包含前端的默认后端名称。可在前端中使用,以检查请求默认将由哪个后端处理。

fe_id: integer 返回一个整数,其中包含当前前端的 ID。该值可在后端中使用,以检查请求源自哪个前端,或用于将通过同一前端访问的全部用户绑定到同一台服务器。

fe_name: string 返回一个包含当前前端名称的字符串。可在后端中使用,以检查其调用来源的前端,或确保通过同一前端访问的所有用户被绑定到同一台服务器。

fe_tarpit_timeout: integer 返回当前前端的 tarpit 超时配置值,单位为毫秒。该超时可被“set-timeout”规则覆盖。

req.bytes_in: integer 此值返回从客户端接收的字节数。该数值对应 HAProxy 实际接收到的数据量,包括部分头信息和内部编码开销。请求压缩不会影响此处报告的数值。

req.bytes_out: 整数 此值返回发送至服务器的字节数。该数值对应 HAProxy 实际发送的数据量,包括部分头信息和内部编码开销。请求压缩会影响此处报告的数值。

res.bytes_in: 整数 此值返回从服务器接收到的字节数。该数值对应 HAProxy 实际接收到的数据量,包括部分头信息和内部编码开销。响应压缩不会影响此处报告的数值。

res.bytes_out: integer 此值返回发送给客户端的字节数。该数值对应 HAProxy 发送的数据量,包括部分头信息和内部编码开销。响应压缩会影响此处报告的数值。

res.timer.data: integer,表示响应负载的总传输时间,直至最后一个字节发送至客户端。在 HTTP 中,该时间从最后一个响应头之后(即 Tr 之后)开始计算。此值等同于日志格式中的 %Td,单位为毫秒(ms)。更多信息请参见 第 8.4 节 “时间事件”

sc_bytes_in_rate(<ctr>[,<table>]): integer

sc_bytes_in_rate(<ctr>[,<table>]): integer
sc0_bytes_in_rate([<table>]): integer
sc1_bytes_in_rate([<table>]): integer
sc2_bytes_in_rate([<table>]): integer

返回当前跟踪计数器的客户端到服务器字节速率平均值,单位为字节/周期,周期长度由表中配置的值决定。参见 “table_bytes_in_rate”。

sc_bytes_out_rate(<ctr>[,<table>]): integer

sc_bytes_out_rate(<ctr>[,<table>]): integer
sc0_bytes_out_rate([<table>]): integer
sc1_bytes_out_rate([<table>]): integer
sc2_bytes_out_rate([<table>]): integer

返回当前跟踪计数器的平均服务器到客户端字节速率,单位为字节,按表中配置的周期计算。另请参见 “table_bytes_out_rate”。

sc_clr_gpc(<idx>,<ctr>[,<table>]): integer

sc_clr_gpc(<idx>,<ctr>[,<table>]): integer

清除当前代理的粘性表中指定 ID <ctr> 的跟踪计数器关联数组在索引 <idx> 处的通用计数器值,或从指定的粘性表 <table> 中清除,并返回其先前值。<idx> 为 0 至 99 之间的整数,<ctr> 为 0 至 2 之间的整数。首次调用前,存储值为零,因此首次调用将始终返回零。此获取操作仅适用于 ‘gpc’ 数组 data_type(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ data_type)。

sc_clr_gpc0(<ctr>[,<table>]): integer

sc_clr_gpc0(<ctr>[,<table>]): integer
sc0_clr_gpc0([<table>]): integer
sc1_clr_gpc0([<table>]): integer
sc2_clr_gpc0([<table>]): integer

清除当前跟踪计数器关联的第一个通用计数器,并返回其先前的值。首次调用前,存储的值为零,因此首次调用将始终返回零。通常作为表达式中的第二个 ACL 使用,以便在第一个 ACL 验证通过时标记连接:

示例:

# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse sc0_http_req_rate gt 10
acl kill  sc0_inc_gpc0 gt 5
acl save  sc0_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill

sc_clr_gpc1(<ctr>[,<table>]): integer

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>]): integer

sc_conn_cnt(<ctr>[,<table>]): integer
sc0_conn_cnt([<table>]): integer
sc1_conn_cnt([<table>]): integer
sc2_conn_cnt([<table>]): integer

返回当前跟踪计数器中累计的入站连接数量。另请参见 “table_conn_cnt”。

sc_conn_cur(<ctr>[,<table>]): integer

sc_conn_cur(<ctr>[,<table>]): integer
sc0_conn_cur([<table>]): integer
sc1_conn_cur([<table>]): integer
sc2_conn_cur([<table>]): integer

返回当前正在跟踪相同计数器的并发连接数量。该数值在开始跟踪时自动递增,在停止跟踪时自动递减。另请参见 “table_conn_cur”。

sc_conn_rate(<ctr>[,<table>]): integer

sc_conn_rate(<ctr>[,<table>]): integer
sc0_conn_rate([<table>]): integer
sc1_conn_rate([<table>]): integer
sc2_conn_rate([<table>]): integer

返回当前跟踪计数器的平均连接速率,单位为表格中配置周期内的连接数量。参见 “table_conn_rate”。

sc_get_gpc(<idx>,<ctr>[,<table>]): integer

sc_get_gpc(<idx>,<ctr>[,<table>]): integer

返回代理中索引 <idx> 处的通用计数器(GPC)数组值,该值与当前代理的 stick-table 中 ID <ctr> 的跟踪计数器,或指定 stick-table <table> 关联。<idx> 为 0 至 99 之间的整数,<ctr> 为 0 至 2 之间的整数。若该索引处未存储 gpc 值,则返回零。此获取操作仅适用于 ‘gpc’ 数组数据类型(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ 数据类型)。参见 “table_gpc” 和 “sc_inc_gpc”。

sc_get_gpc0(<ctr>[,<table>]): integer

sc_get_gpc0(<ctr>[,<table>]): integer
sc0_get_gpc0([<table>]): integer
sc1_get_gpc0([<table>]): integer
sc2_get_gpc0([<table>]): integer

返回当前跟踪计数器关联的第一个通用计数器的值。 另请参阅 “table_gpc0” 和 sc/sc0/sc1/sc2_inc_gpc0。

sc_get_gpc1(<ctr>[,<table>]): integer

sc_get_gpc1(<ctr>[,<table>]): integer
sc0_get_gpc1([<table>]): integer
sc1_get_gpc1([<table>]): integer
sc2_get_gpc1([<table>]): integer

返回当前跟踪计数器关联的第二个通用计数器的值。参见 “table_gpc1” 和 sc/sc0/sc1/sc2_inc_gpc1。

sc_get_gpt(<idx>,<ctr>[,<table>]): integer

sc_get_gpt(<idx>,<ctr>[,<table>]): integer

返回索引 <idx> 处与 ID <ctr> 关联的计数器跟踪数组中第一个通用标签(GPT)的值,该值来自当前代理的 stick-table 或指定的 stick-table <table>。<idx> 为 0 至 99 之间的整数,<ctr> 为 0 至 2 之间的整数。若该索引处未存储 GPT,则返回零。此获取操作仅适用于 ‘gpt’ 数组数据类型(不适用于旧版 ‘gpt0’ 数据类型)。参见 “table_gpt”。

sc_get_gpt0(<ctr>[,<table>]): integer

sc_get_gpt0(<ctr>[,<table>]): integer
sc0_get_gpt0([<table>]): integer
sc1_get_gpt0([<table>]): integer
sc2_get_gpt0([<table>]): integer

返回当前跟踪计数器关联的第一个通用标签的值。参见 “table_gpt0”。

sc_glitch_cnt(<ctr>[,<table>]): integer

sc_glitch_cnt(<ctr>[,<table>]): integer
sc0_glitch_cnt([<table>]): integer
sc1_glitch_cnt([<table>]): integer
sc2_glitch_cnt([<table>]): integer

返回当前跟踪计数器关联的前端连接中观察到的累积连接异常次数。通常,这些异常会导致请求或连接被中止,因此返回的数值通常对应于过去的连接。该值并无好坏之分,但质量较差的客户端可能每连接偶尔引发数次异常,而极不正常或恶意的客户端可能在短时间内导致单个连接上累计数千次事件。有关当前连接受影响的异常数量,请参见 fc_glitches;按源地址查询异常次数,请参见 src_glitch_cnt;有关事件发生率的度量,请参见 sc_glitch_rate。

sc_glitch_rate(<ctr>[,<table>]): integer

sc_glitch_rate(<ctr>[,<table>]): integer
sc0_glitch_rate([<table>]): integer
sc1_glitch_rate([<table>]): integer
sc2_glitch_rate([<table>]): integer

返回当前跟踪计数器期间,前端连接异常事件的平均发生速率,单位为配置表中设定周期内的事件数量。通常此类异常会导致请求或连接被中止,因此返回的值通常与历史连接相关。该值并无好坏之分,但质量较差的客户端可能每连接偶尔引发数次异常,故通常预期该速率为较低水平。然而,极不正常或恶意的客户端可能在每连接中迅速引发数千次事件,从而维持较高的速率。参见 “table_glitch_rate” 和 “sc_glitch_cnt”。

sc_gpc_rate(<idx>,<ctr>[,<table>]): integer

sc_gpc_rate(<idx>,<ctr>[,<table>]): integer

返回当前代理的表或指定 stick-table <table> 中,ID <ctr> 关联的跟踪计数器数组中索引 <idx> 处的通用计数器(General Purpose Counter)的平均增量速率。该值报告了在配置周期内 gpc 计数器被增量的频率。<idx> 为 0 至 99 之间的整数,<ctr> 为 0 至 2 之间的整数。请注意,‘gpc_rate’ 计数器数组必须存储在 stick-table 中才会有返回值,因为 ‘gpc’ 仅保存事件计数。此获取操作仅适用于 ‘gpc_rate’ 数组 data_type(不适用于旧版 ‘gpc0_rate’ 及 ‘gpc1_rate’ data_type)。另见 “table_gpc_rate”、“sc_get_gpc” 和 “sc_inc_gpc”。

sc_gpc0_rate(<ctr>[,<table>]): integer

sc_gpc0_rate(<ctr>[,<table>]): integer
sc0_gpc0_rate([<table>]): integer
sc1_gpc0_rate([<table>]): integer
sc2_gpc0_rate([<table>]): integer

返回与当前跟踪计数器关联的第一个通用计数器(General Purpose Counter)的平均增量速率。该值报告了在配置周期内 gpc0 计数器的增量频率。参见 src_gpc0_rate、sc/sc0/sc1/sc2_get_gpc0 以及 sc/sc0/sc1/sc2_inc_gpc0。

请注意,“gpc0_rate” 计数器必须存储在 stick-table 中,才会有返回值,因为 “gpc0” 仅保存事件计数。

sc_gpc1_rate(<ctr>[,<table>]): integer

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” 计数器必须存储在 stick-table 中,才会有返回值,因为 “gpc1” 仅保存事件计数。

sc_http_err_cnt(<ctr>[,<table>]): integer

sc_http_err_cnt(<ctr>[,<table>]): integer
sc0_http_err_cnt([<table>]): integer
sc1_http_err_cnt([<table>]): integer
sc2_http_err_cnt([<table>]): integer

返回当前跟踪计数器的累计 HTTP 错误数量。该数值包含请求错误以及 4xx 错误响应。另请参见 “table_http_err_cnt”。

sc_http_err_rate(<ctr>[,<table>]): integer

sc_http_err_rate(<ctr>[,<table>]): integer
sc0_http_err_rate([<table>]): integer
sc1_http_err_rate([<table>]): integer
sc2_http_err_rate([<table>]): integer

返回当前跟踪计数器的 HTTP 错误平均速率,单位为配置表中设定周期内的错误数量。该指标包含请求错误和 4xx 错误响应。参见 src_http_err_rate。

sc_http_fail_cnt(<ctr>[,<table>]): integer

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 状态码。另请参阅 “table_http_fail_cnt”。

sc_http_fail_rate(<ctr>[,<table>]): integer

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 状态码。参见 “table_http_fail_rate”。

sc_http_req_cnt(<ctr>[,<table>]): integer

sc_http_req_cnt(<ctr>[,<table>]): integer
sc0_http_req_cnt([<table>]): integer
sc1_http_req_cnt([<table>]): integer
sc2_http_req_cnt([<table>]): integer

返回当前跟踪计数器累计的 HTTP 请求数。包括所有已启动的请求,无论是否有效。参见 src_http_req_cnt。

sc_http_req_rate(<ctr>[,<table>]): integer

sc_http_req_rate(<ctr>[,<table>]): integer
sc0_http_req_rate([<table>]): integer
sc1_http_req_rate([<table>]): integer
sc2_http_req_rate([<table>]): integer

返回当前跟踪计数器的 HTTP 请求平均速率,单位为每周期内的请求数量,该周期由表中配置的值决定。此值包含所有已启动的请求,无论其是否有效。 参见 src_http_req_rate。

sc_inc_gpc(<idx>,<ctr>[,<table>]): integer

sc_inc_gpc(<idx>,<ctr>[,<table>]): integer

将指定 ID <ctr> 的跟踪计数器关联的数组中索引 <idx> 处的通用计数器值递增,并返回其新值。该操作可从当前代理的粘性表或指定的粘性表 <table> 中执行。<idx> 为 0 至 99 之间的整数,<ctr> 为 0 至 2 之间的整数。首次调用前,存储值为零,因此首次调用将使其增至 1 并返回 1。此获取操作仅适用于 ‘gpc’ 数组 data_type(不适用于旧版 ‘gpc0’ 或 ‘gpc1’ data_type)。

sc_inc_gpc0(<ctr>[,<table>]): integer

sc_inc_gpc0(<ctr>[,<table>]): integer
sc0_inc_gpc0([<table>]): integer
sc1_inc_gpc0([<table>]): integer
sc2_inc_gpc0([<table>]): integer

递增与当前跟踪计数器关联的第一个通用计数器,并返回其新值。首次调用前,存储的值为零,因此首次调用将使其增至 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

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>]): integer

sc_kbytes_in(<ctr>[,<table>]): integer
sc0_kbytes_in([<table>]): integer
sc1_kbytes_in([<table>]): integer
sc2_kbytes_in([<table>]): integer

返回当前跟踪计数器中客户端到服务器的数据总量,单位为千字节。测试当前基于 32 位整数执行,这将数值上限限制为 4 太字节。参见 “table_kbytes_in”。

sc_kbytes_out(<ctr>[,<table>]): integer

sc_kbytes_out(<ctr>[,<table>]): integer
sc0_kbytes_out([<table>]): integer
sc1_kbytes_out([<table>]): integer
sc2_kbytes_out([<table>]): integer

返回当前跟踪计数器中服务器到客户端的数据总量,单位为千字节。测试当前基于 32 位整数执行,因此数值上限为 4 太字节。参见 “table_kbytes_out”。

sc_key(<ctr>): any sc0_key: any sc1_key: any sc2_key: any 返回用于匹配当前跟踪计数器的键。

sc_sess_cnt(<ctr>[,<table>]): integer

sc_sess_cnt(<ctr>[,<table>]): integer
sc0_sess_cnt([<table>]): integer
sc1_sess_cnt([<table>]): integer
sc2_sess_cnt([<table>]): integer

返回从当前跟踪计数器中累计的已转换为会话的入站连接数量,即被“tcp-request connection”规则接受的连接。后端记录的会话数可能多于连接数,因为若客户端与后端之间通过 HTTP 持久连接进行通信,单个连接可能产生多个后端会话。参见 “table_sess_cnt”。

sc_sess_rate(<ctr>[,<table>]): integer

sc_sess_rate(<ctr>[,<table>]): integer
sc0_sess_rate([<table>]): integer
sc1_sess_rate([<table>]): integer
sc2_sess_rate([<table>]): integer

返回当前跟踪计数器的平均会话速率,单位为表格中配置周期内的会话数量。会话指成功通过早期“tcp-request connection”规则的连接。后端统计的会话数可能多于连接数,因为若客户端与后端之间通过连接执行了部分 HTTP 持久连接,单个连接可产生多个后端会话。参见 “table_sess_rate”。

sc_tracked(<ctr>[,<table>]): boolean

sc_tracked(<ctr>[,<table>]): boolean
sc0_tracked([<table>]): boolean
sc1_tracked([<table>]): boolean
sc2_tracked([<table>]): boolean

如果当前会话正在跟踪指定的会话计数器,则返回 true。 这在决定是否将某些值设置到传递给服务器的头中时可能有用。

sc_trackers(<ctr>[,<table>]): integer

sc_trackers(<ctr>[,<table>]): integer
sc0_trackers([<table>]): integer
sc1_trackers([<table>]): integer
sc2_trackers([<table>]): integer

返回当前正在跟踪相同计数器的并发连接数量。当开始跟踪时,该数值自动递增;当停止跟踪时,自动递减。与 sc0_conn_cur 不同,它不依赖任何存储信息,而是基于表的引用计数(即 CLI 中 “show table” 命令返回的“use”值)。在某些情况下,该值更适合用于七层跟踪。例如,可用于告知服务器来自特定地址的并发连接数量。

so_id: integer 返回一个整数,其中包含当前监听套接字的 ID。在涉及多个“bind”指令的前端中,或需将通过同一套接字连接的所有用户绑定到同一服务器时,该值非常有用。

so_name: string 返回一个字符串,其中包含当前监听套接字的名称,该名称由 “bind” 行上的 name 参数定义。其用途与 so_id 相同,但使用字符串而非整数。

src: 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,源地址与目标地址偶尔可能出现颠倒,因为延迟响应可能重新打开已超时的连接,并导致源与目标角色互换。

示例:

# add an HTTP header in requests with the originating address' country
http-request set-header X-Country %[src,map_ip(geoip.lst)]

src_bytes_in_rate([<table>]): integer

src_bytes_in_rate([<table>]): integer

与 “table_bytes_in_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_bytes_in_rate([<table>])

src_bytes_out_rate([<table>]): integer

src_bytes_out_rate([<table>]): integer

与 “table_bytes_out_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_bytes_out_rate([<table>])

src_clr_gpc(<idx>[,<table>]): integer

src_clr_gpc(<idx>[,<table>]): integer

与 “table_clr_gpc” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_clr_gpc(<idx>[,<table>])

src_clr_gpc0([<table>]): integer

src_clr_gpc0([<table>]): integer

与 “table_clr_gpc0” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_clr_gpc0([<table>])

src_clr_gpc1([<table>]): integer

src_clr_gpc1([<table>]): integer

与 “table_clr_gpc1” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_clr_gpc1([<table>])

src_conn_cnt([<table>]): integer

src_conn_cnt([<table>]): integer

与 “table_conn_cnt” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_conn_cnt([<table>])

src_conn_cur([<table>]): integer

src_conn_cur([<table>]): integer

与 “table_conn_cur” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_conn_cur([<table>])

src_conn_rate([<table>]): integer

src_conn_rate([<table>]): integer

与 “table_conn_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_conn_rate([<table>])

src_get_gpc(<idx>[,<table>]): integer

src_get_gpc(<idx>[,<table>]): integer

与 “table_gpc” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpc(<idx>[,<table>])

src_get_gpc0([<table>]): integer

src_get_gpc0([<table>]): integer

与 “table_gpc0” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpc0([<table>])

src_get_gpc1([<table>]): integer

src_get_gpc1([<table>]): integer

与 “table_gpc1” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpc1([<table>])

src_get_gpt(<idx>[,<table>]): integer

src_get_gpt(<idx>[,<table>]): integer

与 “table_gpt” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpt(<idx>[,<table>])

src_get_gpt0([<table>]): integer

src_get_gpt0([<table>]): integer

与 “table_gpt0” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpt0([<table>])

src_glitch_cnt([<table>]): integer

src_glitch_cnt([<table>]): integer

与 “table_glitch_cnt” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_glitch_cnt([<table>])

src_glitch_rate([<table>]): integer

src_glitch_rate([<table>]): integer

与 “table_glitch_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_glitch_rate([<table>])

src_gpc_rate(<idx>[,<table>]): integer

src_gpc_rate(<idx>[,<table>]): integer

与 “table_gpc_rate” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_gpc_rate(<idx>[,<table>])

src_gpc0_rate([<table>]): integer

src_gpc0_rate([<table>]): integer

与 “table_gpc0_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpc0_rate([<table>])

src_gpc1_rate([<table>]): integer

src_gpc1_rate([<table>]): integer

与 “table_gpc1_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_gpc1_rate([<table>])

src_http_err_cnt([<table>]): integer

src_http_err_cnt([<table>]): integer

与 “table_http_err_cnt” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_http_err_cnt([<table>])

src_http_err_rate([<table>]): integer

src_http_err_rate([<table>]): integer

与 “table_http_err_rate” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_http_err_rate([<table>])

src_http_fail_cnt([<table>]): integer

src_http_fail_cnt([<table>]): integer

与 “table_http_fail_cnt” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_http_fail_cnt([<table>])

src_http_fail_rate([<table>]): integer

src_http_fail_rate([<table>]): integer

与 “table_http_fail_rate” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_http_fail_rate([<table>])

src_http_req_cnt([<table>]): integer

src_http_req_cnt([<table>]): integer

与 “table_http_req_cnt” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_http_req_cnt([<table>])

src_http_req_rate([<table>]): integer

src_http_req_rate([<table>]): integer

与 “table_http_req_rate” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_http_req_rate([<table>])

src_inc_gpc(<idx>[,<table>]): integer

src_inc_gpc(<idx>[,<table>]): integer

与 “src_inc_gpc” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_inc_gpc(<idx>[,<table>])

src_inc_gpc0([<table>]): integer

src_inc_gpc0([<table>]): integer

与 “src_inc_gpc0” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_inc_gpc0([<table>])

src_inc_gpc1([<table>]): integer

src_inc_gpc1([<table>]): integer

与 “src_inc_gpc1” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_inc_gpc1([<table>])

src_is_local: boolean 如果传入连接的源地址是系统本地地址,则返回 true;如果该地址在系统中不存在,即来自远程机器,则返回 false。请注意,UNIX 地址被视为本地地址。可以根据客户端来源应用某些访问限制(例如,要求远程机器进行身份认证或使用 HTTPS)。请注意,该检查涉及若干系统调用,因此建议每连接仅执行一次。

src_kbytes_in([<table>]): integer

src_kbytes_in([<table>]): integer

与 “table_kbytes_in” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_kbytes_in([<table>])

src_kbytes_out([<table>]): integer

src_kbytes_out([<table>]): integer

与 “table_kbytes_out” 转换器相同,但键设置为入站连接的源地址。

等价于:src, table_kbytes_out([<table>])

src_port: integer 返回与客户端侧连接的 TCP 源端口对应的整数值,即客户端连接所使用的端口。任何 TCP 或 HTTP 规则均可修改此端口。由于现代协议对源端口的关注度已大幅降低,该函数的使用范围非常有限。

src_sess_cnt([<table>]): integer

src_sess_cnt([<table>]): integer

与 “table_sess_cnt” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_sess_cnt([<table>])

src_sess_rate([<table>]): integer

src_sess_rate([<table>]): integer

与 “table_sess_rate” 转换器相同,但键设置为传入连接的源地址。

等价于:src, table_sess_rate([<table>])

src_updt_conn_cnt([<table>]): integer

src_updt_conn_cnt([<table>]): integer

在当前代理的粘性表或指定的粘性表中,创建或更新与传入连接的源地址关联的条目。该表必须配置为存储 “conn_cnt” 数据类型,否则匹配将被忽略。当前计数加一,并刷新过期计时器。返回更新后的计数,因此该匹配不会返回零。此动作曾用于根据源地址拒绝服务滥用行为。请注意:建议在 “tcp-request” 规则中使用更完整的 “track-sc*” 动作替代。

示例:

# This frontend limits incoming SSH connections to 3 per 10 second for
# each source address, and rejects excess connections until a 10 second
# silence is observed. At most 20 addresses are tracked.
listen ssh
    bind:22
    mode tcp
    maxconn 100
    stick-table type ip size 20 expire 10s store conn_cnt
    tcp-request content reject if { src_updt_conn_cnt gt 3 }
    server local 127.0.0.1:22

srv_id: integer 返回一个整数,其中包含处理响应时服务器的 ID。虽然该字段几乎仅用于 ACL,但也可用于日志记录或调试。它同样可用于 tcp-check 或 http-check 规则集。

srv_name: string 返回一个字符串,其中包含处理响应时服务器的名称。虽然该字段几乎仅用于 ACL,但也可用于日志记录或调试。它同样可用于 tcp-check 或 http-check 规则集中。

txn.conn_retries: 整数 返回此流在尝试连接服务器时经历的连接重试次数。该值在连接未完全建立期间可能发生变化。对于 HTTP 连接,该值可能受 L7 重试影响。

txn.redispatched: boolean 若连接在重试过程中根据“option redispatch”配置发生重分派,则返回 true。该值在连接未完全建立前可能发生变化。对于 HTTP 连接,该值可能受 L7 重试影响。

7.3.4. 在第 5 层获取样本

第五层通常仅指会话层,而在 HAProxy 中,该层对应于所有连接握手完成后但尚未提供任何内容时的会话状态。此处描述的获取方法可应用于最低至 “tcp-request content” 规则集,除非其依赖未来信息。这类方法通常包括 SSL 协商的结果。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                          output type
-------------------------------------------------+-------------
51d.all(<prop>[,<prop>*])                          string
bs.aborted                                         boolean
bs.debug_str([<bitmap>])                           string
bs.id                                              integer
bs.rst_code                                        integer
fs.aborted                                         boolean
fs.debug_str([<bitmap>])                           string
fs.id                                              integer
fs.rst_code                                        integer
ssl_bc                                             boolean
ssl_bc_alg_keysize                                 integer
ssl_bc_alpn                                        string
ssl_bc_cipher                                      string
ssl_bc_client_early_traffic_secret                 string
ssl_bc_client_handshake_traffic_secret             string
ssl_bc_client_random                               binary
ssl_bc_client_traffic_secret_0                     string
ssl_bc_curve                                       string
ssl_bc_early_exporter_secret                       string
ssl_bc_err                                         integer
ssl_bc_err_str                                     string
ssl_bc_exporter_secret                             string
ssl_bc_is_resumed                                  boolean
ssl_bc_npn                                         string
ssl_bc_protocol                                    string
ssl_bc_server_handshake_traffic_secret             string
ssl_bc_server_random                               binary
ssl_bc_server_traffic_secret_0                     string
ssl_bc_session_id                                  binary
ssl_bc_session_key                                 binary
ssl_bc_sni                                         string
ssl_bc_unique_id                                   binary
ssl_bc_use_keysize                                 integer
ssl_c_ca_err                                       integer
ssl_c_ca_err_depth                                 integer
ssl_c_chain_der                                    binary
ssl_c_der                                          binary
ssl_c_err                                          integer
ssl_c_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_key_alg                                      string
ssl_c_notafter                                     string
ssl_c_notbefore                                    string
ssl_c_r_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_c_san                                          string
ssl_c_serial                                       binary
ssl_c_sha1                                         binary
ssl_c_sig_alg                                      string
ssl_c_used                                         boolean
ssl_c_verify                                       integer
ssl_c_version                                      integer
ssl_f_der                                          binary
ssl_f_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_f_key_alg                                      string
ssl_f_notafter                                     string
ssl_f_notbefore                                    string
ssl_f_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_f_serial                                       binary
ssl_f_sha1                                         binary
ssl_f_sig_alg                                      string
ssl_f_version                                      integer
ssl_fc                                             boolean
ssl_fc_alg_keysize                                 integer
ssl_fc_alpn                                        string
ssl_fc_cipher                                      string
ssl_fc_cipherlist_bin([<filter_option>])           binary
ssl_fc_cipherlist_hex([<filter_option>])           string
ssl_fc_cipherlist_str([<filter_option>])           string
ssl_fc_cipherlist_xxh                              integer
ssl_fc_client_early_traffic_secret                 string
ssl_fc_client_handshake_traffic_secret             string
ssl_fc_client_random                               binary
ssl_fc_client_traffic_secret_0                     string
ssl_fc_crtname                                     string
ssl_fc_curve                                       string
ssl_fc_early_exporter_secret                       string
ssl_fc_ecformats_bin                               binary
ssl_fc_eclist_bin([<filter_option>])               binary
ssl_fc_err                                         integer
ssl_fc_err_str                                     string
ssl_fc_exporter_secret                             string
ssl_fc_extlist_bin([<filter_option>])              binary
ssl_fc_has_crt                                     boolean
ssl_fc_has_early                                   boolean
ssl_fc_has_sni                                     boolean
ssl_fc_is_resumed                                  boolean
ssl_fc_npn                                         string
ssl_fc_protocol                                    string
ssl_fc_protocol_hello_id                           integer
ssl_fc_server_handshake_traffic_secret             string
ssl_fc_server_random                               binary
ssl_fc_server_traffic_secret_0                     string
ssl_fc_session_id                                  binary
ssl_fc_session_key                                 binary
ssl_fc_sigalgs_bin([<filter_option>])              binary
ssl_fc_sni                                         string
ssl_fc_supported_versions_bin([<filter_option>])   binary
ssl_fc_unique_id                                   binary
ssl_fc_use_keysize                                 integer
ssl_s_chain_der                                    binary
ssl_s_der                                          binary
ssl_s_i_dn([<entry>[,<occ>[,<format>]]])           string
ssl_s_key_alg                                      string
ssl_s_notafter                                     string
ssl_s_notbefore                                    string
ssl_s_s_dn([<entry>[,<occ>[,<format>]]])           string
ssl_s_serial                                       binary
ssl_s_sha1                                         binary
ssl_s_sig_alg                                      string
ssl_s_version                                      integer
txn.timer.user                                     integer
-------------------------------------------------+-------------

详细列表:

51d.all(<prop>[,<prop>*]): string

51d.all(<prop>[,<prop>*]): string

以字符串形式返回所请求属性的值,各值之间使用“51degrees-property-separator”指定的分隔符分隔。设备通过请求中的所有重要 HTTP 头进行识别。该函数最多可传入五个属性名,若某属性名无法找到,则返回值为“NoData”。

示例:

# Here the header "X-51D-DeviceTypeMobileTablet" is added to the request
# containing the three properties requested using all relevant headers from
# the request.
frontend http-in
  bind *:8081
  default_backend servers
  http-request set-header X-51D-DeviceTypeMobileTablet \
    %[51d.all(DeviceType,IsMobile,IsTablet)]

bs.aborted: 布尔值,若当前流从服务器接收到中止请求,则返回 true;否则返回 false。

bs.debug_str([<bitmap>]): string

bs.debug_str([<bitmap>]): string

此功能专用于开发人员在特定复杂故障排查会话期间使用。它从后端流和连接的底层提取部分内部状态,并将其整理为字符串,通常以一系列以空格分隔的“name=value”形式呈现。<bitmap> 可选参数用于指定要提取信息的层级,其值为以下各项的算术 OR(或求和)结果:- 套接字层:16 - 连接层:8 - 传输层(如 SSL):4 - 多路复用连接:2 - 多路复用流:1

这些值可能随版本变化。默认值 0 具有特殊含义,表示启用所有层。请勿依赖此函数的输出进行长期生产环境监控。该函数即使在稳定分支内也可能持续演进,以满足对更详细信息的需求。一个典型用例是将这些信息与 fs.debug_str() 一同拼接至日志格式的末尾。示例:

log-format "$HAPROXY_HTTP_LOG_FMT fs=<%[fs.debug_str]> bs=<%[bs.debug_str]>"

bs.id: integer 返回服务器端多路复用器的流 ID。由多路复用器负责返回相应信息。

bs.rst_code: integer 返回从服务器接收到的当前流的重置码。返回服务器发送的 H2 RST_STREAM 帧或 QUIC STOP_SENDING 帧的码值。若未接收到中止事件,或服务器流非 H2/QUIC 流,则样本提取失败。

fs.aborted: 布尔型 若当前流从客户端接收到中止请求,则返回 true;否则返回 false。

fs.debug_str([<bitmap>]): string

fs.debug_str([<bitmap>]): string

此功能专供开发人员在特定复杂故障排查会话期间使用。它从前端流和连接的底层提取部分内部状态,并将其整理为字符串,通常以一系列用空格分隔的“name=value”形式呈现。<bitmap> 可选参数用于指定要提取信息的层级,其值为以下各项的算术 OR(或求和)结果:- 套接字层:16 - 连接层:8 - 传输层(如 SSL):4 - 多路复用连接:2 - 多路复用流:1

这些值可能随版本变化。默认值 0 具有特殊含义,表示启用所有层。请勿依赖此函数的输出进行长期生产环境监控。该函数即使在稳定分支内也可能持续演进,以满足对更详细信息的需求。一个典型用例是将这些信息与 bs.debug_str() 一同拼接至日志格式的末尾。示例:

log-format "$HAPROXY_HTTP_LOG_FMT fs=<%[fs.debug_str]> bs=<%[bs.debug_str]>"

fs.id: integer 返回客户端侧多路复用器的流 ID。由多路复用器负责返回适当的信息。例如,在原始 TCP 上,始终返回 0,因为不存在流。

fs.rst_code: integer 返回客户端在当前流中接收到的重置码。返回客户端发送的 H2 RST_STREAM 帧或 QUIC STOP_SENDING 帧的重置码。若未接收到中止事件,或客户端流非 H2/QUIC 流,则样本提取失败。

ssl_bc: boolean 当后端连接通过 SSL/TLS 传输层建立并已在本地解密时返回 true。这意味着出站连接是向启用了“ssl”选项的服务器发起的。该字段可用于 tcp-check 或 http-check 规则集。

ssl_bc_alg_keysize: integer 返回在通过 SSL/TLS 传输层建立出站连接时所支持的对称加密算法密钥长度(单位:位)。该字段可在 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 传输层建立时,返回所使用的加密套件名称。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_client_early_traffic_secret: 字符串 返回 CLIENT_EARLY_TRAFFIC_SECRET 作为十六进制字符串,用于后端连接,当出站连接通过 TLS 1.3 传输层建立时。 要求 OpenSSL >= 1.1.1。此为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须通过在全局段中启用 “tune.ssl.keylog on” 激活 SSL 密钥日志记录。 参见 “tune.ssl.keylog”

ssl_bc_client_handshake_traffic_secret: string 返回 CLIENT_HANDSHAKE_TRAFFIC_SECRET 作为十六进制字符串,用于在出站连接通过 TLS 1.3 传输层建立时的后端连接。要求 OpenSSL ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_bc_client_random: 二进制格式返回后端连接的客户端随机数,当入站连接通过 SSL/TLS 传输层建立时有效。该功能可用于解密使用临时密码套件传输的流量。需使用 OpenSSL >= 1.1.0 或 BoringSSL。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_client_traffic_secret_0: string 返回 CLIENT_TRAFFIC_SECRET_0 作为十六进制字符串,用于后端连接。当出站连接通过 TLS 1.3 传输层建立时使用。 要求 OpenSSL ≥ 1.1.1。此为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。 参见 “tune.ssl.keylog”

ssl_bc_curve: 字符串 返回在通过 SSL/TLS 传输层建立出站连接时用于密钥协商的曲线名称。此功能需要 OpenSSL ≥ 3.0.0 或 AWS-LC ≥ 1.57.0。

ssl_bc_early_exporter_secret: string 当出站连接通过 TLS 1.3 传输层建立时,返回后端连接的 EARLY_EXPORTER_SECRET 作为十六进制字符串。要求 OpenSSL 版本 ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_bc_err: 整数 当出站连接通过 SSL/TLS 传输层建立时,返回后端侧第一个错误堆栈中最后一个错误的 ID。该值可能包含握手错误,以及其他在连接生命周期内发生的读取或写入错误。若需获取该错误码的文本描述,可使用 “ssl_bc_err_str” 样本提取,或使用 “openssl errstr” 命令(需以十六进制表示的错误码作为参数)。请查阅所用 SSL 库文档以获取完整的错误码列表。

ssl_bc_err_str: 字符串 当出站连接通过 SSL/TLS 传输层建立时,返回从后端视角出发,该连接上首个错误堆栈中最后一个错误的字符串表示形式。参见 “ssl_fc_err”。

ssl_bc_exporter_secret: string 当出站连接通过 TLS 1.3 传输层建立时,以十六进制字符串形式返回 EXPORTER_SECRET 作为后端连接的密钥。 要求 OpenSSL 版本 ≥ 1.1.1。 此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。 参见 “tune.ssl.keylog”

ssl_bc_is_resumed: 布尔型 当后端连接通过 SSL/TLS 传输层建立,且新创建的 SSL 会话是通过缓存的会话或 TLS 票据恢复时,返回 true。该字段可用于 tcp-check 或 http-check 规则集。

ssl_bc_npn: string 此字段用于从通过 TLS 传输层建立的出站连接中提取“下一协议协商”(Next Protocol Negotiation)字段。结果为一个字符串,包含与服务器协商确定的协议名称。SSL 库必须在编译时启用了对 TLS 扩展的支持(请检查 HAProxy -vv)。请注意,除非在 “server” 行中通过 “npn” 关键字指定了协议列表,否则不会通告 TLS NPN 扩展。此外,服务器并不强制必须从该列表中选择协议,也可能使用其他协议。请注意,TLS NPN 扩展已被 ALPN 取代。该字段可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_protocol: 字符串 返回通过 SSL/TLS 传输层建立出站连接时所使用的协议名称。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_server_handshake_traffic_secret: string 返回 SERVER_HANDSHAKE_TRAFFIC_SECRET 作为十六进制字符串,用于后端连接,当出站连接通过 TLS 1.3 传输层建立时。要求 OpenSSL >= 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_bc_server_random: 二进制数据 返回通过 SSL/TLS 传输层建立的入站连接所对应的后端连接的服务器随机数。该字段可用于解密使用临时密码套件传输的流量。使用此功能需要 OpenSSL >= 1.1.0 或 BoringSSL。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_server_traffic_secret_0: string 以十六进制字符串形式返回 SERVER_TRAFFIC_SECRET_0,当出站连接通过 TLS 1.3 传输层建立时。要求 OpenSSL 版本 ≥ 1.1.1。此值为 OpenSSL keylog 回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志记录。参见 “tune.ssl.keylog”

ssl_bc_session_id: binary 返回在出站连接通过 SSL/TLS 传输层建立时的后端连接的 SSL ID。该字段可用于日志记录,以判断会话是否被复用。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_session_key: 二进制格式返回后端连接的 SSL 会话主密钥,当出站连接通过 SSL/TLS 传输层建立时。该字段可用于解密使用临时密码套件传输的流量。此功能需要 OpenSSL >= 1.1.0 或 BoringSSL。可在 tcp-check 或 http-check 规则集中使用。

ssl_bc_sni: string 此字段用于获取连接到服务器时所使用的 TLS 扩展字段 Server Name Indication(SNI)。当存在时,结果通常为一个字符串,其内容与 HTTPS 主机名匹配(长度不超过 253 个字符)。主要用途为日志记录和调试(例如,确定连接建立时实际使用的 SNI,以便与服务器端所见内容进行比对)。

ssl_bc_unique_id: binary 当出站连接通过 SSL/TLS 传输层建立时,返回 RFC5929 第 3 节 定义的 TLS 唯一 ID。可通过转换器 “ssl_bc_unique_id,base64” 将其编码为 Base64 格式。该值可用于 tcp-check 或 http-check 规则集。

ssl_bc_use_keysize: integer 返回在通过 SSL/TLS 传输层建立出站连接时所使用的对称加密算法密钥长度(单位:位)。该指标可在 tcp-check 或 http-check 规则集中使用。

ssl_c_ca_err: 整数。当客户端连接通过 SSL/TLS 传输层建立时,返回在深度 > 0 处验证客户端证书时检测到的第一个错误的 ID,若在此验证过程中未发现错误则返回 0。请参阅所用 SSL 库文档以获取完整的错误码列表。

ssl_c_ca_err_depth: 整数。当客户端通过 SSL/TLS 传输层建立连接时,返回在验证客户端证书过程中检测到的第一个错误在 CA 证书链中的深度。若未发现错误,则返回 0。

ssl_c_chain_der: 二进制 返回客户端在通过 SSL/TLS 传输层建立入站连接时提供的链式证书的 DER 格式内容。在用于 ACL 时,匹配值可传入十六进制形式。可使用任意支持 ASN.1 DER 数据的库解析该结果。当前不支持已恢复的会话。

ssl_c_der: 二进制 返回客户端在通过 SSL/TLS 传输层建立连接时提供的 DER 格式证书。在用于 ACL 时,用于匹配的值可按十六进制形式传递。

ssl_c_err: 整数 当入站连接通过 SSL/TLS 传输层建立时,返回在深度 0 验证过程中检测到的第一个错误的 ID,若在此验证过程中未发现错误则返回 0。请参阅所用 SSL 库文档以获取错误代码的完整列表。

ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_i_dn([<entry>[,<occ>[,<format>]]]): string

当通过 SSL/TLS 传输层建立入站连接时,若未指定 <entry>,返回客户端所提交证书的颁发者完整可区分名称(DN);否则返回从 DN 开头起第一个匹配的条目值。若指定正/负数作为可选的第二个参数,则返回从 DN 开头/结尾起第 n 个指定条目的值。例如,“ssl_c_i_dn(OU,2)” 返回第二个组织单位,而 “ssl_c_i_dn(CN)” 返回通用名称。<format> 参数允许获取适用于不同协议处理的 DN 格式。当前支持的格式为 rfc2253(用于 LDAP v3)。若仅需修改格式,可将前两个参数设为空字符串和零。示例:ssl_c_i_dn(,0,rfc2253) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_c_key_alg: 字符串 返回在通过 SSL/TLS 传输层建立入站连接时,客户端所提交证书的密钥生成算法名称。

ssl_c_notafter: 字符串 返回客户端在建立 SSL/TLS 传输层连接时提供的到期日期,格式为格式化字符串 YYMMDDhhmmss[Z]。

ssl_c_notbefore: string 返回客户端在建立入站连接时通过 SSL/TLS 传输层提供的起始日期,格式为格式化字符串 YYMMDDhhmmss[Z]。

ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_r_dn([<entry>[,<occ>[,<format>]]]): string

当通过 SSL/TLS 传输层建立的入站连接成功使用配置的 ca-file 验证时,若未指定 <entry>,返回客户端所提交证书的根 CA 的完整可区分名称;否则返回从 DN 开头起第一个匹配的条目值。若指定正数/负数作为可选的第二个参数,则返回从 DN 开头/结尾起第 n 个给定条目的值。例如,“ssl_c_r_dn(OU,2)” 返回第二个组织单位,而“ssl_c_r_dn(CN)” 返回通用名称。<format> 参数允许获取适用于不同协议消费的 DN 格式。当前支持 rfc2253(用于 LDAP v3)。若仅需修改格式,可将前两个参数设为空字符串和零。示例:ssl_c_r_dn(,0,rfc2253) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_c_s_dn([<entry>[,<occ>[,<format>]]]): string

当通过 SSL/TLS 传输层建立入站连接时,若未指定 <entry>,返回客户端所提交证书中主题的完整可分辨名称;否则返回从 DN 开头起第一个匹配的条目值。若指定正/负的出现次数作为可选的第二个参数,则返回从 DN 开头/结尾起第 n 个指定条目的值。例如,“ssl_c_s_dn(OU,2)” 返回第二个组织单位,而 “ssl_c_s_dn(CN)” 返回通用名称。<format> 参数允许获取适用于不同协议处理的 DN 格式。当前支持的格式为 rfc2253(用于 LDAP v3)。若仅需修改格式,可将前两个参数设为空字符串和零。示例:ssl_c_s_dn(,0,rfc2253) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_c_san: 字符串 当通过 SSL/TLS 传输层建立连接,并提供了客户端证书时,返回该证书中包含的以逗号分隔的 Subject Alt Name 字段字符串。

可用于检查客户端证书。

示例:

acl is_valid_client_cert ssl_c_used && ! ssl_c_verify
http-request set-header X-SSL-Client-SAN %[ssl_c_san] if is_valid_client_cert

将导致:

X-SSL-Client-SAN: IP Address:127.0.0.1, IP Address:127.0.0.2, IP Address:127.0.0.3, URI:http://docs.haproxy.org/2.7/, DNS:ca.tests.haproxy.com

ssl_c_serial: 二进制格式,返回客户端在通过 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: 字符串 返回在通过 SSL/TLS 传输层建立入站连接时,客户端所提交证书的签名算法名称。

ssl_c_used: 布尔值,若当前 SSL 会话使用了客户端证书,则返回 true,即使当前连接使用了 SSL 会话恢复也是如此。参见 “ssl_fc_has_crt”。

ssl_c_verify: integer 当入站连接通过 SSL/TLS 传输层建立时,返回验证结果的错误 ID;若未发生错误,则返回零。请参阅所使用的 SSL 库文档,以获取完整的错误代码列表。

ssl_c_version: 整数 返回客户端在通过 SSL/TLS 传输层建立入站连接时提供的证书版本。

ssl_f_der: 二进制 返回前端在通过 SSL/TLS 传输层建立入站连接时所呈现的 DER 格式证书。在用于 ACL 时,用于匹配的值可按十六进制形式传递。

ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_f_i_dn([<entry>[,<occ>[,<format>]]]): string

当入站连接通过 SSL/TLS 传输层建立时,若未指定 <entry>,返回前端所呈现证书的完整颁发者区分名(DN);否则返回从 DN 开头起第一个匹配的条目值。若指定正/负的出现次数作为可选的第二个参数,则返回从 DN 开头/结尾起第 n 个指定条目的值。例如,“ssl_f_i_dn(OU,2)” 返回第二个组织单位,而 “ssl_f_i_dn(CN)” 返回通用名称。<format> 参数允许获取适用于不同协议消费的 DN 格式。当前支持的格式为 rfc2253(用于 LDAP v3)。若仅需修改格式,可将前两个参数设为空字符串和零。示例:ssl_f_i_dn(,0,rfc2253) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_f_key_alg: 字符串 返回前端在通过 SSL/TLS 传输层建立入站连接时所呈现证书的密钥生成算法名称。

ssl_f_notafter: 字符串 返回前端以格式化字符串形式呈现的证书有效期截止日期,格式为 YYMMDDhhmmss[Z],该日期对应于当前连接通过 SSL/TLS 传输层建立时的前端所呈现的证书有效期。

ssl_f_notbefore:字符串 返回前端以格式化字符串形式呈现的起始日期,格式为 YYMMDDhhmmss[Z],表示通过 SSL/TLS 传输层建立入站连接时的时间。

ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_f_s_dn([<entry>[,<occ>[,<format>]]]): string

当入站连接通过 SSL/TLS 传输层建立时,若未指定 <entry>,返回前端所呈现证书主体的完整可区分名称;否则返回从 DN 开头起第一个匹配的条目值。若指定正/负的出现次数作为可选的第二个参数,则返回从 DN 开头/结尾起第 n 个指定条目的值。例如,“ssl_f_s_dn(OU,2)” 返回第二个组织单位,而 “ssl_f_s_dn(CN)” 返回通用名称。<format> 参数允许获取适用于不同协议处理的 DN 格式。当前支持 rfc2253(用于 LDAP v3)。若仅需修改格式,可将前两个参数设为空字符串和零。示例:ssl_f_s_dn(,0,rfc2253) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_f_serial: binary 返回前端在通过 SSL/TLS 传输层建立入站连接时所呈现的证书序列号。在用于 ACL 时,可传入十六进制形式的值进行匹配。

ssl_f_sha1: 二进制值 返回前端在通过 SSL/TLS 传输层建立入站连接时所呈现的证书的 SHA-1 指纹。此值可用于判断在使用 SNI 时选择了哪个证书。

ssl_f_sig_alg: string 返回在通过 SSL/TLS 传输层建立入站连接时,前端所呈现证书的签名算法名称。

ssl_f_version: integer 返回前端在通过 SSL/TLS 传输层建立入站连接时所出示证书的版本。

ssl_fc: boolean 当前端连接通过 SSL/TLS 传输层建立并已在本地解密时返回 true。这意味着该连接已匹配到使用带有 “ssl” 选项的 “bind” 指令声明的套接字。

示例:

# This passes "X-Proto: https" to servers when client connects over SSL
listen http-https
    bind:80
    bind:443 ssl crt /etc/haproxy.pem
    http-request add-header X-Proto https if { ssl_fc }

ssl_fc_alg_keysize: integer 返回在通过 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

ssl_fc_cipherlist_bin([<filter_option>]): binary

返回客户端 Hello 消息中密码套件列表的二进制形式。返回值的最大长度受 “tune.ssl.capture-buffer-size” 设置所控制的共享捕获缓冲区大小限制。 设置 <filter_option> 可用于过滤返回数据。接受的值包括:

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

示例:

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

ssl_fc_cipherlist_hex([<filter_option>]): string

返回以十六进制编码的客户端 Hello 密码套件列表的二进制形式。返回值的最大长度受共享捕获缓冲区大小限制,该大小由 “tune.ssl.capture-buffer-size” 设置控制。设置 <filter_option> 可用于过滤返回数据。

接受的值:

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

ssl_fc_cipherlist_str([<filter_option>]): string

ssl_fc_cipherlist_str([<filter_option>]): string

返回客户端问候消息中密码套件列表的解码文本形式。返回值的最大长度受共享捕获缓冲区大小限制,该大小由 “tune.ssl.capture-buffer-size” 设置控制。 设置 <filter_option> 可用于过滤返回数据。接受的值如下:

0: return the full list of ciphers (default)
1: exclude GREASE (RFC8701) values from the output

请注意,此样本提取功能仅在 OpenSSL >= 1.0.2 时可用。若该功能未启用,则此样本提取返回的哈希值为 “ssl_fc_cipherlist_xxh”。

ssl_fc_cipherlist_xxh: integer 返回密码套件列表的 xxh64 哈希值。该哈希值仅在 “tune.ssl.capture-buffer-size” 的值大于 0 时才可返回,但哈希值会考虑密码套件列表中的全部数据。

ssl_fc_client_early_traffic_secret: 字符串 返回客户端在通过 TLS 1.3 传输层建立连接时,前端连接的 CLIENT_EARLY_TRAFFIC_SECRET,以十六进制字符串形式输出。 要求 OpenSSL 版本 ≥ 1.1.1。此值为 OpenSSL keylog 回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志记录。 参见 “tune.ssl.keylog”

ssl_fc_client_handshake_traffic_secret: 字符串 返回前端连接在通过 TLS 1.3 传输层建立时的 CLIENT_HANDSHAKE_TRAFFIC_SECRET,以十六进制字符串形式输出。 要求 OpenSSL 版本 ≥ 1.1.1。 此值为 OpenSSL keylog 回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志记录。 参见 “tune.ssl.keylog”

ssl_fc_client_random: binary 返回通过 SSL/TLS 传输层建立的前端连接的客户端随机数。在解密使用临时密码套件传输的流量时非常有用。此功能需要 OpenSSL >= 1.1.0 或 BoringSSL。

ssl_fc_client_traffic_secret_0: string 当前端连接通过 TLS 1.3 传输层建立时,返回 CLIENT_TRAFFIC_SECRET_0 的十六进制字符串形式。 要求 OpenSSL ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_fc_crtname: string 返回用于入站 SSL/TLS 连接的证书名称。该名称与在 “show ssl cert” 中显示的一致:可能是带相对路径或绝对路径的文件名,也可能是别名,具体取决于证书在配置中声明的方式。

示例:

crt-store example
    load crt "example.com.pem"

frontend www
    bind *:443 ssl crt "@example/example.com.pem"
    acl match_certificate ssl_fc_crtname -m beg -i "@example/"
    http-request set-header X-Cert-Name %[ssl_fc_crtname] if match_certificate

ssl_fc_curve: string 返回在通过 SSL/TLS 传输层建立入站连接时用于密钥协商的曲线名称。此功能需要 OpenSSL 版本 ≥ 3.0.0。

ssl_fc_early_rcvd: boolean 若在该连接上检测到早期数据,无论握手是否已完成,均返回 true。该字段在流量处理中无实际用途,但却是唯一能“检测”客户端是否使用 0-RTT 发送早期数据的方式。在调试时偶尔有用,因为其他替代方案仅限于网络流量捕获,或在代码中记录前端连接标志并进行匹配。此外,该字段也可用于统计客户端能力。参见 “ssl_fc_has_early”。

ssl_fc_early_exporter_secret: string 当前端连接通过 TLS 1.3 传输层建立时,以十六进制字符串形式返回 EARLY_EXPORTER_SECRET。要求 OpenSSL 版本 ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_fc_ecformats_bin: binary 返回客户端 Hello 中支持的椭圆曲线点格式的二进制形式。返回值的最大长度受 “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

ssl_fc_eclist_bin([<filter_option>]): binary

返回客户端 Hello 消息中支持的椭圆曲线的二进制形式。返回值的最大长度受 “tune.ssl.capture-buffer-size” 设置所控制的共享捕获缓冲区大小限制。设置 <filter_option> 可用于过滤返回数据。接受的值:

0: return the full list of supported elliptic curves (default)
1: exclude GREASE (RFC8701) values from the output

示例:

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_err: 整数 当客户端连接通过 SSL/TLS 传输层建立时,返回前端侧第一个错误堆栈中最后一个错误的 ID,若未发生错误则返回 0。该字段可用于识别除证书验证错误外的握手相关错误(如加密套件不匹配),以及连接生命周期中发生的其他读取或写入错误。客户端证书验证过程中发生的任何错误均不会通过此获取方式上报,而是通过现有的 “ssl_c_err”、“ssl_c_ca_err” 和 “ssl_c_ca_err_depth” 获取方式上报。如需获取该错误码的文本描述,可使用 “ssl_fc_err_str” 样本提取方式,或使用 “openssl errstr” 命令(需以十六进制形式提供错误码作为参数)。请查阅所用 SSL 库文档以获取完整的错误码列表。

ssl_fc_err_str:字符串 当客户端连接通过 SSL/TLS 传输层建立时,返回前端侧第一个错误堆栈中最后一个错误的字符串表示。客户端证书验证过程中发生的任何错误均不会通过此获取方式返回。参见 “ssl_fc_err”。

ssl_fc_exporter_secret: string 返回 EXPORTER_SECRET 作为十六进制字符串,用于前端连接,当入站连接通过 TLS 1.3 传输层建立时。要求 OpenSSL ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_fc_extlist_bin([<filter_option>]): binary

ssl_fc_extlist_bin([<filter_option>]): binary

返回客户端问候扩展列表的二进制形式。返回值的最大长度受 “tune.ssl.capture-buffer-size” 设置控制的共享捕获缓冲区大小限制。 设置 <filter_option> 可用于过滤返回的数据。接受的值:

0: return the full list of extensions (default)
1: exclude GREASE (RFC8701) values from the output

示例:

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_has_crt: 布尔值,当通过 SSL/TLS 传输层的入站连接中存在客户端证书时返回 true。在设置 ‘verify’ 语句为 ‘optional’ 时尤为有用。请注意:在使用会话 ID 或 TLS 票据进行 SSL 会话恢复时,当前连接中可能不存在客户端证书,但可从缓存或票据中检索。因此,若要检查当前 SSL 会话是否使用了客户端证书,应优先使用 “ssl_c_used”。

ssl_fc_has_early: 布尔值,若已发送早期数据且握手尚未完成,则返回 true。由于存在安全风险,建议能够拒绝此类请求,或通过“wait-for-handshake”动作等待握手完成后再处理。参见 “ssl_fc_early_rcvd”。

ssl_fc_has_sni: 布尔值 此检查用于判断通过 SSL/TLS 传输层建立的入站连接中是否包含服务器名称指示 TLS 扩展(SNI)。当入站连接包含 TLS SNI 字段时,返回 true。此功能要求 SSL 库在编译时启用了对 TLS 扩展的支持(请检查 HAProxy -vv)。

ssl_fc_is_resumed: 布尔值 返回值为 true,表示通过 SSL 会话缓存或 TLS 票据,在基于 SSL/TLS 传输层的入站连接上成功恢复了 SSL/TLS 会话。

ssl_fc_npn: string 此字段从通过 TLS 传输层建立且由 HAProxy 本地解密的入站连接中提取“下一协议协商”(Next Protocol Negotiation)字段。结果为一个字符串,包含客户端通告的协议名称。SSL 库必须在启用 TLS 扩展支持的情况下编译(请检查 HAProxy -vv)。请注意,除非“bind”行上的“npn”关键字指定了协议列表,否则不会通告 TLS NPN 扩展。此外,客户端并不强制必须从该列表中选择协议,也可能请求其他协议。请注意,TLS NPN 扩展已被 ALPN 取代。

ssl_fc_protocol: string 返回通过 SSL/TLS 传输层建立的入站连接所使用的协议名称。

ssl_fc_protocol_hello_id: 整数 客户端在会话期间希望使用的 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_fc_server_handshake_traffic_secret: string 返回前端连接在通过 TLS 1.3 传输层建立时的 SERVER_HANDSHAKE_TRAFFIC_SECRET,以十六进制字符串形式输出。 要求 OpenSSL 版本 ≥ 1.1.1。 此值为 OpenSSL keylog 回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志记录。 另请参见 “tune.ssl.keylog”

ssl_fc_server_random: binary 返回通过 SSL/TLS 传输层建立的前端连接的服务器随机数。在使用临时密码套件加密的流量解密时,该字段非常有用。此功能需要 OpenSSL >= 1.1.0 或 BoringSSL。

ssl_fc_server_traffic_secret_0: string 当前端连接通过 TLS 1.3 传输层建立时,返回 SERVER_TRAFFIC_SECRET_0 的十六进制字符串形式。 要求 OpenSSL 版本 ≥ 1.1.1。此值为 OpenSSL 密钥日志回调导出的密钥之一,用于生成 SSLKEYLOGFILE。 必须在全局段中通过 “tune.ssl.keylog on” 激活 SSL 密钥日志功能。参见 “tune.ssl.keylog”

ssl_fc_session_id: binary 返回通过 SSL/TLS 传输层建立的前端连接的 SSL 会话 ID。该值可用于将特定客户端固定到某台服务器。请注意,部分浏览器会每隔几分钟刷新一次会话 ID。

ssl_fc_session_key: binary 返回前端连接的 SSL 会话主密钥,当入站连接通过 SSL/TLS 传输层建立时有效。该字段可用于解密使用临时密码套件传输的流量。此功能要求 OpenSSL 版本 ≥ 1.1.0,或使用 BoringSSL。

ssl_fc_sigalgs_bin([<filter_option>]): binary

ssl_fc_sigalgs_bin([<filter_option>]): binary

返回在 Client Hello 阶段呈现的 signatures_algorithms (13) TLS 扩展的内容。该扩展提供一个二进制列表,其中包含 TLS RFC 定义的 2 字节算法: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.3 。

该值仅在 “tune.ssl.capture-buffer-size” 的值大于 0 时才可返回。 设置 <filter_option> 可用于过滤返回的数据。可接受的值:0:返回完整的密码套件列表(默认);1:从输出中排除 GREASE(RFC8701)值。

ssl_fc_sni: string 此字段用于从通过 SSL/TLS 传输层建立且由 HAProxy 本地解密的入站连接中提取 Server Name Indication TLS 扩展(SNI)字段。当存在时,结果通常为一个匹配 HTTPS 主机名的字符串(长度不超过 253 个字符)。SSL 库必须在编译时启用 TLS 扩展支持(请检查 HAProxy -vv)。

此 fetch 与上方的 “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: suffix match
ssl_fc_sni_reg: regex match

ssl_fc_supported_versions_bin([<filter_option>]): binary

ssl_fc_supported_versions_bin([<filter_option>]): binary

返回在 Client Hello 中呈现的 supported_versions (43) TLS 扩展的内容。 该内容为一个二进制列表,每个版本占 2 字节,包括 TLSv1.3 (0x0304) 和 TLSv1.2 (0x0303)。

该值仅在 “tune.ssl.capture-buffer-size” 的值大于 0 时才可返回。 设置 <filter_option> 可用于过滤返回的数据。可接受的值:0:返回完整的密码套件列表(默认);1:从输出中排除 GREASE(RFC8701)值。

ssl_fc_unique_id: binary 当通过 SSL/TLS 传输层建立入站连接时,返回 RFC5929 第 3 节 定义的 TLS 唯一 ID。可通过转换器 “ssl_fc_unique_id,base64” 将该唯一 ID 编码为 base64 格式。

ssl_fc_use_keysize: integer 返回在通过 SSL/TLS 传输层建立的入站连接中所使用的对称加密算法密钥长度(单位:位)。

ssl_s_chain_der: 二进制 返回在通过 SSL/TLS 传输层建立出站连接时,服务器提供的 DER 格式证书链。在用于 ACL 时,可传入十六进制形式的值进行匹配。可使用任意支持 ASN.1 DER 数据的库解析该结果。当前不支持已恢复的会话。

ssl_s_der: 二进制格式 返回在通过 SSL/TLS 传输层建立出站连接时,服务器提供的 DER 格式证书。在用于 ACL 时,用于匹配的值可以以十六进制形式传递。

ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string

ssl_s_i_dn([<entry>[,<occ>[,<format>]]]): string

当出站连接通过 SSL/TLS 传输层建立时,若未指定 <entry>,返回服务器所呈现证书的完整颁发者区分名(DN);否则返回从 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) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_s_key_alg: 字符串 返回在通过 SSL/TLS 传输层建立出站连接时,服务器所出示证书的密钥生成算法名称。

ssl_s_notafter: 字符串 返回服务器在建立出站连接时通过 SSL/TLS 传输层提供的结束日期,格式为格式化字符串 YYMMDDhhmmss[Z]。

ssl_s_notbefore: string 返回服务器在建立出站连接时通过 SSL/TLS 传输层提供的起始日期,格式为格式化字符串 YYMMDDhhmmss[Z]。

ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string

ssl_s_s_dn([<entry>[,<occ>[,<format>]]]): string

当出站连接通过 SSL/TLS 传输层建立时,若未指定 <entry>,返回服务器所呈现证书的完整可区分名称(DN);否则返回从 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) 如果请求条目的 ASN.1 值(未指定 <entry> 时则为 DN 中任意条目)包含内嵌 NUL 字节且其后仍有其他数据,则将其视为格式错误,并且不返回任何数据。

ssl_s_serial: binary 返回在通过 SSL/TLS 传输层建立出站连接时,服务器所呈现证书的序列号。在用于 ACL 时,用于匹配的值可以以十六进制形式传入。

ssl_s_sha1: 二进制值 返回在通过 SSL/TLS 传输层建立出站连接时,服务器所呈现证书的 SHA-1 指纹。此值可用于判断在使用 SNI 时选择了哪个证书。

ssl_s_sig_alg: string 返回在通过 SSL/TLS 传输层建立出站连接时,服务器所出示证书的签名算法名称。

ssl_s_version: 整数 返回在通过 SSL/TLS 传输层建立出站连接时,服务器所出示证书的版本。

txn.timer.user: integer 客户端视角下估算的总时间,指代理接收请求的时刻至两端连接关闭时刻之间的实际耗时,不包含空闲时间。该值等效于日志格式中的 %Tu,单位为毫秒(ms)。详细信息请参见 第 8.4 节 “时间事件”

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

从缓冲区内容中提取样本的方式与上述其他样本提取方式略有不同,因为所采样的数据是瞬时的。这些数据仅在可用时才能使用,一旦转发便会丢失。因此,例如在请求过程中从缓冲区内容中提取的样本无法用于响应中。即使在数据提取过程中,其内容也可能发生变化。在某些情况下,有必要设置一定的延迟或结合多种样本提取方法,以确保所期望的数据完整且可用,例如通过 TCP 请求内容检查。有关该主题的更详细信息,请参阅“tcp-request content”关键字。

请注意:若在 HTTP 代理中使用以下样本提取方式,将被忽略。这些方式仅处理缓冲区中原始内容。而 HTTP 代理使用结构化内容,因此这些数据的原始表示毫无意义。若 ACL 依赖以下任一样本提取方式,将发出警告。但无法检测所有无效用法(例如在自定义日志格式或样本表达式中)。请务必小心。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                             output type
----------------------------------------------------+-------------
distcc_body(<token>[,<occ>])                          binary
distcc_param(<token>[,<occ>])                         integer
payload(<offset>,<length>)                            binary
payload_lv(<offset1>,<length>[,<offset2>])            binary
rdp_cookie([<name>])                                  string
rdp_cookie_cnt([name])                                integer
rep_ssl_hello_type                                    integer
req.len                                               integer
req.payload(<offset>,<length>)                        binary
req.payload_lv(<offset1>,<length>[,<offset2>])        binary
req.proto_http                                        boolean
req.rdp_cookie([<name>])                              string
req.rdp_cookie_cnt([name])                            integer
req.ssl_alpn                                          string
req.ssl_cipherlist                                    binary
req.ssl_ec_ext                                        boolean
req.ssl_hello_type                                    integer
req.ssl_keyshare_groups                               binary
req.ssl_sigalgs                                       binary
req.ssl_sni                                           string
req.ssl_st_ext                                        integer
req.ssl_supported_groups                              binary
req.ssl_ver                                           integer
req_len                                               integer
req_proto_http                                        boolean
req_ssl_hello_type                                    integer
req_ssl_sni                                           string
req_ssl_ver                                           integer
res.len                                               integer
res.payload(<offset>,<length>)                        binary
res.payload_lv(<offset1>,<length>[,<offset2>])        binary
res.ssl_hello_type                                    integer
----------------------------------------------------+-------------

详细列表:

distcc_body(<token>[,<occ>]): binary

distcc_body(<token>[,<occ>]): binary

解析一个 distcc 消息,并返回与令牌出现次数 <occ> 对应的正文 <token>。出现次数从 1 开始计算,若未指定,则任意出现次数均可匹配,但目前实际仅检查第一个出现。此功能可用于通过 HAProxy 提取使用 distcc 构建的文件中的文件名或参数。有关支持的令牌完整列表,请参阅 distcc 协议文档。

distcc_param(<token>[,<occ>]): integer

distcc_param(<token>[,<occ>]): integer

解析一个 distcc 消息,并返回与标记 <occ> 第 <token> 次出现关联的参数。出现次数从 1 开始计数,未指定时,任意出现均可匹配,但目前实际仅检查首个出现。此功能可用于提取特定信息,例如协议版本、文件大小或通过 HAProxy 构建的文件中的参数。另一使用场景是在连接服务器前等待预处理文件内容的开始,以避免保持空闲连接。有关支持标记的完整列表,请参阅 distcc 协议文档。

示例:

# wait up to 20s for the pre-processed file to be uploaded
tcp-request inspect-delay 20s
tcp-request content accept if { distcc_param(DOTI) -m found }
# send large files to the big farm
use_backend big_farm if { distcc_param(DOTI) gt 1000000 }

payload(<offset>,<length>): binary (deprecated)

payload(<offset>,<length>): binary (deprecated)

当用于请求上下文时(例如“stick on”、“stick match”),此为 “req.payload” 的别名;当用于响应上下文时(例如“stick store response”),此为 “res.payload” 的别名。

payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)

payload_lv(<offset1>,<length>[,<offset2>]): binary (deprecated)

当在请求上下文中使用时(例如“stick on”、“stick match”),此为 “req.payload_lv” 的别名;当在响应上下文中使用时(例如“stick store response”),此为 “res.payload_lv” 的别名。

req.len: integer req_len: integer (已弃用) 返回请求缓冲区中字节数对应的整数值。该值主要用于 ACL。需要注意的是,只要缓冲区内容在变化,此测试就不会返回假值。这意味着,对零值的相等性检查几乎总会在会话开始时立即匹配,而对更多数据的检测则会等待数据到达,并仅在 HAProxy 确定不会再有更多数据到达时才返回假值。此测试设计用于与 TCP 请求内容检查配合使用。

req.payload(<offset>,<length>): binary

req.payload(<offset>,<length>): binary

提取请求缓冲区中从 <offset> 字节开始、长度为 <length> 字节的二进制数据块。特殊情况下,若 <length> 参数为零,则提取从 <offset> 字节到缓冲区末尾的全部内容。此功能可与 ACL 配合使用,以检查缓冲区任意位置是否存在特定内容。

ACL 衍生规则:

req.payload(<offset>,<length>): hex binary match

req.payload_lv(<offset1>,<length>[,<offset2>]): binary

req.payload_lv(<offset1>,<length>[,<offset2>]): binary

此操作提取一个二进制块,其大小由 <offset1> 指定,长度为 <length> 字节,起始位置为 <offset2>(若已指定)或位于请求缓冲区中长度字段之后。<offset2> 参数还支持相对偏移,若在前缀添加 ‘+’ 或 ‘-’ 符号。

ACL 衍生规则:

req.payload_lv(<offset1>,<length>[,<offset2>]): hex binary match

示例:请参阅“stick store-response”关键字中的示例。

req.proto_http: boolean req_proto_http: boolean(已弃用) 当请求缓冲区中的数据符合 HTTP 格式且能正确解析时返回 true。该检测使用与常规 HTTP 请求解析器相同的解析逻辑,因此不会产生意外结果。该测试仅在请求完成、失败或超时时才生效。此测试可用于在 TCP 日志中报告协议,但其主要用途是在缓冲区中存在完整的 HTTP 请求前,阻止对 TCP 请求的分析,例如用于追踪请求头。

示例:

# track request counts per "base" (concatenation of Host+URL)
tcp-request inspect-delay 10s
tcp-request content reject if !HTTP
tcp-request content track-sc0 base table req-rate

req.rdp_cookie([<name>]): string

req.rdp_cookie([<name>]): string
rdp_cookie([<name>]): string (deprecated)

当请求缓冲区内容看起来符合 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>]): exact string match

示例:

listen tse-farm
    bind 0.0.0.0:3389
    # wait up to 5s for an RDP cookie in the request
    tcp-request inspect-delay 5s
    tcp-request content accept if RDP_COOKIE
    # apply RDP cookie persistence
    persist rdp-cookie
    # Persist based on the mstshash cookie
    # This is only useful makes sense if
    # balance rdp-cookie is not used
    stick-table type string size 204800
    stick on req.rdp_cookie(mstshash)
    server srv1 1.1.1.1:3389
    server srv1 1.1.1.2:3389

另请参阅:“balance rdp-cookie”、“persist rdp-cookie”、“tcp-request”以及 “req.rdp_cookie” ACL。

req.rdp_cookie_cnt([name]): integer

req.rdp_cookie_cnt([name]): integer
rdp_cookie_cnt([name]): integer (deprecated)

尝试将请求缓冲区解析为 RDP 协议,然后返回找到的 RDP Cookie 数量对应的整数。若传入可选的 Cookie 名称,则仅考虑与该名称匹配的 Cookie。此功能主要用于 ACL。

ACL 衍生规则:

req.rdp_cookie_cnt([<name>]): integer match

req.ssl_alpn: string 返回一个字符串,其中包含客户端在 SSL ClientHello 消息中发送的 Application-Layer Protocol Negotiation(ALPN)TLS 扩展(RFC7301)的值。 请注意,此字段仅适用于请求缓冲区中原始获取的内容,不适用于通过 SSL 数据层解密后的内容,因此在使用 “ssl” 选项的 “bind” 语句中无法生效。 此字段可用于 ACL 中,根据 TLS 客户端的 ALPN 优先级做出路由决策,如以下示例所示。另见 “ssl_fc_alpn”。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend bk_acme if { req.ssl_alpn acme-tls/1 }
default_backend bk_default

req.ssl_cipherlist binary

req.ssl_cipherlist binary

返回客户端在 TLS ClientHello 内容中报告的支持的对称加密算法列表的二进制形式。请注意,此功能仅适用于请求缓冲区中原始内容,不适用于通过 SSL 数据层解密后的内容,因此在使用了 “ssl” 选项的 “bind” 语句中无法生效。请参考 “ssl_fc_cipherlist_bin”,该选项为 SSL 绑定的等效配置,可在指定 “ssl” 选项时使用。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_cipherlist,be2hex(:,2),lower -m sub 1302:009f }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

req.ssl_ec_ext: boolean 返回一个布尔值,标识客户端是否在 SSL ClientHello 消息中发送了 RFC4492 第 5.1 节 定义的支持椭圆曲线扩展。该字段可用于在同一 IP 地址上,向支持 ECC 的客户端提供 EC 证书,而对其他客户端使用 RSA。请注意,此功能仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密后的内容,因此在使用了 “ssl” 选项的 “bind” 语句中无法生效。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

req.ssl_hello_type: integer req.ssl_hello_type: integer(已弃用) 返回一个整数值,表示在请求缓冲区中找到的 SSL 握手消息的类型。若缓冲区包含可解析为完整 SSL(v3 或更高版本)客户端握手消息的数据,则返回该类型值。请注意,此功能仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密后的内容,因此在使用“ssl”选项的“bind”行中无法生效。该功能主要用于 ACL 中检测预期包含可用于会话粘性的 SSL 会话 ID 的 SSL 握手消息。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

req.ssl_keyshare_groups binary

req.ssl_keyshare_groups binary

返回客户端在 TLS ClientHello 消息中报告的支持密钥交换的加密参数列表的二进制格式。在 TLS v1.3 中,keyshare 是 ClientHello 消息的一部分,也是客户端 Hello 消息的最后一个扩展。请注意,此功能仅适用于请求缓冲区中原始获取的内容,不适用于通过 SSL 数据层解密的内容,因此在使用带有 “ssl” 选项的 “bind” 语句时无法生效。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_keyshare_groups,be2hex(:,2),lower -m sub 001d  }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

req.ssl_sigalgs binary

req.ssl_sigalgs binary

返回客户端在 TLS ClientHello 中报告的支持的签名算法列表的二进制形式。此信息作为客户端问候扩展可用。请注意,此功能仅适用于请求缓冲区中原始内容,不适用于通过 SSL 数据层解密的内容,因此在使用带有 “ssl” 选项的 “bind” 语句时无法生效。请参考 “ssl_fc_sigalgs_bin”,该配置项是当指定 “ssl” 选项时可使用的 SSL 绑定等效项。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe4 if { req.ssl_sigalgs,be2hex(:,2),lower -m sub 0403:0805 }
server fe4  ${htst_fe4_addr}:${htst_fe4_port}

req.ssl_sni: string req_ssl_sni: string (已弃用) 返回一个字符串,其中包含客户端在通过请求缓冲区的 TLS 流中发送的 Server Name TLS 扩展值。该值仅在缓冲区包含可解析为完整 SSL(v3 或更高版本)客户端 Hello 消息的数据时有效。请注意,此功能仅适用于请求缓冲区中的原始内容,不适用于通过 SSL 数据层解密后的内容,因此在使用了 “ssl” 选项的 “bind” 语句中无法生效。该功能仅适用于 HTTPS(443)、IMAPS(993)、SMTPS(465)等实际基于隐式 TLS 的协议,不适用于 SMTP(25/587)或 IMAP(143)等显式 TLS 协议。SNI 通常包含客户端尝试连接的主机名称(针对较新浏览器)。该测试专为 TCP 请求内容检查设计。若需内容切换,建议首先等待完整的客户端 Hello 消息(类型 1),如以下示例所示。另见 “ssl_fc_sni”。请注意,由于下述 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 等因素,这个 fetch 返回的值不够可靠,不能单独用于允许或拒绝对特定主机的访问。

此 fetch 只解析请求缓冲区中找到的第一个 ClientHello 消息。如果客户端在同一 TCP 流中发送多个 ClientHello,例如服务器在 TLS 1.3 中请求了 HelloRetryRequest(HRR),或客户端发起 TLS 重新协商(稍后在同一 TCP 流中发送新的 ClientHello,且其中可能包含不同的 SNI),则只返回第一个 ClientHello 中携带的 SNI,后续 ClientHello 的内容都会被忽略。

使用 Encrypted Client Hello(ECH)时,网络上可见的 ClientHello 只是“外层”ClientHello,其中嵌入了真实且加密的“内层”ClientHello。此时,该 fetch 提取的是外层 ClientHello 中作为诱饵的 SNI,而不是客户端实际要访问的主机。当前该 fetch 无法解密或分析内层 ClientHello,因此使用 ECH 时不得依赖它做出路由或访问控制决策。

ACL 衍生规则:

req.ssl_sni: exact string match

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use_backend bk_allow if { req.ssl_sni -f allowed_sites }
default_backend bk_sorry_page

req.ssl_st_ext: integer 返回 0 表示客户端未发送 SessionTicket TLS 扩展(RFC5077) 返回 1 表示客户端发送了 SessionTicket TLS 扩展 返回 2 表示客户端还发送了非零长度的 TLS SessionTicket

请注意,此字段仅适用于请求缓冲区中原始内容的检测,不适用于通过 SSL 数据层解密后的内容,因此在使用了 “ssl” 选项的 “bind” 配置行中无法生效。 例如,可利用此字段检测客户端是否发送了 SessionTicket,并据此进行粘性会话处理:若未发送 SessionTicket,则使用 SessionID 进行粘性会话,或不进行粘性会话,因为使用 SessionTicket 时服务器端无状态。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

req.ssl_supported_groups binary

req.ssl_supported_groups binary

返回客户端在 TLS ClientHello 中报告并用于密钥交换的支持组列表的二进制形式,该列表可包含椭圆曲线和非椭圆曲线密钥交换。请注意,此功能仅适用于请求缓冲区中原始内容,不适用于通过 SSL 数据层解密的内容,因此在使用了 “ssl” 选项的 “bind” 语句中无法生效。请参考 “ssl_fc_eclist_bin”,其为指定 “ssl” 选项时可用的 SSL 绑定等效项。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

示例:

# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
use-server fe3 if { req.ssl_supported_groups, be2hex(:,2),lower -m sub 0017 }
server fe3  ${htst_fe3_addr}:${htst_fe3_port}

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。此 fetch 只分析请求缓冲区中找到的第一个 ClientHello 消息;有关 HelloRetryRequest、TLS 重新协商和 Encrypted Client Hello 所造成影响的详情,请参阅 req.ssl_sni 关键字文档。

ACL 衍生规则:

req.ssl_ver: decimal match

res.len: integer 返回响应缓冲区中当前存在的字节数。该值主要用于 ACL。需要注意的是,只要缓冲区内容在变化,此测试就不会返回假值。这意味着,对零值的相等性检查几乎总会在流开始时立即匹配,而对更多数据的检测则会等待数据到达,并仅在 HAProxy 确定不会再有更多数据到达时才返回假值。此测试设计用于 TCP 响应内容检查。也可用于基于 tcp-check 的 expect 规则。

res.payload(<offset>,<length>): binary

res.payload(<offset>,<length>): binary

从响应缓冲区中提取 <length> 字节,起始位置为 <offset> 字节。作为特例,若 <length> 参数为零,则从 <offset> 字节开始提取至缓冲区末尾的全部内容。此功能可与 ACL 配合使用,以检查任意位置的缓冲区中是否存在特定内容,也可用于基于 tcp-check 的 expect 规则中。

res.payload_lv(<offset1>,<length>[,<offset2>]): binary

res.payload_lv(<offset1>,<length>[,<offset2>]): binary

此规则提取一个二进制块,其大小由 <offset1> 指定,长度为 <length> 字节,起始位置为 <offset2>(若已指定)或位于响应缓冲区中长度字段之后。<offset2> 参数还支持相对偏移,若在前缀加上 ‘+’ 或 ‘-’ 符号。该参数也可用于基于 tcp-check 的 expect 规则。

示例:请参阅“stick store-response”关键字中的示例。

res.ssl_hello_type: 整数 rep_ssl_hello_type: 整数(已弃用) 返回一个整数值,表示响应缓冲区中包含的 SSL 握手消息的类型。若缓冲区中包含可解析为完整 SSL(v3 或更高版本)握手消息的数据,则返回该消息的类型。请注意,此功能仅适用于响应缓冲区中的原始内容,不适用于通过 SSL 数据层解密后的内容,因此在使用 “ssl” 选项的 “server” 配置行中无法生效。该功能主要用于 ACL 中检测预期包含可用于会话粘性的 SSL 会话 ID 的 SSL 握手消息。

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

可以在 HTTP 内容、请求和响应中获取样本。此应用层也称为第 7 层。只有在已从相应的请求或响应缓冲区完整解析出 HTTP 请求或响应后,才能在此段中获取数据。所有 HTTP 特定规则以及以 “mode http” 运行的段均始终满足此条件。在使用 TCP 内容检查时,可能需要支持检查延迟,以确保请求或响应先到达。此类获取操作所需的 CPU 资源可能略多于第 4 层操作,但差异不大,因为请求和响应已建立索引。

请注意:关于 tcp-request 内容规则中的 HTTP 处理,从 HTTP 代理角度看,所有功能均可按预期工作。但从 TCP 代理角度看,若未进行 HTTP 升级,则仅支持 HTTP/1 内容。对于 HTTP/2 内容,仅能访问前缀部分。因此,仅可依赖 “req.proto_http”、“req.ver” 以及可选的 “method” 样本提取。其他所有 L7 样本提取将失败。HTTP 升级完成后,其行为将与从 HTTP 代理中获取时相同。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                          output type
-------------------------------------------------+-------------
base                                               string
base32                                             integer
base32+src                                         binary
baseq                                              string
capture.req.hdr(<idx>)                             string
capture.req.method                                 string
capture.req.uri                                    string
capture.req.ver                                    string
capture.res.hdr(<idx>)                             string
capture.res.ver                                    string
cook([<name>])                                     string
cook_cnt([<name>])                                 integer
cook_val([<name>])                                 integer
cookie([<name>])                                   string
hdr([<name>[,<occ>]])                              string
hdr_cnt([<header>])                                integer
hdr_ip([<name>[,<occ>]])                           ip
hdr_val([<name>[,<occ>]])                          integer
http_auth(<userlist>)                              boolean
http_auth_bearer([<header>])                       string
http_auth_group(<userlist>)                        string
http_auth_pass                                     string
http_auth_type                                     string
http_auth_user                                     string
http_first_req                                     boolean
method                                             integer
path                                               string
pathq                                              string
query([<options>])                                 string
req.body                                           binary
req.body_len                                       integer
req.body_param([<name>[,i]])                       string
req.body_size                                      integer
req.cook([<name>])                                 string
req.cook_cnt([<name>])                             integer
req.cook_names([<delim>])                          string
req.cook_val([<name>])                             integer
req.fhdr(<name>[,<occ>])                           string
req.fhdr_cnt([<name>])                             integer
req.hdr([<name>[,<occ>]])                          string
req.hdr_cnt([<name>])                              integer
req.hdr_ip([<name>[,<occ>]])                       ip
req.hdr_names([<delim>])                           string
req.hdr_val([<name>[,<occ>]])                      integer
req.hdrs                                           string
req.hdrs_bin                                       binary
req.timer.hdr                                      integer
req.timer.idle                                     integer
req.timer.queue                                    integer
req.timer.tq                                       integer
req.ver                                            string
req_ver                                            string
request_date([<unit>])                             integer
res.body                                           binary
res.body_len                                       integer
res.body_size                                      integer
res.cache_hit                                      boolean
res.cache_name                                     string
res.comp                                           boolean
res.comp_algo                                      string
res.cook([<name>])                                 string
res.cook_cnt([<name>])                             integer
res.cook_names([<delim>])                          string
res.cook_val([<name>])                             integer
res.fhdr([<name>[,<occ>]])                         string
res.fhdr_cnt([<name>])                             integer
res.hdr([<name>[,<occ>]])                          string
res.hdr_cnt([<name>])                              integer
res.hdr_ip([<name>[,<occ>]])                       ip
res.hdr_names([<delim>])                           string
res.hdr_val([<name>[,<occ>]])                      integer
res.hdrs                                           string
res.hdrs_bin                                       binary
res.timer.hdr                                      integer
res.ver                                            string
resp_ver                                           string
scook([<name>])                                    string
scook_cnt([<name>])                                integer
scook_val([<name>])                                integer
server_status                                      integer
set-cookie([<name>])                               string
shdr([<name>[,<occ>]])                             string
shdr_cnt([<name>])                                 integer
shdr_ip([<name>[,<occ>]])                          ip
shdr_val([<name>[,<occ>]])                         integer
status                                             integer
txn.status                                         integer
txn.timer.total                                    integer
unique-id                                          string
url                                                string
url32                                              integer
url32+src                                          binary
url_ip                                             ip
url_param([<name>[,<delim>[,i]]])                  string
url_port                                           integer
urlp([<name>[,<delim>[,i]]])                       string
urlp_val([<name>[,<delim>[,i]]])                   integer
-------------------------------------------------+-------------

详细列表:

base: string 该选项返回请求的首个 Host 头与路径部分的拼接结果,路径部分从第一个斜杠开始,到问号前结束。在虚拟主机环境中,此选项可用于检测 URL 滥用,同时提升共享缓存的效率。结合有限大小的粘性表使用,还可统计按主机/路径划分的最常请求对象的访问情况。配合 ACL 可实现同时涉及主机和路径的简单内容切换规则,例如 “www.example.com/favicon.ico "。另请参见 “path” 和 “uri”。

ACL 衍生规则:

base    : exact string match
base_beg: prefix match
base_dir: subdir match
base_dom: domain match
base_end: suffix match
base_len: length match
base_reg: regex match
base_sub: substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

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.req.hdr(<idx>): string

此用于提取由 “capture request header” 捕获的头内容,idx 为配置中捕获关键字的位置,首个条目索引为 0。参见:“capture request header”。

capture.req.method: string 该选项用于捕获 HTTP 请求的方法。可在请求和响应中使用。与 “method” 不同,它可在请求和响应中均使用,因为其已分配内存。

capture.req.uri: string 该选项用于捕获请求的 URI,其范围从第一个斜杠开始,到请求中第一个空格之前结束(不包含主机部分)。与“path”和“url”不同,它可在请求和响应中使用,因为其内存已分配。

capture.req.ver: string 该选项用于提取请求的 HTTP 版本,并以 “HTTP/<major>.<minor>” 的格式返回。由于依赖持久化信息,该选项可在请求、响应及日志中使用。若请求版本无效,则该样本提取操作失败。

capture.res.hdr(<idx>): string

capture.res.hdr(<idx>): string

此用于提取由 “capture response header” 捕获的头内容,idx 为配置中捕获关键字的位置,首个条目索引为 0。参见:“capture response header”

capture.res.ver: string 该选项用于提取响应的 HTTP 版本,并以 “HTTP/<major>.<minor>” 的格式返回。由于依赖持久化信息,该选项可用于日志记录。若响应版本无效,则该样本提取操作失败。

cookie([<name>]): string (deprecated)

cookie([<name>]): string (deprecated)

提取请求中 “Cookie” 头字段或响应中 “Set-Cookie” 头字段里最后一个名为 <name> 的 Cookie 值,并以字符串形式返回。典型用途是让共享同一配置文件的多个客户端始终使用同一台服务器。这与使用 “request-learn” 语句时 “appsession” 的功能类似,但支持多对等节点同步以及重启后的状态保持。若未指定名称,则返回第一个 Cookie 值。此获取方式已不再推荐使用,应改用 req.cook() 或 res.cook(),因为该方式在不同使用上下文中会根据方向产生歧义。

hdr([<name>[,<occ>]]): string

hdr([<name>[,<occ>]]): string

这与在请求上使用时的 req.hdr() 等效,与在响应上使用时的 res.hdr() 等效。 请参考相应的样本提取方法以获取更多详细信息。 如对样本提取方向存在疑问,请使用明确的版本。 请注意,与 hdr() 样本提取方法不同,hdr_* ACL 关键字明确应用于请求头。

http_auth(<userlist>): boolean

http_auth(<userlist>): boolean

返回一个布尔值,指示从客户端接收到的认证数据是否与指定 userlist 中存储的用户名和密码匹配。此获取函数在 ACL 之外基本无用。当前仅支持 HTTP Basic 认证。

http_auth_bearer([<header>]): string

http_auth_bearer([<header>]): string

当使用 Bearer 方案时(例如发送 JSON Web Token),返回客户端在授权数据中提供的令牌。不会对客户端发送的数据进行校验。若提供了特定的 <header>,则会解析该头字段而非 Authorization 头。

http_auth_group(<userlist>): string

http_auth_group(<userlist>): string

返回与客户端发送的认证数据中匹配的用户名字符串,前提是该用户名和密码均符合指定 userlist 的验证规则。主要用途是在 ACL 中使用,以检查该用户是否属于列表中的任意组。此获取函数在 ACL 之外基本无实际用途。当前仅支持 HTTP Basic 认证。

ACL 衍生规则:

http_auth_group(<userlist>): group ...
Returns true when the user extracted from the request and whose password is
valid according to the specified userlist belongs to at least one of the
groups.

http_auth_pass: string 返回从客户端接收到的认证数据中的用户密码,该数据由 Authorization 头提供。本样本提取不执行任何校验。仅支持 Basic 认证。

http_auth_type: string 返回从客户端接收的认证数据中找到的认证方法,该数据由 Authorization 头提供。本样本不执行任何检查。仅支持 Basic 认证。

http_auth_user: string 返回从客户端接收的认证数据中提取的用户名,该数据由 Authorization 头提供。本样本提取不执行任何校验。仅支持 Basic 认证。

http_first_req:boolean 当正在处理的请求是该连接中的第一个请求时,返回 true。此字段可用于添加或移除某些请求中可能缺失的头,尤其是在请求非首个时;也可用于帮助在日志中对请求进行分组。

method: 整数 + 字符串 返回与 HTTP 请求中的方法对应的整数值。 例如,“GET” 对应值 1(请查阅源码以确认对应关系)。值 9 表示“其他方法”,可转换为从流中提取的字符串。此值不应直接作为样本使用,仅用于 ACL,ACL 会透明地将模式中的方法转换为整数 + 字符串值。部分预定义的 ACL 已经检查最常见的方法。

ACL 衍生规则:

method: case insensitive method match

示例:

# only accept GET and HEAD requests
acl valid_method method GET HEAD
http-request deny if ! valid_method

path: string 该选项提取请求的 URL 路径,路径从第一个斜杠开始,到问号前结束(不包含主机部分)。典型用途包括与支持预取的缓存配合使用,以及用于需要从多个数据库聚合信息并将其存入缓存的门户。请注意,对于出站缓存,使用 “url” 选项更为合适。在 ACL 中,通常用于匹配精确的文件名(例如 “/login.php”),或使用其衍生形式匹配目录部分。另请参阅 “url” 和 “base” 获取方法。请注意,URI 中的任何片段引用(路径后的 ‘#’)均严格违反 HTTP 标准,将被拒绝。然而,如果接收请求的前端配置了 “option accept-unsafe-violations-in-http-request”,则该片段部分将被接受,并同样出现在路径中。

ACL 衍生规则:

path    : exact string match
path_beg: prefix match
path_dir: subdir match
path_dom: domain match
path_end: suffix match
path_len: length match
path_reg: regex match
path_sub: substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

pathq: string 该样本提取从第一个斜杠开始获取请求的 URL 路径及查询字符串。此样本提取方式非常实用,可始终获取相对 URI,排除协议和权威部分(如存在)。实际上,尽管 HTTP/1.1 请求目标通常采用此种形式,但在 HTTP/2 中常使用绝对 URI。此样本提取在两种情况下均返回相同结果。请注意,URI 中的片段引用(路径后的 ‘#’)严格违反 HTTP 标准,将被拒绝。然而,若接收请求的前端配置了 “option accept-unsafe-violations-in-http-request”,则该片段部分将被接受,并包含在路径中。

query([<options>]): string

query([<options>]): string

提取请求的查询字符串,该字符串从第一个问号之后开始。若不存在问号,则此获取操作返回空值。若存在问号但其后无内容,则返回空字符串。这意味着可借助“found”匹配方法轻松判断查询字符串是否存在。此获取操作与“path”互补,后者在问号前停止;也与 “query_string” 互补,后者包含问号。

可选参数可用于自定义返回值。支持以下选项:

- with_qm: Include the question mark at the beginning ot the query string,
            if not empty.

req.body: binary 此函数返回 HTTP 请求的可用请求体作为数据块。建议启用 “option http-buffer-request”,以确保尽可能等待请求体的完整接收。

req.body_len: integer 此字段返回 HTTP 请求可用正文的字节数。如果正文长度超过缓冲区大小,该值可能低于声明的长度。建议启用 “option http-buffer-request”,以尽可能等待请求正文的完整接收。

req.body_param([<name>[,i]]): string

req.body_param([<name>[,i]]): string

本文假设 POST 请求的请求体为 URL 编码格式。用户可检查 “content-type” 是否包含 “application/x-www-form-urlencoded” 值。该提取操作会获取请求体中第一个出现的参数 <name>,其值在遇到 ‘&’ 前结束。参数名区分大小写,除非额外添加 “i” 作为第二个参数。若未指定参数名,则匹配任意参数,返回第一个匹配项。结果为请求体中参数 <name> 对应的值字符串(不执行 URL 解码)。请注意,ACL 版本的此提取操作会遍历多个参数,若未指定参数名,则会依次报告所有参数的值。

req.body_size: integer 返回 HTTP 请求体的声明长度(以字节为单位)。该值表示声明的 Content-Length 头,或在使用分块编码时可用数据的大小。

req.cook([<name>]): string

req.cook([<name>]): string
cook([<name>]): string (deprecated)

提取请求中 “Cookie” 头字段行里最后一个名为 <name> 的 Cookie 值,并以字符串形式返回。若未指定名称,则返回第一个 Cookie 值。在与 ACL 配合使用时,将评估所有匹配的 Cookie。根据 Cookie 头规范(RFC6265)要求,名称和值周围的空格将被忽略。Cookie 名称区分大小写。空 Cookie 为有效值,因此若存在空 Cookie,其值可能为空。请使用 “found” 匹配来检测其存在性。对服务器发送的响应 Cookie,请使用 res.cook() 变体。

ACL 衍生规则:

req.cook([<name>])    : exact string match
req.cook_beg([<name>]): prefix match
req.cook_dir([<name>]): subdir match
req.cook_dom([<name>]): domain match
req.cook_end([<name>]): suffix match
req.cook_len([<name>]): length match
req.cook_reg([<name>]): regex match
req.cook_sub([<name>]): substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

req.cook_cnt([<name>]): integer

req.cook_cnt([<name>]): integer
cook_cnt([<name>]): integer (deprecated)

返回一个整数值,表示请求中出现的 cookie <name> 的次数,若未指定 <name>,则表示所有 cookie 的数量。

req.cook_names([<delim>]): string

req.cook_names([<delim>]): string

此操作构建一个字符串,该字符串由规则评估时请求中出现的所有 Cookie 名称(来自 Cookie 头)连接而成。默认分隔符为逗号(’,’),但可作为可选参数 <delim> 覆盖。此时,仅考虑 <delim> 的第一个字符。

req.cook_val([<name>]): integer

req.cook_val([<name>]): integer
cook_val([<name>]): integer (deprecated)

从请求的 “Cookie” 头中提取名称为 <name> 的最后一个 Cookie 实例,并将其值转换为整数后返回。若未指定名称,则返回第一个 Cookie 值。在 ACL 中使用时,将遍历所有匹配的名称,直至找到一个值匹配为止。

req.fhdr(<name>[,<occ>]): string

req.fhdr(<name>[,<occ>]): string

返回 HTTP 请求中头 <name> 最后一次出现的完整值。与 req.hdr() 的区别在于,值中包含的任何逗号都会被原样返回,不会作为分隔符使用。在处理如 User-Agent 等头时,此功能有时很有用。

在 ACL 中使用时,将遍历所有出现的项,直到找到匹配项为止。

可选地,可指定特定出现位置为位置编号。正值表示从首次出现开始的位置,1 代表第一个。负值表示相对于最后一个位置,-1 代表最后一个。

req.fhdr_cnt([<name>]): integer

req.fhdr_cnt([<name>]): integer

返回一个整数值,表示请求头字段名 <name> 的出现次数,若未指定 <name>,则返回头字段的总数。与 res.hdr_cnt() 不同,它不会在逗号处拆分头字段,这一点与 req.fhdr() 一致。

req.hdr([<name>[,<occ>]]): string

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>]])    : exact string match
hdr_beg([<name>[,<occ>]]): prefix match
hdr_dir([<name>[,<occ>]]): subdir match
hdr_dom([<name>[,<occ>]]): domain match
hdr_end([<name>[,<occ>]]): suffix match
hdr_len([<name>[,<occ>]]): length match
hdr_reg([<name>[,<occ>]]): regex match
hdr_sub([<name>[,<occ>]]): substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

req.hdr_cnt([<name>]): integer

req.hdr_cnt([<name>]): integer
hdr_cnt([<header>]): integer (deprecated)

返回一个整数值,表示请求头字段名 <name> 的出现次数,若未指定 <name>,则返回头字段值的总数量。与 req.hdr() 类似,它会统计头字段值中每个以逗号分隔的部分。若需统计完整行头的出现次数,则应改用 req.fhdr_cnt()。

通过 ACL,可用来检测特定头的存在、缺失或滥用情况,也可通过拒绝包含某些头字段多个实例的请求,阻止请求走私攻击。

有关头匹配的更多信息,请参见 req.hdr()。

req.hdr_ip([<name>[,<occ>]]): ip

req.hdr_ip([<name>[,<occ>]]): ip
hdr_ip([<name>[,<occ>]]): ip (deprecated)

提取 HTTP 请求中头 <name> 的最后一次出现,将其转换为 IPv4 或 IPv6 地址并返回该地址。与 ACL 配合使用时,将检查所有出现,若 <name> 被省略,则检查每个头的每个值。解析器严格遵循 RFC7239 中描述的格式,但允许 IPv4 地址可选地后跟冒号(’:’)和有效的十进制端口号(0 至 65535),该端口号将被静默丢弃。其他所有格式均不匹配,导致地址被忽略。

<occ> 参数的处理方式与 req.hdr() 相同。

典型用法是与 X-Forwarded-For 和 X-Client-IP 头配合使用。

req.hdr_names([<delim>]): string

req.hdr_names([<delim>]): string

此操作构建一个字符串,该字符串由请求中所有头字段名称按其出现顺序拼接而成。默认分隔符为逗号(’,’),但可作为可选参数 <delim> 覆盖。此时仅考虑 <delim> 的第一个字符。

req.hdr_val([<name>[,<occ>]]): integer

req.hdr_val([<name>[,<occ>]]): integer
hdr_val([<name>[,<occ>]]): integer (deprecated)

提取 HTTP 请求中头 <name> 的最后一次出现,并将其转换为整数值。与 ACL 配合使用时,将检查所有出现的头,若省略 <name>,则检查每个头的每个值。

<occ> 参数的处理方式与 req.hdr() 相同。

典型用法是与 X-Forwarded-For 头配合使用。

req.hdrs: string 返回当前请求头作为字符串,包含分隔头与请求体的最后一个空行。最后一个空行可用于检测头块是否被截断。该样本提取功能对某些 SPOE 头分析器及高级日志记录非常有用。

req.hdrs_bin:以预解析的二进制形式返回当前请求头。此功能适用于通过 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: 整数 该值表示 HTTP 请求的空闲时间(仅限 HTTP 模式)。此计时器统计握手完成与首个 HTTP 请求字节到达之间的时长。单位为毫秒,等效于日志格式中的 %Ti。详见 第 8.4 节 “时间事件”。

req.timer.queue: 整数 用于等待连接槽位的队列中累计耗时。单位为毫秒,等同于日志格式中的 %Tw。详见 第 8.4 节 “时间事件” 获取更多详情。

req.timer.tq:整数,从接受连接时间或上一个响应最后一个字节发出后开始计算,获取客户端请求所花费的总时间。单位为毫秒,等同于日志格式中的 %Tq。详细信息请参见 第 8.4 节 “时间事件”。

req.ver: string req_ver: string(已弃用) 返回 HTTP 请求中的版本字符串,格式为 “<major>.<minor>"。该字段可用于 ACL。部分预定义的 ACL 已经针对常见版本进行检查。由于依赖持久化信息,该样本提取可在请求、响应及日志中使用。若请求版本无效,该样本提取将失败。

常用值为 “1.0”、“1.1”、“2.0” 或 “3.0”。

ACL 衍生规则:

req.ver: exact string match

request_date([<unit>]): integer

request_date([<unit>]): integer

这是 HAProxy 首次接收到 HTTP 请求第一个字节的精确时间(日志格式别名 %tr)。该时间由 accept_date + 握手时间 (%Th) + 空闲时间 (%Ti) 计算得出。

返回自纪元以来的秒数。

<unit> 为可选配置,可设置为 “s” 表示秒(默认行为)、“ms” 表示毫秒或 “us” 表示微秒。若指定单位,返回值为整数,表示自纪元以来的秒、毫秒或微秒数。当需要小于秒级的时间分辨率时,该配置非常有用。

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”。

res.cache_name: string 返回一个字符串,其中包含用于构建 HTTP 响应的 HTTP 缓存名称;若 res.cache_hit 为 true,则返回该缓存名称,否则返回空字符串。

res.comp: boolean 如果响应被 HAProxy 压缩,则返回布尔值 “true”,否则返回布尔值 “false”。此值可用于在日志中添加信息。

res.comp_algo: string 返回一个字符串,其中包含 HAProxy 对响应进行压缩时所使用的算法名称,例如:“deflate”。此字段可用于在日志中添加相关信息。

res.cook([<name>]): string

res.cook([<name>]): string
scook([<name>]): string (deprecated)

从响应的 “Set-Cookie” 头中提取名称为 <name> 的 cookie 的最后一次出现值,并以字符串形式返回。若未指定名称,则返回第一个 cookie 值。

可在基于 tcp-check 的 expect 规则中使用。

ACL 衍生规则:

res.scook([<name>]: exact string match

res.cook_cnt([<name>]): integer

res.cook_cnt([<name>]): integer
scook_cnt([<name>]): integer (deprecated)

返回一个整数值,表示响应中出现的 cookie <name> 的次数,若未指定 <name>,则表示所有 cookie 的数量。此功能主要用于结合 ACL 使用,以检测可疑响应。

可在基于 tcp-check 的 expect 规则中使用。

res.cook_names([<delim>]): string

res.cook_names([<delim>]): string

此操作构建一个字符串,该字符串由规则被评估时响应中(Set-Cookie 头)出现的所有 Cookie 名称拼接而成。默认分隔符为逗号(’,’),但可作为可选参数 <delim> 覆盖。此时,仅考虑 <delim> 的第一个字符。

可在基于 tcp-check 的 expect 规则中使用。

res.cook_val([<name>]): integer

res.cook_val([<name>]): integer
scook_val([<name>]): integer (deprecated)

从响应的 “Set-Cookie” 头中提取 <name> 的最后一次出现,将其值转换为整数并返回。若未指定名称,则返回第一个 cookie 值。

可在基于 tcp-check 的 expect 规则中使用。

res.fhdr([<name>[,<occ>]]): string

res.fhdr([<name>[,<occ>]]): string

此获取方式的功能与 req.fhdr() 获取方式类似,区别在于它作用于 HTTP 响应中的头。

与 req.fhdr() 类似,res.fhdr() 返回完整的值。如果头被定义为列表,则应使用 res.hdr()。

此获取方式在处理 Date 或 Expires 等头时有时很有用。

可在基于 tcp-check 的 expect 规则中使用。

res.fhdr_cnt([<name>]): integer

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

res.hdr([<name>[,<occ>]]): string
shdr([<name>[,<occ>]]): string (deprecated)

此获取方式与 req.hdr() 获取方式类似,区别在于它作用于 HTTP 响应中的头。

与 req.hdr() 类似,res.hdr() 获取器会将逗号视为分隔符。若不希望如此,应使用 res.fhdr()。

可在基于 tcp-check 的 expect 规则中使用。

ACL 衍生规则:

res.hdr([<name>[,<occ>]])    : exact string match
res.hdr_beg([<name>[,<occ>]]): prefix match
res.hdr_dir([<name>[,<occ>]]): subdir match
res.hdr_dom([<name>[,<occ>]]): domain match
res.hdr_end([<name>[,<occ>]]): suffix match
res.hdr_len([<name>[,<occ>]]): length match
res.hdr_reg([<name>[,<occ>]]): regex match
res.hdr_sub([<name>[,<occ>]]): substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

res.hdr_cnt([<name>]): integer

res.hdr_cnt([<name>]): integer
shdr_cnt([<name>]): integer (deprecated)

此获取方式的功能与 req.hdr_cnt() 获取方式类似,区别在于它作用于 HTTP 响应中的头。

与 req.hdr_cnt() 类似,res.hdr_cnt() 也把逗号视为分隔符。若不希望如此,应使用 res.fhdr_cnt()。

可在基于 tcp-check 的 expect 规则中使用。

res.hdr_ip([<name>[,<occ>]]): ip

res.hdr_ip([<name>[,<occ>]]): ip
shdr_ip([<name>[,<occ>]]): ip (deprecated)

此获取方式的功能与 req.hdr_ip() 获取方式类似,区别在于它作用于 HTTP 响应中的头。

这可用于将部分数据载入粘性表。

可在基于 tcp-check 的 expect 规则中使用。

res.hdr_names([<delim>]): string

res.hdr_names([<delim>]): string

此操作构建一个字符串,该字符串由响应中规则被评估时出现的所有头名称拼接而成。默认分隔符为逗号(’,’),但可作为可选参数 <delim> 覆盖。此时,仅考虑 <delim> 的第一个字符。

可在基于 tcp-check 的 expect 规则中使用。

res.hdr_val([<name>[,<occ>]]): integer

res.hdr_val([<name>[,<occ>]]): integer
shdr_val([<name>[,<occ>]]): integer (deprecated)

此获取方式的功能与 req.hdr_val() 获取方式类似,区别在于它作用于 HTTP 响应中的头。

这可用于将部分数据载入粘性表。

可在基于 tcp-check 的 expect 规则中使用。

res.hdrs: string 返回当前响应头作为字符串,包含分隔头与请求体的最后一个空行。最后一个空行可用于检测头块是否被截断。该样本提取方法适用于某些 SPOE 头分析器及高级日志记录。

也可用于基于 tcp-check 的 expect 规则中。

res.hdrs_bin:以预解析的二进制形式返回当前响应头。此功能可用于将部分处理任务卸载至 SPOE。可在基于 tcp-check 的 expect 规则中使用。每个字符串由长度字段后接长度指定的字节数构成。长度采用 SPOE 文档中详述的可变整数编码方式表示。列表末尾以一对空头名称和值(两者长度均为 0)标记。

*(<str:header-name>`` <str:header-value>)<empty string> ``<empty string>

int:请参阅 SPOE 文档以了解编码格式;str:<int:length>`` <bytes>

res.timer.hdr: integer 表示从建立与服务器的 TCP 连接时刻到服务器发送完整响应头时刻之间所经过的时间。该值以毫秒为单位报告,等同于日志格式中的 %Tr。有关更多详细信息,请参见 第 8.4 节 “时间事件”。

res.ver: string resp_ver: string (已弃用) 返回 HTTP 响应中的版本字符串,格式为 “<major>.<minor>"。该字段可用于日志记录,但主要用于 ACL。若响应版本无效,此样本提取将失败。

可在基于 tcp-check 的 expect 规则中使用。

ACL 衍生规则:

resp.ver: exact string match

server_status: integer 返回一个整数,其中包含从服务器接收到的 HTTP 状态码。如果未从服务器接收到响应,样本提取将失败。

set-cookie([<name>]): string (deprecated)

set-cookie([<name>]): string (deprecated)

从响应的 “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 样本提取失败。请注意,唯一 ID 通常用于 HTTP 请求,但此样本提取可与其他协议一同使用。显然,若用于非 HTTP 协议,“unique-id-format” 指令不得包含 HTTP 相关部分。参见:unique-id-format 和 unique-id-header

url: string 此字段提取请求中呈现的请求 URL。典型用途包括与支持预取的缓存配合使用,以及用于需要从多个数据库聚合信息并将其保留在缓存中的门户。在使用 ACL 时,应优先选择使用 “path” 而非 “url”,因为客户端可能像通常对代理那样发送完整 URL。唯一真正的用途是匹配 “*",该匹配在 “path” 中无法实现,且已有预定义的 ACL 可处理此情况。另请参见 “path” 和 “base”。请注意,URI 中的任何片段引用(路径后的 ‘#’)均严格违反 HTTP 标准,将被拒绝。然而,如果接收请求的前端配置了 “option accept-unsafe-violations-in-http-request”,则该片段部分将被接受,并且也会出现在 url 中。

ACL 衍生规则:

url    : exact string match
url_beg: prefix match
url_dir: subdir match
url_dom: domain match
url_end: suffix match
url_len: length match
url_reg: regex match
url_sub: substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

32 位 URL 哈希:整数 该选项返回由首个 Host 头与完整 URL(包括参数)拼接后生成的 32 位哈希值(不同于“base32”获取方式中仅使用请求路径部分)。此方法适用于追踪每个 URL 的活动情况。由于存储的是较短的哈希值,可显著节省内存。输出类型为无符号整数。

url32+src:二进制 该指令返回 “url32” 获取项与 “src” 获取项的拼接结果。结果类型为二进制,长度为 8 字节或 20 字节,具体取决于源地址族。可用于跟踪每个 IP 地址、每个 URL 的计数器。

url_ip: ip 当请求的主机部分以 IP 地址形式呈现时,此选项用于从请求的 URL 中提取 IP 地址。其使用范围非常有限。例如,监控系统可使用此字段作为源 IP 的替代,以测试特定源地址将遵循的路径,或为特定源地址强制在表中添加条目。可与 http-request set-dst 配合使用,以模拟旧版的 option http_proxy。

url_port: integer 从请求的 URL 中提取端口部分。请注意,若请求中未指定端口,则默认使用端口 80。

urlp([<name>[,<delim>[,i]]]): string

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>])    : exact string match
urlp_beg(<name>[,<delim>]): prefix match
urlp_dir(<name>[,<delim>]): subdir match
urlp_dom(<name>[,<delim>]): domain match
urlp_end(<name>[,<delim>]): suffix match
urlp_len(<name>[,<delim>]): length match
urlp_reg(<name>[,<delim>]): regex match
urlp_sub(<name>[,<delim>]): substring match

请注意:ACL 衍生规则不得在后续使用转换器,或在采用“-m”模式匹配方法的 ACL 中使用。

示例:

# match http://example.com/foo?PHPSESSIONID=some_id
stick on urlp(PHPSESSIONID)
# match http://example.com/foo;JSESSIONID=some_id
stick on urlp(JSESSIONID,;)

urlp_val([<name>[,<delim>[,i]]]): integer

urlp_val([<name>[,<delim>[,i]]]): integer

参见上方的 “urlp”。此选项从请求中提取 URL 参数 <name> 并将其转换为整数值。可用于基于用户 ID 的会话粘性,或与 ACL 配合匹配页码或价格。

7.3.7. 获取开发者样本

本组样本提取方法专为开发者保留,严禁在生产环境中使用,除非开发者明确要求,且仅用于调试目的。此外,不会对向后兼容性进行特别维护。无法保证以下样本提取方法不会发生变更、重命名或被直接移除。因此,若必须使用其中任一方法,请务必谨慎。为避免任何歧义,这些样本提取方法均置于专用作用域 “internal” 中,例如 “internal.strm.is_htx”。

本节中各类样本提取方法及其对应类型的摘要:

  keyword                                          output type
-------------------------------------------------+-------------
internal.htx.data                                  integer
internal.htx.free                                  integer
internal.htx.free_data                             integer
internal.htx.has_eom                               boolean
internal.htx.nbblks                                integer
internal.htx.size                                  integer
internal.htx.used                                  integer
internal.htx_blk.size(<idx>)                       integer
internal.htx_blk.type(<idx>)                       string
internal.htx_blk.data(<idx>)                       binary
internal.htx_blk.hdrname(<idx>)                    string
internal.htx_blk.hdrval(<idx>)                     string
internal.htx_blk.start_line(<idx>)                 string
internal.strm.is_htx                               boolean
-------------------------------------------------+-------------

详细列表:

internal.htx.data: integer 返回与通道关联的 HTX 消息中数据所占用的字节数。通道的选择取决于样本方向。

internal.htx.free: 整数 返回与通道关联的 HTX 消息中空闲空间(大小 - 已用)的字节数。通道的选择取决于样本方向。

internal.htx.free_data: integer 返回与通道关联的 HTX 消息中数据部分的可用字节数。通道的选择取决于样本方向。

internal.htx.has_eom: boolean 如果与通道关联的 HTX 消息包含消息结束标志(EOM),则返回 true;否则返回 false。通道的选择取决于样本方向。

internal.htx.nbblks: integer 返回与通道关联的 HTX 消息中包含的块数量。通道的选择取决于样本方向。

internal.htx.size: integer 返回与通道关联的 HTX 消息的总字节数。通道的选择取决于样本方向。

internal.htx.used: integer 返回与通道关联的 HTX 消息中已使用的总字节数(数据 + 元数据)。通道的选择取决于样本方向。

internal.htx_blk.size(<idx>): integer

internal.htx_blk.size(<idx>): integer

返回与通道关联的 HTX 消息中位置 <idx> 处块的大小,若该块不存在则返回 0。通道的选择取决于样本方向。<idx> 可以是任意正整数,或以下特殊值之一: - head:最旧插入的块 - tail:最新插入的块 - first:分析(重新)开始的第一个块

internal.htx_blk.type(<idx>): string

internal.htx_blk.type(<idx>): string

返回与通道关联的 HTX 消息中位置 <idx> 处块的类型,若该块不存在则返回 “HTX_BLK_UNUSED”。通道的选择取决于样本方向。<idx> 可为任意正整数,或以下特殊值之一: * head:最旧插入的块 * tail:最新插入的块 * first:分析(重新)开始的第一个块

internal.htx_blk.data(<idx>): binary

internal.htx_blk.data(<idx>): binary

返回与通道关联的 HTX 消息中位置 <idx> 处的 DATA 块的值,若该位置不存在或其非 DATA 块,则返回空字符串。通道的选择取决于样本方向。<idx> 可为任意正整数,或以下特殊值之一:

* head : The oldest inserted block
* tail : The newest inserted block
* first: The first block where to (re)start the analysis

internal.htx_blk.hdrname(<idx>): string

internal.htx_blk.hdrname(<idx>): string

返回与通道关联的 HTX 消息中位置 <idx> 处的 HEADER 块的头名称,若该块不存在或不是 HEADER 块,则返回空字符串。通道的选择取决于样本方向。<idx> 可以是任意正整数,或以下特殊值之一:

* head : The oldest inserted block
* tail : The newest inserted block
* first: The first block where to (re)start the analysis

internal.htx_blk.hdrval(<idx>): string

internal.htx_blk.hdrval(<idx>): string

返回与通道关联的 HTX 消息中位置 <idx> 处的 HEADER 块的头值,若该块不存在或不是 HEADER 块,则返回空字符串。通道的选择取决于样本方向。<idx> 可以是任意正整数,或以下特殊值之一:

* head : The oldest inserted block
* tail : The newest inserted block
* first: The first block where to (re)start the analysis

internal.htx_blk.start_line(<idx>): string

internal.htx_blk.start_line(<idx>): string

返回通道关联的 HTX 消息中位置 <idx> 处的 REQ_SL 或 RES_SL 块的值,若该块不存在或不是 SL 块,则返回空字符串。通道的选择取决于样本方向。<idx> 可以是任意正整数,或以下特殊值之一:

* head : The oldest inserted block
* tail : The newest inserted block
* first: The first block where to (re)start the analysis

internal.strm.is_htx: boolean 如果当前流为 HTX 流,则返回 true。这意味着通道缓冲区中的数据采用内部 HTX 表示形式存储。否则,返回 false。

7.4. 预定义访问控制列表

部分预定义的 ACL 已被硬编码,因此无需在每个需要它们的前端中声明。它们的名称均采用大写形式,以避免混淆。其等效性如下所示。

ACL name          Equivalent to                Usage
---------------+----------------------------------+------------------------------------------------------
FALSE            always_false                       never match
HTTP             req.proto_http                     match if request protocol is valid HTTP
HTTP_1.0         req.ver 1.0                        match if HTTP request version is 1.0
HTTP_1.1         req.ver 1.1                        match if HTTP request version is 1.1
HTTP_2.0         req.ver 2.0                        match if HTTP request version is 2.0
HTTP_3.0         req.ver 3.0                        match if HTTP request version is 3.0
HTTP_CONTENT     req.hdr_val(content-length) gt 0   match an existing content-length in the HTTP request
HTTP_URL_ABS     url_reg ^[^/:]*://                 match absolute URL with scheme
HTTP_URL_SLASH   url_beg /                          match URL beginning with "/"
HTTP_URL_STAR    url     *                          match URL equal to "*"
LOCALHOST        src 127.0.0.1/8::1                match connection from local host
METH_CONNECT     method  CONNECT                    match HTTP CONNECT method
METH_DELETE      method  DELETE                     match HTTP DELETE method
METH_GET         method  GET HEAD                   match HTTP GET or HEAD method
METH_HEAD        method  HEAD                       match HTTP HEAD method
METH_OPTIONS     method  OPTIONS                    match HTTP OPTIONS method
METH_POST        method  POST                       match HTTP POST method
METH_PUT         method  PUT                        match HTTP PUT method
METH_TRACE       method  TRACE                      match HTTP TRACE method
RDP_COOKIE       req.rdp_cookie_cnt gt 0            match presence of an RDP cookie in the request buffer
REQ_CONTENT      req.len gt 0                       match data in the request buffer
TRUE             always_true                        always match
WAIT_END         wait_end                           wait for end of content analysis
---------------+----------------------------------+------------------------------------------------------