7.1. ACL basics

  1. The use of Access Control Lists (ACL) provides a flexible solution to perform
  2. content switching and generally to take decisions based on content extracted
  3. from the request, the response or any environmental status. The principle is
  4. simple :
  5.  
  6. - extract a data sample from a stream, table or the environment
  7. - optionally apply some format conversion to the extracted sample
  8. - apply one or multiple pattern matching methods on this sample
  9. - perform actions only when a pattern matches the sample
  10.  
  11. The actions generally consist in blocking a request, selecting a backend, or
  12. adding a header.
  13.  
  14. In order to define a test, the "acl" keyword is used. The syntax is :
  15.  
  16. acl <aclname> <criterion> [flags] [operator] [<value>] ...
  17.  
  18. This creates a new ACL <aclname> or completes an existing one with new tests.
  19. Those tests apply to the portion of request/response specified in <criterion>
  20. and may be adjusted with optional flags [flags]. Some criteria also support
  21. an operator which may be specified before the set of values. Optionally some
  22. conversion operators may be applied to the sample, and they will be specified
  23. as a comma-delimited list of keywords just after the first keyword. The values
  24. are of the type supported by the criterion, and are separated by spaces.
  25.  
  26. ACL names must be formed from upper and lower case letters, digits, '-' (dash),
  27. '_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive,
  28. which means that "my_acl" and "My_Acl" are two different ACLs.
  29.  
  30. There is no enforced limit to the number of ACLs. The unused ones do not affect
  31. performance, they just consume a small amount of memory.
  32.  
  33. The criterion generally is the name of a sample fetch method, or one of its ACL
  34. specific declinations. The default test method is implied by the output type of
  35. this sample fetch method. The ACL declinations can describe alternate matching
  36. methods of a same sample fetch method. The sample fetch methods are the only
  37. ones supporting a conversion.
  38.  
  39. Sample fetch methods return data which can be of the following types :
  40. - boolean
  41. - integer (signed or unsigned)
  42. - IPv4 or IPv6 address
  43. - string
  44. - data block
  45.  
  46. Converters transform any of these data into any of these. For example, some
  47. converters might convert a string to a lower-case string while other ones
  48. would turn a string to an IPv4 address, or apply a netmask to an IP address.
  49. The resulting sample is of the type of the last converter applied to the list,
  50. which defaults to the type of the sample fetch method.
  51.  
  52. Each sample or converter returns data of a specific type, specified with its
  53. keyword in this documentation. When an ACL is declared using a standard sample
  54. fetch method, certain types automatically involved a default matching method
  55. which are summarized in the table below :
  56.  
  57. +---------------------+-----------------+
  58. | Sample or converter | Default |
  59. | output type | matching method |
  60. +---------------------+-----------------+
  61. | boolean | bool |
  62. +---------------------+-----------------+
  63. | integer | int |
  64. +---------------------+-----------------+
  65. | ip | ip |
  66. +---------------------+-----------------+
  67. | string | str |
  68. +---------------------+-----------------+
  69. | binary | none, use "-m" |
  70. +---------------------+-----------------+
  71.  
  72. Note that in order to match a binary samples, it is mandatory to specify a
  73. matching method, see below.
  74.  
  75. The ACL engine can match these types against patterns of the following types :
  76. - boolean
  77. - integer or integer range
  78. - IP address / network
  79. - string (exact, substring, suffix, prefix, subdir, domain)
  80. - regular expression
  81. - hex block
  82.  
  83. The following ACL flags are currently supported :
  84.  
  85. -i : ignore case during matching of all subsequent patterns.
  86. -f : load patterns from a file.
  87. -m : use a specific pattern matching method
  88. -n : forbid the DNS resolutions
  89. -M : load the file pointed by -f like a map file.
  90. -u : force the unique id of the ACL
  91. -- : force end of flags. Useful when a string looks like one of the flags.
  92.  
  93. The "-f" flag is followed by the name of a file from which all lines will be
  94. read as individual values. It is even possible to pass multiple "-f" arguments
  95. if the patterns are to be loaded from multiple files. Empty lines as well as
  96. lines beginning with a sharp ('#') will be ignored. All leading spaces and tabs
  97. will be stripped. If it is absolutely necessary to insert a valid pattern
  98. beginning with a sharp, just prefix it with a space so that it is not taken for
  99. a comment. Depending on the data type and match method, haproxy may load the
  100. lines into a binary tree, allowing very fast lookups. This is true for IPv4 and
  101. exact string matching. In this case, duplicates will automatically be removed.
  102.  
  103. The "-M" flag allows an ACL to use a map file. If this flag is set, the file is
  104. parsed as two column file. The first column contains the patterns used by the
  105. ACL, and the second column contain the samples. The sample can be used later by
  106. a map. This can be useful in some rare cases where an ACL would just be used to
  107. check for the existence of a pattern in a map before a mapping is applied.
  108.  
  109. The "-u" flag forces the unique id of the ACL. This unique id is used with the
  110. socket interface to identify ACL and dynamically change its values. Note that a
  111. file is always identified by its name even if an id is set.
  112.  
  113. Also, note that the "-i" flag applies to subsequent entries and not to entries
  114. loaded from files preceding it. For instance :
  115.  
  116. acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test
  117.  
  118. In this example, each line of "exact-ua.lst" will be exactly matched against
  119. the "user-agent" header of the request. Then each line of "generic-ua" will be
  120. case-insensitively matched. Then the word "test" will be insensitively matched
  121. as well.
  122.  
  123. The "-m" flag is used to select a specific pattern matching method on the input
  124. sample. All ACL-specific criteria imply a pattern matching method and generally
  125. do not need this flag. However, this flag is useful with generic sample fetch
  126. methods to describe how they're going to be matched against the patterns. This
  127. is required for sample fetches which return data type for which there is no
  128. obvious matching method (e.g. string or binary). When "-m" is specified and
  129. followed by a pattern matching method name, this method is used instead of the
  130. default one for the criterion. This makes it possible to match contents in ways
  131. that were not initially planned, or with sample fetch methods which return a
  132. string. The matching method also affects the way the patterns are parsed.
  133.  
  134. The "-n" flag forbids the dns resolutions. It is used with the load of ip files.
  135. By default, if the parser cannot parse ip address it considers that the parsed
  136. string is maybe a domain name and try dns resolution. The flag "-n" disable this
  137. resolution. It is useful for detecting malformed ip lists. Note that if the DNS
  138. server is not reachable, the haproxy configuration parsing may last many minutes
  139. waiting for the timeout. During this time no error messages are displayed. The
  140. flag "-n" disable this behavior. Note also that during the runtime, this
  141. function is disabled for the dynamic acl modifications.
  142.  
  143. There are some restrictions however. Not all methods can be used with all
  144. sample fetch methods. Also, if "-m" is used in conjunction with "-f", it must
  145. be placed first. The pattern matching method must be one of the following :
  146.  
  147. - "found" : only check if the requested sample could be found in the stream,
  148. but do not compare it against any pattern. It is recommended not
  149. to pass any pattern to avoid confusion. This matching method is
  150. particularly useful to detect presence of certain contents such
  151. as headers, cookies, etc... even if they are empty and without
  152. comparing them to anything nor counting them.
  153.  
  154. - "bool" : check the value as a boolean. It can only be applied to fetches
  155. which return a boolean or integer value, and takes no pattern.
  156. Value zero or false does not match, all other values do match.
  157.  
  158. - "int" : match the value as an integer. It can be used with integer and
  159. boolean samples. Boolean false is integer 0, true is integer 1.
  160.  
  161. - "ip" : match the value as an IPv4 or IPv6 address. It is compatible
  162. with IP address samples only, so it is implied and never needed.
  163.  
  164. - "bin" : match the contents against a hexadecimal string representing a
  165. binary sequence. This may be used with binary or string samples.
  166.  
  167. - "len" : match the sample's length as an integer. This may be used with
  168. binary or string samples.
  169.  
  170. - "str" : exact match : match the contents against a string. This may be
  171. used with binary or string samples.
  172.  
  173. - "sub" : substring match : check that the contents contain at least one of
  174. the provided string patterns. This may be used with binary or
  175. string samples.
  176.  
  177. - "reg" : regex match : match the contents against a list of regular
  178. expressions. This may be used with binary or string samples.
  179.  
  180. - "beg" : prefix match : check that the contents begin like the provided
  181. string patterns. This may be used with binary or string samples.
  182.  
  183. - "end" : suffix match : check that the contents end like the provided
  184. string patterns. This may be used with binary or string samples.
  185.  
  186. - "dir" : subdir match : check that a slash-delimited portion of the
  187. contents exactly matches one of the provided string patterns.
  188. This may be used with binary or string samples.
  189.  
  190. - "dom" : domain match : check that a dot-delimited portion of the contents
  191. exactly match one of the provided string patterns. This may be
  192. used with binary or string samples.
  193.  
  194. For example, to quickly detect the presence of cookie "JSESSIONID" in an HTTP
  195. request, it is possible to do :
  196.  
  197. acl jsess_present cook(JSESSIONID) -m found
  198.  
  199. In order to apply a regular expression on the 500 first bytes of data in the
  200. buffer, one would use the following acl :
  201.  
  202. acl script_tag payload(0,500) -m reg -i <script>
  203.  
  204. On systems where the regex library is much slower when using "-i", it is
  205. possible to convert the sample to lowercase before matching, like this :
  206.  
  207. acl script_tag payload(0,500),lower -m reg <script>
  208.  
  209. All ACL-specific criteria imply a default matching method. Most often, these
  210. criteria are composed by concatenating the name of the original sample fetch
  211. method and the matching method. For example, "hdr_beg" applies the "beg" match
  212. to samples retrieved using the "hdr" fetch method. Since all ACL-specific
  213. criteria rely on a sample fetch method, it is always possible instead to use
  214. the original sample fetch method and the explicit matching method using "-m".
  215.  
  216. If an alternate match is specified using "-m" on an ACL-specific criterion,
  217. the matching method is simply applied to the underlying sample fetch method.
  218. For example, all ACLs below are exact equivalent :
  219.  
  220. acl short_form hdr_beg(host) www.
  221. acl alternate1 hdr_beg(host) -m beg www.
  222. acl alternate2 hdr_dom(host) -m beg www.
  223. acl alternate3 hdr(host) -m beg www.
  224.  
  225.  
  226. The table below summarizes the compatibility matrix between sample or converter
  227. types and the pattern types to fetch against. It indicates for each compatible
  228. combination the name of the matching method to be used, surrounded with angle
  229. brackets ">" and "<" when the method is the default one and will work by
  230. default without "-m".
  231.  
  232. +-------------------------------------------------+
  233. | Input sample type |
  234. +----------------------+---------+---------+---------+---------+---------+
  235. | pattern type | boolean | integer | ip | string | binary |
  236. +----------------------+---------+---------+---------+---------+---------+
  237. | none (presence only) | found | found | found | found | found |
  238. +----------------------+---------+---------+---------+---------+---------+
  239. | none (boolean value) |> bool <| bool | | bool | |
  240. +----------------------+---------+---------+---------+---------+---------+
  241. | integer (value) | int |> int <| int | int | |
  242. +----------------------+---------+---------+---------+---------+---------+
  243. | integer (length) | len | len | len | len | len |
  244. +----------------------+---------+---------+---------+---------+---------+
  245. | IP address | | |> ip <| ip | ip |
  246. +----------------------+---------+---------+---------+---------+---------+
  247. | exact string | str | str | str |> str <| str |
  248. +----------------------+---------+---------+---------+---------+---------+
  249. | prefix | beg | beg | beg | beg | beg |
  250. +----------------------+---------+---------+---------+---------+---------+
  251. | suffix | end | end | end | end | end |
  252. +----------------------+---------+---------+---------+---------+---------+
  253. | substring | sub | sub | sub | sub | sub |
  254. +----------------------+---------+---------+---------+---------+---------+
  255. | subdir | dir | dir | dir | dir | dir |
  256. +----------------------+---------+---------+---------+---------+---------+
  257. | domain | dom | dom | dom | dom | dom |
  258. +----------------------+---------+---------+---------+---------+---------+
  259. | regex | reg | reg | reg | reg | reg |
  260. +----------------------+---------+---------+---------+---------+---------+
  261. | hex block | | | | bin | bin |
  262. +----------------------+---------+---------+---------+---------+---------+

7.1.1. Matching booleans

  1. In order to match a boolean, no value is needed and all values are ignored.
  2. Boolean matching is used by default for all fetch methods of type "boolean".
  3. When boolean matching is used, the fetched value is returned as-is, which means
  4. that a boolean "true" will always match and a boolean "false" will never match.
  5.  
  6. Boolean matching may also be enforced using "-m bool" on fetch methods which
  7. return an integer value. Then, integer value 0 is converted to the boolean
  8. "false" and all other values are converted to "true".

7.1.2. Matching integers

  1. Integer matching applies by default to integer fetch methods. It can also be
  2. enforced on boolean fetches using "-m int". In this case, "false" is converted
  3. to the integer 0, and "true" is converted to the integer 1.
  4.  
  5. Integer matching also supports integer ranges and operators. Note that integer
  6. matching only applies to positive values. A range is a value expressed with a
  7. lower and an upper bound separated with a colon, both of which may be omitted.
  8.  
  9. For instance, "1024:65535" is a valid range to represent a range of
  10. unprivileged ports, and "1024:" would also work. "0:1023" is a valid
  11. representation of privileged ports, and ":1023" would also work.
  12.  
  13. As a special case, some ACL functions support decimal numbers which are in fact
  14. two integers separated by a dot. This is used with some version checks for
  15. instance. All integer properties apply to those decimal numbers, including
  16. ranges and operators.
  17.  
  18. For an easier usage, comparison operators are also supported. Note that using
  19. operators with ranges does not make much sense and is strongly discouraged.
  20. Similarly, it does not make much sense to perform order comparisons with a set
  21. of values.
  22.  
  23. Available operators for integer matching are :
  24.  
  25. eq : true if the tested value equals at least one value
  26. ge : true if the tested value is greater than or equal to at least one value
  27. gt : true if the tested value is greater than at least one value
  28. le : true if the tested value is less than or equal to at least one value
  29. lt : true if the tested value is less than at least one value
  30.  
  31. For instance, the following ACL matches any negative Content-Length header :
  32.  
  33. acl negative-length hdr_val(content-length) lt 0
  34.  
  35. This one matches SSL versions between 3.0 and 3.1 (inclusive) :
  36.  
  37. acl sslv3 req_ssl_ver 3:3.1

7.1.3. Matching strings

  1. String matching applies to string or binary fetch methods, and exists in 6
  2. different forms :
  3.  
  4. - exact match (-m str) : the extracted string must exactly match the
  5. patterns;
  6.  
  7. - substring match (-m sub) : the patterns are looked up inside the
  8. extracted string, and the ACL matches if any of them is found inside;
  9.  
  10. - prefix match (-m beg) : the patterns are compared with the beginning of
  11. the extracted string, and the ACL matches if any of them matches.
  12.  
  13. - suffix match (-m end) : the patterns are compared with the end of the
  14. extracted string, and the ACL matches if any of them matches.
  15.  
  16. - subdir match (-m dir) : the patterns are looked up inside the extracted
  17. string, delimited with slashes ("/"), and the ACL matches if any of them
  18. matches.
  19.  
  20. - domain match (-m dom) : the patterns are looked up inside the extracted
  21. string, delimited with dots ("."), and the ACL matches if any of them
  22. matches.
  23.  
  24. String matching applies to verbatim strings as they are passed, with the
  25. exception of the backslash ("\") which makes it possible to escape some
  26. characters such as the space. If the "-i" flag is passed before the first
  27. string, then the matching will be performed ignoring the case. In order
  28. to match the string "-i", either set it second, or pass the "--" flag
  29. before the first string. Same applies of course to match the string "--".
  30.  
  31. Do not use string matches for binary fetches which might contain null bytes
  32. (0x00), as the comparison stops at the occurrence of the first null byte.
  33. Instead, convert the binary fetch to a hex string with the hex converter first.

Example:

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

7.1.4. Matching regular expressions (regexes)

  1. Just like with string matching, regex matching applies to verbatim strings as
  2. they are passed, with the exception of the backslash ("\") which makes it
  3. possible to escape some characters such as the space. If the "-i" flag is
  4. passed before the first regex, then the matching will be performed ignoring
  5. the case. In order to match the string "-i", either set it second, or pass
  6. the "--" flag before the first string. Same principle applies of course to
  7. match the string "--".

7.1.5. Matching arbitrary data blocks

  1. It is possible to match some extracted samples against a binary block which may
  2. not safely be represented as a string. For this, the patterns must be passed as
  3. a series of hexadecimal digits in an even number, when the match method is set
  4. to binary. Each sequence of two digits will represent a byte. The hexadecimal
  5. digits may be used upper or lower case.

Example :

  1. # match "Hello\n" in the input stream (\x48 \x65 \x6c \x6c \x6f \x0a)
  2. acl hello payload(0,6) -m bin 48656c6c6f0a

7.1.6. Matching IPv4 and IPv6 addresses

  1. IPv4 addresses values can be specified either as plain addresses or with a
  2. netmask appended, in which case the IPv4 address matches whenever it is
  3. within the network. Plain addresses may also be replaced with a resolvable
  4. host name, but this practice is generally discouraged as it makes it more
  5. difficult to read and debug configurations. If hostnames are used, you should
  6. at least ensure that they are present in /etc/hosts so that the configuration
  7. does not depend on any random DNS match at the moment the configuration is
  8. parsed.
  9.  
  10. The dotted IPv4 address notation is supported in both regular as well as the
  11. abbreviated form with all-0-octets omitted:
  12.  
  13. +------------------+------------------+------------------+
  14. | Example 1 | Example 2 | Example 3 |
  15. +------------------+------------------+------------------+
  16. | 192.168.0.1 | 10.0.0.12 | 127.0.0.1 |
  17. | 192.168.1 | 10.12 | 127.1 |
  18. | 192.168.0.1/22 | 10.0.0.12/8 | 127.0.0.1/8 |
  19. | 192.168.1/22 | 10.12/8 | 127.1/8 |
  20. +------------------+------------------+------------------+
  21.  
  22. Notice that this is different from RFC 4632 CIDR address notation in which
  23. 192.168.42/24 would be equivalent to 192.168.42.0/24.
  24.  
  25. IPv6 may be entered in their usual form, with or without a netmask appended.
  26. Only bit counts are accepted for IPv6 netmasks. In order to avoid any risk of
  27. trouble with randomly resolved IP addresses, host names are never allowed in
  28. IPv6 patterns.
  29.  
  30. HAProxy is also able to match IPv4 addresses with IPv6 addresses in the
  31. following situations :
  32. - tested address is IPv4, pattern address is IPv4, the match applies
  33. in IPv4 using the supplied mask if any.
  34. - tested address is IPv6, pattern address is IPv6, the match applies
  35. in IPv6 using the supplied mask if any.
  36. - tested address is IPv6, pattern address is IPv4, the match applies in IPv4
  37. using the pattern's mask if the IPv6 address matches with 2002:IPV4::,
  38. ::IPV4 or ::ffff:IPV4, otherwise it fails.
  39. - tested address is IPv4, pattern address is IPv6, the IPv4 address is first
  40. converted to IPv6 by prefixing ::ffff: in front of it, then the match is
  41. applied in IPv6 using the supplied IPv6 mask.