Searching HAProxy Enterprise 1.6r2
Setting Up Access Control Lists (ACLs)
Setting Up Access Control Lists (ACLs)
The purpose in using Access Control Lists (ACL) is to provide a flexible solution to make decisions based on content extracted from the request, the response, or any environmental status.
Its principle is the following:
Extract a data sample from a stream, table, or the environment
Apply optionally some format conversion to the extracted sample
Apply one or multiple pattern matching methods on this sample
ACL Syntax
ACLs are defined using the keyword acl
. The syntax is:
# Used in the a frontend, listen, or backend section
acl <aclname> <criterion>[,<converter>] [flags] [operator] [<pattern>] ...
ACLs require the following parameters:
Parameter | Description |
---|---|
| Name of the ACL to describe it as much as possible. It must have upper and lower case letters, digits, It is case sensitive; hence my_acl and My_Acl are two different ACLs. |
| Based on sample fetches, it describes the portion of the request or response where this ACL applies. |
| One or several |
| Completes the |
| It is possible to apply an |
| Data provided by It is as the same type as the data provided by the Matching results will define the result of the whole ACL. |
An ACL can return two values:
Value | Description |
---|---|
| when the data from |
| when the data from |
ACL Rules
For ACLs sharing the same name, the following rules apply:
It is possible to use the same <aclname> for many ACLs, even if they do not have the same matching criterion
A logical OR applies between all of them
ACL Criterion
The criterion is generally the name of a sample fetch method, or one of the Sample fetch ACL derivatives declinations.
Note
The sample fetch methods are the only ones that support a conversion.
The ACL declinations can describe alternate matching methods for a same sample fetch method.
As a reminder, sample fetch methods can return the following data types:
boolean
integer (signed or unsigned)
IPv4 or IPv6 address
string
binary data block
Criterion converters
Converters transform any supported data type any other data type.
The resulting sample's type is the same as the type of the last converter applied to the list, which defaults to the type of the sample fetch method.
Sample fetch ACL derivatives
All ACL-specific criteria imply a default matching method. Most often, these criteria are built by concatenating the name of the original sample fetch method and the matching method.
For example, hdr_beg applies the beg match to the sample retrieved using the hdr fetch.
Since all ACL-specific criteria rely on a sample fetch method, you can use the original sample fetch method and the explicit matching method with -m.
If an alternate match is specified using -m
on an ACL-specific criterion, the matching method is applied to the underlying sample fetch method.
For example, all ACLs below are exactly equivalent:
# Used in the a frontend, listen, or backend section
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 presents ACL derivatives from their respective sample fetch:
Sample fetch | Derivative ACLs | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
| ||||||||||||||||
|
|
ACL Flags
ACLs support the following flags:
Flag | Description |
---|---|
| ignores case during matching of all subsequent patterns |
| loads patterns from |
| uses a specific pattern matching method |
| forbids DNS resolution |
| loads the file pointed by |
| forces the ACL unique id |
| forces end of flags. Useful when a pattern looks like one of the flags. |
acl -f flag
Note
If you use -m
in conjunction with -f
, you must place it first.
The -f
flag must be followed by the name of a file from which all lines will be read as individual pattern. It is possible to pass multiple -f
arguments if the patterns must be loaded from multiple files.
The following actions happen when HAProxy loads an ACL pattern list from a file:
Empty lines are ignored
Lines starting with a sharp (
#
) are ignoredAll leading spaces and tabs are stripped
Note
If it is absolutely necessary to insert a valid pattern that begins with a sharp character, you can prefix it with a space character so it is not read as a comment.
acl -M flag
The -M
flag allows an ACL to use a map file. With this flag set, the file is parsed as a two column file:
The first column contains the patterns used by the ACL, and the second column contain the samples. The samples can be used later by a map. This can be useful in some cases where an ACL would be used to check for a pattern in a map before it applies mapping.
acl -u flag
The -u
flag forces the unique ID of the ACL.
This unique ID is used with the stats socket interface to identify an ACL and dynamically change its values.
Note
An ACL that uses a file is always identified by its file name even if an ID is set.
acl -m flag
Note
If you use -m
in conjunction with -f
, you must place it first.
The -m
flag is used to select a specific matching method on the input sample.
All ACL-specific criteria imply a matching method and generally do not need this flag. However, this flag is useful with generic sample fetch methods to describe how they get matched against the patterns.
This is required for sample fetches which return data type for which there is no obvious matching method (e.g. string or binary).
When -m
is specified and followed by a 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.
Note
There are some restrictions. Not all methods can be used with all sample fetch methods.
The matching <methods>
must be one of the following:
Code | Description |
---|---|
| Only checks if the requested sample could be found in the stream, but does not compare it against any pattern. It is recommended not to pass any pattern to avoid confusion. This matching method is useful to detect the presence of certain contents such as headers, cookies, etc. even if they are empty, without comparing or counting them. |
| Checks the sample as a boolean. This method only applies to fetches which return a boolean or integer value, and takes no pattern. Value zero or false does not match, all other values match. |
| Matches the sample as an integer. Can apply to integer and boolean samples. Boolean false is integer 0, true is integer 1. |
| Matches the sample as an IPv4 or IPv6 address. It is compatible with IP address sample only. |
| Matches the sample against an hexadecimal string representing a binary sequence. Can apply to binary or string samples. |
| Matches the sample's length as an integer. Can apply to binary or string samples. |
| Exact string match. can apply to binary or string samples. |
| Substring match: checks that the sample contains at least one of the provided string patterns. Can apply to binary or string samples. |
| Regex match: matches the sample against a list of regular expressions. This may be used with binary or string samples. |
| Prefix match: checks that the sample begins like any of the provided pattern. Can apply to binary or string samples. |
| Suffix match: checks that the sample finishes like any of the provided pattern. Can apply to binary or string samples. |
| Subdir match: checks that a slash-delimited portion of the sample exactly matches one of the provided patterns. Can apply to binary or string samples. |
| Domain match: checks that a dot-delimited portion of the sample exactly matches one of the provided pattern. Can apply to binary or string samples. |
acl -n flag
The -n
flag forbids DNS resolutions. It is used when loading IPs from a file. By default, when the parser can not parse an IP address, it considers that the parsed string is a domain name and tries to resolve it using DNS.
If the DNS server is not reachable, the HAProxy configuration parsing can take several minutes waiting for DNS timeouts. During this time, it does not display error messages.
Data types and matching between samples and patterns
The default test method is implied by the output data type of this sample fetch method.
Each sample fetch or converter returns a specific data type, specified with its keyword.
When an ACL is declared using a standard sample fetch method, certain types automatically default to a 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 |
Note
In order to match a binary sample, 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 table below summarizes the compatibility matrix between pattern and samples or converter . It indicates the name of the matching method to use for each compatible combination.
The method in bold is the default and works without any -m flag.
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 |
Matching booleans
Boolean matching applies by default to boolean fetch methods or converters.
In order to match a Boolean, no pattern is required and all patterns are ignored. When using Boolean matching, the criterion returns the sample as is (hence the fetch), which means that a Boolean true will always match and a Boolean false will never match.
You can enforce Boolean matching by using the flag -m
bool on fetch method returning an integer type. In such cases, 0 is converted to a Boolean false
and all other values are converted to Boolean true
.
Matching integers
Note
Integer matching only applies to positive values.
Integer matching applies by default to integer fetch methods or converters.
You can also enforce it on boolean fetches using the flag -m
int. In such cases, false
is converted to the integer 0, and true
is converted to the integer 1.
Integer matching also supports integer ranges and operators.
Note
Using operators with ranges is not recommended.
Integer ranges
A range is a value expressed with a lower and an upper bound separated by a colon, which can both be omitted.
When one of the bound is omitted, it means than the range has either no start or no end. Basically, it means you want to match anything higher than or anything lower than the specified lower or upper bound specified.
1024:65535 or 1024: is a valid range to represent a range of unprivileged ports.
0:1023 or:1023 is a valid representation of privileged ports.
Integer operators
For easier use, comparison operators are also supported.
Available operators for integer matching are:
Operator | Description |
---|---|
|
|
|
|
|
|
|
|
|
|
Decimal numbers
As a special case, some ACL functions support decimal numbers, which are two integers separated by a period. For example, this is used with version checks.
All integer properties apply to decimal numbers, including ranges and operators.
Matching strings
By default, string matching applies to string or binary fetch methods or converters, and exists in 6 formats.
They use the -m
flag:
Parameter | Description |
---|---|
exact match | The sample string must match exactly any of the patterns |
substring match | The patterns are looked up inside the sample string, and the ACL makes a match if any is found. |
prefix match | The patterns are compared with the beginning of the sample string, and the ACL makes a match if any is found. |
suffix match | The patterns are compared with the end of the sample string, and the ACL makes a match if any is found. |
subdir match | The patterns are looked up inside the sample string, delimited with slashes ( |
domain match | The patterns are looked up inside the sample string, delimited with periods ( |
String matching applies to verbatim strings as they are passed, with the exception of the backslash (\). This enables you to avoid characters such as the space.
When the flag -i
is passed before the first string, then the matching performed is not case-sensitive.
To match the pattern -i
, you can either set it after, or pass the specific flag --
before the first pattern. The same applies to match the pattern -
.
Matching regular expressions
Regex matching applies to verbatim samples as they are passed, with the exception of the backslash (\). This enables you to avoid characters such as the space.
When the flag -i
is passed before the first regex, then the matching performed is not case-sensitive.
To match the pattern -i
, you can either set it after, or pass the specific flag --
before the first pattern. The same applies to match the pattern -
.
Matching arbitrary data blocks
It is possible to match samples against a binary block which may not be safely represented as a string. For this, the patterns must be passed as a series of hexadecimal digits in an even number.
This works when the match method is set to binary. Each sequence of two digits represents a byte. The hexadecimal digits can either be in upper or lower case.
Matching IPv4 and IPv6 addresses
You can specify a pattern of IPv4 addresses either as plain addresses or with an appended netmask, in which case the IPv4 address matches whenever it is within the network.
You can also replace plain addresses with a resolvable host name using DNS, but this practice is generally not recommended as it makes it more difficult to read and debug configurations.
If you use host names, 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.
You can enter IPv6 addresses in their usual form, with or without an appended netmask . Only bit counts are accepted for IPv6 netmasks.
To avoid any risk of problems with randomly resolved IP addresses, host names are never allowed for IPv6 patterns.
HAProxy can also match IPv4 addresses with IPv6 addresses in the following situations:
Sample address family | Pattern address family | Match |
---|---|---|
IPv4 | IPv4 | IPv4 using the supplied mask. |
IPv6 | IPv6 | IPv6 using the supplied mask. |
IPv6 | IPv4 | IPv4 using the pattern's mask if the IPv6 address matches with 2002:IPV4::, ::IPV4 or ::ffff:IPV4; otherwise it fails. |
IPv4 | IPv6 | IPv4 is first converted to IPv6 by prefixing it with ::ffff: Then the match is applied in IPv6 using the supplied IPv6 mask. |
Predefined ACLs
Certain predefined ACLs are hard-coded in HAProxy, so they don't need to be declared in every section that requires them. Their names are in upper case to avoid confusion.
Below is the list of predefined ACLs with their equivalence:
ACL name | Equivalent to | Usage |
---|---|---|
|
| Never match |
|
| Match if protocol is valid HTTP |
|
| Match HTTP version 1.0 |
|
| Match HTTP version 1.1 |
|
| Match an existing content-length |
|
| Match absolute URL with scheme |
|
| Match URL beginning with |
|
| Match URL equal to |
|
| Match connection from local host |
|
| Match HTTP CONNECT method |
|
| Match HTTP GET or HEAD method |
|
| Match HTTP HEAD method |
|
| Match HTTP OPTIONS method |
|
| Match HTTP POST method |
|
| Match HTTP TRACE method |
|
| Match presence of an RDP cookie |
|
| Match data in the request buffer |
|
| Always match |
|
| Wait for end of content analysis |
ACL Examples
To detect quickly the presence of a cookie JSESSIONID in an HTTP request:
# Used in the a frontend, listen, or backend section
acl jsess_present req.cook(JSESSIONID) -m found
Apply a regular expression over the first 500 bytes of data in the request buffer:
# Used in the a frontend, listen, or backend section
acl script_tag req.payload(0,500) -m reg -i <script>
Apply both case-sensitive and non-case-sensitve matches, using the 'i flag:
# Used in the a frontend, listen, or backend section
acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test
The following happens:
each line of
exact-ua.lst
is matched exactly against the user-agent header of the request.each line of
generic-ua.lst
is matched without case-sensitivity.the word test is also matched without case-sensitivity.
Match any negative Content-Length header:
# Used in the a frontend, listen, or backend section
acl negative-length hdr_val(content-length) lt 0
Match any SSL version between 3.0 and 3.1 (inclusive):
# Used in the a frontend, listen, or backend section
acl sslv3 req_ssl_ver 3:3.1
Look for the string -i in the User-Agent header:
# Used in the a frontend, listen, or backend section
acl hdr_sub -- -i
Match the string Hello at the beginning of the input stream (Hexa values: x48 x65 x6c x6c x6f x0a):
# Used in the a frontend, listen, or backend section
acl hello payload(0,6) -m bin 48656c6c6f0a
Convert the X-Forwarded-For header into IP addresses and match for private IPs:
# Used in the a frontend, listen, or backend section
acl req.fhdr(X-Forwarded-For) -m ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
Match static content either in the Host header or in the URL path:
# Used in the a frontend, listen, or backend section
acl static hdr_dom(Host) -i static.domain.com assets.domain.com
acl static path_beg -i /static/ /images/ /css/