Tag Archives: acl

7.1.1. Matching booleans



In order to match a boolean, no value is needed and all values are ignored.

Boolean matching is used by default for all fetch methods of type “boolean”.

When boolean matching is used, the fetched value is returned as-is, which means that a boolean “true” will always match and a boolean “false” will never match.

Boolean matching may also be enforced using “-m bool” on fetch methods which return an integer value. Then, integer value 0 is converted to the boolean “false” and all other values are converted to “true”.

Share Button

7.1.2. Matching integers



Integer matching applies by default to integer fetch methods. It can also be enforced on boolean fetches using “-m int”. In this case, “false” is converted to the integer 0, and “true” is converted to the integer 1.

Integer matching also supports integer ranges and operators. Note that integer matching only applies to positive values. A range is a value expressed with a lower and an upper bound separated with a colon, both of which may be omitted.

For instance, “1024:65535” is a valid range to represent a range of unprivileged ports, and “1024:” would also work. “0:1023” is a valid representation of privileged ports, and “:1023” would also work.

As a special case, some ACL functions support decimal numbers which are in fact two integers separated by a dot. This is used with some version checks for instance. All integer properties apply to those decimal numbers, including ranges and operators.

For an easier usage, comparison operators are also supported. Note that using operators with ranges does not make much sense and is strongly discouraged.

Similarly, it does not make much sense to perform order comparisons with a set of values.

Available operators for integer matching are :

  • 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

For instance, the following ACL matches any negative Content-Length header :

acl negative-length hdr_val(content-length) lt 0

This one matches SSL versions between 3.0 and 3.1 (inclusive) :

acl sslv3 req_ssl_ver 3:3.1
Share Button

7.1.3. String matching



String matching applies to string or binary fetch methods, and exists in 6 different forms :

  • exact match (-m str) : the extracted string must exactly match the patterns;
  • substring match (-m sub) : the patterns are looked up inside the extracted string, and the ACL matches if any of them is found inside
  • prefix match (-m beg) : the patterns are compared with the beginning of the extracted string, and the ACL matches if any of them matches.
  • suffix match (-m end) : the patterns are compared with the end of the extracted string, and the ACL matches if any of them matches.
  • subdir match (-m sub) : the patterns are looked up inside the extracted string, delimited with slashes (“/”), and the ACL matches if any of them matches.
  • domain match (-m dom) : the patterns are looked up inside the extracted string, delimited with dots (“.”), and the ACL matches if any of them matches.

String matching applies to verbatim strings as they are passed, with the exception of the backslash (“\”) which makes it possible to escape some characters such as the space. If the “-i” flag is passed before the first string, then the matching will be performed ignoring the case.
In order to match the string “-i”, either set it second, or pass the “–” flag before the first string. Same applies of course to match the string “–“.

Share Button

7.1.4. Matching regular expressions (regexes)



Just like with string matching, regex matching applies to verbatim strings as they are passed, with the exception of the backslash (“\”) which makes it possible to escape some characters such as the space.

If the “-i” flag is passed before the first regex, then the matching will be performed ignoring the case. In order to match the string “-i”, either set it second, or pass the “–” flag before the first string.

Same principle applies of course to match the string “–“.

Share Button

7.1.5. Matching arbitrary data blocks



It is possible to match some extracted samples against a binary data blocks which may not safely be represented as a string.
For this, the patterns must be passed as a series of hexadecimal digits in an even number, when the match method is set to binary. Each sequence of two digits will represent a byte.

The hexadecimal digits may be used upper or lower case.

Example :

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

7.1.6. Matching IPv4 and IPv6 addresses



IPv4 addresses values can be specified either as plain addresses or with a netmask appended, in which case the IPv4 address matches whenever it is within the network. Plain addresses may also be replaced with a resolvable host name, but this practice is generally discouraged as it makes it more difficult to read and debug configurations. If hostnames are used, you should at least ensure that they are present in /etc/hosts so that the configuration does not depend on any random DNS match at the moment the configuration is parsed.

IPv6 may be entered in their usual form, with or without a netmask appended.
Only bit counts are accepted for IPv6 netmasks. In order to avoid any risk of trouble with randomly resolved IP addresses, host names are never allowed in IPv6 patterns.

HAProxy is also able to match IPv4 addresses with IPv6 addresses in the following situations :

  • tested address is IPv4, pattern address is IPv4, the match applies in IPv4 using the supplied mask if any.
  • tested address is IPv6, pattern address is IPv6, the match applies in IPv6 using the supplied mask if any.
  • tested address is IPv6, pattern address is IPv4, the match applies in IPv4 using the pattern’s mask if the IPv6 address matches with 2002:IPV4::, ::IPV4 or ::ffff:IPV4, otherwise it fails.
  • tested address is IPv4, pattern address is IPv6, the IPv4 address is first converted to IPv6 by prefixing ::ffff: in front of it, then the match is applied in IPv6 using the supplied IPv6 mask.
Share Button

7.1. ACL basics



The use of Access Control Lists (ACL) provides a flexible solution to perform content switching and generally to take decisions based on content extracted from the request, the response or any environmental status. The principle is simple :

  • extract a data sample from a stream, table or the environment
  • optionally apply some format conversion to the extracted sample
  • apply one or multiple pattern matching methods on this sample
  • perform actions only when a pattern matches the sample

The actions generally consist in blocking a request, selecting a backend, or adding a header.

In order to define a test, the “acl” keyword is used. The syntax is :

acl   [flags] [operator] [] ...

This creates a new ACL or completes an existing one with new tests.
Those tests apply to the portion of request/response specified in and may be adjusted with optional flags [flags]. Some criteria also support an operator which may be specified before the set of values. Optionally some conversion operators may be applied to the sample, and they will be specified as a comma-delimited list of keywords just after the first keyword. The values are of the type supported by the criterion, and are separated by spaces.

ACL names must be formed from upper and lower case letters, digits, ‘-‘ (dash), ‘_’ (underscore) , ‘.’ (dot) and ‘:’ (colon). ACL names are case-sensitive, which means that “my_acl” and “My_Acl” are two different ACLs.

There is no enforced limit to the number of ACLs. The unused ones do not affect performance, they just consume a small amount of memory.
The criterion generally is the name of a sample fetch method, or one of its ACL specific declinations. The default test method is implied by the output type of this sample fetch method. The ACL declinations can describe alternate matching methods of a same sample fetch method. The sample fetch methods are the only ones supporting a conversion.

Sample fetch methods return data which can be of the following types :

  • boolean
  • integer (signed or unsigned)
  • IPv4 or IPv6 address
  • string
  • data block

Converters transform any of these data into any of these. For example, some converters might convert a string to a lower-case string while other ones would turn a string to an IPv4 address, or apply a netmask to an IP address.
The resulting sample is of the type of the last converter applied to the list, which defaults to the type of the sample fetch method.

Each sample or converter returns data of a specific type, specified with its keyword in this documentation. When an ACL is declared using a standard sample fetch method, certain types automatically involved a default matching method which are summarized in the table below :

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

Note that in order to match a binary samples, it is mandatory to specify a matching method, see below.

The ACL engine can match these types against patterns of the following types :

  • boolean
  • integer or integer range
  • IP address / network
  • string (exact, substring, suffix, prefix, subdir, domain)
  • regular expression
  • hex block

The following ACL flags are currently supported :

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

The “-f” flag is followed by the name of a file from which all lines will be read as individual values. It is even possible to pass multiple “-f” arguments if the patterns are to be loaded from multiple files.
Empty lines as well as lines beginning with a sharp (‘#’) will be ignored. All leading spaces and tabs will be stripped. If it is absolutely necessary to insert a valid pattern beginning with a sharp, just prefix it with a space so that it is not taken for a comment.
Depending on the data type and match method, haproxy may load the lines into a binary tree, allowing very fast lookups. This is true for IPv4 and exact string matching. In this case, duplicates will automatically be removed.

The “-M” flag allows an ACL to use a map file. If this flag is set, the file is parsed as two column file. The first column contains the patterns used by the ACL, and the second column contain the samples. The sample can be used later by a map. This can be useful in some rare cases where an ACL would just be used to check for the existence of a pattern in a map before a mapping is applied.

The “-u” flag forces the unique id of the ACL. This unique id is used with the socket interface to identify ACL and dynamically change its values. Note that a file is always identified by its name even if an id is set.

Also, note that the “-i” flag applies to subsequent entries and not to entries loaded from files preceding it. For instance :

    acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test

In this example, each line of “exact-ua.lst” will be exactly matched against the “user-agent” header of the request. Then each line of “generic-ua” will be case-insensitively matched. Then the word “test” will be insensitively matched as well.

The “-m” flag is used to select a specific pattern matching method on the input sample. All ACL-specific criteria imply a pattern matching method and generally do not need this flag. However, this flag is useful with generic sample fetch methods to describe how they’re going to be matched against the patterns. This is required for sample fetches which return data type for which there is no obvious matching method (eg: string or binary). When “-m” is specified and followed by a pattern matching method name, this method is used instead of the default one for the criterion. This makes it possible to match contents in ways that were not initially planned, or with sample fetch methods which return a string. The matching method also affects the way the patterns are parsed.

The “-n” flag forbids the dns resolutions. It is used with the load of ip files. By default, if the parser cannot parse ip address it considers that the parsed string is maybe a domain name and try dns resolution. The flag “-n” disable this resolution. It is useful for detecting malformed ip lists. Note that if the DNS server is not reachable, the haproxy configuration parsing may last many minutes waiting fir the timeout. During this time no error messages are displayed. The flag “-n” disable this behavior. Note also that during the runtime, this function is disabled for the dynamic acl modifications.

There are some restrictions however. Not all methods can be used with all sample fetch methods. Also, if “-m” is used in conjunction with “-f”, it must be placed first. The pattern matching method must be one of the following :

  • found” : only check if the requested sample could be found in the stream, but do not compare it against any pattern. It is recommended not to pass any pattern to avoid confusion. This matching method is particularly useful to detect presence of certain contents such as headers, cookies, etc… even if they are empty and without comparing them to anything nor counting them.
  • bool” : check the value as a boolean. It can only be applied to fetches which return a boolean or integer value, and takes no pattern. Value zero or false does not match, all other values do match.
  • int” : match the value as an integer. It can be used with integer and boolean samples. Boolean false is integer 0, true is integer 1.
  • ip” : match the value as an IPv4 or IPv6 address. It is compatible with IP address samples only, so it is implied and never needed.
  • bin” : match the contents against an hexadecimal string representing a binary sequence. This may be used with binary or string samples.
  • len” : match the sample’s length as an integer. This may be used with binary or string samples
  • str” : exact match : match the contents against a string. This may be used with binary or string samples.
  • sub” : substring match : check that the contents contain at least one of the provided string patterns. This may be used with binary or string samples.
  • reg” : regex match : match the contents against a list of regular expressions. This may be used with binary or string samples.
  • beg” : prefix match : check that the contents begin like the provided string patterns. This may be used with binary or string samples.
  • end” : suffix match : check that the contents end like the provided string patterns. This may be used with binary or string samples.
  • dir” : subdir match : check that a slash-delimited portion of the contents exactly matches one of the provided string patterns. This may be used with binary or string samples.
  • dom” : domain match : check that a dot-delimited portion of the contents exactly match one of the provided string patterns. This may be used with binary or string samples.

For example, to quickly detect the presence of cookie “JSESSIONID” in an HTTP request, it is possible to do :

    acl jsess_present cook(JSESSIONID) -m found

In order to apply a regular expression on the 500 first bytes of data in the buffer, one would use the following acl :

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

On systems where the regex library is much slower when using “-i”, it is possible to convert the sample to lowercase before matching, like this :

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

All ACL-specific criteria imply a default matching method. Most often, these criteria are composed by concatenating the name of the original sample fetch method and the matching method. For example, “hdr_beg” applies the “beg” match to samples retrieved using the “hdr” fetch method. Since all ACL-specific criteria rely on a sample fetch method, it is always possible instead to use the original sample fetch method and the explicit matching method using “-m”.

If an alternate match is specified using “-m” on an ACL-specific criterion, the matching method is simply applied to the underlying sample fetch method.
For example, all ACLs below are exact equivalent :

    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.

The table below summarizes the compatibility matrix between sample or converter types and the pattern types to fetch against. It indicates for each compatible combination the name of the matching method to be used, surrounded with angle brackets “>” and “<" when the method is the default one and will work by default without "-m". [table width=70%] | pattern type | | Input | sample |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 | [/table]

Share Button

7.2. Using ACLs to form conditions



Some actions are only performed upon a valid condition. A condition is a combination of ACLs with operators. 3 operators are supported :

– AND (implicit)
– OR (explicit with the “or” keyword or the “||” operator)
– Negation with the exclamation mark (“!”)

A condition is formed as a disjunctive form:

 [!]acl1 [!]acl2 ... [!]acln  { or [!]acl1 [!]acl2 ... [!]acln } ...

Such conditions are generally used after an “if” or “unless” statement, indicating when the condition will trigger the action.

For instance, to block HTTP requests to the “*” URL with methods other than “OPTIONS”, as well as POST requests without content-length, and GET or HEAD requests with a content-length greater than 0, and finally every request which is not either GET/HEAD/POST/OPTIONS !

   acl missing_cl hdr_cnt(Content-length) eq 0
   block if HTTP_URL_STAR !METH_OPTIONS || METH_POST missing_cl
   block if METH_GET HTTP_CONTENT
   block unless METH_GET or METH_POST or METH_OPTIONS

To select a different backend for requests to static contents on the “www” site and to every request on the “img”, “video”, “download” and “ftp” hosts :

   acl url_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

It is also possible to form rules using “anonymous ACLs”. Those are unnamed ACL expressions that are built on the fly without needing to be declared. They must be enclosed between braces, with a space before and after each brace (because the braces must be seen as independent words). Example :

The following rule :

acl missing_cl hdr_cnt(Content-length) eq 0
       block if METH_POST missing_cl

Can also be written that way :

block if METH_POST { hdr_cnt(Content-length) eq 0 }

It is generally not recommended to use this construct because it’s a lot easier to leave errors in the configuration when written that way. However, for very simple rules matching only one source IP address for instance, it can make more sense to use them than to declare ACLs with random names. Another example of good use is the following :

With named ACLs :

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

With anonymous ACLs :

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

See section 4.2 for detailed help on the “block” and “use_backend” keywords.

Share Button

7. Using ACLs and fetching samples



Haproxy is capable of extracting data from request or response streams, from client or server information, from tables, environmental information etc…

The action of extracting such data is called fetching a sample. Once retrieved, these samples may be used for various purposes such as a key to a stick-table, but most common usages consist in matching them against predefined constant data called patterns.

Share Button

7.4. Pre-defined ACLs



Some pre-defined ACLs are hard-coded so that they do not have to be declared in every frontend which needs them. They all have their names in upper case in order to avoid confusion. Their equivalence is provided below.

ACL name Equivalent to Usage
FALSE always_false never match
HTTP req_proto_http match if protocol is valid HTTP
HTTP_1.0 req_ver 1.0 match HTTP version 1.0
HTTP_1.1 req_ver 1.1 match HTTP version 1.1
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme
HTTP_URL_SLASH url_beg / match URL beginning with "/"
HTTP_URL_STAR url * match URL equal to "*"
LOCALHOST src 127.0.0.1/8 match connection from local host
METH_CONNECT method CONNECT match HTTP CONNECT method
METH_GET method GET HEAD match HTTP GET or HEAD method
METH_HEAD method HEAD match HTTP HEAD method
METH_OPTIONS method OPTIONS match HTTP OPTIONS method
METH_POST method POST match HTTP POST method
METH_TRACE method TRACE match HTTP TRACE method
RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie
REQ_CONTENT req_len gt 0 match data in the request buffer
TRUE always_true always match
WAIT_END wait_end wait for end of content analysis
Share Button