Understanding HAProxy ACL: Decoding “acl cdn_name hdr_beg(host) -i foo.bar.com” Configuration


5 views

In HAProxy configurations, ACLs (Access Control Lists) are powerful tools for making routing decisions. The line acl cdn_name hdr_beg(host) -i foo.bar.com consists of several important components:

acl       // Declares an ACL rule
cdn_name  // The name you'll reference later in your config
hdr_beg   // Matches the beginning of a header value
(host)    // Specifically checks the Host header
-i        // Makes the match case-insensitive
foo.bar.com // The value to match against

This ACL creates a condition named cdn_name that evaluates to true when:

  • The HTTP Host header begins with "foo.bar.com"
  • The match is case-insensitive (so FOO.bar.com would also match)

This is different from hdr(host) which would require an exact match, or hdr_end(host) which would match the end of the string.

Here's how you might use this ACL in a complete HAProxy configuration:

frontend http-in
    bind *:80
    acl cdn_provider hdr_beg(host) -i foo.bar.com
    use_backend cdn_servers if cdn_provider
    default_backend web_servers

backend cdn_servers
    server cdn1 10.0.0.1:80 check
    server cdn2 10.0.0.2:80 check

backend web_servers
    server web1 10.0.1.1:80 check
    server web2 10.0.1.2:80 check

You might encounter these similar patterns in real-world configurations:

# Match multiple domains
acl cdn_provider hdr_beg(host) -i foo.bar.com bar.foo.com

# Combine with other conditions
acl cdn_provider hdr_beg(host) -i foo.bar.com
acl secure_path path_beg /secure
use_backend cdn_servers if cdn_provider secure_path

If your ACL isn't working as expected:

  1. Check the HAProxy logs with tail -f /var/log/haproxy.log
  2. Enable debug mode temporarily: haproxy -d -f /etc/haproxy/haproxy.cfg
  3. Verify the exact Host header being sent using curl: curl -v http://foo.bar.com

When examining HAProxy configurations, ACLs (Access Control Lists) are among the most powerful yet potentially confusing elements. Let's dissect the specific configuration you encountered:

acl cdn_name hdr_beg(host) -i foo.bar.com

acl: The keyword indicating an Access Control List definition

cdn_name: The arbitrary name given to this ACL (used for reference later in the config)

hdr_beg(host): The matching function that checks the beginning of the Host header

-i: Case-insensitive matching flag

foo.bar.com: The string to match against

Your understanding is mostly correct. This ACL creates a logical condition named "cdn_name" that evaluates to TRUE when:

  1. The HTTP request contains a Host header
  2. The beginning of that Host header matches "foo.bar.com"
  3. The comparison is case-insensitive (due to -i flag)

This pattern is frequently used in CDN configurations to route traffic based on domain patterns. For example:

frontend http-in
    acl cdn_prod hdr_beg(host) -i cdn.example.com
    acl cdn_staging hdr_beg(host) -i staging-cdn.example.com
    
    use_backend cdn_prod_servers if cdn_prod
    use_backend cdn_staging_servers if cdn_staging

Other common Host header matching methods in HAProxy:

  • hdr(host) - Exact match
  • hdr_end(host) - Match end of host
  • hdr_dom(host) - Match domain part

To test your ACL matching:

frontend http-in
    acl test_acl hdr_beg(host) -i foo.bar.com
    http-request deny if test_acl

This will deny requests matching your pattern, making it immediately visible in logs whether the ACL is triggering as expected.

When dealing with many domain patterns, consider:

  • Using hdr_dom instead of hdr_beg when possible
  • Combining multiple conditions with logical operators
  • Placing more specific matches before general ones

Example of optimized ordering:

acl specific_match hdr(host) -i exact.example.com
acl general_match hdr_beg(host) -i example.com