Syntax
An ACL is split into four parts:
a name for the ACL, which you choose
a fetch to collect information from the client's session
optional flags
a value to match against
In the example below, we mark these parts:
frontend www
bind :80
# name fetch flags value
acl image_url path -i -m beg /images/
Fetches
An ACL compares a value with a result from a fetch method. See Fetches to learn more about fetch methods.
The fetch part of an ACL returns a value of a certain data type. For example, the path
fetch returns a string, which you match against an expected string value. In the previous example, we attempted to match the path
fetch against the string /images/.
The data types are:
Boolean
Integer (signed or unsigned)
IPv4 or IPv6 address
String
Binary data block
Here are examples of ACLs that use fetches of various data types:
frontend www
bind :80
# Boolean. Did the connection arrive over SSL?
# Note that boolean expressions do not include an explicit value to match against.
acl ssl_was_used ssl_fc
# Integer. Is the destination port 8080?
acl is_8080 dst_port 8080
# IP address. Is the destination IP address localhost (i.e. 127.0.0.1)?
acl localhost dst 127.0.0.1
# Binary. Does the request body contain the substring 'PING'?
# For binary fetches, you must set a match type.
acl contains_ping req.body -m sub PING
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; it is useful when a pattern looks like one of the flags. |
-f Flag
The -f
flag loads a file that contains values to match against. It must be followed by the name of a file from which HAProxy Enterprise reads all lines as individual patterns. It's possible to pass multiple -f
arguments if the patterns come from multiple files.
Example file patterns.txt:
/images/
/photos/
HAProxy Enterprise configuration:
frontend www
bind :80
acl images_url path -i -m beg -f /etc/hapee-1.9/patterns.txt
Things to know
Empty lines are ignored.
Lines starting with a sharp (
#
) are ignored.All leading spaces and tabs are stripped.
If you use
-f
in conjunction with-m
, the-m
must come first.
-M flag
The -M
flag allows an ACL to load a map file. A map file contains two columns. The first column is a key and the second is an associated value. An ACL line reads only the first column; but you can use the second column later, such as by the map
converter on an http-request
line.
Example file redirects.map:
www.test.com www.test.com
docs.test.com www.test.com/docs
blog.test.com www.test.com/blog
The ACL only considers the first column, in the same way as the -f
flag with a single-column file. However, the http-request redirect
line that follows finds the matching Host header from the key column, and fills in the redirect URL from the value column:
frontend www
bind :80
# Does the Host header match a key in the map file?
acl requires_redirect req.hdr(Host) -i -M -f /etc/hapee-1.9/redirects.map
# Use the correct redirect URL based on the Host header
http-request redirect prefix https://%[req.hdr(Host),lower,map(/etc/hapee-1.9/redirects.map)] code 301 if requires_redirect
-u Flag
The -u
flag lets you set the unique ID for the ACL. Then, when you use the Runtime API command show acl
, it displays a unique ID next to the ACL you've defined:
$ echo "show acl" | socat tcp-connect:127.0.0.1:9024
# id (file) description
0 () acl 'ssl_fc' file '/etc/hapee-1.9/hapee-lb.cfg' line 45
1 () acl 'dst_port' file '/etc/hapee-1.9/hapee-lb.cfg' line 48
2 () acl 'dst' file '/etc/hapee-1.9/hapee-lb.cfg' line 51
3 () acl 'req.body' file '/etc/hapee-1.9/hapee-lb.cfg' line 55
4 () acl 'path' file '/etc/hapee-1.9/hapee-lb.cfg' line 6
You can use other Runtime API commands, such as get acl
, to test a particular value against an ACL, which you reference by its unique ID:
$ echo "get acl #4 /images/" | socat tcp-connect:127.0.0.1:9024 -
type=str, case=sensitive, match=yes, idx=tree, pattern="/images/"
$ echo "get acl #4 /test/" | socat tcp-connect:127.0.0.1:9024 -
type=str, case=sensitive, match=no
By default, HAProxy Enterprise controls the unique ID for each ACL. However, you can use the -u
flag to set it yourself:
frontend www bind :80 acl image_url path_beg
-i -u 50 /images/
-m Flag
The -m
flag sets a specific match type to use when comparing against the input sample.
All fetches imply a matching type and generally do not need this flag. However, it is useful with generic fetches to make the match type explicit or to override the default match type.
Things to know
If you use
-f
in conjunction with-m
, the-m
must come first.Not all match types can work with all sample fetch methods.
The match type must be one of the following:
Code | Description |
---|---|
| Only checks for the existence of the requested sample in the stream. For example, use this to check whether a URL parameter exists, without concern for its value. |
| Matches the sample as a Boolean. This method only applies to fetches that return a boolean or integer value. Value zero or false does not match, all other values match. |
| Matches the sample as an integer. It 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 samples only. |
| Matches the sample against a hexadecimal string representing a binary sequence. It can apply to binary or string samples. |
| Matches the sample's length as an integer. It can apply to binary or string samples. |
| Exact string match. It can apply to binary or string samples. |
| Substring match: checks that the sample contains at least one of the provided string patterns. It can apply to binary or string samples. |
| Regex match: matches the sample against a list of regular expressions. This can work with binary or string samples. |
| Prefix match: checks that the sample begins like any of the provided patterns. It can apply to binary or string samples. |
| Suffix match: checks that the sample finishes like any of the provided patterns. It 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. It can apply to binary or string samples. |
| Domain match: checks that a dot-delimited portion of the sample exactly matches one of the provided patterns. It can apply to binary or string samples. |
-n Flag
The -n
flag forbids DNS resolutions when loading IP addresses 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 Enterprise configuration parsing can take several minutes to wait for DNS timeouts. During this time, it does not display error messages. Therefore, this flag avoids this scenario entirely.
Example
An IP address file, safelist.txt, contains a gibberish domain name:
192.168.0.10 ssdfasdfasddfasdfa.com
HAProxy Enterprise configuration:
frontend www bind :80 acl safe_ip src -n -f
/etc/hapee-1.9/safelist.txttcp-request content reject unless safe_ip
When reloading HAProxy, the following error displays:
error detected while parsing ACL 'safe_ip' : 'ssdfasdfasddfasdfa.com' is not a valid IPv4 or IPv6 address at line 2
Special matching
Some expressions go beyond the simple matching rules described so far. For example, you can try to match a range of integers or a range of IP addresses.
Match integer ranges
Express a range of integers as a lower and an upper bound separated by a colon:
frontend www
bind :80
# Is the response status from the server between 500 and 511?
acl response_5xx status 500:511
When one of the bounds is missing, it indicates that the range has either no start or no end. It means you want to match anything higher than or anything lower than the specified lower or upper bound.
frontend www
bind *:80
# Is port 1024 or higher?
acl high_port dst_port 1024:
# Is port 1023 or lower?
acl low_port dst_port :1023
Match integer operators
Use operators to compare two integers.
frontend www
bind :80
# Is the HTTP response body greater than 10000 bytes?
acl 10kb_response res.body_len gt 10000
Available operators for integer matching are:
Operator | Description |
---|---|
|
|
|
|
|
|
|
|
|
|
Match decimal numbers
As a special case, some ACL functions support decimal numbers, which are two integers separated by a period. In the example below, the two ACLS, tlsv1 and ssl3_or_tls1 call the req.ssl_ver
fetch method, which returns a decimal number that indicates the version of SSL/TLS used. We then compare that value with a literal value 3.1 and the range 3:3.1:
frontend www bind :80 # Match TLV v1.0 acl tlsv1 req.ssl_ver 3.1 # Match SSL 3.0 or TLS 1.0 acl ssl3_or_tls1 req.ssl_ver 3:3.1
All integer properties apply to decimal numbers, including ranges and operators.
Match strings
String matching applies to string or binary fetch methods or converters. It and can be categorized into six match types. Use the -m
flag to indicate the match type:
Parameter | Description |
---|---|
Exact match | Matches the string exactly. |
Substring match | Matches a portion of the string. |
Prefix match | Matches the beginning of the string. |
Suffix match | Matches the end of the string. |
Subdir match | Matches part of a URL or file path, delimited with slashes ( |
Domain match | Matches part of a domain, delimited with periods ( |
Things to know
String matching applies to verbatim strings as they pass, with the exception of the backslash (\). This enables you to avoid characters such as the space.
When the flag
-i
passes before the first string, the matching 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-
.
Match regular expressions
Use the -m reg
match type to compare a fetch method's value with a regular expression. You can escape backslashes by prefixing them with another backslash \\
.
frontend www bind :80 # Path contains cat, caat, caaat, etc. acl contains_cat path
-m reg ca+t
Things to know
When the flag
-i
is passed before the first regex, the matching is not case-sensitive.To match the literal
-i
, you can either set it after, or pass the specific flag--
before the first pattern. The same applies to match the pattern-
.
Match arbitrary data blocks
It is possible to match samples against a binary block when you cannot safely represent it as a string. To do this, the patterns must be passed as a series of hexadecimal digits in an even number. Set the match type to bin
. Each sequence of two digits represents a byte. The hexadecimal digits can be in either upper or lowercase.
# Match the string Hello at the beginning of the input stream # (Hexadecimal values: x48 x65 x6c x6c x6f x0a) acl hello payload(0,6) -m bin 48656c6c6f0a
Match IPv4 and IPv6 addresses
You can match against IPv4 addresses with or without an appended netmask. When you use a netmask, the IPv4 address matches whenever it is within the network.
You can enter IPv6 addresses in their usual form with or without an appended netmask. Only bit counts are accepted for IPv6 netmasks.
frontend www
bind :80
# Is the client's IP address localhost?
acl is_localhost src 127.0.0.1
# Is the client's IP address in the IPv4 range?
acl allowed_ipv4 src 192.168.0.0/16
# Is the client's IP address in the given IPv6 range?
acl allowed_ipv6 src 2001:db8::/48
Next up
Inline ACLs